From a96bc2f28af0ef84dc00fe8280daf58c55025c12 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 1 Aug 2024 00:54:31 +0000 Subject: [PATCH] Added chart versions: jenkins/jenkins: - 5.5.1 linux-polska/ezd-backend: - 1.5.1 linux-polska/ezd-crd: - 1.5.1 --- assets/jenkins/jenkins-5.5.1.tgz | Bin 0 -> 76995 bytes assets/linux-polska/ezd-backend-1.5.1.tgz | Bin 0 -> 8255 bytes assets/linux-polska/ezd-crd-1.5.1.tgz | Bin 0 -> 592967 bytes charts/jenkins/jenkins/5.5.1/CHANGELOG.md | 3045 ++++ charts/jenkins/jenkins/5.5.1/Chart.yaml | 54 + charts/jenkins/jenkins/5.5.1/README.md | 706 + charts/jenkins/jenkins/5.5.1/UPGRADING.md | 148 + charts/jenkins/jenkins/5.5.1/VALUES.md | 311 + charts/jenkins/jenkins/5.5.1/VALUES.md.gotmpl | 28 + .../jenkins/jenkins/5.5.1/templates/NOTES.txt | 68 + .../jenkins/5.5.1/templates/_helpers.tpl | 673 + .../5.5.1/templates/auto-reload-config.yaml | 60 + .../5.5.1/templates/config-init-scripts.yaml | 18 + .../jenkins/5.5.1/templates/config.yaml | 92 + .../jenkins/5.5.1/templates/deprecation.yaml | 151 + .../jenkins/5.5.1/templates/home-pvc.yaml | 41 + .../jenkins/5.5.1/templates/jcasc-config.yaml | 53 + .../5.5.1/templates/jenkins-agent-svc.yaml | 43 + .../jenkins-aws-security-group-policies.yaml | 16 + .../jenkins-controller-alerting-rules.yaml | 26 + .../jenkins-controller-backendconfig.yaml | 24 + .../templates/jenkins-controller-ingress.yaml | 77 + .../jenkins-controller-networkpolicy.yaml | 76 + .../templates/jenkins-controller-pdb.yaml | 34 + .../jenkins-controller-podmonitor.yaml | 30 + .../templates/jenkins-controller-route.yaml | 34 + .../jenkins-controller-secondary-ingress.yaml | 56 + .../jenkins-controller-servicemonitor.yaml | 45 + .../jenkins-controller-statefulset.yaml | 424 + .../templates/jenkins-controller-svc.yaml | 56 + .../jenkins/jenkins/5.5.1/templates/rbac.yaml | 149 + .../5.5.1/templates/secret-additional.yaml | 21 + .../5.5.1/templates/secret-claims.yaml | 29 + .../5.5.1/templates/secret-https-jks.yaml | 20 + .../jenkins/5.5.1/templates/secret.yaml | 20 + .../templates/service-account-agent.yaml | 26 + .../5.5.1/templates/service-account.yaml | 26 + .../5.5.1/templates/tests/jenkins-test.yaml | 49 + .../5.5.1/templates/tests/test-config.yaml | 14 + charts/jenkins/jenkins/5.5.1/values.yaml | 1337 ++ .../ezd-backend/1.5.1/.helmignore | 23 + .../linux-polska/ezd-backend/1.5.1/Chart.yaml | 26 + .../linux-polska/ezd-backend/1.5.1/README.md | 75 + .../ezd-backend/1.5.1/app-readme.md | 17 + .../ezd-backend/1.5.1/questions.yaml | 279 + .../ezd-backend/1.5.1/templates/NOTES.txt | 41 + .../ezd-backend/1.5.1/templates/_helpers.tpl | 163 + .../templates/ezdrp-app/rabbitmq-secret.yaml | 17 + .../ezdrp-app/redis-append-secret.yaml | 16 + .../templates/ezdrp-app/redis-secret.yaml | 16 + .../ezdrp-app/relationaldb-secret.yaml | 14 + .../1.5.1/templates/global-secret.yaml | 13 + .../1.5.1/templates/postgresql-cluster.yaml | 42 + .../1.5.1/templates/postgresql-secret.yaml | 25 + .../1.5.1/templates/rabbitmq-ingress.yaml | 67 + .../templates/rabbitmq-rabbitmqcluster.yaml | 27 + .../1.5.1/templates/rabbitmq-secret.yaml | 19 + .../1.5.1/templates/redis-redis.yaml | 47 + .../1.5.1/templates/redis-secret.yaml | 13 + .../ezd-backend/1.5.1/values.yaml | 205 + charts/linux-polska/ezd-crd/1.5.1/.helmignore | 23 + charts/linux-polska/ezd-crd/1.5.1/Chart.lock | 12 + charts/linux-polska/ezd-crd/1.5.1/Chart.yaml | 45 + charts/linux-polska/ezd-crd/1.5.1/README.md | 84 + .../linux-polska/ezd-crd/1.5.1/app-readme.md | 22 + .../1.5.1/charts/cloudnative-pg/.helmignore | 23 + .../1.5.1/charts/cloudnative-pg/Chart.lock | 6 + .../1.5.1/charts/cloudnative-pg/Chart.yaml | 25 + .../1.5.1/charts/cloudnative-pg/LICENSE | 202 + .../1.5.1/charts/cloudnative-pg/README.md | 73 + .../cloudnative-pg/charts/cluster/.helmignore | 23 + .../cloudnative-pg/charts/cluster/Chart.yaml | 6 + .../cloudnative-pg/charts/cluster/README.md | 59 + .../charts/cluster/README.md.gotmpl | 59 + .../charts/cluster/grafana-dashboard.json | 9189 ++++++++++ .../charts/cluster/templates/NOTES.txt | 5 + .../cluster/templates/sidecar-configmap.yaml | 21 + .../charts/cluster/values.schema.json | 35 + .../cloudnative-pg/charts/cluster/values.yaml | 20 + .../monitoring/grafana-dashboard.json | 3 + .../charts/cloudnative-pg/templates/NOTES.txt | 18 + .../cloudnative-pg/templates/_helpers.tpl | 62 + .../cloudnative-pg/templates/config.yaml | 45 + .../cloudnative-pg/templates/crds/crds.yaml | 15073 ++++++++++++++++ .../cloudnative-pg/templates/deployment.yaml | 141 + .../templates/monitoring-configmap.yaml | 29 + .../mutatingwebhookconfiguration.yaml | 92 + .../cloudnative-pg/templates/podmonitor.yaml | 21 + .../charts/cloudnative-pg/templates/rbac.yaml | 451 + .../cloudnative-pg/templates/service.yaml | 34 + .../validatingwebhookconfiguration.yaml | 113 + .../charts/cloudnative-pg/values.schema.json | 269 + .../1.5.1/charts/cloudnative-pg/values.yaml | 555 + .../rabbitmq-cluster-operator/.helmignore | 25 + .../rabbitmq-cluster-operator/Chart.lock | 6 + .../rabbitmq-cluster-operator/Chart.yaml | 38 + .../rabbitmq-cluster-operator/README.md | 634 + .../charts/common/.helmignore | 26 + .../charts/common/Chart.yaml | 23 + .../charts/common/README.md | 235 + .../charts/common/templates/_affinities.tpl | 139 + .../charts/common/templates/_capabilities.tpl | 229 + .../common/templates/_compatibility.tpl | 42 + .../charts/common/templates/_errors.tpl | 28 + .../charts/common/templates/_images.tpl | 109 + .../charts/common/templates/_ingress.tpl | 73 + .../charts/common/templates/_labels.tpl | 46 + .../charts/common/templates/_names.tpl | 71 + .../charts/common/templates/_resources.tpl | 50 + .../charts/common/templates/_secrets.tpl | 182 + .../charts/common/templates/_storage.tpl | 21 + .../charts/common/templates/_tplvalues.tpl | 38 + .../charts/common/templates/_utils.tpl | 77 + .../charts/common/templates/_warnings.tpl | 109 + .../templates/validations/_cassandra.tpl | 77 + .../common/templates/validations/_mariadb.tpl | 108 + .../common/templates/validations/_mongodb.tpl | 113 + .../common/templates/validations/_mysql.tpl | 108 + .../templates/validations/_postgresql.tpl | 134 + .../common/templates/validations/_redis.tpl | 81 + .../templates/validations/_validations.tpl | 51 + .../charts/common/values.yaml | 8 + .../rabbitmq.com_bindings.yaml | 148 + .../rabbitmq.com_exchanges.yaml | 146 + .../rabbitmq.com_federations.yaml | 178 + .../rabbitmq.com_operatorpolicies.yaml | 163 + .../rabbitmq.com_permissions.yaml | 165 + .../rabbitmq.com_policies.yaml | 165 + .../rabbitmq.com_queues.yaml | 155 + .../rabbitmq.com_schemareplications.yaml | 166 + .../rabbitmq.com_shovels.yaml | 232 + .../rabbitmq.com_superstreams.yaml | 152 + .../rabbitmq.com_topicpermissions.yaml | 164 + .../rabbitmq.com_users.yaml | 187 + .../rabbitmq.com_vhosts.yaml | 144 + .../rabbitmq.com_rabbitmqclusters.yaml | 5006 +++++ .../templates/NOTES.txt | 52 + .../templates/_helpers.tpl | 143 + .../aggregate-cluster-roles.yaml | 31 + .../cluster-operator/clusterrole.yaml | 168 + .../cluster-operator/clusterrolebinding.yaml | 51 + .../cluster-operator/deployment.yaml | 169 + .../cluster-operator/metrics-service.yaml | 55 + .../cluster-operator/networkpolicy.yaml | 93 + .../cluster-operator/podmonitor.yaml | 73 + .../templates/cluster-operator/role.yaml | 37 + .../cluster-operator/rolebinding.yaml | 26 + .../cluster-operator/service-account.yaml | 20 + .../cluster-operator/servicemonitor.yaml | 56 + .../templates/extra-list.yaml | 9 + .../templates/issuer.yaml | 16 + .../aggregate-cluster-roles.yaml | 44 + .../certificate.yaml | 29 + .../clusterrole.yaml | 414 + .../clusterrolebinding.yaml | 51 + .../deployment.yaml | 183 + .../metrics-service.yaml | 58 + .../networkpolicy.yaml | 98 + .../podmonitor.yaml | 53 + .../messaging-topology-operator/role.yaml | 51 + .../rolebinding.yaml | 28 + .../service-account.yaml | 22 + .../servicemonitor.yaml | 53 + .../validating-webhook-configuration.yaml | 358 + .../webhook-service.yaml | 57 + .../rabbitmq-cluster-operator/values.yaml | 1229 ++ .../1.5.1/charts/redis-operator/.gitignore | 1 + .../1.5.1/charts/redis-operator/Chart.lock | 6 + .../1.5.1/charts/redis-operator/Chart.yaml | 25 + .../charts/cert-manager/Chart.yaml | 24 + .../charts/cert-manager/README.md | 271 + .../charts/cert-manager/templates/NOTES.txt | 15 + .../cert-manager/templates/_helpers.tpl | 174 + .../templates/cainjector-deployment.yaml | 117 + .../cainjector-poddisruptionbudget.yaml | 26 + .../templates/cainjector-psp-clusterrole.yaml | 20 + .../cainjector-psp-clusterrolebinding.yaml | 22 + .../templates/cainjector-psp.yaml | 51 + .../templates/cainjector-rbac.yaml | 103 + .../templates/cainjector-serviceaccount.yaml | 27 + .../charts/cert-manager/templates/crds.yaml | 4462 +++++ .../cert-manager/templates/deployment.yaml | 204 + .../templates/networkpolicy-egress.yaml | 23 + .../templates/networkpolicy-webhooks.yaml | 25 + .../templates/poddisruptionbudget.yaml | 26 + .../templates/psp-clusterrole.yaml | 18 + .../templates/psp-clusterrolebinding.yaml | 20 + .../charts/cert-manager/templates/psp.yaml | 49 + .../charts/cert-manager/templates/rbac.yaml | 544 + .../cert-manager/templates/service.yaml | 31 + .../templates/serviceaccount.yaml | 25 + .../templates/servicemonitor.yaml | 45 + .../templates/startupapicheck-job.yaml | 88 + .../startupapicheck-psp-clusterrole.yaml | 24 + ...tartupapicheck-psp-clusterrolebinding.yaml | 26 + .../templates/startupapicheck-psp.yaml | 51 + .../templates/startupapicheck-rbac.yaml | 48 + .../startupapicheck-serviceaccount.yaml | 27 + .../templates/webhook-config.yaml | 25 + .../templates/webhook-deployment.yaml | 185 + .../templates/webhook-mutating-webhook.yaml | 46 + .../webhook-poddisruptionbudget.yaml | 26 + .../templates/webhook-psp-clusterrole.yaml | 18 + .../webhook-psp-clusterrolebinding.yaml | 20 + .../cert-manager/templates/webhook-psp.yaml | 54 + .../cert-manager/templates/webhook-rbac.yaml | 83 + .../templates/webhook-service.yaml | 32 + .../templates/webhook-serviceaccount.yaml | 25 + .../templates/webhook-validating-webhook.yaml | 55 + .../charts/cert-manager/values.yaml | 692 + .../redis-operator/crds/redis-cluster.yaml | 13686 ++++++++++++++ .../crds/redis-replication.yaml | 9978 ++++++++++ .../redis-operator/crds/redis-sentinel.yaml | 7043 ++++++++ .../charts/redis-operator/crds/redis.yaml | 9966 ++++++++++ .../1.5.1/charts/redis-operator/readme.md | 115 + .../redis-operator/templates/_helpers.tpl | 34 + .../templates/cert-manager.yaml | 43 + .../templates/operator-deployment.yaml | 81 + .../templates/role-binding.yaml | 23 + .../charts/redis-operator/templates/role.yaml | 128 + .../templates/service-account.yaml | 17 + .../redis-operator/templates/service.yaml | 20 + .../1.5.1/charts/redis-operator/values.yaml | 76 + .../linux-polska/ezd-crd/1.5.1/questions.yaml | 97 + .../ezd-crd/1.5.1/templates/_helpers.tpl | 46 + .../ezd-crd/1.5.1/templates/configmap.yaml | 11 + .../1.5.1/templates/global-secret.yaml | 13 + charts/linux-polska/ezd-crd/1.5.1/values.yaml | 71 + index.yaml | 139 +- 229 files changed, 99307 insertions(+), 1 deletion(-) create mode 100644 assets/jenkins/jenkins-5.5.1.tgz create mode 100644 assets/linux-polska/ezd-backend-1.5.1.tgz create mode 100644 assets/linux-polska/ezd-crd-1.5.1.tgz create mode 100644 charts/jenkins/jenkins/5.5.1/CHANGELOG.md create mode 100644 charts/jenkins/jenkins/5.5.1/Chart.yaml create mode 100644 charts/jenkins/jenkins/5.5.1/README.md create mode 100644 charts/jenkins/jenkins/5.5.1/UPGRADING.md create mode 100644 charts/jenkins/jenkins/5.5.1/VALUES.md create mode 100644 charts/jenkins/jenkins/5.5.1/VALUES.md.gotmpl create mode 100644 charts/jenkins/jenkins/5.5.1/templates/NOTES.txt create mode 100644 charts/jenkins/jenkins/5.5.1/templates/_helpers.tpl create mode 100644 charts/jenkins/jenkins/5.5.1/templates/auto-reload-config.yaml create mode 100644 charts/jenkins/jenkins/5.5.1/templates/config-init-scripts.yaml create mode 100644 charts/jenkins/jenkins/5.5.1/templates/config.yaml create mode 100644 charts/jenkins/jenkins/5.5.1/templates/deprecation.yaml create mode 100644 charts/jenkins/jenkins/5.5.1/templates/home-pvc.yaml create mode 100644 charts/jenkins/jenkins/5.5.1/templates/jcasc-config.yaml create mode 100644 charts/jenkins/jenkins/5.5.1/templates/jenkins-agent-svc.yaml create mode 100644 charts/jenkins/jenkins/5.5.1/templates/jenkins-aws-security-group-policies.yaml create mode 100644 charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-alerting-rules.yaml create mode 100644 charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-backendconfig.yaml create mode 100644 charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-ingress.yaml create mode 100644 charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-networkpolicy.yaml create mode 100644 charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-pdb.yaml create mode 100644 charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-podmonitor.yaml create mode 100644 charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-route.yaml create mode 100644 charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-secondary-ingress.yaml create mode 100644 charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-servicemonitor.yaml create mode 100644 charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-statefulset.yaml create mode 100644 charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-svc.yaml create mode 100644 charts/jenkins/jenkins/5.5.1/templates/rbac.yaml create mode 100644 charts/jenkins/jenkins/5.5.1/templates/secret-additional.yaml create mode 100644 charts/jenkins/jenkins/5.5.1/templates/secret-claims.yaml create mode 100644 charts/jenkins/jenkins/5.5.1/templates/secret-https-jks.yaml create mode 100644 charts/jenkins/jenkins/5.5.1/templates/secret.yaml create mode 100644 charts/jenkins/jenkins/5.5.1/templates/service-account-agent.yaml create mode 100644 charts/jenkins/jenkins/5.5.1/templates/service-account.yaml create mode 100644 charts/jenkins/jenkins/5.5.1/templates/tests/jenkins-test.yaml create mode 100644 charts/jenkins/jenkins/5.5.1/templates/tests/test-config.yaml create mode 100644 charts/jenkins/jenkins/5.5.1/values.yaml create mode 100644 charts/linux-polska/ezd-backend/1.5.1/.helmignore create mode 100644 charts/linux-polska/ezd-backend/1.5.1/Chart.yaml create mode 100644 charts/linux-polska/ezd-backend/1.5.1/README.md create mode 100644 charts/linux-polska/ezd-backend/1.5.1/app-readme.md create mode 100644 charts/linux-polska/ezd-backend/1.5.1/questions.yaml create mode 100644 charts/linux-polska/ezd-backend/1.5.1/templates/NOTES.txt create mode 100644 charts/linux-polska/ezd-backend/1.5.1/templates/_helpers.tpl create mode 100644 charts/linux-polska/ezd-backend/1.5.1/templates/ezdrp-app/rabbitmq-secret.yaml create mode 100644 charts/linux-polska/ezd-backend/1.5.1/templates/ezdrp-app/redis-append-secret.yaml create mode 100644 charts/linux-polska/ezd-backend/1.5.1/templates/ezdrp-app/redis-secret.yaml create mode 100644 charts/linux-polska/ezd-backend/1.5.1/templates/ezdrp-app/relationaldb-secret.yaml create mode 100644 charts/linux-polska/ezd-backend/1.5.1/templates/global-secret.yaml create mode 100644 charts/linux-polska/ezd-backend/1.5.1/templates/postgresql-cluster.yaml create mode 100644 charts/linux-polska/ezd-backend/1.5.1/templates/postgresql-secret.yaml create mode 100644 charts/linux-polska/ezd-backend/1.5.1/templates/rabbitmq-ingress.yaml create mode 100644 charts/linux-polska/ezd-backend/1.5.1/templates/rabbitmq-rabbitmqcluster.yaml create mode 100644 charts/linux-polska/ezd-backend/1.5.1/templates/rabbitmq-secret.yaml create mode 100644 charts/linux-polska/ezd-backend/1.5.1/templates/redis-redis.yaml create mode 100644 charts/linux-polska/ezd-backend/1.5.1/templates/redis-secret.yaml create mode 100644 charts/linux-polska/ezd-backend/1.5.1/values.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/.helmignore create mode 100644 charts/linux-polska/ezd-crd/1.5.1/Chart.lock create mode 100644 charts/linux-polska/ezd-crd/1.5.1/Chart.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/README.md create mode 100644 charts/linux-polska/ezd-crd/1.5.1/app-readme.md create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/.helmignore create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/Chart.lock create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/Chart.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/LICENSE create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/README.md create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/charts/cluster/.helmignore create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/charts/cluster/Chart.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/charts/cluster/README.md create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/charts/cluster/README.md.gotmpl create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/charts/cluster/grafana-dashboard.json create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/charts/cluster/templates/NOTES.txt create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/charts/cluster/templates/sidecar-configmap.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/charts/cluster/values.schema.json create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/charts/cluster/values.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/monitoring/grafana-dashboard.json create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/templates/NOTES.txt create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/templates/_helpers.tpl create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/templates/config.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/templates/crds/crds.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/templates/deployment.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/templates/monitoring-configmap.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/templates/mutatingwebhookconfiguration.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/templates/podmonitor.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/templates/rbac.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/templates/service.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/templates/validatingwebhookconfiguration.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/values.schema.json create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/values.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/.helmignore create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/Chart.lock create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/Chart.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/README.md create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/.helmignore create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/Chart.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/README.md create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_affinities.tpl create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_capabilities.tpl create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_compatibility.tpl create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_errors.tpl create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_images.tpl create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_ingress.tpl create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_labels.tpl create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_names.tpl create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_resources.tpl create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_secrets.tpl create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_storage.tpl create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_tplvalues.tpl create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_utils.tpl create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_warnings.tpl create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/validations/_cassandra.tpl create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/validations/_mariadb.tpl create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/validations/_mongodb.tpl create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/validations/_mysql.tpl create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/validations/_postgresql.tpl create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/validations/_redis.tpl create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/validations/_validations.tpl create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/values.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_bindings.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_exchanges.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_federations.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_operatorpolicies.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_permissions.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_policies.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_queues.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_schemareplications.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_shovels.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_superstreams.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_topicpermissions.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_users.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_vhosts.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/rabbitmq-cluster/rabbitmq.com_rabbitmqclusters.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/NOTES.txt create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/_helpers.tpl create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/aggregate-cluster-roles.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/clusterrole.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/clusterrolebinding.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/deployment.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/metrics-service.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/networkpolicy.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/podmonitor.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/role.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/rolebinding.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/service-account.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/servicemonitor.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/extra-list.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/issuer.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/aggregate-cluster-roles.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/certificate.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/clusterrole.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/clusterrolebinding.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/deployment.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/metrics-service.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/networkpolicy.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/podmonitor.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/role.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/rolebinding.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/service-account.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/servicemonitor.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/validating-webhook-configuration.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/webhook-service.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/values.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/.gitignore create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/Chart.lock create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/Chart.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/Chart.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/README.md create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/NOTES.txt create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/_helpers.tpl create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/cainjector-deployment.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/cainjector-poddisruptionbudget.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/cainjector-psp-clusterrole.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/cainjector-psp-clusterrolebinding.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/cainjector-psp.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/cainjector-rbac.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/cainjector-serviceaccount.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/crds.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/deployment.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/networkpolicy-egress.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/networkpolicy-webhooks.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/poddisruptionbudget.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/psp-clusterrole.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/psp-clusterrolebinding.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/psp.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/rbac.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/service.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/serviceaccount.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/servicemonitor.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/startupapicheck-job.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/startupapicheck-psp-clusterrole.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/startupapicheck-psp-clusterrolebinding.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/startupapicheck-psp.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/startupapicheck-rbac.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/startupapicheck-serviceaccount.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-config.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-deployment.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-mutating-webhook.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-poddisruptionbudget.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-psp-clusterrole.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-psp-clusterrolebinding.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-psp.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-rbac.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-service.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-serviceaccount.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-validating-webhook.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/values.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/crds/redis-cluster.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/crds/redis-replication.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/crds/redis-sentinel.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/crds/redis.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/readme.md create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/templates/_helpers.tpl create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/templates/cert-manager.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/templates/operator-deployment.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/templates/role-binding.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/templates/role.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/templates/service-account.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/templates/service.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/values.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/questions.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/templates/_helpers.tpl create mode 100644 charts/linux-polska/ezd-crd/1.5.1/templates/configmap.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/templates/global-secret.yaml create mode 100644 charts/linux-polska/ezd-crd/1.5.1/values.yaml diff --git a/assets/jenkins/jenkins-5.5.1.tgz b/assets/jenkins/jenkins-5.5.1.tgz new file mode 100644 index 0000000000000000000000000000000000000000..154154bd05f79e3bdcc878de120b8ab5345b9113 GIT binary patch literal 76995 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 N|NpGdYqDc zVQyr3R8em|NM&qo0PKDJciT3yXn$S)6;pZlHO>vG56gC=-t2jf?bqhiaeQs3Ioo!R z3Xzb6nj{ziw5_;#fBQZ7APG{`mo3}r);PPV1rC6j!C){03;_Hoa0kf0z;V#rA0sBb z35vq6)|y(aR%@r*RsU_ZTGjuyx4JuDwYxjpo$c+NcBk`ItG%_g-Tew$>qVnJrCcEP zRqM`eRf+qPBoxO~AVFx%dk%n)1PbZM^N|oC_6TjFR8W`1T%a)QffN^?1+O9`{BbS3 zkC`Atf`c9;h=~}pTCjldBt#Q8MiK78(FwfPLI^|3;PB@II6bK?caaXTdx;q*H15GS z|9sW<+ArPKH?_c&_aG#3dR_aK;SeK^4GPvka8N>i%9^U7=qOK;cf zZaV?yJ|l@x-_9_*BtGU4V;^&l*aQRxmd1u4KuO|^scda5M8bQ`rot|vA-_PLPa}u; zvZ5ggaj)4#oMXY8GLJVc{JbO{ITv_xMOnamjtf4Ghh*eP-uzUTUfX%>QTF8~TmN68FvWcR6Tp1^-|lo<+g1I) z({4TK|A$B$aDay>4F%}lSNhl1HO>Z{j|m6D0l~la-X6I_$|58L4wRmf00-C)5yNna z7(s&&bE)?R7!s+$0wA%VFrg^}fukfu0&~xCoKZ*zD3r4fiO>k|GaTSp5EQDJC{rnZ zk?k@(B3!VED;22($ufG-$g~BC1AOfT)W5(?YWd4{v!P&9j+w5qp)(|QQibLjM#-sP z0Zu|XiEu15G7@b`cn`jjYL>-VVE&Ezq_xjCe#!-nWEMk%0TIzhT~gQ71Hn?PGBlw6 z2vT?RG)k1R8lsR(n1pgMVwisnZ(Rk$0pYhS?PLV(t9eBN4%0A{%zJl<86$yYVwhwy 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 literal 0 HcmV?d00001 diff --git a/assets/linux-polska/ezd-crd-1.5.1.tgz b/assets/linux-polska/ezd-crd-1.5.1.tgz new file mode 100644 index 0000000000000000000000000000000000000000..1972d27e404f74e9435badc2ffcf7f199ef91bd4 GIT binary patch literal 592967 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

Dyi5$WaRb?;F9^GeEMY@CqjgXUQV+7IbdN?in1 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

odPG&(?N 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∋(Vh*Z^Zcw=w(of(qa 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�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%0AqK@;ov^$KqVRH5 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 [!CAUTION] + > Several fields have been renamed or removed. See [UPGRADING.md](./UPGRADING.md#to-500) + +The Helm Chart is now updated automatically via [Renovate](https://docs.renovatebot.com/) + +## 4.12.1 + +Update Jenkins image and appVersion to jenkins lts release version 2.426.3 + +## 4.12.0 + +Add support for [generic ephemeral storage](https://github.com/jenkinsci/kubernetes-plugin/pull/1489) in `agent.volumes` and `agents.workspaceVolume`. + +| plugin | old version | new version | +|------------|---------------------|--------------------| +| kubernetes | 4029.v5712230ccb_f8 | 4174.v4230d0ccd951 | + +## 4.11.2 + +Fixed documentation for controller.initScripts. + +## 4.11.1 + +Updated helm-unittest and made unittests compatible. + +## 4.11.0 + +Add multi-cloud support. + +## 4.10.0 + +Bumped Jenkins inbound agent from 3107.v665000b_51092-15 to 3192.v713e3b_039fb_e-5. + +## 4.9.2 + +Update Jenkins image and appVersion to jenkins lts release version 2.426.2 + + +Notes about [Artifact Hub](https://artifacthub.io/packages/helm/jenkinsci/jenkins?modal=changelog) changelog processing: +- Remove empty lines +- Keep only ASCII characters (no emojis) +- One change per line +- Remove table(s) (lines starting by "|") +- Backticks aren't rendered on artifacthub.io changelog + +## 4.9.1 + +Restore artifact hub notes location in CHANGELOG.md + +## 4.9.0 + +Update base images from JDK 11 to JDK 17. + +## 4.8.6 + +Proper `artifacthub.io/changes` changelog annotation preprocessing. + +## 4.8.5 + +Fix `artifacthub.io/changes` changelog annotation added to the released chart. + +## 4.8.4 + +Add `artifacthub.io/changes` changelog annotation to the released chart. + +## 4.8.3 + +Update Jenkins image and appVersion to jenkins lts release version 2.426.1 + +## 4.8.2 + +Add the ability to modify `retentionTimeout` and `waitForPodSec` default value in JCasC + +## 4.8.1 + +Reintroduces changes from 4.7.0 (reverted in 4.7.1), with additional fixes: + +- METHOD is now allowed in `env` and is not duplicated anymore +- No calls to JCasC reload endpoint from the init container + +## 4.8.0 + +Adds support for ephemeralStorage request and limit in Kubernetes plugin JCasC template + +## 4.7.4 + +Add the config-init-script checksum into the controller statefullset pod annotations to trigger restart of the pod in case of updated init scripts. + +## 4.7.3 + +Update Jenkins image and appVersion to jenkins lts release version 2.414.3 + +## 4.7.1 + +Changes in 4.7.0 were reverted. + +## 4.7.0 + +Runs `config-reload` as an init container, in addition to the sidecar container, to ensure that JCasC YAMLs are present before the main Jenkins container starts. This should fix some race conditions and crashes on startup. + +## 4.6.7 + +Change jenkins-test image label to match the other jenkins images + +## 4.6.5 + +Update Jenkins image and appVersion to jenkins lts release version 2.414.2 + +## 4.6.4 + +Introducing TPL function on variables related to hostname in `./charts/jenkins/templates/jenkins-controller-ingress.yaml` + +## 4.6.3 + +Add values to documentation + +## 4.6.2 + +Update word from hundreds to over 1800 to align with blurb at . + +## 4.6.1 + +Update `configuration-as-code` plugin to fix dependency issues with `azure-ad` plugin + +## 4.6.0 + +Added `.Values.controller.httpsKeyStore.jenkinsHttpsJksSecretKey` to allow overriding the default secret key containing the JKS file. +Added `.Values.controller.httpsKeyStore.jenkinsHttpsJksPasswordSecretName` to allow getting the JKS password from a different secret. +Added `.Values.controller.httpsKeyStore.jenkinsHttpsJksPasswordSecretKey` to allow overriding the default secret key containing the JKS password. + +## 4.5.1 + +Update Jenkins image and appVersion to jenkins lts release version 2.414.1 + + +## 4.5.0 + +Added `.Values.persistence.dataSource` to allow cloning home PVC from existing dataSource. + +## 4.4.2 + +Update Jenkins image and appVersion to jenkins lts release version 2.401.3 + + +## 4.4.1 + +Added `.Values.agent.jnlpregistry` to allow agents to be configured with private registry. + +## 4.4.0 + +Add config keys for liveness probes on agent containers. + + +## 4.3.30 + +Update Jenkins version in controller test matching LTS version + +## 4.3.29 + +Update Jenkins image and appVersion to jenkins lts release version 2.401.2 + + +## 4.3.28 + +Allow the kubernetes API server URL to be configurable. + +## 4.3.27 + +Bump kiwigrid/k8s-sidecar from 1.23.1 to 1.24.4 and jenkins/inbound-agent from 3107.v665000b_51092-5 to 3107.v665000b_51092-15. + +## 4.3.26 + +Fix various typos in the chart documentation. + +## 4.3.25 + +| plugin | old version | new version | +|-----------------------|----------------------|-----------------------| +| kubernetes | 3900.va_dce992317b_4 | 3937.vd7b_82db_e347b_ | +| configuration-as-code | 1625.v27444588cc3d | 1647.ve39ca_b_829b_42 | +| git | 5.0.0 | 5.1.0 | +| ldap | 671.v2a_9192a_7419d | 682.v7b_544c9d1512 | + +## 4.3.24 + +Update Jenkins image and appVersion to jenkins lts release version 2.401.1 + + +## 4.3.23 + +Update Jenkins image and appVersion to jenkins lts release version 2.387.3 + + +## 4.3.22 + + +Bump chart version. + +## 4.3.21 + + +Document building charts for weekly releases. + +## 4.3.20 + + +Enhance repository appearance and miscellaneous cleanup. + +## 4.3.19 + + +Comply with superlinter rules and address ShellCheck issues. + +## 4.3.18 + + +Bump kiwigrid/k8s-sidecar from 1.15.0 to 1.23.1. + +## 4.3.17 + + +Bump jenkins/inbound-agent from 4.11.2-4 to 3107.v665000b_51092-5. + +## 4.3.16 + + +Update bundled plugins: +- [ldap](https://plugins.jenkins.io/ldap/): From 2.5 to 671.v2a_9192a_7419d +- [kubernetes](https://plugins.jenkins.io/kubernetes/): From 3734.v562b_b_a_627ea_c to 3900.va_dce992317b_4 +- [workflow-aggregator](https://plugins.jenkins.io/workflow-aggregator/): From 590.v6a_d052e5a_a_b_5 to 590.v6a_d052e5a_a_b_5 +- [configuration-as-code](https://plugins.jenkins.io/configuration-as-code/): From 1569.vb_72405b_80249 to 1625.v27444588cc3d + +## 4.3.15 + + +Update bats from 1.2.1 to 1.9.0. + +## 4.3.14 + + +Update various GH actions, typo fixes, and miscellaneous chores. + +## 4.3.13 + + +Bump helm-unittest from 0.2.8 to 0.2.11. + +## 4.3.12 + + +Update wording in values.yml. + +## 4.3.11 + +Update Jenkins image and appVersion to jenkins lts release version 2.387.2 + + +## 4.3.10 + +Correct incorrect env var definition +Disable volume mount if disableSecretMount enabled + +## 4.3.9 + +Document `.Values.agent.directConnection` in readme. +Add default value for `.Values.agent.directConnection` to `values.yaml` + +## 4.3.8 + +Added `.Values.agent.directConnection` to allow agents to be configured to connect direct to the JNLP port on the +controller, preventing the need for an external HTTP endpoint for this purpose. + +## 4.3.7 + +Added `.Values.controller.shareProcessNamespace` and `.Values.controller.httpsKeyStore.disableSecretMount` to enable sourcing TLS certs from external issuers + +## 4.3.6 + +Update Jenkins image and appVersion to jenkins lts release version 2.387.1 + +## 4.3.5 + +Added `.Values.helmtest.bats.image` and `.Values.helmtest.bats.image` to allow unit tests to be configurable. Fixes [https://github.com/jenkinsci/helm-charts/issues/683] + +## 4.3.4 + +Update Jenkins image and appVersion to jenkins lts release version 2.375.3 + + +## 4.3.3 + +Removed hardcoding of chart version in tests to make maintenance easier + +## 4.3.2 + +Added `.Values.serviceAccount.extraLabels` on Service Account +Added `.Values.serviceAccountAgent.extraLabels` on Agent's Service Account + + +## 4.3.0 + +Moved use of `.Values.containerEnv` within `jenkins` Container to top of `env` block to allow for subsequent Environment Variables to reference these additional ones. + +## 4.2.21 + +Update Jenkins image and appVersion to jenkins lts release version 2.375.2 + + +## 4.2.20 + +Fixed the `controller.prometheus.metricRelabelings` being unable to convert the value to the ServiceMonitor. +Added `controller.prometheus.relabelings` to allow relabling before scrape. +Added default values for `controller.prometheus.relabelings` and `controller.prometheus.metricRelabelings`. + +## 4.2.19 + +CronJob API version upgraded to batch/v1 + +## 4.2.18 + +Added option to set secretEnvVars. + +## 4.2.17 + +Update Jenkins image and appVersion to jenkins lts release version 2.375.1 + + +## 4.2.16 + +Fixed chart notes not rendering Jenkins URL with prefix when `controller.jenkinsUriPrefix` is set. +Fixed chart notes not rendering Jenkins URL with `https` when `controller.ingress.tls` or `controller.controller.httpsKeyStore.enable` is set. +Fixed chart notes rendering wrong JCasC URL when not using `controller.ingress`. + +## 4.2.15 + +Update Jenkins image and appVersion to jenkins lts release version 2.361.4 + +## 4.2.14 + +Added option to mount all keys from an existing k8s secret + +## 4.2.13 + +Adding `tpl` to `controller.additionalExistingSecrets` + +## 4.2.12 + +Update Jenkins image and appVersion to jenkins lts release version 2.361.3 + + +## 4.2.11 + +Update default plugin versions + +| plugin | old version | new version | +|-----------------------|-----------------------|------------------------| +| kubernetes | 3706.vdfb_d599579f3 | 3734.v562b_b_a_627ea_c | +| git | 4.11.5 | 4.13.0 | +| configuration-as-code | 1512.vb_79d418d5fc8 | 1569.vb_72405b_80249 | + +## 4.2.10 +Fix grammar and typos + +## 4.2.9 +Update Jenkins image and appVersion to jenkins lts release version 2.361.2 + +## 4.2.8 +Modify the condition to trigger copying jenkins_config files when configAutoReload option is disabled during Jenkins initialization + +## 4.2.7 +Support for remote URL for configuration + +## 4.2.6 +Add option to set hostnetwork for agents + +## 4.2.5 +Add an extra optional argument to extraPorts in order to specify targetPort + +## 4.2.4 +Remove k8s capibility requirements when setting priority class for controller + +## 4.2.3 Update plugin versions + +| plugin | old version | new version | +| --------------------- | --------------------- | --------------------- | +| kubernetes | 3600.v144b_cd192ca_a_ | 3706.vdfb_d599579f3 | +| workflow-aggregator | 581.v0c46fa_697ffd | 590.v6a_d052e5a_a_b_5 | +| configuration-as-code | 1429.v09b_044a_c93de | 1512.vb_79d418d5fc8 | +| git | 4.11.3 | 4.11.5 | + +Resolve version conflict between default install of plugins. + +## 4.2.2 + +Support Google Managed Prometheus + +## 4.2.1 + +Remove option to provide command and args of agent as YAML. This feature was never supported by the Jenkins Kubernetes +plugin. + +## 4.2.0 + +Add option to provide additional containers to agents + +## 4.1.18 + +Update Jenkins image and appVersion to jenkins lts release version 2.361.1 + + +## 4.1.17 + +Update Jenkins casc default settings to allow `security` configs to be provided + + +## 4.1.16 + +Update Jenkins image and appVersion to jenkins lts release version 2.346.3 + + +## 4.1.15 + +`projectNamingStrategy` is configurable in default config. + +## 4.1.14 + +If `installPlugins` is disabled, don't create unused plugins volume. + +## 4.1.13 + +Update Jenkins image and appVersion to jenkins lts release version 2.346.2 + + +## 4.1.12 + +If keystore is defined, it is now also made available in the initContainer. + +## 4.1.11 + +JCasC ConfigMaps now generate their name from the `jenkins.casc.configName` helper + +## 4.1.10 + +Update Jenkins image and appVersion to jenkins lts release version 2.346.1 + + +## 4.1.9 + +Allow setting `imagePullSecret` for backup job via `backup.imagePullSecretName` + +## 4.1.8 + +Fix path of projected secrets from `additionalExistingSecrets`. + +## 4.1.7 + +Update readme with explanation on the required environmental variable `AWS_REGION` in case of using an S3 bucket. + +## 4.1.6 + +project adminSecret, additionalSecrets and additionalExistingSecrets instead of mount with subPath + +## 4.1.5 + +Update readme to fix `JAVA_OPTS` name. + +## 4.1.4 +Update plugins + +## 4.1.3 +Update jenkins-controller-statefulset projected volumes definition + +## 4.1.1 +Added 'controller.prometheus.metricRelabelings' to allow relabling and dropping unused prometheus metrics + +## 4.1.0 + +Added `controller.sidecars.configAutoReload.envFrom`, `controller.initContainerEnvFrom`, `controller.containerEnvFrom` + +## 4.0.1 + +No code changes - CI updated to run unit tests using Helm 3.8.2. + +## 4.0.0 + +Removes automatic `remotingSecurity` setting when using a container tag older than `2.326` (introduced in [`3.11.7`](#3117)). If you're using a version older than `2.326`, you should explicitly set `.controller.legacyRemotingSecurityEnabled` to `true`. + +## 3.12.2 + +Update Jenkins image and appVersion to jenkins lts release version 2.332.3 + +## 3.12.1 + +Make namespace configurable for agents and additional agents. + +## 3.12.0 + +Added a flag for disabling the default Jenkins Agent configuration. + +## 3.11.10 + +Update Jenkins image and appVersion to jenkins lts release version 2.332.2 + +## 3.11.9 Bump configuration-as-code plugin version + +| plugin | old version | new version | +| --------------------- | ----------- | ----------- | +| configuration-as-code | 1.51 | 1414.v878271fc496f | + +## 3.11.8 + +Make [externalTrafficPolicy](https://kubernetes.io/docs/concepts/services-networking/service/#traffic-policies) and `loadBalancerSourceRanges` fields customizable for Agent listener service via `controller.agentListenerExternalTrafficPolicy` and `controller.loadBalancerSourceRanges`. + +## 3.11.7 + +Removed Configuration as Code `remotingSecurity` section for Jenkins 2.326 or newer. See [Documentation](https://www.jenkins.io/redirect/AdminWhitelistRule) to learn more. + +## 3.11.6 + +Update Jenkins image and appVersion to jenkins lts release version 2.332.1 + + +## 3.11.5 + +Change Backup Role name function call to match the RoleDef function call in the Backup RoleBinding + +## 3.11.4 + +Update Jenkins image and appVersion to jenkins lts release version 2.319.3 + + +## 3.11.3 + +Update kiwigrid/k8s-sidecar:1.15.0 +Update jenkins/inbound-agent:4.11.2-4 + +## 3.11.2 + +Improve example for workspaceVolume. Clarify that this is not a list. + +## 3.11.1 + +Update configuration-as-code plugin to 1.55.1 + + +## 3.11.0 + +Update default plugin versions + +| plugin | old version | new version | +| --------------------- | ----------- | ----------- | +| kubernetes | 1.31.1 | 1.31.3 | +| git | 4.10.1 | 4.10.2 | + +## 3.10.3 + +Update Jenkins image and appVersion to jenkins lts release version 2.319.2 + + +## 3.10.2 + +Fix definition of startupProbe when deploying on a Kubernetes cluster < 1.16 + +## 3.10.1 + +correct VALUES_SUMMARY.md for installLatestPlugins + +## 3.10.0 + +Update default plugin versions + +| plugin | old version | new version | +| --------------------- | ----------- | ----------- | +| kubernetes | 1.30.11 | 1.31.1 | +| git | 4.10.0 | 4.10.1 | +| configuration-as-code | 1.54 | 1.55 | + +## 3.9.4 + +Add JAVA_OPTIONS to the readme so proxy settings get picked by jenkins-plugin-cli + +## 3.9.3 + +Fix config reload request URL when httpsKeystore in use + +## 3.9.2 + +Update Jenkins image and appVersion to jenkins lts release version 2.319.1 +Update following plugins: + +* kubernetes:1.30.11 +* git:4.10.0 +* configuration-as-code:1.54 + +## 3.9.1 + +Adding `tpl` to `controller.overrideArgs` + +## 3.9.0 + +Added containerSecurityContext + +## 3.8.9 + +Fix mounting of HTTPS keystore secret when httpsKeyStore is enabled + +## 3.8.8 + +Update Jenkins image and appVersion to jenkins lts release version 2.303.3 + +## 3.8.7 + +Adding `tpl` to `initScripts` + +## 3.8.6 + +Add `controller.tagLabel` to specify the label for the image tag, for example `jdk11` or `alpine` + +## 3.8.5 + +Move jenkins web root outside of home dir + +## 3.8.4 + +Add `controller.initConfigMap` to pass pre-existing `init.groovy.d` ConfigMaps to the controller + +## 3.8.3 + +Update missed reference to jenkins/inbound-agent:4.11-1 + +## 3.8.2 + +Update jenkins/inbound-agent:4.11-1 + +## 3.8.1 + +Update jenkins/inbound-agent:4.10-3 + +## 3.8.0 + +Update kiwigrid/k8s-sidecar:1.14.2 + +## 3.7.1 + +Update git and casc plugins versions + +## 3.7.0 + +Added the option to create AWS SecurityGroupPolicy resources + +## 3.6.2 + +Fix httpsKeyStore mount when `controller.httpsKeyStore.enable` is `true` + +## 3.6.1 + +Update Jenkins image and appVersion to jenkins lts release version 2.303.2 + + +## 3.6.0 +Support custom agent pod labels + +## 3.5.20 +Disallow ingress on port 50000 when agent listener is disabled + +## 3.5.19 +Add support for specifying termination-log behaviour for Jenkins controller + +## 3.5.18 +Add support for creating a Pod Disruption Budget for Jenkins controller + +## 3.5.17 +Update workdingDir to `/home/jenkins/agent` + +## 3.5.16 +Update location of icon (wiki.jenkins.io is down) + +## 3.5.15 +Add support for adding labels to the Jenkins home Persistent Volume Claim (pvc) + +## 3.5.14 + +* Updated versions of default plugins +* Use verbose logging during plugin installation +* download the latest version of all plugin dependencies (Fixes #442) + +## 3.5.13 + +Update Jenkins image and appVersion to jenkins lts release version 2.303.1 + +## 3.5.12 + +Added extended documentation for Backup and Restore. + +## 3.5.11 + +Sanitized the Jenkins Label + +## 3.5.10 + +Fixed `controller.customJenkinsLabels` not getting templated into the controller `labelString:` field in JCasC + +## 3.5.9 + +Update Jenkins image and appVersion to jenkins lts release version 2.289.3 + + +## 3.5.8 + +Add parameter `backup.serviceAccount.create` to disable service account creation for backup service and `backup.serviceAccount.name` to allow change of the SA name. +`backup.annotations` was moved to `backup.serviceAccount.annotations` + +## 3.5.7 + +Enable setting `controller.serviceExternalTrafficPolicy` to set [the standard Service option](https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip). `externalTrafficPolicy` denotes if this Service desires to route external traffic to node-local or cluster-wide endpoints. + +## 3.5.6 + +Add optional `controller.initContainerResources`, if set, it will change resources allocation for init controller, overwise the `controller.resources` will be used + +## 3.5.5 + +Allow to configure nodeUsageMode via `agent.nodeUsageMode` + +## 3.5.4 + +Update tests to work with unittest 0.2.6 + +## 3.5.3 + +Update Jenkins image and appVersion to jenkins lts release version 2.289.2 + +## 3.5.2 + +Enable setting `controller.installLatestSpecifiedPlugins` to set whether to download the latest dependencies of any plugin that is requested to have the latest version. + +## 3.5.1 +Fix activeDeadlineSeconds wrong type bug in jenkins-backup-cronjob template + +## 3.5.0 + +Allow `controller.podAnnotations` to be render as a template + +## 3.4.1 + +Allow showRawYaml for the default agent's pod template to be customized. + +## 3.4.0 + +configAutoReload container updated from `kiwigrid/k8s-sidecar:0.1.275` to `kiwigrid/k8s-sidecar:1.12.2` + +## 3.3.23 + +Make `controller.ingress.resourceRootUrl` compatible with API version networking.k8s.io/v1 on k8s >= 1.19.x + +## 3.3.22 + +Update Jenkins image and appVersion to jenkins lts release version 2.289.1 + +## 3.3.21 +`persistence.mounts` additionally mount to init container to allow custom CA certificate keystore + +## 3.3.18 +Added `controller.overrideArgs` so any cli argument can be passed to the WAR. + +## 3.3.17 +Correct docs on disabling plugin installation + +## 3.3.16 +Support generating `SecretClaim` resources in order to read secrets from HashiCorp Vault into Kubernetes using `kube-vault-controller`. + +## 3.3.15 +Prevent `controller.httpsKeyStore` from improperly being quoted, leading to an invalid location on disk + +## 3.3.14 +Correct docs on disabling plugin installation + +## 3.3.13 +Update plugins + +## 3.3.12 +Add `controller.additionalExistingSecrets` property + +## 3.3.11 +Add support for disabling the Agent listener service via `controller.agentListenerEnabled`. + +## 3.3.10 +Update Jenkins image and appVersion to jenkins lts release version 2.277.4 + +## 3.3.9 +* Change helper template so user defined `agent.jenkinsUrl` value will always be used, if set +* Simplify logic for `jenkinsUrl` and `jenkinsTunnel` generation: always use fully qualified address + +## 3.3.8 +Update Jenkins image and appVersion to jenkins lts release version 2.277.3 + +## 3.3.7 +fix controller-ingress line feed bug + +## 3.3.6 + +Update Git plugin version to v4.7.1 +Update ldap plugin version to v2.5 + +## 3.3.5 + +Use tpl function for environment vars. Fixes [https://github.com/jenkinsci/helm-charts/issues/324] + +## 3.3.4 + +Update Jenkins image and appVersion to jenkins lts release version 2.277.2 + + +## 3.3.3 + +Enable setting `controller.installLatestPlugins` to set whether to download the minimum required version of all dependencies. + +## 3.3.2 + +Add `controller.additionalSecrets` documentation + +## 3.3.1 + +Add `controller.additionalSecrets` property + +## 3.3.0 + +Change default Jenkins image to `jdk11` variant + +## 3.2.6 + +Add missing `controller.jenkinsUrlProtocol` property + +## 3.2.5 + +Add additional metadata `artifacthub.io/images` for artifacthub + +## 3.2.4 +Update Jenkins image and appVersion to jenkins lts release version 2.277.1 +Update Git plugin version to v4.6.0 +Update kubernetes plugin version to v1.29.2 + +## 3.2.3 + +Fix rendering `controller.ingress.path` + +## 3.2.2 + +Added description for `controller.jenkinsUrl` value + +## 3.2.1 + +Enable setting ImagePullSecrets to controller and agent service accounts. + +## 3.2.0 + +Calculate consistent unique agent IDs to be used in pod templates. Fixes [https://github.com/jenkinsci/helm-charts/issues/270] + +## 3.1.15 + +Fix documentation for the kubernetes probes + +## 3.1.14 + +Typo in documentation + +## 3.1.13 + +Update Jenkins image and appVersion to jenkins lts release version 2.263.4 + +## 3.1.12 + +Added GitHub Action to automate the updating of LTS releases. + +## 3.1.11 + +Enable setting controller.updateStrategy to change the update strategy for StatefulSet + +## 3.1.10 + +Fixed issue for the AgentListener where it was not possible to attribute a NodePort + +## 3.1.9 + +Upgrade kubernetes plugin to 1.29.0 and CasC plugin to 1.47 + +## 3.1.8 + +Fix init scripts config map name + +## 3.1.7 + +Fix missing newline when `httpsKeyStore` is enabled + +## 3.1.6 + +Mount controller init scripts from ConfigMap + +## 3.1.5 + +Fix `namespaceOverride` not applied when loading JCasC + +## 3.1.4 + +Update Git plugin version to v4.5.2 + +## 3.1.3 + +Update Jenkins image and appVersion to jenkins lts release version 2.263.3 + +## 3.1.2 + +Enable setting maxRequestsPerHostStr to change the max concurrent connections to Kubernetes API + +## 3.1.1 + +Update Jenkins image and appVersion to jenkins lts release version 2.263.2 + +## 3.1.0 + +* Added `.Values.controller.podSecurityContextOverride` and `.Values.backup.podSecurityContextOverride`. +* Added simple default values tests for `jenkins-backup-cronjob.yaml`. + +## 3.0.14 + +Enable to only backup job folder instead of whole jenkins + +## 3.0.13 + +Improve Documentation around JCasc and Custom Image + +## 3.0.12 + +Added GitHub Action testing on Kind 1.16, 1.17, 1.18, 1.19 & 1.20 + +## 3.0.11 + +Fixes & unit tests for Ingress resources on Kubernetes 1.19 and above + +## 3.0.10 + +Ingress resources on Kubernetes 1.19 (or above) are created with the version `networking.k8s.io/v1` + +## 3.0.9 + +Added support for backing up to Azure Blob Storage. + +## 3.0.8 + +* Typo in documentation + +## 3.0.7 + +* Add support for setting default agent workspaceVolume + +## 3.0.6 + +Use 2.263.1 image + +## 3.0.5 + +* Update appVersion to reflect new jenkins lts release version 2.263.1 + +## 3.0.4 + +* Fix documentation for additional secret mounts + +## 3.0.3 + +* Update `README.md` with explanation on how to mount additional secrets + +## 3.0.2 + +* Fix `.Values.controller.tolerations` and `.Values.controller.nodeSelector` variable names in templates\jenkins-backup-cronjob.yaml + +## 3.0.1 + +* added 'runAsNonroot' to security context + +## 3.0.0 + +* Chart uses StatefulSet instead of Deployment +* XML configuration was removed in favor of JCasC +* chart migrated to helm 3.0.0 (apiVersion v2) +* offending terms have been removed +* values have been renamed and re-ordered to make it easier to use +* already deprecated items have been removed +* componentName for the controller is now `jenkins-controller` +* componentName for the agent is now `jenkins-agent` +* container names are now + * `init` for the init container which downloads Jenkins plugins + * `jenkins` for the Jenkins controller + * `config-reload` for the sidecar container which automatically reloads JCasC +* Updated UI tests to use official `bats/bats` image instead of `dduportal/bats` + +For migration instructions from previous versions and additional information check README.md. + +## 2.19.0 + +* Use lts version 2.249.3 +* Update kubernetes, workflow-aggregator, git and configuration-as-code plugins. +* Fail apply_config.sh script if an error occurs. + +## 2.18.2 + +Fix: `master.javaOpts` issue with quoted values + +## 2.18.1 + +Recommend installing plugins in custom image + +## 2.18.0 + +Removed /tmp volume. Making /tmp a volume causes permission issues with jmap/jstack on certain Kubernetes clusters + +## 2.17.1 + +Fix location of jenkins.war file. +It is located in `/usr/share/jenkins/jenkins.war` and can be fonfigured via `master.jenkinsWar`. + +## 2.17.0 + +Add support for plugin-installation-manager-tool + +## 2.16.0 + +Added Startup probe for Jenkins pod when Kubernetes cluster is 1.16 or newer + +## 2.15.5 + +scriptApproval is taken into account when enableXmlConfig is false. + +## 2.15.4 + +Add Tilt support for easier helm chart development. + +## 2.15.3 + +Fix error on missing `ingress.paths` value + +## 2.15.2 + +Added documentation for ingress and jenkins URL + +## 2.15.1 + +Fix priorityClassName entry in values.yaml file + +## 2.15.0 + +Added support for disabling the helm.sh/chart annotation + +## 2.14.0 + +Added support for annotations in podTemplates + +## 2.13.2 + +Add nodeSelector in the backup pod +Fix tolerations in the backup pod + +## 2.13.1 + +Update list of maintainers + +## 2.13.0 + +Added Support for websockets in the default Jcasc config +Added trailing slash to JENKINS_URL env var + +## 2.12.2 + +Added unit tests for most resources in the Helm chart. + +## 2.12.1 + +Helm chart readme update + +## 2.12.0 + +Add option to configure securityContext capabilities + +## 2.11.0 + +Added configurable security context for jenkins backup CronJob and annotations to its serviceaccount. + +## 2.10.0 + +Make activeDeadlineSeconds for backup job configurable + +## 2.9.0 + +Make namespace of PrometheusRule configurable + +## 2.8.2 + +Bumped configuration-as-code plugin version from 1.41 to 1.43. +See [configuration-as-code plugin issue #1478](https://github.com/jenkinsci/configuration-as-code-plugin/issues/1478) + +## 2.8.1 + +Fix indentation of JAVA_OPTS + +## 2.8.0 + +Add support for helm unittest and include first tests + +## 2.7.2 + +Target port of container `jenkins-sc-config` taken the value from values.yaml. + +## 2.7.0 + +Add a secondary ingress template for those who want a second ingress with different labels or annotations or whatever else. + +Example: You want /github-webhook to be on a public ingress, while the main Jenkins intance to be on a private locked down ingress. + +## 2.6.5 + +Update configScripts example + +## 2.6.4 + +Add timja as a maintainer + +## 2.6.3 + +Update k8s-sidecar image to 0.1.193 + +## 2.6.2 + +Only mount empty dir secrets-dir if either `master.enableXmlConfig` or `master.secretsFilesSecret` is set +Fixes #19 + +## 2.6.1 Do not render empty JCasC templates + +## 2.6.0 First release in jenkinsci GitHub org + +Updated readme for new location + +## 2.5.2 + +Fix as per JENKINS-47112 + +## 2.5.1 + +Support Jenkins Resource Root URL + +## 2.5.0 + +Add an option to specify that Jenkins master should be initialized only once, during first install. + +## 2.4.1 + +Reorder readme parameters into sections to facilitate chart usage and maintenance + +## 2.4.0 Update default agent image + +`jenkins/jnlp-slave` is deprected and `jenkins/inbound-agent` should be used instead. +Also updated it to newest version (4.3-4). + +## 2.3.3 correct templating of master.slaveJenkinsUrl + +Fixes #22708 + +## 2.3.2 Fix wrong value for overwritePluginsFromImage + +Fixes #23003 +Fixes #22633 + +Also fixes indentation for #23114 + +## 2.3.1 + +Always mount {{ .Values.master.jenkinsRef }}/secrets/ directory. Previous it +was mounted only when `master.enableXmlConfig` was enabled. + +## 2.3.0 + +Add an option to specify pod based on labels that can connect to master if NetworkPolicy is enabled + +## 2.2.0 increase retry for config auto reload + +Configure `REQ_RETRY_CONNECT` to `10` to give Jenkins more time to start up. + + +Value can be configured via `master.sidecars.configAutoReload.reqRetryConnect` + +## 2.1.2 updated readme + +## 2.1.1 update credentials-binding plugin to 1.23 + +## 2.1.0 + +Add support to set `runAsUser` and `runAsGroup` for `agent`. + +## 2.0.1 + +Only render authorizationStrategy and securityRealm when values are set. + +## 2.0.0 Configuration as Code now default + container does not run as root anymore + +The readme contains more details for this update. +Please note that the updated values contain breaking changes. + +## 1.27.0 Update plugin versions & sidecar container + +| plugin | old version | new version | +| --------------------- | ----------- | ----------- | +| kubernetes | 1.25.3 | 1.25.7 | +| workflow-job | 2.38 | 2.39 | +| credentials-binding | 1.21 | 1.22 | +| configuration-as-code | 1.39 | 1.41 | + +configAutoReload container updated from `kiwigrid/k8s-sidecar:0.1.132` to `kiwigrid/k8s-sidecar:0.1.144` + +## 1.26.0 + +Add support to override `workingDir` for default pod template + +## 1.25.0 + +Add support for installing plugins in addition to the chart's default plugins via `master.additionalPlugins` + +## 1.24.0 + +Allow configuration of yamlMergeStrategy via `agent.yamlMergeStrategy` + +## 1.23.2 + +In the `jenkins.xml.podTemplate` helper function, allow templating of all string values under `agent.volumes` except `type` by rendering them with the `tpl` function + +## 1.23.1 + +Added auto detection for Ingress API version + +## 1.23.0 + +Allow to use an existing secret for the jenkins admin credentials + +## 1.22.0 + +Add support for UI security in the default JCasC via `master.JCasC.securityRealm` and `master.JCasC.authorizationStrategy` which deny anonymous access by default + +## 1.21.3 + +Render `agent.envVars` in kubernetes pod template JCasC + +## 1.21.2 + +Cleanup `agent.yamlTemplate` rendering in kubernetes pod template XML configuration + +## 1.21.1 + +Render `agent.nodeSelector` in the kubernetes pod template JCasC + +## 1.21.0 + +Add support for overriding Ingress paths via `master.ingress.paths` + +## 1.20.0 + +Add the following options for configuring the Kubernetes plugin. + +- master.slaveDefaultsProviderTemplate +- master.slaveJenkinsUrl +- master.slaveJenkinsTunnel +- master.slaveConnectTimeout +- master.slaveReadTimeout + +## 1.19.0 + +Add support for disabling remember me via `master.disableRememberMe` +Add support for using a different markup formatter via `master.markupFormatter` + +## 1.18.1 + +Add support for executor mode configuraton with `master.executorMode`. + +## 1.18.0 Make installation of configuration-as-code plugin explicit + +Instead of configuring the configuration-as-code plugin version via +`master.JCasC.pluginVersion` it is now installed via `master.installPlugins` + +## 1.17.2 + +Allow templating of `serviceAccount.annotations` and `serviceAccountAgent.annotations` by rendering them with the `tpl` function + +## 1.17.1 + +Add support for Persistent Volume Claim (PVC) in `agent.volumes` + +## 1.17.0 + +Render `agent.volumes` in kubernetes pod template JCasC + +## 1.16.2 + +Reverts 1.16.1 as it introduced an error #22047 + +## 1.16.1 + +Fixed a bug with master.runAsUser variable due to use wrong type for comparison. + +## 1.16.0 + +Add `master.overwritePluginsFromImage` to allow support for jenkins plugins installed in the master image to persist. + +## 1.15.0 Update plugin versions & sidecar container + +| plugin | old version | new version | +| --------------------- | ----------- | ----------- | +| kubernetes | 1.25.1 | 1.25.3 | +| workflow-job | 2.36 | 2.38 | +| git | 4.2.0 | 4.2.2 | +| configuration-as-code | 1.36 | 1.39 | + +configAutoReload container updated from `kiwigrid/k8s-sidecar:0.1.20` to `kiwigrid/k8s-sidecar:0.1.132` + +## 1.14.0 + +support auto-reload container environment variables configuration + +## 1.13.3 + +Fix wrong indent in tolerations + +## 1.13.2 + +Add support for custom ClusterIP + +## 1.13.1 + +Fix `agent.yamlTemplate` rendering in kubernetes pod template JCasC + +## 1.13.0 + +Add `master.networkPolicy.internalAgents` and `master.networkPolicy.externalAgents` stanzas to fine grained controls over where internal/external agents can connect from. Internal ones are allowed based on pod labels and (optionally) namespaces, and external ones are allowed based on IP ranges. + +## 1.12.0 Support additional agents + +Add support for easy configuration of additional agents which inherit values from `agent`. + +## 1.11.3 + +Update the kubernetes plugin from 1.24.1 to 1.25.1 and grant 'watch' permission to 'events' which is required since this plugin version. + +## 1.11.2 Configure agent.args in values.yaml + +## 1.11.1 Support for master.additionalConfig + +Fixed a bug with jenkinsHome variable in range block when master.additionalConfig is set - Helm cannot evaluate field Values in type interface {}. + +## 1.11.0 Add support for configuring custom pod templates + +Add `agent.podTemplates` option for declaring custom pod templates in the default configured kubernetes cloud. + +## 1.10.1 Only copy JCasC files if there are any + +The chart always tried to copy Configuration as Code configs even if there are none. That resulted in an error which is resolved with this. + +## 1.10.0 Remove configuration-as-code-support plugins + +In recent version of configuration-as-code-plugin this is no longer necessary. + +## 1.9.24 + +Update JCasC auto-reload docs and remove stale SSH key references from version "1.8.0 JCasC auto reload works without SSH keys" + +## 1.9.23 Support jenkinsUriPrefix when JCasC is enabled + +Fixed a bug in the configuration as code reload URL, where it wouldn't work with a jenkinsUriPrefix set. + +## 1.9.22 + +Add `master.jenkinsHome` and `master.jenkinsRef` options to use docker images derivates from Jenkins + +## 1.9.21 + +Add `master.terminationGracePeriodSeconds` option + +## 1.9.20 + +Update default plugins + +- kubernetes:1.24.1 +- workflow-job:2.36 +- workflow-aggregator:2.6 +- credentials-binding:1.21 +- git:4.2.0 +- configuration-as-code:1.36 + +## 1.9.19 + +Update docs for Helm 3 + +## 1.9.18 + +Make `jenkins-home` attachable to Azure Disks without pvc + +```yaml + volumes: + - name: jenkins-home + azureDisk: + kind: Managed + diskName: myAKSDisk + diskURI: /subscriptions//resourceGroups/MC_myAKSCluster_myAKSCluster_eastus/providers/Microsoft.Compute/disks/myAKSDisk +``` + +## 1.9.16 + +Fix PodLabel for NetworkPolicy to work if enabled + +## 1.9.14 + +Properly fix case sense in `Values.master.overwriteConfig` in `config.yaml` + +## 1.9.13 + +Fix case sense in `Values.master.overwriteConfig` in `config.yaml` + +## 1.9.12 + +Scriptapprovals are overwritten when overwriteConfig is enabled + +## 1.9.10 + +Added documentation for `persistence.storageClass`. + +## 1.9.9 +Make `master.deploymentAnnotation` configurable. + +## 1.9.8 + +Make `agent.slaveConnectTimeout` configurable: by increasing this value Jenkins will not cancel&ask k8s for a pod again, while it's on `ContainerCreating`. Useful when you have big images or autoscaling takes some time. + +## 1.9.7 Update plugin versions + +| plugin | old version | new version | +|-----------------------|-------------|-------------| +| kubernetes | 1.18.2 | 1.21.2 | +| workflow-job | 2.33 | 2.36 | +| credentials-binding | 1.19 | 1.20 | +| git | 3.11.0 | 4.0.0 | +| configuration-as-code | 1.27 | 1.32 | + +## 1.9.6 + +Enables jenkins to use keystore inorder to have native ssl support #17790 + +## 1.9.5 Enable remoting security + +`Manage Jenkins` -> `Configure Global Security` -> `Enable Agent → Master Access Control` is now enabled via configuration as code plugin + +## 1.9.4 Option to set existing secret with Google Application Default Credentials + +Google application credentials are kept in a file, which has to be mounted to a pod. You can set `gcpcredentials` in `existingSecret` as follows: + +```yaml + existingSecret: + jenkins-service-account: + gcpcredentials: application_default_credentials.json +``` + +Helm template then creates the necessary volume mounts and `GOOGLE_APPLICATION_CREDENTIALS` environmental variable. + +## 1.9.3 Fix `JAVA_OPTS` when config auto-reload is enabled + +## 1.9.2 Add support for kubernetes-credentials-provider-plugin + +[kubernetes-credentials-provider-plugin](https://jenkinsci.github.io/kubernetes-credentials-provider-plugin/) needs permissions to get/watch/list kubernetes secrets in the namespaces where Jenkins is running. + +The necessary role binding can be created using `rbac.readSecrets` when `rbac.create` is `true`. + +To quote from the plugin documentation: + +> Because granting these permissions for secrets is not something that should be done lightly it is highly advised for security reasons that you both create a unique service account to run Jenkins as, and run Jenkins in a unique namespace. + +Therefor this is disabled by default. + +## 1.9.1 Update kubernetes plugin URL + +## 1.9.0 Change default serviceType to ClusterIP + +## 1.8.2 + +Revert fix in `1.7.10` since direct connection is now disabled by default. + +## 1.8.1 + +Add `master.schedulerName` to allow setting a Kubernetes custom scheduler + +## 1.8.0 JCasC auto reload works without SSH keys + +We make use of the fact that the Jenkins Configuration as Code Plugin can be triggered via http `POST` to `JENKINS_URL/configuration-as-code/reload`and a pre-shared key. +The sidecar container responsible for reloading config changes is now `kiwigrid/k8s-sidecar:0.1.20` instead of it's fork `shadwell/k8s-sidecar`. + +References: + +- [Triggering Configuration Reload](https://github.com/jenkinsci/configuration-as-code-plugin/blob/master/docs/features/configurationReload.md) +- [kiwigrid/k8s-sidecar](https://hub.docker.com/r/kiwigrid/k8s-sidecar) + +`master.sidecars.configAutoReload.enabled` now works using `casc.reload.token` + +## 1.7.10 + +Disable direct connection in default configuration (when kubernetes plugin version >= 1.20.2). +Note: In case direct connection is going to be used `jenkins/jnlp-slave` needs to be version `3.35-5` or newer. + +## 1.7.9 + +Prevented Jenkins Setup Wizard on new installations + +## 1.7.8 + +Extend extraPorts to be opened on the Service object, not just the container. + +## 1.7.7 + +Add persistentvolumeclaim permission to the role to support new dynamic pvc workspaces. + +## 1.7.6 + +Updated `master.slaveKubernetesNamespace` to parse helm templates. +Defined an sensible empty value to the following variables, to silence invalid warnings: + +- master.extraPorts +- master.scriptApproval +- master.initScripts +- master.JCasC.configScripts +- master.sidecars.other +- agent.envVars +- agent.volumes + +## 1.7.5 + +Fixed an issue where the JCasC won't run if JCasC auto-reload is enabled [issue #17135](https://github.com/helm/charts/issues/17135) + +## 1.7.4 + +Comments out JCasC example of jenkins.systemMessage so that it can be used by end users. Previously, an attempt to set systemMessage causes Jenkins to startup, citing duplicate JCasC settings for systemMessage [issue #13333](https://github.com/helm/charts/issues/13333) + +## 1.7.2 + +Update kubernetes-plugin to version 1.18.2 which fixes frequently encountered [JENKINS-59000](https://issues.jenkins-ci.org/plugins/servlet/mobile#issue/JENKINS-59000) + +## 1.7.1 + +Update the default requirements for jenkins-agent to 512Mi which fixes frequently encountered [issue #3723](https://github.com/helm/charts/issues/3723) + +## 1.7.0 + +[Jenkins Configuration as Code Plugin](https://github.com/jenkinsci/configuration-as-code-plugin) default configuration can now be enabled via `master.JCasC.defaultConfig`. + +JCasC default configuration includes: + +- Jenkins URL +- Admin email `master.jenkinsAdminEmail` +- crumbIssuer +- disableRememberMe: false +- mode: NORMAL +- numExecutors: {{ .Values.master.numExecutors }} +- projectNamingStrategy: "standard" +- kubernetes plugin + - containerCapStr via `agent.containerCap` + - jenkinsTunnel + - jenkinsUrl + - maxRequestsPerHostStr: "32" + - name: "kubernetes" + - namespace + - serverUrl: `"https://kubernetes.default"` + - template + - containers + - alwaysPullImage: `agent.alwaysPullImage` + - args + - command + - envVars + - image: `agent.image:agent.imageTag` + - name: `.agent.sideContainerName` + - privileged: `.agent.privileged` + - resourceLimitCpu: `agent.resources.limits.cpu` + - resourceLimitMemory: `agent.resources.limits.memory` + - resourceRequestCpu: `agent.resources.requests.cpu` + - resourceRequestMemory: `agent.resources.requests.memory` + - ttyEnabled: `agent.TTYEnabled` + - workingDir: "/home/jenkins" + - idleMinutes: `agent.idleMinutes` + - instanceCap: 2147483647 + - imagePullSecrets: + - name: `.agent.imagePullSecretName` + - label + - name + - nodeUsageMode: "NORMAL" + - podRetention: `agent.podRetention` + - serviceAccount + - showRawYaml: true + - slaveConnectTimeoutStr: "100" + - yaml: `agent.yamlTemplate` + - yamlMergeStrategy: "override" +- security: + - apiToken: + - creationOfLegacyTokenEnabled: false + - tokenGenerationOnCreationEnabled: false + - usageStatisticsEnabled: true + +Example `values.yaml` which enables JCasC, it's default config and configAutoReload: + +```yaml +master: + JCasC: + enabled: true + defaultConfig: true + sidecars: + configAutoReload: + enabled: true +``` + +add master.JCasC.defaultConfig and configure location + +- JCasC configuration is stored in template `jenkins.casc.defaults` + so that it can be used in `config.yaml` and `jcasc-config.yaml` + depending on if configAutoReload is enabled or not + +- Jenkins Location (URL) is configured to provide a startin point + for the config + +## 1.6.1 + +Print error message when `master.sidecars.configAutoReload.enabled` is `true`, but the admin user can't be found to configure the SSH key. + +## 1.6.0 + +Add support for Google Cloud Storage for backup CronJob (migrating from nuvo/kube-tasks to maorfr/kube-tasks) + +## 1.5.9 + +Fixed a warning when sidecar resources are provided through a parent chart or override values + +## 1.5.8 + +Fixed an issue when master.enableXmlConfig is set to false: Always mount jenkins-secrets volume if secretsFilesSecret is set (#16512) + +## 1.5.7 + +added initial changelog (#16324) +commit: cee2ebf98 + +## 1.5.6 + +enable xml config misspelling (#16477) +commit: a125b99f9 + +## 1.5.5 + +Jenkins master label (#16469) +commit: 4802d14c9 + +## 1.5.4 + +add option enableXmlConfig (#16346) +commit: 387d97a4c + +## 1.5.3 + +extracted "jenkins.URL" into template (#16347) +commit: f2fdf5332 + +## 1.5.2 + +Fix backups when deployment has custom name (#16279) +commit: 16b89bfff + +## 1.5.1 + +Ability to set custom namespace for ServiceMonitor (#16145) +commit: 18ee6cf01 + +## 1.5.0 + +update Jenkins plugins to fix security issue (#16069) +commit: 603cf2d2b + +## 1.4.3 + +Use fixed container name (#16068) +commit: b3e4b4a49 + +## 1.4.2 + +Provide default job value (#15963) +commit: c462e2017 + +## 1.4.1 + +Add Jenkins backendconfig values (#15471) +commit: 7cc9b54c7 + +## 1.4.0 + +Change the value name for docker image tags - standartise to helm preferred value name - tag; this also allows auto-deployments using weaveworks flux (#15565) +commit: 5c3d920e7 + +## 1.3.6 + +jenkins deployment port should be target port (#15503) +commit: 83909ebe3 + +## 1.3.5 + +Add support for namespace specification (#15202) +commit: e773201a6 + +## 1.3.4 + +Adding sub-path option for scraping (#14833) +commit: e04021154 + +## 1.3.3 + +Add existingSecret to Jenkins backup AWS credentials (#13392) +commit: d9374f57d + +## 1.3.2 + +Fix JCasC version (#14992) +commit: 26a6d2b99 + +## 1.3.1 + +Update affinity for a backup cronjob (#14886) +commit: c21ed8331 + +## 1.3.0 + +only install casc support plugin when needed (#14862) +commit: a56fc0540 + +## 1.2.2 + +DNS Zone customization (#14775) +commit: da2910073 + +## 1.2.1 + +only render comment if configAutoReload is enabled (#14754) +commit: e07ead283 + +## 1.2.0 + +update plugins to latest version (#14744) +commit: 84336558e + +## 1.1.24 + +add example for EmptyDir volume (#14499) +commit: cafb60209 + +## 1.1.23 + +check if installPlugins is set before using it (#14168) +commit: 1218f0359 + +## 1.1.22 + +Support servicemonitor and alerting rules (#14124) +commit: e15a27f48 + +## 1.1.21 + +Fix: healthProbe timeouts mapping to initial delay (#13875) +commit: 825b32ece + +## 1.1.20 + +Properly handle overwrite config for additional configs (#13915) +commit: 18ce9b558 + +## 1.1.18 + +update maintainer (#13897) +commit: 223002b27 + +## 1.1.17 + +add apiVersion (#13795) +commit: cd1e5c35a + +## 1.1.16 + +allow changing of the target port to support TLS termination sidecar (#13576) +commit: a34d3bbcc + +## 1.1.15 + +fix wrong pod selector in jenkins-backup (#13542) +commit: b5df4fd7e + +## 1.1.14 + +allow templating of customInitContainers (#13536) +commit: d1e1421f4 + +## 1.1.13 + +fix #13467 (wrong deprecation message) (#13511) +commit: fbe28fa1c + +## 1.1.12 + +Correct customInitContainers Name example. (#13405) +commit: 6c6e40405 + +## 1.1.11 + +fix master.runAsUser, master.fsGroup examples (#13389) +commit: 2d7e5bf72 + +## 1.1.10 + +Ability to specify raw yaml template (#13319) +commit: 77aaa9a5f + +## 1.1.9 + +correct NOTES.txt - use master.ingress.hostname (#13318) +commit: b08ef6280 + +## 1.1.8 + +explain how to upgrade major versions (#13273) +commit: e7617a97e + +## 1.1.7 + +Add support for idleMinutes and serviceAccount (#13263) +commit: 4595ee033 + +## 1.1.6 + +Use same JENKINS_URL no matter if slaves use different namespace (#12564) +commit: 94c90339f + +## 1.1.5 + +fix deprecation checks (#13224) +commit: c7d2f8105 + +## 1.1.4 + +Fix issue introduced in #13136 (#13232) +commit: 0dbcded2e + +## 1.1.3 + +fix chart errors (#13197) +commit: 692a1e3da + +## 1.1.2 + +correct selector for jenkins pod (#13200) +commit: 4537e7fda + +## 1.1.1 + +Fix rendering of customInitContainers and lifecycle for Jenkins helm chart (#13189) +commit: e8f6b0ada + +## 1.1.0 + +Add support for openshift route in jenkins (#12973) +commit: 48c58a430 + +## 1.0.0 + +helm chart best practices (#13136) +commit: b02ae3f48 + +### Breaking changes + +- values have been renamed to follow helm chart best practices for naming conventions so + that all variables start with a lowercase letter and words are separated with camelcase + +- all resources are now using recommended standard labels + + +As a result of the label changes also the selectors of the deployment have been updated. +Those are immutable so trying an updated will cause an error like: + +```text +Error: Deployment.apps "jenkins" is invalid: spec.selector: Invalid value: v1.LabelSelector{MatchLabels:map[string]string{"app.kubernetes.io/component":"jenkins-master", "app.kubernetes.io/instance":"jenkins"}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable +``` + +In order to upgrade, delete the Jenkins Deployment before upgrading: + +```console +kubectl delete deploy jenkins +``` + +## 0.40.0 + +Allow to override jenkins location protocol (#12257) +commit: 18a830626 + +## 0.39.0 + +Add possibility to add custom init-container and lifecycle for master-container (#13062) +commit: 14d043593 + +## 0.38.0 + +Support `priorityClassName` on Master Deployment (#13069) +commit: e896c62bc + +## 0.37.3 + +Add support for service account annotations in jenkins (#12969) +commit: b22774e2f + +## 0.37.2 + +fix: add hostName to ingress in values.yaml (#12946) +commit: 041045e9b + +## 0.37.1 + +Update to match actual defaults in value.yaml (#12904) +commit: 73b6d37eb + +## 0.37.0 + +Support multiple Jenkins instances in same namespace (#12748) +commit: 32ff2f343 + +## 0.36.5 + +Fix wrong comment in values.yaml (#12761) +commit: 9db8ced23 + +## 0.36.4 + +Re-add value for Ingress API Version (#12753) +commit: ecb7791b5 + +## 0.36.3 + +allow templating of volumes (#12734) +commit: adbda2ca6 + +## 0.36.2 + +Fix self-introduced whitespace bug (#12528) +commit: eec1678eb + +## 0.36.1 + +Add flag to overwrite jobs definition from values.yaml (#12427) +commit: fd349b2fc + +## 0.36.0 + +Replace OwnSshKey with AdminSshKey (#12140) (#12466) +commit: 80a8c9eb6 + +## 0.35.2 + +add note for breaking changes (#12203) +commit: e779c5a54 + +## 0.35.1 + +Allow Jenkins to run with READONLYROOTFS psp (#12338) +commit: 7c419e191 + +## 0.35.0 + +Jenkins OverwriteConfig setting also overwrites init scripts (#9468) +commit: 501335b76 + +## 0.34.1 + +Fix typo on hostname variable (#12156) +commit: 3d337d8dd + +## 0.34.0 + +Allow ingress without host rule (#11960) +commit: ddc966d1e + +## 0.33.2 + +Improve documentation - clarify that rbac is needed for autoreload (#11739) +commit: 9d75a5c34 + +## 0.33.1 + +use object for rollingUpdate (#11909) +commit: cb9cf21e8 + +## 0.33.0 + +Add hostAliases (#11701) +commit: 0b89e1094 + +## 0.32.10 + +Fix slave jnlp port always being reset when container is restarted (#11685) +commit: d7d51797b + +## 0.32.9 + +add ingress Hostname an ApiVersion to docs (#11576) +commit: 4d3e77137 + +## 0.32.8 + +Support custom master pod labels in deployment (#9714) (#11511) +commit: 9de96faa0 + +## 0.32.7 + +Fix Markdown syntax in readme (#11496) +commit: a32221a95 + +## 0.32.6 + +Added custom labels on jenkins ingress (#11466) +commit: c875d2b9b + +## 0.32.5 + +fix typo in default jenkins agent image fixes #11356 (#11463) +commit: 30adb9a91 + +## 0.32.4 + +fix incorrect Deployment when using sidecars (#11413) +commit: 362b4cef8 + +## 0.32.3 + +[]: #10131 (#11411) +commit: 49cb72055 + +## 0.32.2 + +Option to expose the slave listener port as host port (#11187) +commit: 2f85a9663 + +## 0.32.1 + +Updating Jenkins deployment fails appears rollingUpdate needs to be (#11166) +commit: 07fc9dbde + +## 0.32.0 + +Merge Sidecard configs (#11339) +commit: 3696090b9 + +## 0.31.0 + +Add option to overwrite plugins (#11231) +commit: 0e9aa00a5 + +## 0.30.0 + +Added slave Pod env vars (#8743) +commit: 1499f6608 + +## 0.29.3 + +revert indentation to previous working version (#11293) +commit: 61662f17a + +## 0.29.2 + +allow running sidecar containers for Jenkins master (#10950) +commit: 9084ce54a + +## 0.29.1 + +Indent lines related to EnableRawHtmlMarkupFormatter (#11252) +commit: 20b310c08 + +## 0.29.0 + +Jenkins Configuration as Code (#9057) +commit: c3e8c0b17 + +## 0.28.11 + +Allow to enable OWASP Markup Formatter Plugin (#10851) +commit: 9486e5ddf + +## 0.28.10 + +Fixes #1341 -- update Jenkins chart documentation (#10290) +commit: 411c81cd0 + +## 0.28.9 + +Quoted JavaOpts values (#10671) +commit: 926a843a8 + +## 0.28.8 + +Support custom labels in deployment (#9714) (#10533) +commit: 3e00b47fa + +## 0.28.7 + +separate test resources (#10597) +commit: 7b7ae2d11 + +## 0.28.6 + +allow customizing livenessProbe periodSeconds (#10534) +commit: 3c94d250d + +## 0.28.5 + +Add role kind option (#8498) +commit: e791ad124 + +## 0.28.4 + +workaround for busybox's cp (Closes: #10471) (#10497) +commit: 0d51a4187 + +## 0.28.3 + +fix parsing java options (#10140) +commit: 9448d0293 + +## 0.28.2 + +Fix job definitions in standard values.yaml (#10184) +commit: 6b6355ae7 + +## 0.28.1 + +add numExecutors as a variable in values file (#10236) +commit: d5ea2050f + +## 0.28.0 + +various (#10223) +commit: e17d2a65d + +## 0.27.0 + +add backup cronjob (#10095) +commit: 863ead8db + +## 0.26.2 + +add namespace flag for port-forwarding in jenkins notes (#10399) +commit: 846b589a9 + +## 0.26.1 + +- fixes #10267 when executed with helm template - otherwise produces an invalid template. (#10403) + commit: 266f9d839 + +## 0.26.0 + +Add subPath for jenkins-home mount (#9671) +commit: a9c76ac9b + +## 0.25.1 + +update readme to indicate the correct image that is used by default (#9915) +commit: 6aba9631c + +## 0.25.0 + +Add ability to manually set Jenkins URL (#7405) +commit: a0178fcb4 + +## 0.24.0 + +Make AuthorizationStrategy configurable (#9567) +commit: 06545b226 + +## 0.23.0 + +Update Jenkins public chart (#9296) +commit: 4e5f5918b + +## 0.22.0 + +allow to override jobs (#9004) +commit: dca9f9ab9 + +## 0.21.0 + +Simple implementation of the option to define the ingress path to the jenkins service (#8101) +commit: 013159609 + +## 0.20.2 + +Cosmetic change to remove necessity of changing "appVersion" for every new LTS release (#8866) +commit: f52af042a + +## 0.20.1 + +Added ExtraPorts to open in the master pod (#7759) +commit: 78858a2fb + +## 0.19.1 + +Fix component label in NOTES.txt ... (#8300) +commit: c5494dbfe + +## 0.19.0 + +Kubernetes 1.9 support as well as automatic apiVersion detection (#7988) +commit: 6853ad364 + +## 0.18.1 + +Respect SlaveListenerPort value in config.xml (#7220) +commit: 0a5ddac35 + +## 0.18.0 + +Allow replacement of Jenkins config with configMap. (#7450) +commit: c766da3de + +## 0.17.0 + +Add option to allow host networking (#7530) +commit: dc2eeff32 + +## 0.16.25 + +add custom jenkins labels to the build agent (#7167) +commit: 3ecde5dbf + +## 0.16.24 + +Move kubernetes and job plugins to latest versions (#7438) +commit: 019e39456 + +## 0.16.23 + +Add different Deployment Strategies based on persistence (#6132) +commit: e0a20b0b9 + +## 0.16.22 + +avoid linting errors when adding Values.Ingress.Annotations (#7425) +commit: 99eacc854 + +## 0.16.21 + +bump appVersion to reflect new jenkins lts release version 2.121.3 (#7217) +commit: 296df165d + +## 0.16.20 + +Configure kubernetes plugin for including namespace value (#7164) +commit: c0dc6cc48 + +## 0.16.19 + +make pod retention policy setting configurable (#6962) +commit: e614c1033 + +## 0.16.18 + +Update plugins version (#6988) +commit: bf8180018 + +## 0.16.17 + +Add Master.AdminPassword in readme (#6987) +commit: 13e754ad7 + +## 0.16.16 + +Added jenkins location configuration (#6573) +commit: 79de7026c + +## 0.16.15 + +use generic env var, not oracle specific env var (#6116) +commit: 6084ab4a4 + +## 0.16.14 + +Allow to specify resource requests and limits on initContainers (#6723) +commit: 942a33b1a + +## 0.16.13 + +Added support for NodePort service type for jenkens agent svc (#6571) +commit: 89a213c2b + +## 0.16.12 + +Added ability to configure multiple LoadBalancerSourceRanges (#6243) +commit: 01604ddbc + +## 0.16.11 + +Removing ContainerPort configuration as at the moment it does not work when you change this setting (#6411) +commit: e1c0468bd + +## 0.16.9 + +Fix jobs parsing for configmap by adding toYaml to jobs.yaml template (#3747) +commit: b2542a123 + +## 0.16.8 + +add jenkinsuriprefix in healthprobes (#5737) +commit: 435d7a7b9 + +## 0.16.7 + +Added the ability to switch from ClusterRoleBinding to RoleBinding. (#6190) +commit: dde03ede0 + +## 0.16.6 + +Make jenkins master pod security context optional (#6122) +commit: 63653fd59 + +## 0.16.5 + +Rework resources requests and limits (#6077) (#6077) +commit: e738f99d0 + +## 0.16.4 + +Add jenkins master pod annotations (#6313) +commit: 5e7325721 + +## 0.16.3 + +Split Jenkins readiness and liveness probe periods (#5704) +commit: fc6100c38 + +## 0.16.1 + +fix typo in jenkins readme (#5228) +commit: 3cd3f4b8b + +## 0.16.0 + +Inherit existing plugins from Jenkins image (#5409) +commit: fd93bff82 + +## 0.15.1 + +Allow NetworkPolicy.ApiVersion and Master.Ingress.ApiVersion to Differ (#5103) +commit: 78ee4ba15 + +## 0.15.0 + +Secure Defaults (#5026) +commit: 0fe90b520 + +## 0.14.6 + +Wait for up to 2 minutes before failing liveness check (#5161) +commit: 2cd3fc481 + +## 0.14.5 + +correct ImageTag setting (#4371) +commit: 8ea04174d + +## 0.14.4 + +Update jenkins/README.md (#4559) +commit: d4e6352dd + +## 0.14.3 + +Bump appVersion (#4177) +commit: 605d3d441 + +## 0.14.2 + +Master.InitContainerEnv: Init Container Env Vars (#3495) +commit: c64abe27d + +## 0.14.1 + +Allow more configuration of Jenkins agent service (#4028) +commit: fc82f39b2 + +## 0.14.0 + +Add affinity settings (#3839) +commit: 64e82fa6a + +## 0.13.5 + +bump test timeouts (#3886) +commit: cd05dd99c + +## 0.13.4 + +Add OWNERS to jenkins chart (#3881) +commit: 1c106b9c8 + +## 0.13.3 + +Add fullnameOverride support (#3705) +commit: ec8080839 + +## 0.13.2 + +Update README.md (#3638) +commit: f6d274c37 + +## 0.13.1 + +Lower initial healthcheck delay (#3463) +commit: 9b99db67c + +## 0.13.0 + +Provision credentials.xml, secrets files and jobs (#3316) +commit: d305c5961 + +## 0.12.1 + +fix the default value for nodeUsageMode. (#3299) +commit: b68d19516 + +## 0.12.0 + +Recreate pods when CustomConfigMap is true and there are changes to the ConfigMap (which is how the vanilla chart works) (#3181) +commit: 86d29f804 + +## 0.11.1 + +Optionally adds liveness and readiness probes to jenkins (#3245) +commit: 8b9aa73ee + +## 0.11.0 + +Feature/run jenkins as non root user (#2899) +commit: 8918f4175 + +## 0.10.3 + +template the version to keep them synced (#3084) +commit: 35e7fa49a + +## 0.10.2 + +Update Chart.yaml +commit: e3e617a0b + +## 0.10.1 + +Merge branch 'master' into jenkins-test-timeout +commit: 9a230a6b1 + +Double retry count for Jenkins test +commit: 129c8e824 + +Jenkins: Update readme | Master.ServiceAnnotations (#2757) +commit: 6571810bc + +## 0.10.0 + +Update Jenkins images and plugins (#2496) +commit: 2e2622682 + +## 0.9.4 + +Updating to remove the `.lock` directory as well (#2747) +commit: 6e676808f + +## 0.9.3 + +Use variable for service port when testing (#2666) +commit: d044f99be + +## 0.9.2 + +Review jenkins networkpolicy docs (#2618) +commit: 49911e458 + +Add image pull secrets to jenkins templates (#1389) +commit: 4dfae21fd + +## 0.9.1 + +Added persistent volume claim annotations (#2619) +commit: ac9e5306e + +Fix failing CI lint (#2758) +commit: 26f709f0e + +## 0.9.0 + +namespace defined templates with chart name (#2140) +commit: 408ae0b3f + +## 0.8.9 + +added useSecurity and adminUser to params (#1903) +commit: 39d2a03cd + +Use storageClassName for jenkins. (#1997) +commit: 802f6449b + +## 0.8.8 + +Remove old plugin locks before installing plugins (#1746) +commit: 6cd7b8ff4 + +promote initContainrs to podspec (#1740) +commit: fecc804fc + +## 0.8.7 + +add optional LoadBalancerIP option. (#1568) +commit: d39f11408 + +## 0.8.6 + +Fix bad key in values.yaml (#1633) +commit: dc27e5af3 + +## 0.8.5 + +Update Jenkins to support node selectors for agents. (#1532) +commit: 4af5810ff + +## 0.8.4 + +Add support for supplying JENKINS_OPTS and/or URI prefix (#1405) +commit: 6a331901a + +## 0.8.3 + +Add serviceAccountName to deployment (#1477) +commit: 0dc349b44 + +## 0.8.2 + +Remove path from ingress specification to allow other paths (#1599) +commit: e727f6b32 + +Update git plugin to 3.4.0 for CVE-2017-1000084 (#1505) +commit: 03482f995 + +## 0.8.1 + +Use consistent whitespace in template placeholders (#1437) +commit: 912f50c71 + +add configurable service annotations #1234 (#1244) +commit: 286861ca8 + +## 0.8.0 + +Jenkins v0.8.0 (#1385) +commit: 0009a2393 + +## 0.7.4 + +Use imageTag as version in config map (#1333) +commit: e8bb6ebb4 + +## 0.7.3 + +Add NetworkPolicy to Jenkins (#1228) +commit: 572b36c6d + +## 0.7.2 + +- Workflow plugin pin (#1178) + commit: ac3a0c7bc + +## 0.7.1 + +copy over plugins.txt in case of update (#1222) +commit: 75b5b1174 + +## 0.7.0 + +add jmx option (#964) +commit: 6ae8d1945 + +## 0.6.4 + +update jenkins to latest LTS 2.46.3 (#1182) +commit: ad90b4c27 + +## 0.6.3 + +Update chart maints to gh u/n (#1107) +commit: f357b77ed + +## 0.6.2 + +Add Agent.Privileged option (#957) +commit: 2cf4aced2 + +## 0.6.1 + +Upgrade jenkins to 2.46.2 (#971) +commit: 41bd742b4 + +## 0.6.0 + +Smoke test for Jenkins Chart (#944) +commit: 110441054 + +## 0.5.1 + +removed extra space from hardcoded password (#925) +commit: 85a9b9123 + +## 0.5.0 + +move config to init-container allowing use of upstream containers (#921) +commit: 1803c3d33 + +## 0.4.1 + +add ability to toggle jnlp-agent podTemplate generation (#918) +commit: accd53203 + +## 0.4.0 + +Jenkins add script approval (#916) +commit: c1746656e + +## 0.3.1 + +Update Jenkins to Latest LTS fixes #731 (#733) +commit: e9a3aed8b + +## 0.3.0 + +Added option to add Jenkins init scripts (#617) +commit: b889623d0 + +## 0.2.0 + +Add existing PVC (#716) +commit: 05271f145 + +## 0.1.15 + +use Master.ServicePort in config.xml (#769) +commit: f351f4b16 + +## 0.1.14 + +Added option to disable security on master node (#403) +commit: 3a6113d18 + +## 0.1.13 + +Added: extra mount points support for jenkins master (#474) +commit: fab0f7eb1 + +## 0.1.12 + +fix storageclass config typo (#548) +commit: 6fc0ff242 + +## 0.1.10 + +Changed default value of Kubernetes Cloud name to match one in kubernetes plugin (#404) +commit: 68351304a + +Add support for overriding the Jenkins ConfigMap (#524) +commit: f97ca53b1 + +## 0.1.9 + +Added jenkins-master ingress support (#402) +commit: d76a09588 + +## 0.1.8 + +Change description (#553) +commit: 91f5c24e1 + +Removed default Persistence.StorageClass: generic (#530) +commit: c87494c10 + +Update to the recommended pvc patterns. (#448) +commit: a7fc595aa + +Remove helm.sh/created annotations (#505) +commit: f380da2fb + +## 0.1.7 + +add support for explicit NodePort on jenkins chart (#342) +commit: f63c188da + +Add configurable loadBalancerSourceRanges for jenkins chart (#360) +commit: 44007c50e + +Update Jenkins version to current LTS (2.19.4) and Kubernetes Plugin to 0.10 (#341) +commit: 6c8678167 + +## 0.1.6 + +Add imagePullPolicy to init container (#295) +commit: 103ee1952 + +## 0.1.5 + +bump chart version with PVC metadata label additions +commit: 4aa9cf5b1 + +## 0.1.4 + +removed `*` from `jenkins/templates/NOTES.txt` +commit: 76212230b + +apply standard metadata labels to PVC's +commit: 58b730836 + +specify namespace in `kubectl get svc` commands in NOTES.txt +commit: 7d3287e81 + +Update Jenkins version to current LTS (#194) +commit: 2c0404049 + +## 0.1.1 + +escape fixed +commit: 2026e1d15 + +.status.loadBalancer.ingress[0].ip is empty in AWS +commit: 1810e37f4 + +.status.loadBalancer.ingress[0].ip is empty in AWS +commit: 3cbd3ced6 + +Remove 'Getting Started:' from various NOTES.txt. (#181) +commit: 2f63fd524 + +docs(\*): update readmes to reference chart repos (#119) +commit: c7d1bff05 + +## 0.1.0 + +Move first batch of PVC charts to stable +commit: d745f4879 diff --git a/charts/jenkins/jenkins/5.5.1/Chart.yaml b/charts/jenkins/jenkins/5.5.1/Chart.yaml new file mode 100644 index 000000000..c0777b2a5 --- /dev/null +++ b/charts/jenkins/jenkins/5.5.1/Chart.yaml @@ -0,0 +1,54 @@ +annotations: + artifacthub.io/category: integration-delivery + artifacthub.io/changes: | + - Update `kubernetes` to version `4265.v78b_d4a_1c864a_` + artifacthub.io/images: | + - name: jenkins + image: docker.io/jenkins/jenkins:2.452.3-jdk17 + - name: k8s-sidecar + image: docker.io/kiwigrid/k8s-sidecar:1.27.5 + - name: inbound-agent + image: jenkins/inbound-agent:3256.v88a_f6e922152-1 + artifacthub.io/license: Apache-2.0 + artifacthub.io/links: | + - name: Chart Source + url: https://github.com/jenkinsci/helm-charts/tree/main/charts/jenkins + - name: Jenkins + url: https://www.jenkins.io/ + - name: support + url: https://github.com/jenkinsci/helm-charts/issues + catalog.cattle.io/certified: partner + catalog.cattle.io/display-name: Jenkins + catalog.cattle.io/kube-version: '>=1.14-0' + catalog.cattle.io/release-name: jenkins +apiVersion: v2 +appVersion: 2.452.3 +description: 'Jenkins - Build great things at any scale! As the leading open source + automation server, Jenkins provides over 1800 plugins to support building, deploying + and automating any project. ' +home: https://www.jenkins.io/ +icon: file://assets/icons/jenkins.svg +keywords: +- jenkins +- ci +- devops +kubeVersion: '>=1.14-0' +maintainers: +- email: maor.friedman@redhat.com + name: maorfr +- email: mail@torstenwalter.de + name: torstenwalter +- email: garridomota@gmail.com + name: mogaal +- email: wmcdona89@gmail.com + name: wmcdona89 +- email: timjacomb1@gmail.com + name: timja +name: jenkins +sources: +- https://github.com/jenkinsci/jenkins +- https://github.com/jenkinsci/docker-inbound-agent +- https://github.com/maorfr/kube-tasks +- https://github.com/jenkinsci/configuration-as-code-plugin +type: application +version: 5.5.1 diff --git a/charts/jenkins/jenkins/5.5.1/README.md b/charts/jenkins/jenkins/5.5.1/README.md new file mode 100644 index 000000000..4ddd1faa4 --- /dev/null +++ b/charts/jenkins/jenkins/5.5.1/README.md @@ -0,0 +1,706 @@ +# Jenkins + +[![Artifact Hub](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/jenkins)](https://artifacthub.io/packages/helm/jenkinsci/jenkins) +[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) +[![Releases downloads](https://img.shields.io/github/downloads/jenkinsci/helm-charts/total.svg)](https://github.com/jenkinsci/helm-charts/releases) +[![Join the chat at https://app.gitter.im/#/room/#jenkins-ci:matrix.org](https://badges.gitter.im/badge.svg)](https://app.gitter.im/#/room/#jenkins-ci:matrix.org) + +[Jenkins](https://www.jenkins.io/) is the leading open source automation server, Jenkins provides over 1800 plugins to support building, deploying and automating any project. + +This chart installs a Jenkins server which spawns agents on [Kubernetes](http://kubernetes.io) utilizing the [Jenkins Kubernetes plugin](https://plugins.jenkins.io/kubernetes/). + +Inspired by the awesome work of [Carlos Sanchez](https://github.com/carlossg). + +## Get Repository Info + +```console +helm repo add jenkins https://charts.jenkins.io +helm repo update +``` + +_See [`helm repo`](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + +## Install Chart + +```console +# Helm 3 +$ helm install [RELEASE_NAME] jenkins/jenkins [flags] +``` + +_See [configuration](#configuration) below._ + +_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ + +## Uninstall Chart + +```console +# Helm 3 +$ helm uninstall [RELEASE_NAME] +``` + +This removes all the Kubernetes components associated with the chart and deletes the release. + +_See [helm uninstall](https://helm.sh/docs/helm/helm_uninstall/) for command documentation._ + +## Upgrade Chart + +```console +# Helm 3 +$ helm upgrade [RELEASE_NAME] jenkins/jenkins [flags] +``` + +_See [helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) for command documentation._ + +Visit the chart's [CHANGELOG](https://github.com/jenkinsci/helm-charts/blob/main/charts/jenkins/CHANGELOG.md) to view the chart's release history. +For migration between major version check [migration guide](#migration-guide). + +## Building weekly releases + +The default charts target Long-Term-Support (LTS) releases of Jenkins. +To use other versions the easiest way is to update the image tag to the version you want. +You can also rebuild the chart if you want the `appVersion` field to match. + +## Configuration + +See [Customizing the Chart Before Installing](https://helm.sh/docs/intro/using_helm/#customizing-the-chart-before-installing). +To see all configurable options with detailed comments, visit the chart's [values.yaml](https://github.com/jenkinsci/helm-charts/blob/main/charts/jenkins/values.yaml), or run these configuration commands: + +```console +# Helm 3 +$ helm show values jenkins/jenkins +``` + +For a summary of all configurable options, see [VALUES_SUMMARY.md](https://github.com/jenkinsci/helm-charts/blob/main/charts/jenkins/VALUES_SUMMARY.md). + +### Configure Security Realm and Authorization Strategy + +This chart configured a `securityRealm` and `authorizationStrategy` as shown below: + +```yaml +controller: + JCasC: + securityRealm: |- + local: + allowsSignup: false + enableCaptcha: false + users: + - id: "${chart-admin-username}" + name: "Jenkins Admin" + password: "${chart-admin-password}" + authorizationStrategy: |- + loggedInUsersCanDoAnything: + allowAnonymousRead: false +``` + +With the configuration above there is only a single user. +This is fine for getting started quickly, but it needs to be adjusted for any serious environment. + +So you should adjust this to suite your needs. +That could be using LDAP / OIDC / .. as authorization strategy and use globalMatrix as authorization strategy to configure more fine-grained permissions. + +### Consider using a custom image + +This chart allows the user to specify plugins which should be installed. However, for production use cases one should consider to build a custom Jenkins image which has all required plugins pre-installed. +This way you can be sure which plugins Jenkins is using when starting up and you avoid trouble in case of connectivity issues to the Jenkins update site. + +The [docker repository](https://github.com/jenkinsci/docker) for the Jenkins image contains [documentation](https://github.com/jenkinsci/docker#preinstalling-plugins) how to do it. + +Here is an example how that can be done: + +```Dockerfile +FROM jenkins/jenkins:lts +RUN jenkins-plugin-cli --plugins kubernetes workflow-aggregator git configuration-as-code +``` + +NOTE: If you want a reproducible build then you should specify a non-floating tag for the image `jenkins/jenkins:2.249.3` and specify plugin versions. + +Once you built the image and pushed it to your registry you can specify it in your values file like this: + +```yaml +controller: + image: "registry/my-jenkins" + tag: "v1.2.3" + installPlugins: false +``` + +Notice: `installPlugins` is set to false to disable plugin download. In this case, the image `registry/my-jenkins:v1.2.3` must have the plugins specified as default value for [the `controller.installPlugins` directive](https://github.com/jenkinsci/helm-charts/blob/main/charts/jenkins/VALUES_SUMMARY.md#jenkins-plugins) to ensure that the configuration side-car system works as expected. + +In case you are using a private registry you can use 'imagePullSecretName' to specify the name of the secret to use when pulling the image: + +```yaml +controller: + image: "registry/my-jenkins" + tag: "v1.2.3" + imagePullSecretName: registry-secret + installPlugins: false +``` + +### External URL Configuration + +If you are using the ingress definitions provided by this chart via the `controller.ingress` block the configured hostname will be the ingress hostname starting with `https://` or `http://` depending on the `tls` configuration. +The Protocol can be overwritten by specifying `controller.jenkinsUrlProtocol`. + +If you are not using the provided ingress you can specify `controller.jenkinsUrl` to change the URL definition. + +### Configuration as Code + +Jenkins Configuration as Code (JCasC) is now a standard component in the Jenkins project. +To allow JCasC's configuration from the helm values, the plugin [`configuration-as-code`](https://plugins.jenkins.io/configuration-as-code/) must be installed in the Jenkins Controller's Docker image (which is the case by default as specified by the [default value of the directive `controller.installPlugins`](https://github.com/jenkinsci/helm-charts/blob/main/charts/jenkins/VALUES_SUMMARY.md#jenkins-plugins)). + +JCasc configuration is passed through Helm values under the key `controller.JCasC`. +The section ["Jenkins Configuration as Code (JCasC)" of the page "VALUES_SUMMARY.md"](https://github.com/jenkinsci/helm-charts/blob/main/charts/jenkins/VALUES_SUMMARY.md#jenkins-configuration-as-code-jcasc) lists all the possible directives. + +In particular, you may specify custom JCasC scripts by adding sub-key under the `controller.JCasC.configScripts` for each configuration area where each corresponds to a plugin or section of the UI. + +The sub-keys (prior to `|` character) are only labels used to give the section a meaningful name. +The only restriction is they must conform to RFC 1123 definition of a DNS label, so they may only contain lowercase letters, numbers, and hyphens. + +Each key will become the name of a configuration yaml file on the controller in `/var/jenkins_home/casc_configs` (by default) and will be processed by the Configuration as Code Plugin during Jenkins startup. + +The lines after each `|` become the content of the configuration yaml file. + +The first line after this is a JCasC root element, e.g. jenkins, credentials, etc. + +Best reference is the Documentation link here: `https:///configuration-as-code`. + +The example below sets custom systemMessage: + +```yaml +controller: + JCasC: + configScripts: + welcome-message: | + jenkins: + systemMessage: Welcome to our CI\CD server. +``` + +More complex example that creates ldap settings: + +```yaml +controller: + JCasC: + configScripts: + ldap-settings: | + jenkins: + securityRealm: + ldap: + configurations: + - server: ldap.acme.com + rootDN: dc=acme,dc=uk + managerPasswordSecret: ${LDAP_PASSWORD} + groupMembershipStrategy: + fromUserRecord: + attributeName: "memberOf" +``` + +Keep in mind that default configuration file already contains some values that you won't be able to override under configScripts section. + +For example, you can not configure Jenkins URL and System Admin email address like this because of conflicting configuration error. + +Incorrect: + +```yaml +controller: + JCasC: + configScripts: + jenkins-url: | + unclassified: + location: + url: https://example.com/jenkins + adminAddress: example@mail.com +``` + +Correct: + +```yaml +controller: + jenkinsUrl: https://example.com/jenkins + jenkinsAdminEmail: example@mail.com +``` + +Further JCasC examples can be found [here](https://github.com/jenkinsci/configuration-as-code-plugin/tree/master/demos). + +#### Breaking out large Config as Code scripts + +Jenkins Config as Code scripts can become quite large, and maintaining all of your scripts within one yaml file can be difficult. The Config as Code plugin itself suggests updating the `CASC_JENKINS_CONFIG` environment variable to be a comma separated list of paths for the plugin to traverse, picking up the yaml files as needed. +However, under the Jenkins helm chart, this `CASC_JENKINS_CONFIG` value is maintained through the templates. A better solution is to split your `controller.JCasC.configScripts` into separate values files, and provide each file during the helm install. + +For example, you can have a values file (e.g values_main.yaml) that defines the values described in the `VALUES_SUMMARY.md` for your Jenkins configuration: + +```yaml +jenkins: + controller: + jenkinsUrlProtocol: https + installPlugins: false + ... +``` + +In a second file (e.g values_jenkins_casc.yaml), you can define a section of your config scripts: + +```yaml +jenkins: + controller: + JCasC: + configScripts: + jenkinsCasc: | + jenkins: + disableRememberMe: false + mode: NORMAL + ... +``` + +And keep extending your config scripts by creating more files (so not all config scripts are located in one yaml file for better maintenance): + +values_jenkins_unclassified.yaml + +```yaml +jenkins: + controller: + JCasC: + configScripts: + unclassifiedCasc: | + unclassified: + ... +``` + +When installing, you provide all relevant yaml files (e.g `helm install -f values_main.yaml -f values_jenkins_casc.yaml -f values_jenkins_unclassified.yaml ...`). Instead of updating the `CASC_JENKINS_CONFIG` environment variable to include multiple paths, multiple CasC yaml files will be created in the same path `var/jenkins_home/casc_configs`. + +#### Config as Code With or Without Auto-Reload + +Config as Code changes (to `controller.JCasC.configScripts`) can either force a new pod to be created and only be applied at next startup, or can be auto-reloaded on-the-fly. +If you set `controller.sidecars.configAutoReload.enabled` to `true`, a second, auxiliary container will be installed into the Jenkins controller pod, known as a "sidecar". +This watches for changes to configScripts, copies the content onto the Jenkins file-system and issues a POST to `http:///reload-configuration-as-code` with a pre-shared key. +You can monitor this sidecar's logs using command `kubectl logs -c config-reload -f`. +If you want to enable auto-reload then you also need to configure rbac as the container which triggers the reload needs to watch the config maps: + +```yaml +controller: + sidecars: + configAutoReload: + enabled: true +rbac: + create: true +``` + +### Allow Limited HTML Markup in User-Submitted Text + +Some third-party systems (e.g. GitHub) use HTML-formatted data in their payload sent to a Jenkins webhook (e.g. URL of a pull-request being built). +To display such data as processed HTML instead of raw text set `controller.enableRawHtmlMarkupFormatter` to true. +This option requires installation of the [OWASP Markup Formatter Plugin (antisamy-markup-formatter)](https://plugins.jenkins.io/antisamy-markup-formatter/). +This plugin is **not** installed by default but may be added to `controller.additionalPlugins`. + +### Change max connections to Kubernetes API +When using agents with containers other than JNLP, The kubernetes plugin will communicate with those containers using the Kubernetes API. this changes the maximum concurrent connections +```yaml +agent: + maxRequestsPerHostStr: "32" +``` +This will change the configuration of the kubernetes "cloud" (as called by jenkins) that is created automatically as part of this helm chart. + +### Change container cleanup timeout API +For tasks that use very large images, this timeout can be increased to avoid early termination of the task while the Kubernetes pod is still deploying. +```yaml +agent: + retentionTimeout: "32" +``` +This will change the configuration of the kubernetes "cloud" (as called by jenkins) that is created automatically as part of this helm chart. + +### Change seconds to wait for pod to be running +This will change how long Jenkins will wait (seconds) for pod to be in running state. +```yaml +agent: + waitForPodSec: "32" +``` +This will change the configuration of the kubernetes "cloud" (as called by jenkins) that is created automatically as part of this helm chart. + +### Mounting Volumes into Agent Pods + +Your Jenkins Agents will run as pods, and it's possible to inject volumes where needed: + +```yaml +agent: + volumes: + - type: Secret + secretName: jenkins-mysecrets + mountPath: /var/run/secrets/jenkins-mysecrets +``` + +The supported volume types are: `ConfigMap`, `EmptyDir`, `HostPath`, `Nfs`, `PVC`, `Secret`. +Each type supports a different set of configurable attributes, defined by [the corresponding Java class](https://github.com/jenkinsci/kubernetes-plugin/tree/master/src/main/java/org/csanchez/jenkins/plugins/kubernetes/volumes). + +### NetworkPolicy + +To make use of the NetworkPolicy resources created by default, install [a networking plugin that implements the Kubernetes NetworkPolicy spec](https://kubernetes.io/docs/tasks/administer-cluster/declare-network-policy#before-you-begin). + +[Install](#install-chart) helm chart with network policy enabled by setting `networkPolicy.enabled` to `true`. + +You can use `controller.networkPolicy.internalAgents` and `controller.networkPolicy.externalAgents` stanzas for fine-grained controls over where internal/external agents can connect from. +Internal ones are allowed based on pod labels and (optionally) namespaces, and external ones are allowed based on IP ranges. + +### Script approval list + +`controller.scriptApproval` allows to pass function signatures that will be allowed in pipelines. +Example: + +```yaml +controller: + scriptApproval: + - "method java.util.Base64$Decoder decode java.lang.String" + - "new java.lang.String byte[]" + - "staticMethod java.util.Base64 getDecoder" +``` + +### Custom Labels + +`controller.serviceLabels` can be used to add custom labels in `jenkins-controller-svc.yaml`. +For example: + +```yaml +ServiceLabels: + expose: true +``` + +### Persistence + +The Jenkins image stores persistence under `/var/jenkins_home` path of the container. +A dynamically managed Persistent Volume Claim is used to keep the data across deployments, by default. +This is known to work in GCE, AWS, and minikube. Alternatively, a previously configured Persistent Volume Claim can be used. + +It is possible to mount several volumes using `persistence.volumes` and `persistence.mounts` parameters. +See additional `persistence` values using [configuration commands](#configuration). + +#### Existing PersistentVolumeClaim + +1. Create the PersistentVolume +2. Create the PersistentVolumeClaim +3. [Install](#install-chart) the chart, setting `persistence.existingClaim` to `PVC_NAME` + +#### Long Volume Attach/Mount Times + +Certain volume type and filesystem format combinations may experience long +attach/mount times, [10 or more minutes][K8S_VOLUME_TIMEOUT], when using +`fsGroup`. This issue may result in the following entries in the pod's event +history: + +```console +Warning FailedMount 38m kubelet, aks-default-41587790-2 Unable to attach or mount volumes: unmounted volumes=[jenkins-home], unattached volumes=[plugins plugin-dir jenkins-token-rmq2g sc-config-volume tmp jenkins-home jenkins-config secrets-dir]: timed out waiting for the condition +``` + +In these cases, experiment with replacing `fsGroup` with +`supplementalGroups` in the pod's `securityContext`. This can be achieved by +setting the `controller.podSecurityContextOverride` Helm chart value to +something like: + +```yaml +controller: + podSecurityContextOverride: + runAsNonRoot: true + runAsUser: 1000 + supplementalGroups: [1000] +``` + +This issue has been reported on [azureDisk with ext4][K8S_VOLUME_TIMEOUT] and +on [Alibaba cloud][K8S_VOLUME_TIMEOUT_ALIBABA]. + +[K8S_VOLUME_TIMEOUT]: https://github.com/kubernetes/kubernetes/issues/67014 +[K8S_VOLUME_TIMEOUT_ALIBABA]: https://github.com/kubernetes/kubernetes/issues/67014#issuecomment-698770511 + +#### Storage Class + +It is possible to define which storage class to use, by setting `persistence.storageClass` to `[customStorageClass]`. +If set to a dash (`-`), dynamic provisioning is disabled. +If the storage class is set to null or left undefined (`""`), the default provisioner is used (gp2 on AWS, standard on GKE, AWS & OpenStack). + +### Additional Secrets + +Additional secrets and Additional Existing Secrets, +can be mounted into the Jenkins controller through the chart or created using `controller.additionalSecrets` or `controller.additionalExistingSecrets`. +A common use case might be identity provider credentials if using an external LDAP or OIDC-based identity provider. +The secret may then be referenced in JCasC configuration (see [JCasC configuration](#configuration-as-code)). + +`values.yaml` controller section, referencing mounted secrets: +```yaml +controller: + # the 'name' and 'keyName' are concatenated with a '-' in between, so for example: + # an existing secret "secret-credentials" and a key inside it named "github-password" should be used in Jcasc as ${secret-credentials-github-password} + # 'name' and 'keyName' must be lowercase RFC 1123 label must consist of lower case alphanumeric characters or '-', + # and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc') + # existingSecret existing secret "secret-credentials" and a key inside it named "github-username" should be used in Jcasc as ${github-username} + # When using existingSecret no need to specify the keyName under additionalExistingSecrets. + existingSecret: secret-credentials + + additionalExistingSecrets: + - name: secret-credentials + keyName: github-username + - name: secret-credentials + keyName: github-password + - name: secret-credentials + keyName: token + + additionalSecrets: + - name: client_id + value: abc123 + - name: client_secret + value: xyz999 + JCasC: + securityRealm: | + oic: + clientId: ${client_id} + clientSecret: ${client_secret} + ... + configScripts: + jenkins-casc-configs: | + credentials: + system: + domainCredentials: + - credentials: + - string: + description: "github access token" + id: "github_app_token" + scope: GLOBAL + secret: ${secret-credentials-token} + - usernamePassword: + description: "github access username password" + id: "github_username_pass" + password: ${secret-credentials-github-password} + scope: GLOBAL + username: ${secret-credentials-github-username} +``` + +For more information, see [JCasC documentation](https://github.com/jenkinsci/configuration-as-code-plugin/blob/master/docs/features/secrets.adoc#kubernetes-secrets). + +### Secret Claims from HashiCorp Vault + +It's possible for this chart to generate `SecretClaim` resources in order to automatically create and maintain Kubernetes `Secrets` from HashiCorp [Vault](https://www.vaultproject.io/) via [`kube-vault-controller`](https://github.com/roboll/kube-vault-controller) + +These `Secrets` can then be referenced in the same manner as Additional Secrets above. + +This can be achieved by defining required Secret Claims within `controller.secretClaims`, as follows: +```yaml +controller: + secretClaims: + - name: jenkins-secret + path: secret/path + - name: jenkins-short-ttl + path: secret/short-ttl-path + renew: 60 +``` + +### RBAC + +RBAC is enabled by default. If you want to disable it you will need to set `rbac.create` to `false`. + +### Adding Custom Pod Templates + +It is possible to add custom pod templates for the default configured kubernetes cloud. +Add a key under `agent.podTemplates` for each pod template. Each key (prior to `|` character) is just a label, and can be any value. +Keys are only used to give the pod template a meaningful name. The only restriction is they may only contain RFC 1123 \ DNS label characters: lowercase letters, numbers, and hyphens. Each pod template can contain multiple containers. +There's no need to add the _jnlp_ container since the kubernetes plugin will automatically inject it into the pod. +For this pod templates configuration to be loaded the following values must be set: + +```yaml +controller.JCasC.defaultConfig: true +``` + +The example below creates a python pod template in the kubernetes cloud: + +```yaml +agent: + podTemplates: + python: | + - name: python + label: jenkins-python + serviceAccount: jenkins + containers: + - name: python + image: python:3 + command: "/bin/sh -c" + args: "cat" + ttyEnabled: true + privileged: true + resourceRequestCpu: "400m" + resourceRequestMemory: "512Mi" + resourceLimitCpu: "1" + resourceLimitMemory: "1024Mi" +``` + +Best reference is `https:///configuration-as-code/reference#Cloud-kubernetes`. + +### Adding Pod Templates Using additionalAgents + +`additionalAgents` may be used to configure additional kubernetes pod templates. +Each additional agent corresponds to `agent` in terms of the configurable values and inherits all values from `agent` so you only need to specify values which differ. +For example: + +```yaml +agent: + podName: default + customJenkinsLabels: default + # set resources for additional agents to inherit + resources: + limits: + cpu: "1" + memory: "2048Mi" + +additionalAgents: + maven: + podName: maven + customJenkinsLabels: maven + # An example of overriding the jnlp container + # sideContainerName: jnlp + image: jenkins/jnlp-agent-maven + tag: latest + python: + podName: python + customJenkinsLabels: python + sideContainerName: python + image: python + tag: "3" + command: "/bin/sh -c" + args: "cat" + TTYEnabled: true +``` + +### Ingress Configuration + +This chart provides ingress resources configurable via the `controller.ingress` block. + +The simplest configuration looks like the following: + +```yaml +controller: + ingress: + enabled: true + paths: [] + apiVersion: "extensions/v1beta1" + hostName: jenkins.example.com +``` + +This snippet configures an ingress rule for exposing jenkins at `jenkins.example.com` + +You can define labels and annotations via `controller.ingress.labels` and `controller.ingress.annotations` respectively. +Additionally, you can configure the ingress tls via `controller.ingress.tls`. +By default, this ingress rule exposes all paths. +If needed this can be overwritten by specifying the wanted paths in `controller.ingress.paths` + +If you want to configure a secondary ingress e.g. you don't want the jenkins instance exposed but still want to receive webhooks you can configure `controller.secondaryingress`. +The secondaryingress doesn't expose anything by default and has to be configured via `controller.secondaryingress.paths`: + +```yaml +controller: + ingress: + enabled: true + apiVersion: "extensions/v1beta1" + hostName: "jenkins.internal.example.com" + annotations: + kubernetes.io/ingress.class: "internal" + secondaryingress: + enabled: true + apiVersion: "extensions/v1beta1" + hostName: "jenkins-scm.example.com" + annotations: + kubernetes.io/ingress.class: "public" + paths: + - /github-webhook +``` + +## Prometheus Metrics + +If you want to expose Prometheus metrics you need to install the [Jenkins Prometheus Metrics Plugin](https://github.com/jenkinsci/prometheus-plugin). +It will expose an endpoint (default `/prometheus`) with metrics where a Prometheus Server can scrape. + +If you have implemented [Prometheus Operator](https://github.com/prometheus-operator/prometheus-operator), you can set `controller.prometheus.enabled` to `true` to configure a `ServiceMonitor` and `PrometheusRule`. +If you want to further adjust alerting rules you can do so by configuring `controller.prometheus.alertingrules` + +If you have implemented Prometheus without using the operator, you can leave `controller.prometheus.enabled` set to `false`. + +### Running Behind a Forward Proxy + +The controller pod uses an Init Container to install plugins etc. If you are behind a corporate proxy it may be useful to set `controller.initContainerEnv` to add environment variables such as `http_proxy`, so that these can be downloaded. + +Additionally, you may want to add env vars for the init container, the Jenkins container, and the JVM (`controller.javaOpts`): + +```yaml +controller: + initContainerEnv: + - name: http_proxy + value: "http://192.168.64.1:3128" + - name: https_proxy + value: "http://192.168.64.1:3128" + - name: no_proxy + value: "" + - name: JAVA_OPTS + value: "-Dhttps.proxyHost=proxy_host_name_without_protocol -Dhttps.proxyPort=3128" + containerEnv: + - name: http_proxy + value: "http://192.168.64.1:3128" + - name: https_proxy + value: "http://192.168.64.1:3128" + javaOpts: >- + -Dhttp.proxyHost=192.168.64.1 + -Dhttp.proxyPort=3128 + -Dhttps.proxyHost=192.168.64.1 + -Dhttps.proxyPort=3128 +``` + +### HTTPS Keystore Configuration + +[This configuration](https://wiki.jenkins.io/pages/viewpage.action?pageId=135468777) enables jenkins to use keystore in order to serve HTTPS. +Here is the [value file section](https://wiki.jenkins.io/pages/viewpage.action?pageId=135468777#RunningJenkinswithnativeSSL/HTTPS-ConfigureJenkinstouseHTTPSandtheJKSkeystore) related to keystore configuration. +Keystore itself should be placed in front of `jenkinsKeyStoreBase64Encoded` key and in base64 encoded format. To achieve that after having `keystore.jks` file simply do this: `cat keystore.jks | base64` and paste the output in front of `jenkinsKeyStoreBase64Encoded`. +After enabling `httpsKeyStore.enable` make sure that `httpPort` and `targetPort` are not the same, as `targetPort` will serve HTTPS. +Do not set `controller.httpsKeyStore.httpPort` to `-1` because it will cause readiness and liveliness prob to fail. +If you already have a kubernetes secret that has keystore and its password you can specify its' name in front of `jenkinsHttpsJksSecretName`, You need to remember that your secret should have proper data key names `jenkins-jks-file` (or override the key name using `jenkinsHttpsJksSecretKey`) +and `https-jks-password` (or override the key name using `jenkinsHttpsJksPasswordSecretKey`; additionally you can make it get the password from a different secret using `jenkinsHttpsJksPasswordSecretName`). Example: + +```yaml +controller: + httpsKeyStore: + enable: true + jenkinsHttpsJksSecretName: '' + httpPort: 8081 + path: "/var/jenkins_keystore" + fileName: "keystore.jks" + password: "changeit" + jenkinsKeyStoreBase64Encoded: '' +``` +### AWS Security Group Policies + +To create SecurityGroupPolicies set `awsSecurityGroupPolicies.enabled` to true and add your policies. Each policy requires a `name`, array of `securityGroupIds` and a `podSelector`. Example: + +```yaml +awsSecurityGroupPolicies: + enabled: true + policies: + - name: "jenkins-controller" + securityGroupIds: + - sg-123456789 + podSelector: + matchExpressions: + - key: app.kubernetes.io/component + operator: In + values: + - jenkins-controller +``` + +### Agent Direct Connection + +Set `directConnection` to `true` to allow agents to connect directly to a given TCP port without having to negotiate a HTTP(S) connection. This can allow you to have agent connections without an external HTTP(S) port. Example: + +```yaml +agent: + jenkinsTunnel: "jenkinsci-agent:50000" + directConnection: true +``` + +## Migration Guide + +### From stable repository + +Upgrade an existing release from `stable/jenkins` to `jenkins/jenkins` seamlessly by ensuring you have the latest [repository info](#get-repository-info) and running the [upgrade commands](#upgrade-chart) specifying the `jenkins/jenkins` chart. + +### Major Version Upgrades + +Chart release versions follow [SemVer](../../CONTRIBUTING.md#versioning), where a MAJOR version change (example `1.0.0` -> `2.0.0`) indicates an incompatible breaking change needing manual actions. + +See [UPGRADING.md](./UPGRADING.md) for a list of breaking changes diff --git a/charts/jenkins/jenkins/5.5.1/UPGRADING.md b/charts/jenkins/jenkins/5.5.1/UPGRADING.md new file mode 100644 index 000000000..0ff90112d --- /dev/null +++ b/charts/jenkins/jenkins/5.5.1/UPGRADING.md @@ -0,0 +1,148 @@ +# Upgrade Notes + +## To 5.0.0 +- `controller.image`, `controller.tag`, and `controller.tagLabel` have been removed. If you want to overwrite the image you now need to configure any or all of: + - `controller.image.registry` + - `controller.image.repository` + - `controller.image.tag` + - `controller.image.tagLabel` +- `controller.imagePullPolicy` has been removed. If you want to overwrite the pull policy you now need to configure `controller.image.pullPolicy`. +- `controller.sidecars.configAutoReload.image` has been removed. If you want to overwrite the configAutoReload image you now need to configure any or all of: + - `controller.sidecars.configAutoReload.image.registry` + - `controller.sidecars.configAutoReload.image.repository` + - `controller.sidecars.configAutoReload.image.tag` +- `controller.sidecars.other` has been renamed to `controller.sidecars.additionalSidecarContainers`. +- `agent.image` and `agent.tag` have been removed. If you want to overwrite the agent image you now need to configure any or all of: + - `agent.image.repository` + - `agent.image.tag` + - The registry can still be overwritten by `agent.jnlpregistry` +- `agent.additionalContainers[*].image` has been renamed to `agent.additionalContainers[*].image.repository` +- `agent.additionalContainers[*].tag` has been renamed to `agent.additionalContainers[*].image.tag` +- `additionalAgents.*.image` has been renamed to `additionalAgents.*.image.repository` +- `additionalAgents.*.tag` has been renamed to `additionalAgents.*.image.tag` +- `additionalClouds.*.additionalAgents.*.image` has been renamed to `additionalClouds.*.additionalAgents.*.image.repository` +- `additionalClouds.*.additionalAgents.*.tag` has been renamed to `additionalClouds.*.additionalAgents.*.image.tag` +- `helmtest.bats.image` has been split up to: + - `helmtest.bats.image.registry` + - `helmtest.bats.image.repository` + - `helmtest.bats.image.tag` +- `controller.adminUsername` and `controller.adminPassword` have been renamed to `controller.admin.username` and `controller.admin.password` respectively +- `controller.adminSecret` has been renamed to `controller.admin.createSecret` +- `backup.*` was unmaintained and has thus been removed. See the following page for alternatives: [Kubernetes Backup and Migrations](https://nubenetes.com/kubernetes-backup-migrations/). + +## To 4.0.0 +Removes automatic `remotingSecurity` setting when using a container tag older than `2.326` (introduced in [`3.11.7`](./CHANGELOG.md#3117)). If you're using a version older than `2.326`, you should explicitly set `.controller.legacyRemotingSecurityEnabled` to `true`. + +## To 3.0.0 + +* Check `securityRealm` and `authorizationStrategy` and adjust it. + Otherwise, your configured users and permissions will be overridden. +* You need to use helm version 3 as the `Chart.yaml` uses `apiVersion: v2`. +* All XML configuration options have been removed. + In case those are still in use you need to migrate to configuration as code. + Upgrade guide to 2.0.0 contains pointers how to do that. +* Jenkins is now using a `StatefulSet` instead of a `Deployment` +* terminology has been adjusted that's also reflected in values.yaml + The following values from `values.yaml` have been renamed: + + * `master` => `controller` + * `master.useSecurity` => `controller.adminSecret` + * `master.slaveListenerPort` => `controller.agentListenerPort` + * `master.slaveHostPort` => `controller.agentListenerHostPort` + * `master.slaveKubernetesNamespace` => `agent.namespace` + * `master.slaveDefaultsProviderTemplate` => `agent.defaultsProviderTemplate` + * `master.slaveJenkinsUrl` => `agent.jenkinsUrl` + * `master.slaveJenkinsTunnel` => `agent.jenkinsTunnel` + * `master.slaveConnectTimeout` => `agent.kubernetesConnectTimeout` + * `master.slaveReadTimeout` => `agent.kubernetesReadTimeout` + * `master.slaveListenerServiceAnnotations` => `controller.agentListenerServiceAnnotations` + * `master.slaveListenerServiceType` => `controller.agentListenerServiceType` + * `master.slaveListenerLoadBalancerIP` => `controller.agentListenerLoadBalancerIP` + * `agent.slaveConnectTimeout` => `agent.connectTimeout` +* Removed values: + + * `master.imageTag`: use `controller.image` and `controller.tag` instead + * `slave.imageTag`: use `agent.image` and `agent.tag` instead + +## To 2.0.0 + +Configuration as Code is now default + container does not run as root anymore. + +### Configuration as Code new default + +Configuration is done via [Jenkins Configuration as Code Plugin](https://github.com/jenkinsci/configuration-as-code-plugin) by default. +That means that changes in values which result in a configuration change are always applied. +In contrast, the XML configuration was only applied during the first start and never altered. + +:exclamation::exclamation::exclamation: +Attention: +This also means if you manually altered configuration then this will most likely be reset to what was configured by default. +It also applies to `securityRealm` and `authorizationStrategy` as they are also configured using configuration as code. +:exclamation::exclamation::exclamation: + +### Image does not run as root anymore + +It's not recommended to run containers in Kubernetes as `root`. + +❗Attention: If you had not configured a different user before then you need to ensure that your image supports the user and group ID configured and also manually change permissions of all files so that Jenkins is still able to use them. + +### Summary of updated values + +As version 2.0.0 only updates default values and nothing else it's still possible to migrate to this version and opt out of some or all new defaults. +All you have to do is ensure the old values are set in your installation. + +Here we show which values have changed and the previous default values: + +```yaml +controller: + runAsUser: 1000 # was unset before + fsGroup: 1000 # was unset before + JCasC: + enabled: true # was false + defaultConfig: true # was false + sidecars: + configAutoReload: + enabled: true # was false +``` + +### Migration steps + +Migration instructions heavily depend on your current setup. +So think of the list below more as a general guideline of what should be done. + +- Ensure that the Jenkins image you are using contains a user with ID 1000 and a group with the same ID. + That's the case for `jenkins/jenkins:lts` image, which the chart uses by default +- Make a backup of your existing installation especially the persistent volume +- Ensure that you have the configuration as code plugin installed +- Export your current settings via the plugin: + `Manage Jenkins` -> `Configuration as Code` -> `Download Configuration` +- prepare your values file for the update e.g. add additional configuration as code setting that you need. + The export taken from above might be a good starting point for this. + In addition, the [demos](https://github.com/jenkinsci/configuration-as-code-plugin/tree/master/demos) from the plugin itself are quite useful. +- Test drive those setting on a separate installation +- Put Jenkins to Quiet Down mode so that it does not accept new jobs + `/quietDown` +- Change permissions of all files and folders to the new user and group ID: + + ```console + kubectl exec -it -c jenkins /bin/bash + chown -R 1000:1000 /var/jenkins_home + ``` + +- Update Jenkins + +## To 1.0.0 + +Breaking changes: + +- Values have been renamed to follow [helm recommended naming conventions](https://helm.sh/docs/chart_best_practices/#naming-conventions) so that all variables start with a lowercase letter and words are separated with camelcase +- All resources are now using [helm recommended standard labels](https://helm.sh/docs/chart_best_practices/#standard-labels) + +As a result of the label changes also the selectors of the deployment have been updated. +Those are immutable so trying an updated will cause an error like: + +```console +Error: Deployment.apps "jenkins" is invalid: spec.selector: Invalid value: v1.LabelSelector{MatchLabels:map[string]string{"app.kubernetes.io/component":"jenkins-controller", "app.kubernetes.io/instance":"jenkins"}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable +``` + +In order to upgrade, [uninstall](./README.md#uninstall-chart) the Jenkins Deployment before upgrading: diff --git a/charts/jenkins/jenkins/5.5.1/VALUES.md b/charts/jenkins/jenkins/5.5.1/VALUES.md new file mode 100644 index 000000000..7e3377b0e --- /dev/null +++ b/charts/jenkins/jenkins/5.5.1/VALUES.md @@ -0,0 +1,311 @@ +# Jenkins + +## Configuration + +The following tables list the configurable parameters of the Jenkins chart and their default values. + +## Values + +| Key | Type | Description | Default | +|:----|:-----|:---------|:------------| +| [additionalAgents](./values.yaml#L1169) | object | Configure additional | `{}` | +| [additionalClouds](./values.yaml#L1194) | object | | `{}` | +| [agent.TTYEnabled](./values.yaml#L1087) | bool | Allocate pseudo tty to the side container | `false` | +| [agent.additionalContainers](./values.yaml#L1122) | list | Add additional containers to the agents | `[]` | +| [agent.alwaysPullImage](./values.yaml#L980) | bool | Always pull agent container image before build | `false` | +| [agent.annotations](./values.yaml#L1118) | object | Annotations to apply to the pod | `{}` | +| [agent.args](./values.yaml#L1081) | string | Arguments passed to command to execute | `"${computer.jnlpmac} ${computer.name}"` | +| [agent.command](./values.yaml#L1079) | string | Command to execute when side container starts | `nil` | +| [agent.componentName](./values.yaml#L948) | string | | `"jenkins-agent"` | +| [agent.connectTimeout](./values.yaml#L1116) | int | Timeout in seconds for an agent to be online | `100` | +| [agent.containerCap](./values.yaml#L1089) | int | Max number of agents to launch | `10` | +| [agent.customJenkinsLabels](./values.yaml#L945) | list | Append Jenkins labels to the agent | `[]` | +| [agent.defaultsProviderTemplate](./values.yaml#L907) | string | The name of the pod template to use for providing default values | `""` | +| [agent.directConnection](./values.yaml#L951) | bool | | `false` | +| [agent.disableDefaultAgent](./values.yaml#L1140) | bool | Disable the default Jenkins Agent configuration | `false` | +| [agent.enabled](./values.yaml#L905) | bool | Enable Kubernetes plugin jnlp-agent podTemplate | `true` | +| [agent.envVars](./values.yaml#L1062) | list | Environment variables for the agent Pod | `[]` | +| [agent.hostNetworking](./values.yaml#L959) | bool | Enables the agent to use the host network | `false` | +| [agent.idleMinutes](./values.yaml#L1094) | int | Allows the Pod to remain active for reuse until the configured number of minutes has passed since the last step was executed on it | `0` | +| [agent.image.repository](./values.yaml#L938) | string | Repository to pull the agent jnlp image from | `"jenkins/inbound-agent"` | +| [agent.image.tag](./values.yaml#L940) | string | Tag of the image to pull | `"3256.v88a_f6e922152-1"` | +| [agent.imagePullSecretName](./values.yaml#L947) | string | Name of the secret to be used to pull the image | `nil` | +| [agent.inheritYamlMergeStrategy](./values.yaml#L1114) | bool | Controls whether the defined yaml merge strategy will be inherited if another defined pod template is configured to inherit from the current one | `false` | +| [agent.jenkinsTunnel](./values.yaml#L915) | string | Overrides the Kubernetes Jenkins tunnel | `nil` | +| [agent.jenkinsUrl](./values.yaml#L911) | string | Overrides the Kubernetes Jenkins URL | `nil` | +| [agent.jnlpregistry](./values.yaml#L935) | string | Custom registry used to pull the agent jnlp image from | `nil` | +| [agent.kubernetesConnectTimeout](./values.yaml#L921) | int | The connection timeout in seconds for connections to Kubernetes API. The minimum value is 5 | `5` | +| [agent.kubernetesReadTimeout](./values.yaml#L923) | int | The read timeout in seconds for connections to Kubernetes API. The minimum value is 15 | `15` | +| [agent.livenessProbe](./values.yaml#L970) | object | | `{}` | +| [agent.maxRequestsPerHostStr](./values.yaml#L925) | string | The maximum concurrent connections to Kubernetes API | `"32"` | +| [agent.namespace](./values.yaml#L931) | string | Namespace in which the Kubernetes agents should be launched | `nil` | +| [agent.nodeSelector](./values.yaml#L1073) | object | Node labels for pod assignment | `{}` | +| [agent.nodeUsageMode](./values.yaml#L943) | string | | `"NORMAL"` | +| [agent.podLabels](./values.yaml#L933) | object | Custom Pod labels (an object with `label-key: label-value` pairs) | `{}` | +| [agent.podName](./values.yaml#L1091) | string | Agent Pod base name | `"default"` | +| [agent.podRetention](./values.yaml#L989) | string | | `"Never"` | +| [agent.podTemplates](./values.yaml#L1150) | object | Configures extra pod templates for the default kubernetes cloud | `{}` | +| [agent.privileged](./values.yaml#L953) | bool | Agent privileged container | `false` | +| [agent.resources](./values.yaml#L961) | object | Resources allocation (Requests and Limits) | `{"limits":{"cpu":"512m","memory":"512Mi"},"requests":{"cpu":"512m","memory":"512Mi"}}` | +| [agent.restrictedPssSecurityContext](./values.yaml#L986) | bool | Set a restricted securityContext on jnlp containers | `false` | +| [agent.retentionTimeout](./values.yaml#L927) | int | Time in minutes after which the Kubernetes cloud plugin will clean up an idle worker that has not already terminated | `5` | +| [agent.runAsGroup](./values.yaml#L957) | string | Configure container group | `nil` | +| [agent.runAsUser](./values.yaml#L955) | string | Configure container user | `nil` | +| [agent.secretEnvVars](./values.yaml#L1066) | list | Mount a secret as environment variable | `[]` | +| [agent.showRawYaml](./values.yaml#L993) | bool | | `true` | +| [agent.sideContainerName](./values.yaml#L1083) | string | Side container name | `"jnlp"` | +| [agent.skipTlsVerify](./values.yaml#L917) | bool | Disables the verification of the controller certificate on remote connection. This flag correspond to the "Disable https certificate check" flag in kubernetes plugin UI | `false` | +| [agent.usageRestricted](./values.yaml#L919) | bool | Enable the possibility to restrict the usage of this agent to specific folder. This flag correspond to the "Restrict pipeline support to authorized folders" flag in kubernetes plugin UI | `false` | +| [agent.volumes](./values.yaml#L1000) | list | Additional volumes | `[]` | +| [agent.waitForPodSec](./values.yaml#L929) | int | Seconds to wait for pod to be running | `600` | +| [agent.websocket](./values.yaml#L950) | bool | Enables agent communication via websockets | `false` | +| [agent.workingDir](./values.yaml#L942) | string | Configure working directory for default agent | `"/home/jenkins/agent"` | +| [agent.workspaceVolume](./values.yaml#L1035) | object | Workspace volume (defaults to EmptyDir) | `{}` | +| [agent.yamlMergeStrategy](./values.yaml#L1112) | string | Defines how the raw yaml field gets merged with yaml definitions from inherited pod templates. Possible values: "merge" or "override" | `"override"` | +| [agent.yamlTemplate](./values.yaml#L1101) | string | The raw yaml of a Pod API Object to merge into the agent spec | `""` | +| [awsSecurityGroupPolicies.enabled](./values.yaml#L1320) | bool | | `false` | +| [awsSecurityGroupPolicies.policies[0].name](./values.yaml#L1322) | string | | `""` | +| [awsSecurityGroupPolicies.policies[0].podSelector](./values.yaml#L1324) | object | | `{}` | +| [awsSecurityGroupPolicies.policies[0].securityGroupIds](./values.yaml#L1323) | list | | `[]` | +| [checkDeprecation](./values.yaml#L1317) | bool | Checks if any deprecated values are used | `true` | +| [clusterZone](./values.yaml#L21) | string | Override the cluster name for FQDN resolving | `"cluster.local"` | +| [controller.JCasC.authorizationStrategy](./values.yaml#L533) | string | Jenkins Config as Code Authorization Strategy-section | `"loggedInUsersCanDoAnything:\n allowAnonymousRead: false"` | +| [controller.JCasC.configMapAnnotations](./values.yaml#L538) | object | Annotations for the JCasC ConfigMap | `{}` | +| [controller.JCasC.configScripts](./values.yaml#L507) | object | List of Jenkins Config as Code scripts | `{}` | +| [controller.JCasC.configUrls](./values.yaml#L504) | list | Remote URLs for configuration files. | `[]` | +| [controller.JCasC.defaultConfig](./values.yaml#L498) | bool | Enables default Jenkins configuration via configuration as code plugin | `true` | +| [controller.JCasC.overwriteConfiguration](./values.yaml#L502) | bool | Whether Jenkins Config as Code should overwrite any existing configuration | `false` | +| [controller.JCasC.security](./values.yaml#L514) | object | Jenkins Config as Code security-section | `{"apiToken":{"creationOfLegacyTokenEnabled":false,"tokenGenerationOnCreationEnabled":false,"usageStatisticsEnabled":true}}` | +| [controller.JCasC.securityRealm](./values.yaml#L522) | string | Jenkins Config as Code Security Realm-section | `"local:\n allowsSignup: false\n enableCaptcha: false\n users:\n - id: \"${chart-admin-username}\"\n name: \"Jenkins Admin\"\n password: \"${chart-admin-password}\""` | +| [controller.additionalExistingSecrets](./values.yaml#L459) | list | List of additional existing secrets to mount | `[]` | +| [controller.additionalPlugins](./values.yaml#L409) | list | List of plugins to install in addition to those listed in controller.installPlugins | `[]` | +| [controller.additionalSecrets](./values.yaml#L468) | list | List of additional secrets to create and mount | `[]` | +| [controller.admin.createSecret](./values.yaml#L91) | bool | Create secret for admin user | `true` | +| [controller.admin.existingSecret](./values.yaml#L94) | string | The name of an existing secret containing the admin credentials | `""` | +| [controller.admin.password](./values.yaml#L81) | string | Admin password created as a secret if `controller.admin.createSecret` is true | `` | +| [controller.admin.passwordKey](./values.yaml#L86) | string | The key in the existing admin secret containing the password | `"jenkins-admin-password"` | +| [controller.admin.userKey](./values.yaml#L84) | string | The key in the existing admin secret containing the username | `"jenkins-admin-user"` | +| [controller.admin.username](./values.yaml#L78) | string | Admin username created as a secret if `controller.admin.createSecret` is true | `"admin"` | +| [controller.affinity](./values.yaml#L660) | object | Affinity settings | `{}` | +| [controller.agentListenerEnabled](./values.yaml#L318) | bool | Create Agent listener service | `true` | +| [controller.agentListenerExternalTrafficPolicy](./values.yaml#L328) | string | Traffic Policy of for the agentListener service | `nil` | +| [controller.agentListenerHostPort](./values.yaml#L322) | string | Host port to listen for agents | `nil` | +| [controller.agentListenerLoadBalancerIP](./values.yaml#L358) | string | Static IP for the agentListener LoadBalancer | `nil` | +| [controller.agentListenerLoadBalancerSourceRanges](./values.yaml#L330) | list | Allowed inbound IP for the agentListener service | `["0.0.0.0/0"]` | +| [controller.agentListenerNodePort](./values.yaml#L324) | string | Node port to listen for agents | `nil` | +| [controller.agentListenerPort](./values.yaml#L320) | int | Listening port for agents | `50000` | +| [controller.agentListenerServiceAnnotations](./values.yaml#L353) | object | Annotations for the agentListener service | `{}` | +| [controller.agentListenerServiceType](./values.yaml#L350) | string | Defines how to expose the agentListener service | `"ClusterIP"` | +| [controller.backendconfig.annotations](./values.yaml#L763) | object | backendconfig annotations | `{}` | +| [controller.backendconfig.apiVersion](./values.yaml#L757) | string | backendconfig API version | `"extensions/v1beta1"` | +| [controller.backendconfig.enabled](./values.yaml#L755) | bool | Enables backendconfig | `false` | +| [controller.backendconfig.labels](./values.yaml#L761) | object | backendconfig labels | `{}` | +| [controller.backendconfig.name](./values.yaml#L759) | string | backendconfig name | `nil` | +| [controller.backendconfig.spec](./values.yaml#L765) | object | backendconfig spec | `{}` | +| [controller.cloudName](./values.yaml#L487) | string | Name of default cloud configuration. | `"kubernetes"` | +| [controller.clusterIp](./values.yaml#L217) | string | k8s service clusterIP. Only used if serviceType is ClusterIP | `nil` | +| [controller.componentName](./values.yaml#L34) | string | Used for label app.kubernetes.io/component | `"jenkins-controller"` | +| [controller.containerEnv](./values.yaml#L150) | list | Environment variables for Jenkins Container | `[]` | +| [controller.containerEnvFrom](./values.yaml#L147) | list | Environment variable sources for Jenkins Container | `[]` | +| [controller.containerSecurityContext](./values.yaml#L205) | object | Allow controlling the securityContext for the jenkins container | `{"allowPrivilegeEscalation":false,"readOnlyRootFilesystem":true,"runAsGroup":1000,"runAsUser":1000}` | +| [controller.csrf.defaultCrumbIssuer.enabled](./values.yaml#L339) | bool | Enable the default CSRF Crumb issuer | `true` | +| [controller.csrf.defaultCrumbIssuer.proxyCompatability](./values.yaml#L341) | bool | Enable proxy compatibility | `true` | +| [controller.customInitContainers](./values.yaml#L541) | list | Custom init-container specification in raw-yaml format | `[]` | +| [controller.customJenkinsLabels](./values.yaml#L68) | list | Append Jenkins labels to the controller | `[]` | +| [controller.disableRememberMe](./values.yaml#L59) | bool | Disable use of remember me | `false` | +| [controller.disabledAgentProtocols](./values.yaml#L333) | list | Disabled agent protocols | `["JNLP-connect","JNLP2-connect"]` | +| [controller.enableRawHtmlMarkupFormatter](./values.yaml#L429) | bool | Enable HTML parsing using OWASP Markup Formatter Plugin (antisamy-markup-formatter) | `false` | +| [controller.executorMode](./values.yaml#L65) | string | Sets the executor mode of the Jenkins node. Possible values are "NORMAL" or "EXCLUSIVE" | `"NORMAL"` | +| [controller.existingSecret](./values.yaml#L456) | string | | `nil` | +| [controller.extraPorts](./values.yaml#L388) | list | Optionally configure other ports to expose in the controller container | `[]` | +| [controller.fsGroup](./values.yaml#L186) | int | Deprecated in favor of `controller.podSecurityContextOverride`. uid that will be used for persistent volume. | `1000` | +| [controller.googlePodMonitor.enabled](./values.yaml#L826) | bool | | `false` | +| [controller.googlePodMonitor.scrapeEndpoint](./values.yaml#L831) | string | | `"/prometheus"` | +| [controller.googlePodMonitor.scrapeInterval](./values.yaml#L829) | string | | `"60s"` | +| [controller.healthProbes](./values.yaml#L248) | bool | Enable Kubernetes Probes configuration configured in `controller.probes` | `true` | +| [controller.hostAliases](./values.yaml#L779) | list | Allows for adding entries to Pod /etc/hosts | `[]` | +| [controller.hostNetworking](./values.yaml#L70) | bool | | `false` | +| [controller.httpsKeyStore.disableSecretMount](./values.yaml#L847) | bool | | `false` | +| [controller.httpsKeyStore.enable](./values.yaml#L838) | bool | Enables HTTPS keystore on jenkins controller | `false` | +| [controller.httpsKeyStore.fileName](./values.yaml#L855) | string | Jenkins keystore filename which will appear under controller.httpsKeyStore.path | `"keystore.jks"` | +| [controller.httpsKeyStore.httpPort](./values.yaml#L851) | int | HTTP Port that Jenkins should listen to along with HTTPS, it also serves as the liveness and readiness probes port. | `8081` | +| [controller.httpsKeyStore.jenkinsHttpsJksPasswordSecretKey](./values.yaml#L846) | string | Name of the key in the secret that contains the JKS password | `"https-jks-password"` | +| [controller.httpsKeyStore.jenkinsHttpsJksPasswordSecretName](./values.yaml#L844) | string | Name of the secret that contains the JKS password, if it is not in the same secret as the JKS file | `""` | +| [controller.httpsKeyStore.jenkinsHttpsJksSecretKey](./values.yaml#L842) | string | Name of the key in the secret that already has ssl keystore | `"jenkins-jks-file"` | +| [controller.httpsKeyStore.jenkinsHttpsJksSecretName](./values.yaml#L840) | string | Name of the secret that already has ssl keystore | `""` | +| [controller.httpsKeyStore.jenkinsKeyStoreBase64Encoded](./values.yaml#L860) | string | Base64 encoded Keystore content. Keystore must be converted to base64 then being pasted here | `nil` | +| [controller.httpsKeyStore.password](./values.yaml#L857) | string | Jenkins keystore password | `"password"` | +| [controller.httpsKeyStore.path](./values.yaml#L853) | string | Path of HTTPS keystore file | `"/var/jenkins_keystore"` | +| [controller.image.pullPolicy](./values.yaml#L47) | string | Controller image pull policy | `"Always"` | +| [controller.image.registry](./values.yaml#L37) | string | Controller image registry | `"docker.io"` | +| [controller.image.repository](./values.yaml#L39) | string | Controller image repository | `"jenkins/jenkins"` | +| [controller.image.tag](./values.yaml#L42) | string | Controller image tag override; i.e., tag: "2.440.1-jdk17" | `nil` | +| [controller.image.tagLabel](./values.yaml#L45) | string | Controller image tag label | `"jdk17"` | +| [controller.imagePullSecretName](./values.yaml#L49) | string | Controller image pull secret | `nil` | +| [controller.ingress.annotations](./values.yaml#L702) | object | Ingress annotations | `{}` | +| [controller.ingress.apiVersion](./values.yaml#L698) | string | Ingress API version | `"extensions/v1beta1"` | +| [controller.ingress.enabled](./values.yaml#L681) | bool | Enables ingress | `false` | +| [controller.ingress.hostName](./values.yaml#L715) | string | Ingress hostname | `nil` | +| [controller.ingress.labels](./values.yaml#L700) | object | Ingress labels | `{}` | +| [controller.ingress.path](./values.yaml#L711) | string | Ingress path | `nil` | +| [controller.ingress.paths](./values.yaml#L685) | list | Override for the default Ingress paths | `[]` | +| [controller.ingress.resourceRootUrl](./values.yaml#L717) | string | Hostname to serve assets from | `nil` | +| [controller.ingress.tls](./values.yaml#L719) | list | Ingress TLS configuration | `[]` | +| [controller.initConfigMap](./values.yaml#L446) | string | Name of the existing ConfigMap that contains init scripts | `nil` | +| [controller.initContainerEnv](./values.yaml#L141) | list | Environment variables for Init Container | `[]` | +| [controller.initContainerEnvFrom](./values.yaml#L137) | list | Environment variable sources for Init Container | `[]` | +| [controller.initContainerResources](./values.yaml#L128) | object | Resources allocation (Requests and Limits) for Init Container | `{}` | +| [controller.initScripts](./values.yaml#L442) | object | Map of groovy init scripts to be executed during Jenkins controller start | `{}` | +| [controller.initializeOnce](./values.yaml#L414) | bool | Initialize only on first installation. Ensures plugins do not get updated inadvertently. Requires `persistence.enabled` to be set to `true` | `false` | +| [controller.installLatestPlugins](./values.yaml#L403) | bool | Download the minimum required version or latest version of all dependencies | `true` | +| [controller.installLatestSpecifiedPlugins](./values.yaml#L406) | bool | Set to true to download the latest version of any plugin that is requested to have the latest version | `false` | +| [controller.installPlugins](./values.yaml#L395) | list | List of Jenkins plugins to install. If you don't want to install plugins, set it to `false` | `["kubernetes:4265.v78b_d4a_1c864a_","workflow-aggregator:600.vb_57cdd26fdd7","git:5.2.2","configuration-as-code:1836.vccda_4a_122a_a_e"]` | +| [controller.javaOpts](./values.yaml#L156) | string | Append to `JAVA_OPTS` env var | `nil` | +| [controller.jenkinsAdminEmail](./values.yaml#L96) | string | Email address for the administrator of the Jenkins instance | `nil` | +| [controller.jenkinsHome](./values.yaml#L101) | string | Custom Jenkins home path | `"/var/jenkins_home"` | +| [controller.jenkinsOpts](./values.yaml#L158) | string | Append to `JENKINS_OPTS` env var | `nil` | +| [controller.jenkinsRef](./values.yaml#L106) | string | Custom Jenkins reference path | `"/usr/share/jenkins/ref"` | +| [controller.jenkinsUriPrefix](./values.yaml#L173) | string | Root URI Jenkins will be served on | `nil` | +| [controller.jenkinsUrl](./values.yaml#L168) | string | Set Jenkins URL if you are not using the ingress definitions provided by the chart | `nil` | +| [controller.jenkinsUrlProtocol](./values.yaml#L165) | string | Set protocol for Jenkins URL; `https` if `controller.ingress.tls`, `http` otherwise | `nil` | +| [controller.jenkinsWar](./values.yaml#L109) | string | | `"/usr/share/jenkins/jenkins.war"` | +| [controller.jmxPort](./values.yaml#L385) | string | Open a port, for JMX stats | `nil` | +| [controller.legacyRemotingSecurityEnabled](./values.yaml#L361) | bool | Whether legacy remoting security should be enabled | `false` | +| [controller.lifecycle](./values.yaml#L51) | object | Lifecycle specification for controller-container | `{}` | +| [controller.loadBalancerIP](./values.yaml#L376) | string | Optionally assign a known public LB IP | `nil` | +| [controller.loadBalancerSourceRanges](./values.yaml#L372) | list | Allowed inbound IP addresses | `["0.0.0.0/0"]` | +| [controller.markupFormatter](./values.yaml#L433) | string | Yaml of the markup formatter to use | `"plainText"` | +| [controller.nodePort](./values.yaml#L223) | string | k8s node port. Only used if serviceType is NodePort | `nil` | +| [controller.nodeSelector](./values.yaml#L647) | object | Node labels for pod assignment | `{}` | +| [controller.numExecutors](./values.yaml#L62) | int | Set Number of executors | `0` | +| [controller.overwritePlugins](./values.yaml#L418) | bool | Overwrite installed plugins on start | `false` | +| [controller.overwritePluginsFromImage](./values.yaml#L422) | bool | Overwrite plugins that are already installed in the controller image | `true` | +| [controller.podAnnotations](./values.yaml#L668) | object | Annotations for controller pod | `{}` | +| [controller.podDisruptionBudget.annotations](./values.yaml#L312) | object | | `{}` | +| [controller.podDisruptionBudget.apiVersion](./values.yaml#L310) | string | Policy API version | `"policy/v1beta1"` | +| [controller.podDisruptionBudget.enabled](./values.yaml#L305) | bool | Enable Kubernetes Pod Disruption Budget configuration | `false` | +| [controller.podDisruptionBudget.labels](./values.yaml#L313) | object | | `{}` | +| [controller.podDisruptionBudget.maxUnavailable](./values.yaml#L315) | string | Number of pods that can be unavailable. Either an absolute number or a percentage | `"0"` | +| [controller.podLabels](./values.yaml#L241) | object | Custom Pod labels (an object with `label-key: label-value` pairs) | `{}` | +| [controller.podSecurityContextOverride](./values.yaml#L202) | string | Completely overwrites the contents of the pod security context, ignoring the values provided for `runAsUser`, `fsGroup`, and `securityContextCapabilities` | `nil` | +| [controller.priorityClassName](./values.yaml#L665) | string | The name of a `priorityClass` to apply to the controller pod | `nil` | +| [controller.probes.livenessProbe.failureThreshold](./values.yaml#L266) | int | Set the failure threshold for the liveness probe | `5` | +| [controller.probes.livenessProbe.httpGet.path](./values.yaml#L269) | string | Set the Pod's HTTP path for the liveness probe | `"{{ default \"\" .Values.controller.jenkinsUriPrefix }}/login"` | +| [controller.probes.livenessProbe.httpGet.port](./values.yaml#L271) | string | Set the Pod's HTTP port to use for the liveness probe | `"http"` | +| [controller.probes.livenessProbe.initialDelaySeconds](./values.yaml#L280) | string | Set the initial delay for the liveness probe in seconds | `nil` | +| [controller.probes.livenessProbe.periodSeconds](./values.yaml#L273) | int | Set the time interval between two liveness probes executions in seconds | `10` | +| [controller.probes.livenessProbe.timeoutSeconds](./values.yaml#L275) | int | Set the timeout for the liveness probe in seconds | `5` | +| [controller.probes.readinessProbe.failureThreshold](./values.yaml#L284) | int | Set the failure threshold for the readiness probe | `3` | +| [controller.probes.readinessProbe.httpGet.path](./values.yaml#L287) | string | Set the Pod's HTTP path for the liveness probe | `"{{ default \"\" .Values.controller.jenkinsUriPrefix }}/login"` | +| [controller.probes.readinessProbe.httpGet.port](./values.yaml#L289) | string | Set the Pod's HTTP port to use for the readiness probe | `"http"` | +| [controller.probes.readinessProbe.initialDelaySeconds](./values.yaml#L298) | string | Set the initial delay for the readiness probe in seconds | `nil` | +| [controller.probes.readinessProbe.periodSeconds](./values.yaml#L291) | int | Set the time interval between two readiness probes executions in seconds | `10` | +| [controller.probes.readinessProbe.timeoutSeconds](./values.yaml#L293) | int | Set the timeout for the readiness probe in seconds | `5` | +| [controller.probes.startupProbe.failureThreshold](./values.yaml#L253) | int | Set the failure threshold for the startup probe | `12` | +| [controller.probes.startupProbe.httpGet.path](./values.yaml#L256) | string | Set the Pod's HTTP path for the startup probe | `"{{ default \"\" .Values.controller.jenkinsUriPrefix }}/login"` | +| [controller.probes.startupProbe.httpGet.port](./values.yaml#L258) | string | Set the Pod's HTTP port to use for the startup probe | `"http"` | +| [controller.probes.startupProbe.periodSeconds](./values.yaml#L260) | int | Set the time interval between two startup probes executions in seconds | `10` | +| [controller.probes.startupProbe.timeoutSeconds](./values.yaml#L262) | int | Set the timeout for the startup probe in seconds | `5` | +| [controller.projectNamingStrategy](./values.yaml#L425) | string | | `"standard"` | +| [controller.prometheus.alertingRulesAdditionalLabels](./values.yaml#L812) | object | Additional labels to add to the PrometheusRule object | `{}` | +| [controller.prometheus.alertingrules](./values.yaml#L810) | list | Array of prometheus alerting rules | `[]` | +| [controller.prometheus.enabled](./values.yaml#L795) | bool | Enables prometheus service monitor | `false` | +| [controller.prometheus.metricRelabelings](./values.yaml#L822) | list | | `[]` | +| [controller.prometheus.prometheusRuleNamespace](./values.yaml#L814) | string | Set a custom namespace where to deploy PrometheusRule resource | `""` | +| [controller.prometheus.relabelings](./values.yaml#L820) | list | | `[]` | +| [controller.prometheus.scrapeEndpoint](./values.yaml#L805) | string | The endpoint prometheus should get metrics from | `"/prometheus"` | +| [controller.prometheus.scrapeInterval](./values.yaml#L801) | string | How often prometheus should scrape metrics | `"60s"` | +| [controller.prometheus.serviceMonitorAdditionalLabels](./values.yaml#L797) | object | Additional labels to add to the service monitor object | `{}` | +| [controller.prometheus.serviceMonitorNamespace](./values.yaml#L799) | string | Set a custom namespace where to deploy ServiceMonitor resource | `nil` | +| [controller.resources](./values.yaml#L115) | object | Resource allocation (Requests and Limits) | `{"limits":{"cpu":"2000m","memory":"4096Mi"},"requests":{"cpu":"50m","memory":"256Mi"}}` | +| [controller.route.annotations](./values.yaml#L774) | object | Route annotations | `{}` | +| [controller.route.enabled](./values.yaml#L770) | bool | Enables openshift route | `false` | +| [controller.route.labels](./values.yaml#L772) | object | Route labels | `{}` | +| [controller.route.path](./values.yaml#L776) | string | Route path | `nil` | +| [controller.runAsUser](./values.yaml#L183) | int | Deprecated in favor of `controller.podSecurityContextOverride`. uid that jenkins runs with. | `1000` | +| [controller.schedulerName](./values.yaml#L643) | string | Name of the Kubernetes scheduler to use | `""` | +| [controller.scriptApproval](./values.yaml#L437) | list | List of groovy functions to approve | `[]` | +| [controller.secondaryingress.annotations](./values.yaml#L737) | object | | `{}` | +| [controller.secondaryingress.apiVersion](./values.yaml#L735) | string | | `"extensions/v1beta1"` | +| [controller.secondaryingress.enabled](./values.yaml#L729) | bool | | `false` | +| [controller.secondaryingress.hostName](./values.yaml#L744) | string | | `nil` | +| [controller.secondaryingress.labels](./values.yaml#L736) | object | | `{}` | +| [controller.secondaryingress.paths](./values.yaml#L732) | list | | `[]` | +| [controller.secondaryingress.tls](./values.yaml#L745) | string | | `nil` | +| [controller.secretClaims](./values.yaml#L480) | list | List of `SecretClaim` resources to create | `[]` | +| [controller.securityContextCapabilities](./values.yaml#L192) | object | | `{}` | +| [controller.serviceAnnotations](./values.yaml#L230) | object | Jenkins controller service annotations | `{}` | +| [controller.serviceExternalTrafficPolicy](./values.yaml#L227) | string | | `nil` | +| [controller.serviceLabels](./values.yaml#L236) | object | Labels for the Jenkins controller-service | `{}` | +| [controller.servicePort](./values.yaml#L219) | int | k8s service port | `8080` | +| [controller.serviceType](./values.yaml#L214) | string | k8s service type | `"ClusterIP"` | +| [controller.shareProcessNamespace](./values.yaml#L124) | bool | | `false` | +| [controller.sidecars.additionalSidecarContainers](./values.yaml#L625) | list | Configures additional sidecar container(s) for the Jenkins controller | `[]` | +| [controller.sidecars.configAutoReload.additionalVolumeMounts](./values.yaml#L571) | list | Enables additional volume mounts for the config auto-reload container | `[]` | +| [controller.sidecars.configAutoReload.containerSecurityContext](./values.yaml#L620) | object | Enable container security context | `{"allowPrivilegeEscalation":false,"readOnlyRootFilesystem":true}` | +| [controller.sidecars.configAutoReload.enabled](./values.yaml#L554) | bool | Enables Jenkins Config as Code auto-reload | `true` | +| [controller.sidecars.configAutoReload.env](./values.yaml#L602) | object | Environment variables for the Jenkins Config as Code auto-reload container | `{}` | +| [controller.sidecars.configAutoReload.envFrom](./values.yaml#L600) | list | Environment variable sources for the Jenkins Config as Code auto-reload container | `[]` | +| [controller.sidecars.configAutoReload.folder](./values.yaml#L613) | string | | `"/var/jenkins_home/casc_configs"` | +| [controller.sidecars.configAutoReload.image.registry](./values.yaml#L557) | string | Registry for the image that triggers the reload | `"docker.io"` | +| [controller.sidecars.configAutoReload.image.repository](./values.yaml#L559) | string | Repository of the image that triggers the reload | `"kiwigrid/k8s-sidecar"` | +| [controller.sidecars.configAutoReload.image.tag](./values.yaml#L561) | string | Tag for the image that triggers the reload | `"1.27.5"` | +| [controller.sidecars.configAutoReload.imagePullPolicy](./values.yaml#L562) | string | | `"IfNotPresent"` | +| [controller.sidecars.configAutoReload.logging](./values.yaml#L577) | object | Config auto-reload logging settings | `{"configuration":{"backupCount":3,"formatter":"JSON","logLevel":"INFO","logToConsole":true,"logToFile":false,"maxBytes":1024,"override":false}}` | +| [controller.sidecars.configAutoReload.logging.configuration.override](./values.yaml#L581) | bool | Enables custom log config utilizing using the settings below. | `false` | +| [controller.sidecars.configAutoReload.reqRetryConnect](./values.yaml#L595) | int | How many connection-related errors to retry on | `10` | +| [controller.sidecars.configAutoReload.resources](./values.yaml#L563) | object | | `{}` | +| [controller.sidecars.configAutoReload.scheme](./values.yaml#L590) | string | The scheme to use when connecting to the Jenkins configuration as code endpoint | `"http"` | +| [controller.sidecars.configAutoReload.skipTlsVerify](./values.yaml#L592) | bool | Skip TLS verification when connecting to the Jenkins configuration as code endpoint | `false` | +| [controller.sidecars.configAutoReload.sleepTime](./values.yaml#L597) | string | How many seconds to wait before updating config-maps/secrets (sets METHOD=SLEEP on the sidecar) | `nil` | +| [controller.sidecars.configAutoReload.sshTcpPort](./values.yaml#L611) | int | | `1044` | +| [controller.statefulSetAnnotations](./values.yaml#L670) | object | Annotations for controller StatefulSet | `{}` | +| [controller.statefulSetLabels](./values.yaml#L232) | object | Jenkins controller custom labels for the StatefulSet | `{}` | +| [controller.targetPort](./values.yaml#L221) | int | k8s target port | `8080` | +| [controller.terminationGracePeriodSeconds](./values.yaml#L653) | string | Set TerminationGracePeriodSeconds | `nil` | +| [controller.terminationMessagePath](./values.yaml#L655) | string | Set the termination message path | `nil` | +| [controller.terminationMessagePolicy](./values.yaml#L657) | string | Set the termination message policy | `nil` | +| [controller.testEnabled](./values.yaml#L834) | bool | Can be used to disable rendering controller test resources when using helm template | `true` | +| [controller.tolerations](./values.yaml#L651) | list | Toleration labels for pod assignment | `[]` | +| [controller.topologySpreadConstraints](./values.yaml#L677) | object | Topology spread constraints | `{}` | +| [controller.updateStrategy](./values.yaml#L674) | object | Update strategy for StatefulSet | `{}` | +| [controller.usePodSecurityContext](./values.yaml#L176) | bool | Enable pod security context (must be `true` if podSecurityContextOverride, runAsUser or fsGroup are set) | `true` | +| [credentialsId](./values.yaml#L27) | string | The Jenkins credentials to access the Kubernetes API server. For the default cluster it is not needed. | `nil` | +| [fullnameOverride](./values.yaml#L13) | string | Override the full resource names | `jenkins-(release-name)` or `jenkins` if the release-name is `jenkins` | +| [helmtest.bats.image.registry](./values.yaml#L1333) | string | Registry of the image used to test the framework | `"docker.io"` | +| [helmtest.bats.image.repository](./values.yaml#L1335) | string | Repository of the image used to test the framework | `"bats/bats"` | +| [helmtest.bats.image.tag](./values.yaml#L1337) | string | Tag of the image to test the framework | `"1.11.0"` | +| [kubernetesURL](./values.yaml#L24) | string | The URL of the Kubernetes API server | `"https://kubernetes.default"` | +| [nameOverride](./values.yaml#L10) | string | Override the resource name prefix | `Chart.Name` | +| [namespaceOverride](./values.yaml#L16) | string | Override the deployment namespace | `Release.Namespace` | +| [networkPolicy.apiVersion](./values.yaml#L1263) | string | NetworkPolicy ApiVersion | `"networking.k8s.io/v1"` | +| [networkPolicy.enabled](./values.yaml#L1258) | bool | Enable the creation of NetworkPolicy resources | `false` | +| [networkPolicy.externalAgents.except](./values.yaml#L1277) | list | A list of IP sub-ranges to be excluded from the allowlisted IP range | `[]` | +| [networkPolicy.externalAgents.ipCIDR](./values.yaml#L1275) | string | The IP range from which external agents are allowed to connect to controller, i.e., 172.17.0.0/16 | `nil` | +| [networkPolicy.internalAgents.allowed](./values.yaml#L1267) | bool | Allow internal agents (from the same cluster) to connect to controller. Agent pods will be filtered based on PodLabels | `true` | +| [networkPolicy.internalAgents.namespaceLabels](./values.yaml#L1271) | object | A map of labels (keys/values) that agents namespaces must have to be able to connect to controller | `{}` | +| [networkPolicy.internalAgents.podLabels](./values.yaml#L1269) | object | A map of labels (keys/values) that agent pods must have to be able to connect to controller | `{}` | +| [persistence.accessMode](./values.yaml#L1233) | string | The PVC access mode | `"ReadWriteOnce"` | +| [persistence.annotations](./values.yaml#L1229) | object | Annotations for the PVC | `{}` | +| [persistence.dataSource](./values.yaml#L1239) | object | Existing data source to clone PVC from | `{}` | +| [persistence.enabled](./values.yaml#L1213) | bool | Enable the use of a Jenkins PVC | `true` | +| [persistence.existingClaim](./values.yaml#L1219) | string | Provide the name of a PVC | `nil` | +| [persistence.labels](./values.yaml#L1231) | object | Labels for the PVC | `{}` | +| [persistence.mounts](./values.yaml#L1251) | list | Additional mounts | `[]` | +| [persistence.size](./values.yaml#L1235) | string | The size of the PVC | `"8Gi"` | +| [persistence.storageClass](./values.yaml#L1227) | string | Storage class for the PVC | `nil` | +| [persistence.subPath](./values.yaml#L1244) | string | SubPath for jenkins-home mount | `nil` | +| [persistence.volumes](./values.yaml#L1246) | list | Additional volumes | `[]` | +| [rbac.create](./values.yaml#L1283) | bool | Whether RBAC resources are created | `true` | +| [rbac.readSecrets](./values.yaml#L1285) | bool | Whether the Jenkins service account should be able to read Kubernetes secrets | `false` | +| [renderHelmLabels](./values.yaml#L30) | bool | Enables rendering of the helm.sh/chart label to the annotations | `true` | +| [serviceAccount.annotations](./values.yaml#L1295) | object | Configures annotations for the ServiceAccount | `{}` | +| [serviceAccount.create](./values.yaml#L1289) | bool | Configures if a ServiceAccount with this name should be created | `true` | +| [serviceAccount.extraLabels](./values.yaml#L1297) | object | Configures extra labels for the ServiceAccount | `{}` | +| [serviceAccount.imagePullSecretName](./values.yaml#L1299) | string | Controller ServiceAccount image pull secret | `nil` | +| [serviceAccount.name](./values.yaml#L1293) | string | | `nil` | +| [serviceAccountAgent.annotations](./values.yaml#L1310) | object | Configures annotations for the agent ServiceAccount | `{}` | +| [serviceAccountAgent.create](./values.yaml#L1304) | bool | Configures if an agent ServiceAccount should be created | `false` | +| [serviceAccountAgent.extraLabels](./values.yaml#L1312) | object | Configures extra labels for the agent ServiceAccount | `{}` | +| [serviceAccountAgent.imagePullSecretName](./values.yaml#L1314) | string | Agent ServiceAccount image pull secret | `nil` | +| [serviceAccountAgent.name](./values.yaml#L1308) | string | The name of the agent ServiceAccount to be used by access-controlled resources | `nil` | diff --git a/charts/jenkins/jenkins/5.5.1/VALUES.md.gotmpl b/charts/jenkins/jenkins/5.5.1/VALUES.md.gotmpl new file mode 100644 index 000000000..21080e35a --- /dev/null +++ b/charts/jenkins/jenkins/5.5.1/VALUES.md.gotmpl @@ -0,0 +1,28 @@ +# Jenkins + +## Configuration + +The following tables list the configurable parameters of the Jenkins chart and their default values. + +{{- define "chart.valueDefaultColumnRender" -}} +{{- $defaultValue := (trimAll "`" (default .Default .AutoDefault) | replace "\n" "") -}} +`{{- $defaultValue | replace "\n" "" -}}` +{{- end -}} + +{{- define "chart.typeColumnRender" -}} +{{- .Type -}} +{{- end -}} + +{{- define "chart.valueDescription" -}} +{{- default .Description .AutoDescription }} +{{- end -}} + +{{- define "chart.valuesTable" -}} +| Key | Type | Description | Default | +|:----|:-----|:---------|:------------| +{{- range .Values }} +| [{{ .Key }}](./values.yaml#L{{ .LineNumber }}) | {{ template "chart.typeColumnRender" . }} | {{ template "chart.valueDescription" . }} | {{ template "chart.valueDefaultColumnRender" . }} | +{{- end }} +{{- end }} + +{{ template "chart.valuesSection" . }} diff --git a/charts/jenkins/jenkins/5.5.1/templates/NOTES.txt b/charts/jenkins/jenkins/5.5.1/templates/NOTES.txt new file mode 100644 index 000000000..953dd2606 --- /dev/null +++ b/charts/jenkins/jenkins/5.5.1/templates/NOTES.txt @@ -0,0 +1,68 @@ +{{- $prefix := .Values.controller.jenkinsUriPrefix | default "" -}} +{{- $url := "" -}} +1. Get your '{{ .Values.controller.admin.username }}' user password by running: + kubectl exec --namespace {{ template "jenkins.namespace" . }} -it svc/{{ template "jenkins.fullname" . }} -c jenkins -- /bin/cat /run/secrets/additional/chart-admin-password && echo +{{- if .Values.controller.ingress.hostName -}} +{{- if .Values.controller.ingress.tls -}} +{{- $url = print "https://" .Values.controller.ingress.hostName $prefix -}} +{{- else -}} +{{- $url = print "http://" .Values.controller.ingress.hostName $prefix -}} +{{- end }} +2. Visit {{ $url }} +{{- else }} +2. Get the Jenkins URL to visit by running these commands in the same shell: +{{- if contains "NodePort" .Values.controller.serviceType }} + export NODE_PORT=$(kubectl get --namespace {{ template "jenkins.namespace" . }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "jenkins.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ template "jenkins.namespace" . }} -o jsonpath="{.items[0].status.addresses[0].address}") +{{- if .Values.controller.httpsKeyStore.enable -}} +{{- $url = print "https://$NODE_IP:$NODE_PORT" $prefix -}} +{{- else -}} +{{- $url = print "http://$NODE_IP:$NODE_PORT" $prefix -}} +{{- end }} + echo {{ $url }} + +{{- else if contains "LoadBalancer" .Values.controller.serviceType }} + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch the status of by running 'kubectl get svc --namespace {{ template "jenkins.namespace" . }} -w {{ template "jenkins.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ template "jenkins.namespace" . }} {{ template "jenkins.fullname" . }} --template "{{ "{{ range (index .status.loadBalancer.ingress 0) }}{{ . }}{{ end }}" }}") +{{- if .Values.controller.httpsKeyStore.enable -}} +{{- $url = print "https://$SERVICE_IP:" .Values.controller.servicePort $prefix -}} +{{- else -}} +{{- $url = print "http://$SERVICE_IP:" .Values.controller.servicePort $prefix -}} +{{- end }} + echo {{ $url }} + +{{- else if contains "ClusterIP" .Values.controller.serviceType -}} +{{- if .Values.controller.httpsKeyStore.enable -}} +{{- $url = print "https://127.0.0.1:" .Values.controller.servicePort $prefix -}} +{{- else -}} +{{- $url = print "http://127.0.0.1:" .Values.controller.servicePort $prefix -}} +{{- end }} + echo {{ $url }} + kubectl --namespace {{ template "jenkins.namespace" . }} port-forward svc/{{template "jenkins.fullname" . }} {{ .Values.controller.servicePort }}:{{ .Values.controller.servicePort }} +{{- end }} +{{- end }} + +3. Login with the password from step 1 and the username: {{ .Values.controller.admin.username }} +4. Configure security realm and authorization strategy +5. Use Jenkins Configuration as Code by specifying configScripts in your values.yaml file, see documentation: {{ $url }}/configuration-as-code and examples: https://github.com/jenkinsci/configuration-as-code-plugin/tree/master/demos + +For more information on running Jenkins on Kubernetes, visit: +https://cloud.google.com/solutions/jenkins-on-container-engine + +For more information about Jenkins Configuration as Code, visit: +https://jenkins.io/projects/jcasc/ + +{{ if and (eq .Values.controller.image.repository "jenkins/jenkins") (eq .Values.controller.image.registry "docker.io") }} +NOTE: Consider using a custom image with pre-installed plugins +{{- else if .Values.controller.installPlugins }} +NOTE: Consider disabling `installPlugins` if your image already contains plugins. +{{- end }} + +{{- if .Values.persistence.enabled }} +{{- else }} +################################################################################# +###### WARNING: Persistence is disabled!!! You will lose your data when ##### +###### the Jenkins pod is terminated. ##### +################################################################################# +{{- end }} diff --git a/charts/jenkins/jenkins/5.5.1/templates/_helpers.tpl b/charts/jenkins/jenkins/5.5.1/templates/_helpers.tpl new file mode 100644 index 000000000..fef2bf585 --- /dev/null +++ b/charts/jenkins/jenkins/5.5.1/templates/_helpers.tpl @@ -0,0 +1,673 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "jenkins.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Expand the label of the chart. +*/}} +{{- define "jenkins.label" -}} +{{- printf "%s-%s" (include "jenkins.name" .) .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + + +{{/* +Allow the release namespace to be overridden for multi-namespace deployments in combined charts. +*/}} +{{- define "jenkins.namespace" -}} + {{- if .Values.namespaceOverride -}} + {{- .Values.namespaceOverride -}} + {{- else -}} + {{- .Release.Namespace -}} + {{- end -}} +{{- end -}} + +{{- define "jenkins.agent.namespace" -}} + {{- if .Values.agent.namespace -}} + {{- tpl .Values.agent.namespace . -}} + {{- else -}} + {{- if .Values.namespaceOverride -}} + {{- .Values.namespaceOverride -}} + {{- else -}} + {{- .Release.Namespace -}} + {{- end -}} + {{- end -}} +{{- end -}} + + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "jenkins.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Returns the admin password +https://github.com/helm/charts/issues/5167#issuecomment-619137759 +*/}} +{{- define "jenkins.password" -}} + {{- if .Values.controller.admin.password -}} + {{- .Values.controller.admin.password | b64enc | quote }} + {{- else -}} + {{- $secret := (lookup "v1" "Secret" .Release.Namespace (include "jenkins.fullname" .)).data -}} + {{- if $secret -}} + {{/* + Reusing current password since secret exists + */}} + {{- index $secret ( .Values.controller.admin.passwordKey | default "jenkins-admin-password" ) -}} + {{- else -}} + {{/* + Generate new password + */}} + {{- randAlphaNum 22 | b64enc | quote }} + {{- end -}} + {{- end -}} +{{- end -}} + +{{/* +Returns the Jenkins URL +*/}} +{{- define "jenkins.url" -}} +{{- if .Values.controller.jenkinsUrl }} + {{- .Values.controller.jenkinsUrl }} +{{- else }} + {{- if .Values.controller.ingress.hostName }} + {{- if .Values.controller.ingress.tls }} + {{- default "https" .Values.controller.jenkinsUrlProtocol }}://{{ tpl .Values.controller.ingress.hostName $ }}{{ default "" .Values.controller.jenkinsUriPrefix }} + {{- else }} + {{- default "http" .Values.controller.jenkinsUrlProtocol }}://{{ tpl .Values.controller.ingress.hostName $ }}{{ default "" .Values.controller.jenkinsUriPrefix }} + {{- end }} + {{- else }} + {{- default "http" .Values.controller.jenkinsUrlProtocol }}://{{ template "jenkins.fullname" . }}:{{.Values.controller.servicePort}}{{ default "" .Values.controller.jenkinsUriPrefix }} + {{- end}} +{{- end}} +{{- end -}} + +{{/* +Returns configuration as code default config +*/}} +{{- define "jenkins.casc.defaults" -}} +jenkins: + {{- $configScripts := toYaml .Values.controller.JCasC.configScripts }} + {{- if and (.Values.controller.JCasC.authorizationStrategy) (not (contains "authorizationStrategy:" $configScripts)) }} + authorizationStrategy: + {{- tpl .Values.controller.JCasC.authorizationStrategy . | nindent 4 }} + {{- end }} + {{- if and (.Values.controller.JCasC.securityRealm) (not (contains "securityRealm:" $configScripts)) }} + securityRealm: + {{- tpl .Values.controller.JCasC.securityRealm . | nindent 4 }} + {{- end }} + disableRememberMe: {{ .Values.controller.disableRememberMe }} + {{- if .Values.controller.legacyRemotingSecurityEnabled }} + remotingSecurity: + enabled: true + {{- end }} + mode: {{ .Values.controller.executorMode }} + numExecutors: {{ .Values.controller.numExecutors }} + {{- if not (kindIs "invalid" .Values.controller.customJenkinsLabels) }} + labelString: "{{ join " " .Values.controller.customJenkinsLabels }}" + {{- end }} + {{- if .Values.controller.projectNamingStrategy }} + {{- if kindIs "string" .Values.controller.projectNamingStrategy }} + projectNamingStrategy: "{{ .Values.controller.projectNamingStrategy }}" + {{- else }} + projectNamingStrategy: + {{- toYaml .Values.controller.projectNamingStrategy | nindent 4 }} + {{- end }} + {{- end }} + markupFormatter: + {{- if .Values.controller.enableRawHtmlMarkupFormatter }} + rawHtml: + disableSyntaxHighlighting: true + {{- else }} + {{- toYaml .Values.controller.markupFormatter | nindent 4 }} + {{- end }} + clouds: + - kubernetes: + containerCapStr: "{{ .Values.agent.containerCap }}" + {{- if .Values.agent.jnlpregistry }} + jnlpregistry: "{{ .Values.agent.jnlpregistry }}" + {{- end }} + defaultsProviderTemplate: "{{ .Values.agent.defaultsProviderTemplate }}" + connectTimeout: "{{ .Values.agent.kubernetesConnectTimeout }}" + readTimeout: "{{ .Values.agent.kubernetesReadTimeout }}" + {{- if .Values.agent.directConnection }} + directConnection: true + {{- else }} + {{- if .Values.agent.jenkinsUrl }} + jenkinsUrl: "{{ tpl .Values.agent.jenkinsUrl . }}" + {{- else }} + jenkinsUrl: "http://{{ template "jenkins.fullname" . }}.{{ template "jenkins.namespace" . }}.svc.{{.Values.clusterZone}}:{{.Values.controller.servicePort}}{{ default "" .Values.controller.jenkinsUriPrefix }}" + {{- end }} + {{- if not .Values.agent.websocket }} + {{- if .Values.agent.jenkinsTunnel }} + jenkinsTunnel: "{{ tpl .Values.agent.jenkinsTunnel . }}" + {{- else }} + jenkinsTunnel: "{{ template "jenkins.fullname" . }}-agent.{{ template "jenkins.namespace" . }}.svc.{{.Values.clusterZone}}:{{ .Values.controller.agentListenerPort }}" + {{- end }} + {{- else }} + webSocket: true + {{- end }} + {{- end }} + skipTlsVerify: {{ .Values.agent.skipTlsVerify | default false}} + usageRestricted: {{ .Values.agent.usageRestricted | default false}} + maxRequestsPerHostStr: {{ .Values.agent.maxRequestsPerHostStr | quote }} + retentionTimeout: {{ .Values.agent.retentionTimeout | quote }} + waitForPodSec: {{ .Values.agent.waitForPodSec | quote }} + name: "{{ .Values.controller.cloudName }}" + namespace: "{{ template "jenkins.agent.namespace" . }}" + restrictedPssSecurityContext: {{ .Values.agent.restrictedPssSecurityContext }} + serverUrl: "{{ .Values.kubernetesURL }}" + credentialsId: "{{ .Values.credentialsId }}" + {{- if .Values.agent.enabled }} + podLabels: + - key: "jenkins/{{ .Release.Name }}-{{ .Values.agent.componentName }}" + value: "true" + {{- range $key, $val := .Values.agent.podLabels }} + - key: {{ $key | quote }} + value: {{ $val | quote }} + {{- end }} + templates: + {{- if not .Values.agent.disableDefaultAgent }} + {{- include "jenkins.casc.podTemplate" . | nindent 8 }} + {{- end }} + {{- if .Values.additionalAgents }} + {{- /* save .Values.agent */}} + {{- $agent := .Values.agent }} + {{- range $name, $additionalAgent := .Values.additionalAgents }} + {{- $additionalContainersEmpty := and (hasKey $additionalAgent "additionalContainers") (empty $additionalAgent.additionalContainers) }} + {{- /* merge original .Values.agent into additional agent to ensure it at least has the default values */}} + {{- $additionalAgent := merge $additionalAgent $agent }} + {{- /* clear list of additional containers in case it is configured empty for this agent (merge might have overwritten that) */}} + {{- if $additionalContainersEmpty }} + {{- $_ := set $additionalAgent "additionalContainers" list }} + {{- end }} + {{- /* set .Values.agent to $additionalAgent */}} + {{- $_ := set $.Values "agent" $additionalAgent }} + {{- include "jenkins.casc.podTemplate" $ | nindent 8 }} + {{- end }} + {{- /* restore .Values.agent */}} + {{- $_ := set .Values "agent" $agent }} + {{- end }} + {{- if .Values.agent.podTemplates }} + {{- range $key, $val := .Values.agent.podTemplates }} + {{- tpl $val $ | nindent 8 }} + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.additionalClouds }} + {{- /* save root */}} + {{- $oldRoot := deepCopy $ }} + {{- range $name, $additionalCloud := .Values.additionalClouds }} + {{- $newRoot := deepCopy $ }} + {{- /* clear additionalAgents from the copy if override set to `true` */}} + {{- if .additionalAgentsOverride }} + {{- $_ := set $newRoot.Values "additionalAgents" list}} + {{- end}} + {{- $newValues := merge $additionalCloud $newRoot.Values }} + {{- $_ := set $newRoot "Values" $newValues }} + {{- /* clear additionalClouds from the copy */}} + {{- $_ := set $newRoot.Values "additionalClouds" list }} + {{- with $newRoot}} + - kubernetes: + containerCapStr: "{{ .Values.agent.containerCap }}" + {{- if .Values.agent.jnlpregistry }} + jnlpregistry: "{{ .Values.agent.jnlpregistry }}" + {{- end }} + defaultsProviderTemplate: "{{ .Values.agent.defaultsProviderTemplate }}" + connectTimeout: "{{ .Values.agent.kubernetesConnectTimeout }}" + readTimeout: "{{ .Values.agent.kubernetesReadTimeout }}" + {{- if .Values.agent.directConnection }} + directConnection: true + {{- else }} + {{- if .Values.agent.jenkinsUrl }} + jenkinsUrl: "{{ tpl .Values.agent.jenkinsUrl . }}" + {{- else }} + jenkinsUrl: "http://{{ template "jenkins.fullname" . }}.{{ template "jenkins.namespace" . }}.svc.{{.Values.clusterZone}}:{{.Values.controller.servicePort}}{{ default "" .Values.controller.jenkinsUriPrefix }}" + {{- end }} + {{- if not .Values.agent.websocket }} + {{- if .Values.agent.jenkinsTunnel }} + jenkinsTunnel: "{{ tpl .Values.agent.jenkinsTunnel . }}" + {{- else }} + jenkinsTunnel: "{{ template "jenkins.fullname" . }}-agent.{{ template "jenkins.namespace" . }}.svc.{{.Values.clusterZone}}:{{ .Values.controller.agentListenerPort }}" + {{- end }} + {{- else }} + webSocket: true + {{- end }} + {{- end }} + skipTlsVerify: {{ .Values.agent.skipTlsVerify | default false}} + usageRestricted: {{ .Values.agent.usageRestricted | default false}} + maxRequestsPerHostStr: {{ .Values.agent.maxRequestsPerHostStr | quote }} + retentionTimeout: {{ .Values.agent.retentionTimeout | quote }} + waitForPodSec: {{ .Values.agent.waitForPodSec | quote }} + name: {{ $name | quote }} + namespace: "{{ template "jenkins.agent.namespace" . }}" + restrictedPssSecurityContext: {{ .Values.agent.restrictedPssSecurityContext }} + serverUrl: "{{ .Values.kubernetesURL }}" + credentialsId: "{{ .Values.credentialsId }}" + {{- if .Values.agent.enabled }} + podLabels: + - key: "jenkins/{{ .Release.Name }}-{{ .Values.agent.componentName }}" + value: "true" + {{- range $key, $val := .Values.agent.podLabels }} + - key: {{ $key | quote }} + value: {{ $val | quote }} + {{- end }} + templates: + {{- if not .Values.agent.disableDefaultAgent }} + {{- include "jenkins.casc.podTemplate" . | nindent 8 }} + {{- end }} + {{- if .Values.additionalAgents }} + {{- /* save .Values.agent */}} + {{- $agent := .Values.agent }} + {{- range $name, $additionalAgent := .Values.additionalAgents }} + {{- $additionalContainersEmpty := and (hasKey $additionalAgent "additionalContainers") (empty $additionalAgent.additionalContainers) }} + {{- /* merge original .Values.agent into additional agent to ensure it at least has the default values */}} + {{- $additionalAgent := merge $additionalAgent $agent }} + {{- /* clear list of additional containers in case it is configured empty for this agent (merge might have overwritten that) */}} + {{- if $additionalContainersEmpty }} + {{- $_ := set $additionalAgent "additionalContainers" list }} + {{- end }} + {{- /* set .Values.agent to $additionalAgent */}} + {{- $_ := set $.Values "agent" $additionalAgent }} + {{- include "jenkins.casc.podTemplate" $ | nindent 8 }} + {{- end }} + {{- /* restore .Values.agent */}} + {{- $_ := set .Values "agent" $agent }} + {{- end }} + {{- with .Values.agent.podTemplates }} + {{- range $key, $val := . }} + {{- tpl $val $ | nindent 8 }} + {{- end }} + {{- end }} + {{- end }} + {{- end }} + {{- end }} + {{- /* restore root */}} + {{- $_ := set $ "Values" $oldRoot.Values }} + {{- end }} + {{- if .Values.controller.csrf.defaultCrumbIssuer.enabled }} + crumbIssuer: + standard: + excludeClientIPFromCrumb: {{ if .Values.controller.csrf.defaultCrumbIssuer.proxyCompatability }}true{{ else }}false{{- end }} + {{- end }} +{{- include "jenkins.casc.security" . }} +{{- with .Values.controller.scriptApproval }} + scriptApproval: + approvedSignatures: + {{- range $key, $val := . }} + - "{{ $val }}" + {{- end }} +{{- end }} +unclassified: + location: + {{- with .Values.controller.jenkinsAdminEmail }} + adminAddress: {{ . }} + {{- end }} + url: {{ template "jenkins.url" . }} +{{- end -}} + +{{/* +Returns a name template to be used for jcasc configmaps, using +suffix passed in at call as index 0 +*/}} +{{- define "jenkins.casc.configName" -}} +{{- $name := index . 0 -}} +{{- $root := index . 1 -}} +"{{- include "jenkins.fullname" $root -}}-jenkins-{{ $name }}" +{{- end -}} + +{{/* +Returns kubernetes pod template configuration as code +*/}} +{{- define "jenkins.casc.podTemplate" -}} +- name: "{{ .Values.agent.podName }}" + namespace: "{{ template "jenkins.agent.namespace" . }}" +{{- if .Values.agent.annotations }} + annotations: + {{- range $key, $value := .Values.agent.annotations }} + - key: {{ $key }} + value: {{ $value | quote }} + {{- end }} +{{- end }} + id: {{ sha256sum (toYaml .Values.agent) }} + containers: + - name: "{{ .Values.agent.sideContainerName }}" + alwaysPullImage: {{ .Values.agent.alwaysPullImage }} + args: "{{ .Values.agent.args | replace "$" "^$" }}" + {{- with .Values.agent.command }} + command: {{ . }} + {{- end }} + envVars: + - envVar: + {{- if .Values.agent.directConnection }} + key: "JENKINS_DIRECT_CONNECTION" + {{- if .Values.agent.jenkinsTunnel }} + value: "{{ tpl .Values.agent.jenkinsTunnel . }}" + {{- else }} + value: "{{ template "jenkins.fullname" . }}-agent.{{ template "jenkins.namespace" . }}.svc.{{.Values.clusterZone}}:{{ .Values.controller.agentListenerPort }}" + {{- end }} + {{- else }} + key: "JENKINS_URL" + {{- if .Values.agent.jenkinsUrl }} + value: {{ tpl .Values.agent.jenkinsUrl . }} + {{- else }} + value: "http://{{ template "jenkins.fullname" . }}.{{ template "jenkins.namespace" . }}.svc.{{.Values.clusterZone}}:{{.Values.controller.servicePort}}{{ default "/" .Values.controller.jenkinsUriPrefix }}" + {{- end }} + {{- end }} + image: "{{ .Values.agent.image.repository }}:{{ .Values.agent.image.tag }}" + {{- if .Values.agent.livenessProbe }} + livenessProbe: + execArgs: {{.Values.agent.livenessProbe.execArgs | quote}} + failureThreshold: {{.Values.agent.livenessProbe.failureThreshold}} + initialDelaySeconds: {{.Values.agent.livenessProbe.initialDelaySeconds}} + periodSeconds: {{.Values.agent.livenessProbe.periodSeconds}} + successThreshold: {{.Values.agent.livenessProbe.successThreshold}} + timeoutSeconds: {{.Values.agent.livenessProbe.timeoutSeconds}} + {{- end }} + privileged: "{{- if .Values.agent.privileged }}true{{- else }}false{{- end }}" + resourceLimitCpu: {{.Values.agent.resources.limits.cpu}} + resourceLimitMemory: {{.Values.agent.resources.limits.memory}} + {{- with .Values.agent.resources.limits.ephemeralStorage }} + resourceLimitEphemeralStorage: {{.}} + {{- end }} + resourceRequestCpu: {{.Values.agent.resources.requests.cpu}} + resourceRequestMemory: {{.Values.agent.resources.requests.memory}} + {{- with .Values.agent.resources.requests.ephemeralStorage }} + resourceRequestEphemeralStorage: {{.}} + {{- end }} + {{- with .Values.agent.runAsUser }} + runAsUser: {{ . }} + {{- end }} + {{- with .Values.agent.runAsGroup }} + runAsGroup: {{ . }} + {{- end }} + ttyEnabled: {{ .Values.agent.TTYEnabled }} + workingDir: {{ .Values.agent.workingDir }} +{{- range $additionalContainers := .Values.agent.additionalContainers }} + - name: "{{ $additionalContainers.sideContainerName }}" + alwaysPullImage: {{ $additionalContainers.alwaysPullImage | default $.Values.agent.alwaysPullImage }} + args: "{{ $additionalContainers.args | replace "$" "^$" }}" + {{- with $additionalContainers.command }} + command: {{ . }} + {{- end }} + envVars: + - envVar: + key: "JENKINS_URL" + {{- if $additionalContainers.jenkinsUrl }} + value: {{ tpl ($additionalContainers.jenkinsUrl) . }} + {{- else }} + value: "http://{{ template "jenkins.fullname" $ }}.{{ template "jenkins.namespace" $ }}.svc.{{ $.Values.clusterZone }}:{{ $.Values.controller.servicePort }}{{ default "/" $.Values.controller.jenkinsUriPrefix }}" + {{- end }} + image: "{{ $additionalContainers.image.repository }}:{{ $additionalContainers.image.tag }}" + {{- if $additionalContainers.livenessProbe }} + livenessProbe: + execArgs: {{$additionalContainers.livenessProbe.execArgs | quote}} + failureThreshold: {{$additionalContainers.livenessProbe.failureThreshold}} + initialDelaySeconds: {{$additionalContainers.livenessProbe.initialDelaySeconds}} + periodSeconds: {{$additionalContainers.livenessProbe.periodSeconds}} + successThreshold: {{$additionalContainers.livenessProbe.successThreshold}} + timeoutSeconds: {{$additionalContainers.livenessProbe.timeoutSeconds}} + {{- end }} + privileged: "{{- if $additionalContainers.privileged }}true{{- else }}false{{- end }}" + resourceLimitCpu: {{ if $additionalContainers.resources }}{{ $additionalContainers.resources.limits.cpu }}{{ else }}{{ $.Values.agent.resources.limits.cpu }}{{ end }} + resourceLimitMemory: {{ if $additionalContainers.resources }}{{ $additionalContainers.resources.limits.memory }}{{ else }}{{ $.Values.agent.resources.limits.memory }}{{ end }} + resourceRequestCpu: {{ if $additionalContainers.resources }}{{ $additionalContainers.resources.requests.cpu }}{{ else }}{{ $.Values.agent.resources.requests.cpu }}{{ end }} + resourceRequestMemory: {{ if $additionalContainers.resources }}{{ $additionalContainers.resources.requests.memory }}{{ else }}{{ $.Values.agent.resources.requests.memory }}{{ end }} + {{- if or $additionalContainers.runAsUser $.Values.agent.runAsUser }} + runAsUser: {{ $additionalContainers.runAsUser | default $.Values.agent.runAsUser }} + {{- end }} + {{- if or $additionalContainers.runAsGroup $.Values.agent.runAsGroup }} + runAsGroup: {{ $additionalContainers.runAsGroup | default $.Values.agent.runAsGroup }} + {{- end }} + ttyEnabled: {{ $additionalContainers.TTYEnabled | default $.Values.agent.TTYEnabled }} + workingDir: {{ $additionalContainers.workingDir | default $.Values.agent.workingDir }} +{{- end }} +{{- if or .Values.agent.envVars .Values.agent.secretEnvVars }} + envVars: + {{- range $index, $var := .Values.agent.envVars }} + - envVar: + key: {{ $var.name }} + value: {{ tpl $var.value $ }} + {{- end }} + {{- range $index, $var := .Values.agent.secretEnvVars }} + - secretEnvVar: + key: {{ $var.key }} + secretName: {{ $var.secretName }} + secretKey: {{ $var.secretKey }} + optional: {{ $var.optional | default false }} + {{- end }} +{{- end }} + idleMinutes: {{ .Values.agent.idleMinutes }} + instanceCap: 2147483647 + {{- if .Values.agent.hostNetworking }} + hostNetwork: {{ .Values.agent.hostNetworking }} + {{- end }} + {{- if .Values.agent.imagePullSecretName }} + imagePullSecrets: + - name: {{ .Values.agent.imagePullSecretName }} + {{- end }} + label: "{{ .Release.Name }}-{{ .Values.agent.componentName }} {{ .Values.agent.customJenkinsLabels | join " " }}" +{{- if .Values.agent.nodeSelector }} + nodeSelector: + {{- $local := dict "first" true }} + {{- range $key, $value := .Values.agent.nodeSelector }} + {{- if $local.first }} {{ else }},{{ end }} + {{- $key }}={{ tpl $value $ }} + {{- $_ := set $local "first" false }} + {{- end }} +{{- end }} + nodeUsageMode: {{ quote .Values.agent.nodeUsageMode }} + podRetention: {{ .Values.agent.podRetention }} + showRawYaml: {{ .Values.agent.showRawYaml }} + serviceAccount: "{{ include "jenkins.serviceAccountAgentName" . }}" + slaveConnectTimeoutStr: "{{ .Values.agent.connectTimeout }}" +{{- if .Values.agent.volumes }} + volumes: + {{- range $index, $volume := .Values.agent.volumes }} + -{{- if (eq $volume.type "ConfigMap") }} configMapVolume: + {{- else if (eq $volume.type "EmptyDir") }} emptyDirVolume: + {{- else if (eq $volume.type "EphemeralVolume") }} genericEphemeralVolume: + {{- else if (eq $volume.type "HostPath") }} hostPathVolume: + {{- else if (eq $volume.type "Nfs") }} nfsVolume: + {{- else if (eq $volume.type "PVC") }} persistentVolumeClaim: + {{- else if (eq $volume.type "Secret") }} secretVolume: + {{- else }} {{ $volume.type }}: + {{- end }} + {{- range $key, $value := $volume }} + {{- if not (eq $key "type") }} + {{ $key }}: {{ if kindIs "string" $value }}{{ tpl $value $ | quote }}{{ else }}{{ $value }}{{ end }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} +{{- if .Values.agent.workspaceVolume }} + workspaceVolume: + {{- if (eq .Values.agent.workspaceVolume.type "DynamicPVC") }} + dynamicPVC: + {{- else if (eq .Values.agent.workspaceVolume.type "EmptyDir") }} + emptyDirWorkspaceVolume: + {{- else if (eq .Values.agent.workspaceVolume.type "EphemeralVolume") }} + genericEphemeralVolume: + {{- else if (eq .Values.agent.workspaceVolume.type "HostPath") }} + hostPathWorkspaceVolume: + {{- else if (eq .Values.agent.workspaceVolume.type "Nfs") }} + nfsWorkspaceVolume: + {{- else if (eq .Values.agent.workspaceVolume.type "PVC") }} + persistentVolumeClaimWorkspaceVolume: + {{- else }} + {{ .Values.agent.workspaceVolume.type }}: + {{- end }} + {{- range $key, $value := .Values.agent.workspaceVolume }} + {{- if not (eq $key "type") }} + {{ $key }}: {{ if kindIs "string" $value }}{{ tpl $value $ | quote }}{{ else }}{{ $value }}{{ end }} + {{- end }} + {{- end }} +{{- end }} +{{- if .Values.agent.yamlTemplate }} + yaml: |- + {{- tpl (trim .Values.agent.yamlTemplate) . | nindent 4 }} +{{- end }} + yamlMergeStrategy: {{ .Values.agent.yamlMergeStrategy }} + inheritYamlMergeStrategy: {{ .Values.agent.inheritYamlMergeStrategy }} +{{- end -}} + +{{- define "jenkins.kubernetes-version" -}} + {{- if .Values.controller.installPlugins -}} + {{- range .Values.controller.installPlugins -}} + {{- if hasPrefix "kubernetes:" . }} + {{- $split := splitList ":" . }} + {{- printf "%s" (index $split 1 ) -}} + {{- end -}} + {{- end -}} + {{- end -}} +{{- end -}} + +{{- define "jenkins.casc.security" }} +security: +{{- with .Values.controller.JCasC }} +{{- if .security }} + {{- .security | toYaml | nindent 2 }} +{{- end }} +{{- end }} +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "jenkins.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "jenkins.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the service account for Jenkins agents to use +*/}} +{{- define "jenkins.serviceAccountAgentName" -}} +{{- if .Values.serviceAccountAgent.create -}} + {{ default (printf "%s-%s" (include "jenkins.fullname" .) "agent") .Values.serviceAccountAgent.name }} +{{- else -}} + {{ default "default" .Values.serviceAccountAgent.name }} +{{- end -}} +{{- end -}} + +{{/* +Create a full tag name for controller image +*/}} +{{- define "controller.image.tag" -}} +{{- if .Values.controller.image.tagLabel -}} + {{- default (printf "%s-%s" .Chart.AppVersion .Values.controller.image.tagLabel) .Values.controller.image.tag -}} +{{- else -}} + {{- default .Chart.AppVersion .Values.controller.image.tag -}} +{{- end -}} +{{- end -}} + +{{/* +Create the HTTP port for interacting with the controller +*/}} +{{- define "controller.httpPort" -}} +{{- if .Values.controller.httpsKeyStore.enable -}} + {{- .Values.controller.httpsKeyStore.httpPort -}} +{{- else -}} + {{- .Values.controller.targetPort -}} +{{- end -}} +{{- end -}} + +{{- define "jenkins.configReloadContainer" -}} +{{- $root := index . 0 -}} +{{- $containerName := index . 1 -}} +{{- $containerType := index . 2 -}} +- name: {{ $containerName }} + image: "{{ $root.Values.controller.sidecars.configAutoReload.image.registry }}/{{ $root.Values.controller.sidecars.configAutoReload.image.repository }}:{{ $root.Values.controller.sidecars.configAutoReload.image.tag }}" + imagePullPolicy: {{ $root.Values.controller.sidecars.configAutoReload.imagePullPolicy }} + {{- if $root.Values.controller.sidecars.configAutoReload.containerSecurityContext }} + securityContext: {{- toYaml $root.Values.controller.sidecars.configAutoReload.containerSecurityContext | nindent 4 }} + {{- end }} + {{- if $root.Values.controller.sidecars.configAutoReload.envFrom }} + envFrom: +{{ (tpl (toYaml $root.Values.controller.sidecars.configAutoReload.envFrom) $root) | indent 4 }} + {{- end }} + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: LABEL + value: "{{ template "jenkins.fullname" $root }}-jenkins-config" + - name: FOLDER + value: "{{ $root.Values.controller.sidecars.configAutoReload.folder }}" + - name: NAMESPACE + value: '{{ $root.Values.controller.sidecars.configAutoReload.searchNamespace | default (include "jenkins.namespace" $root) }}' + {{- if eq $containerType "init" }} + - name: METHOD + value: "LIST" + {{- else if $root.Values.controller.sidecars.configAutoReload.sleepTime }} + - name: METHOD + value: "SLEEP" + - name: SLEEP_TIME + value: "{{ $root.Values.controller.sidecars.configAutoReload.sleepTime }}" + {{- end }} + {{- if eq $containerType "sidecar" }} + - name: REQ_URL + value: "{{- default "http" $root.Values.controller.sidecars.configAutoReload.scheme }}://localhost:{{- include "controller.httpPort" $root -}}{{- $root.Values.controller.jenkinsUriPrefix -}}/reload-configuration-as-code/?casc-reload-token=$(POD_NAME)" + - name: REQ_METHOD + value: "POST" + - name: REQ_RETRY_CONNECT + value: "{{ $root.Values.controller.sidecars.configAutoReload.reqRetryConnect }}" + {{- if $root.Values.controller.sidecars.configAutoReload.skipTlsVerify }} + - name: REQ_SKIP_TLS_VERIFY + value: "true" + {{- end }} + {{- end }} + + {{- if $root.Values.controller.sidecars.configAutoReload.env }} + {{- range $envVarItem := $root.Values.controller.sidecars.configAutoReload.env -}} + {{- if or (ne $containerType "init") (ne .name "METHOD") }} +{{- (tpl (toYaml (list $envVarItem)) $root) | nindent 4 }} + {{- end -}} + {{- end -}} + {{- end }} + {{- if $root.Values.controller.sidecars.configAutoReload.logging.configuration.override }} + - name: LOG_CONFIG + value: "{{ $root.Values.controller.jenkinsHome }}/auto-reload/auto-reload-config.yaml" + {{- end }} + + resources: +{{ toYaml $root.Values.controller.sidecars.configAutoReload.resources | indent 4 }} + volumeMounts: + - name: sc-config-volume + mountPath: {{ $root.Values.controller.sidecars.configAutoReload.folder | quote }} + - name: jenkins-home + mountPath: {{ $root.Values.controller.jenkinsHome }} + {{- if $root.Values.persistence.subPath }} + subPath: {{ $root.Values.persistence.subPath }} + {{- end }} + {{- if $root.Values.controller.sidecars.configAutoReload.logging.configuration.override }} + - name: auto-reload-config + mountPath: {{ $root.Values.controller.jenkinsHome }}/auto-reload + - name: auto-reload-config-logs + mountPath: {{ $root.Values.controller.jenkinsHome }}/auto-reload-logs + {{- end }} + {{- if $root.Values.controller.sidecars.configAutoReload.additionalVolumeMounts }} +{{ (tpl (toYaml $root.Values.controller.sidecars.configAutoReload.additionalVolumeMounts) $root) | indent 4 }} + {{- end }} + +{{- end -}} diff --git a/charts/jenkins/jenkins/5.5.1/templates/auto-reload-config.yaml b/charts/jenkins/jenkins/5.5.1/templates/auto-reload-config.yaml new file mode 100644 index 000000000..8c177d7f3 --- /dev/null +++ b/charts/jenkins/jenkins/5.5.1/templates/auto-reload-config.yaml @@ -0,0 +1,60 @@ +{{- if .Values.controller.sidecars.configAutoReload.logging.configuration.override }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "jenkins.fullname" . }}-auto-reload-config + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": {{ template "jenkins.name" . }} + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ .Chart.Name }}-{{ .Chart.Version }}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ $.Release.Service }}" + "app.kubernetes.io/instance": "{{ $.Release.Name }}" + "app.kubernetes.io/component": "{{ $.Values.controller.componentName }}" +data: + auto-reload-config.yaml: |- + version: 1 + disable_existing_loggers: false + root: + level: {{ .Values.controller.sidecars.configAutoReload.logging.configuration.logLevel }} + handlers: + {{- if .Values.controller.sidecars.configAutoReload.logging.configuration.logToConsole}} + - console + {{- end }} + {{- if .Values.controller.sidecars.configAutoReload.logging.configuration.logToFile }} + - file + {{- end }} + handlers: + {{- if .Values.controller.sidecars.configAutoReload.logging.configuration.logToConsole}} + console: + class: logging.StreamHandler + level: {{ .Values.controller.sidecars.configAutoReload.logging.configuration.logLevel }} + formatter: {{ .Values.controller.sidecars.configAutoReload.logging.configuration.formatter }} + {{- end }} + {{- if .Values.controller.sidecars.configAutoReload.logging.configuration.logToFile }} + file: + class : logging.handlers.RotatingFileHandler + formatter: {{ .Values.controller.sidecars.configAutoReload.logging.configuration.formatter }} + filename: {{ .Values.controller.jenkinsHome }}/auto-reload-logs/file.log + maxBytes: {{ .Values.controller.sidecars.configAutoReload.logging.configuration.maxBytes }} + backupCount: {{ .Values.controller.sidecars.configAutoReload.logging.configuration.backupCount }} + {{- end }} + formatters: + JSON: + "()": logger.JsonFormatter + format: "%(levelname)s %(message)s" + rename_fields: + message: msg + levelname: level + LOGFMT: + "()": logger.LogfmtFormatter + keys: + - time + - level + - msg + mapping: + time: asctime + level: levelname + msg: message + {{- end }} \ No newline at end of file diff --git a/charts/jenkins/jenkins/5.5.1/templates/config-init-scripts.yaml b/charts/jenkins/jenkins/5.5.1/templates/config-init-scripts.yaml new file mode 100644 index 000000000..7dd253cc3 --- /dev/null +++ b/charts/jenkins/jenkins/5.5.1/templates/config-init-scripts.yaml @@ -0,0 +1,18 @@ +{{- if .Values.controller.initScripts -}} + +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "jenkins.fullname" . }}-init-scripts + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" +data: +{{- range $key, $val := .Values.controller.initScripts }} + init{{ $key }}.groovy: |- +{{ tpl $val $ | indent 4 }} +{{- end }} +{{- end }} diff --git a/charts/jenkins/jenkins/5.5.1/templates/config.yaml b/charts/jenkins/jenkins/5.5.1/templates/config.yaml new file mode 100644 index 000000000..5de0b9f72 --- /dev/null +++ b/charts/jenkins/jenkins/5.5.1/templates/config.yaml @@ -0,0 +1,92 @@ +{{- $jenkinsHome := .Values.controller.jenkinsHome -}} + +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "jenkins.fullname" . }} + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" +data: + apply_config.sh: |- + set -e +{{- if .Values.controller.initializeOnce }} + if [ -f {{ .Values.controller.jenkinsHome }}/initialization-completed ]; then + echo "controller was previously initialized, refusing to re-initialize" + exit 0 + fi +{{- end }} + echo "disable Setup Wizard" + # Prevent Setup Wizard when JCasC is enabled + echo $JENKINS_VERSION > {{ .Values.controller.jenkinsHome }}/jenkins.install.UpgradeWizard.state + echo $JENKINS_VERSION > {{ .Values.controller.jenkinsHome }}/jenkins.install.InstallUtil.lastExecVersion +{{- if .Values.controller.overwritePlugins }} + echo "remove all plugins from shared volume" + # remove all plugins from shared volume + rm -rf {{ .Values.controller.jenkinsHome }}/plugins/* +{{- end }} +{{- if .Values.controller.JCasC.overwriteConfiguration }} + echo "deleting all XML config files" + rm -f {{ .Values.controller.jenkinsHome }}/config.xml + rm -f {{ .Values.controller.jenkinsHome }}/*plugins*.xml + find {{ .Values.controller.jenkinsHome }} -maxdepth 1 -type f -iname '*configuration*.xml' -exec rm -f {} \; +{{- end }} +{{- if .Values.controller.installPlugins }} + echo "download plugins" + # Install missing plugins + cp /var/jenkins_config/plugins.txt {{ .Values.controller.jenkinsHome }}; + rm -rf {{ .Values.controller.jenkinsRef }}/plugins/*.lock + version () { echo "$@" | awk -F. '{ printf("%d%03d%03d%03d\n", $1,$2,$3,$4); }'; } + if [ -f "{{ .Values.controller.jenkinsWar }}" ] && [ -n "$(command -v jenkins-plugin-cli)" 2>/dev/null ] && [ $(version $(jenkins-plugin-cli --version)) -ge $(version "2.1.1") ]; then + jenkins-plugin-cli --verbose --war "{{ .Values.controller.jenkinsWar }}" --plugin-file "{{ .Values.controller.jenkinsHome }}/plugins.txt" --latest {{ .Values.controller.installLatestPlugins }}{{- if .Values.controller.installLatestSpecifiedPlugins }} --latest-specified{{- end }}; + else + /usr/local/bin/install-plugins.sh `echo $(cat {{ .Values.controller.jenkinsHome }}/plugins.txt)`; + fi + echo "copy plugins to shared volume" + # Copy plugins to shared volume + yes n | cp -i {{ .Values.controller.jenkinsRef }}/plugins/* /var/jenkins_plugins/; +{{- end }} + {{- if not .Values.controller.sidecars.configAutoReload.enabled }} + echo "copy configuration as code files" + mkdir -p {{ .Values.controller.jenkinsHome }}/casc_configs; + rm -rf {{ .Values.controller.jenkinsHome }}/casc_configs/* + {{- if or .Values.controller.JCasC.defaultConfig .Values.controller.JCasC.configScripts }} + cp -v /var/jenkins_config/*.yaml {{ .Values.controller.jenkinsHome }}/casc_configs + {{- end }} + {{- end }} + echo "finished initialization" +{{- if .Values.controller.initializeOnce }} + touch {{ .Values.controller.jenkinsHome }}/initialization-completed +{{- end }} + {{- if not .Values.controller.sidecars.configAutoReload.enabled }} +# Only add config to this script if we aren't auto-reloading otherwise the pod will restart upon each config change: +{{- if .Values.controller.JCasC.defaultConfig }} + jcasc-default-config.yaml: |- + {{- include "jenkins.casc.defaults" . |nindent 4}} +{{- end }} +{{- range $key, $val := .Values.controller.JCasC.configScripts }} + {{ $key }}.yaml: |- +{{ tpl $val $| indent 4 }} +{{- end }} +{{- end }} + plugins.txt: |- +{{- if .Values.controller.installPlugins }} + {{- range $installPlugin := .Values.controller.installPlugins }} + {{- $installPlugin | nindent 4 }} + {{- end }} + {{- range $addlPlugin := .Values.controller.additionalPlugins }} + {{- /* duplicate plugin check */}} + {{- range $installPlugin := $.Values.controller.installPlugins }} + {{- if eq (splitList ":" $addlPlugin | first) (splitList ":" $installPlugin | first) }} + {{- $message := print "[PLUGIN CONFLICT] controller.additionalPlugins contains '" $addlPlugin "'" }} + {{- $message := print $message " but controller.installPlugins already contains '" $installPlugin "'." }} + {{- $message := print $message " Override controller.installPlugins to use '" $addlPlugin "' plugin." }} + {{- fail $message }} + {{- end }} + {{- end }} + {{- $addlPlugin | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/jenkins/jenkins/5.5.1/templates/deprecation.yaml b/charts/jenkins/jenkins/5.5.1/templates/deprecation.yaml new file mode 100644 index 000000000..f54017ce4 --- /dev/null +++ b/charts/jenkins/jenkins/5.5.1/templates/deprecation.yaml @@ -0,0 +1,151 @@ +{{- if .Values.checkDeprecation }} + {{- if .Values.master }} + {{ fail "`master` does no longer exist. It has been renamed to `controller`" }} + {{- end }} + + {{- if .Values.controller.imageTag }} + {{ fail "`controller.imageTag` does no longer exist. Please use `controller.image.tag` instead" }} + {{- end }} + + {{- if .Values.controller.slaveListenerPort }} + {{ fail "`controller.slaveListenerPort` does no longer exist. It has been renamed to `controller.agentListenerPort`" }} + {{- end }} + + {{- if .Values.controller.slaveHostPort }} + {{ fail "`controller.slaveHostPort` does no longer exist. It has been renamed to `controller.agentListenerHostPort`" }} + {{- end }} + + {{- if .Values.controller.slaveKubernetesNamespace }} + {{ fail "`controller.slaveKubernetesNamespace` does no longer exist. It has been renamed to `agent.namespace`" }} + {{- end }} + + {{- if .Values.controller.slaveDefaultsProviderTemplate }} + {{ fail "`controller.slaveDefaultsProviderTemplate` does no longer exist. It has been renamed to `agent.defaultsProviderTemplate`" }} + {{- end }} + + {{- if .Values.controller.useSecurity }} + {{ fail "`controller.useSecurity` does no longer exist. It has been renamed to `controller.adminSecret`" }} + {{- end }} + + {{- if .Values.controller.slaveJenkinsUrl }} + {{ fail "`controller.slaveJenkinsUrl` does no longer exist. It has been renamed to `agent.jenkinsUrl`" }} + {{- end }} + + {{- if .Values.controller.slaveJenkinsTunnel }} + {{ fail "`controller.slaveJenkinsTunnel` does no longer exist. It has been renamed to `agent.jenkinsTunnel`" }} + {{- end }} + + {{- if .Values.controller.slaveConnectTimeout }} + {{ fail "`controller.slaveConnectTimeout` does no longer exist. It has been renamed to `agent.kubernetesConnectTimeout`" }} + {{- end }} + + {{- if .Values.controller.slaveReadTimeout }} + {{ fail "`controller.slaveReadTimeout` does no longer exist. It has been renamed to `agent.kubernetesReadTimeout`" }} + {{- end }} + + {{- if .Values.controller.slaveListenerServiceType }} + {{ fail "`controller.slaveListenerServiceType` does no longer exist. It has been renamed to `controller.agentListenerServiceType`" }} + {{- end }} + + {{- if .Values.controller.slaveListenerLoadBalancerIP }} + {{ fail "`controller.slaveListenerLoadBalancerIP` does no longer exist. It has been renamed to `controller.agentListenerLoadBalancerIP`" }} + {{- end }} + + {{- if .Values.controller.slaveListenerServiceAnnotations }} + {{ fail "`controller.slaveListenerServiceAnnotations` does no longer exist. It has been renamed to `controller.agentListenerServiceAnnotations`" }} + {{- end }} + + {{- if .Values.agent.slaveConnectTimeout }} + {{ fail "`agent.slaveConnectTimeout` does no longer exist. It has been renamed to `agent.connectTimeout`" }} + {{- end }} + + {{- if .Values.NetworkPolicy }} + + {{- if .Values.NetworkPolicy.Enabled }} + {{ fail "`NetworkPolicy.Enabled` does no longer exist. It has been renamed to `networkPolicy.enabled`" }} + {{- end }} + + {{- if .Values.NetworkPolicy.ApiVersion }} + {{ fail "`NetworkPolicy.ApiVersion` does no longer exist. It has been renamed to `networkPolicy.apiVersion`" }} + {{- end }} + + {{ fail "NetworkPolicy.* values have been renamed, please check the documentation" }} + {{- end }} + + + {{- if .Values.rbac.install }} + {{ fail "`rbac.install` does no longer exist. It has been renamed to `rbac.create` and is enabled by default!" }} + {{- end }} + + {{- if .Values.rbac.serviceAccountName }} + {{ fail "`rbac.serviceAccountName` does no longer exist. It has been renamed to `serviceAccount.name`" }} + {{- end }} + + {{- if .Values.rbac.serviceAccountAnnotations }} + {{ fail "`rbac.serviceAccountAnnotations` does no longer exist. It has been renamed to `serviceAccount.annotations`" }} + {{- end }} + + {{- if .Values.rbac.roleRef }} + {{ fail "`rbac.roleRef` does no longer exist. RBAC roles are now generated, please check the documentation" }} + {{- end }} + + {{- if .Values.rbac.roleKind }} + {{ fail "`rbac.roleKind` does no longer exist. RBAC roles are now generated, please check the documentation" }} + {{- end }} + + {{- if .Values.rbac.roleBindingKind }} + {{ fail "`rbac.roleBindingKind` does no longer exist. RBAC roles are now generated, please check the documentation" }} + {{- end }} + + {{- if .Values.controller.JCasC.pluginVersion }} + {{ fail "controller.JCasC.pluginVersion has been deprecated, please use controller.installPlugins instead" }} + {{- end }} + + {{- if .Values.controller.deploymentLabels }} + {{ fail "`controller.deploymentLabels` does no longer exist. It has been renamed to `controller.statefulSetLabels`" }} + {{- end }} + + {{- if .Values.controller.deploymentAnnotations }} + {{ fail "`controller.deploymentAnnotations` does no longer exist. It has been renamed to `controller.statefulSetAnnotations`" }} + {{- end }} + + {{- if .Values.controller.rollingUpdate }} + {{ fail "`controller.rollingUpdate` does no longer exist. It is no longer relevant, since a StatefulSet is used for the Jenkins controller" }} + {{- end }} + + {{- if .Values.controller.tag }} + {{ fail "`controller.tag` no longer exists. It has been renamed to `controller.image.tag'" }} + {{- end }} + + {{- if .Values.controller.tagLabel }} + {{ fail "`controller.tagLabel` no longer exists. It has been renamed to `controller.image.tagLabel`" }} + {{- end }} + + {{- if .Values.controller.adminSecret }} + {{ fail "`controller.adminSecret` no longer exists. It has been renamed to `controller.admin.createSecret`" }} + {{- end }} + + {{- if .Values.controller.adminUser }} + {{ fail "`controller.adminUser` no longer exists. It has been renamed to `controller.admin.username`" }} + {{- end }} + + {{- if .Values.controller.adminPassword }} + {{ fail "`controller.adminPassword` no longer exists. It has been renamed to `controller.admin.password`" }} + {{- end }} + + {{- if .Values.controller.sidecars.other }} + {{ fail "`controller.sidecars.other` no longer exists. It has been renamed to `controller.sidecars.additionalSidecarContainers`" }} + {{- end }} + + {{- if .Values.agent.tag }} + {{ fail "`controller.agent.tag` no longer exists. It has been renamed to `controller.agent.image.tag`" }} + {{- end }} + + {{- if .Values.backup }} + {{ fail "`controller.backup` no longer exists." }} + {{- end }} + + {{- if .Values.helmtest.bats.tag }} + {{ fail "`helmtest.bats.tag` no longer exists. It has been renamed to `helmtest.bats.image.tag`" }} + {{- end }} +{{- end }} diff --git a/charts/jenkins/jenkins/5.5.1/templates/home-pvc.yaml b/charts/jenkins/jenkins/5.5.1/templates/home-pvc.yaml new file mode 100644 index 000000000..f417d23ad --- /dev/null +++ b/charts/jenkins/jenkins/5.5.1/templates/home-pvc.yaml @@ -0,0 +1,41 @@ +{{- if not (contains "jenkins-home" (quote .Values.persistence.volumes)) }} +{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) -}} +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: +{{- if .Values.persistence.annotations }} + annotations: +{{ toYaml .Values.persistence.annotations | indent 4 }} +{{- end }} + name: {{ template "jenkins.fullname" . }} + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" +{{- if .Values.persistence.labels }} +{{ toYaml .Values.persistence.labels | indent 4 }} +{{- end }} +spec: +{{- if .Values.persistence.dataSource }} + dataSource: +{{ toYaml .Values.persistence.dataSource | indent 4 }} +{{- end }} + accessModes: + - {{ .Values.persistence.accessMode | quote }} + resources: + requests: + storage: {{ .Values.persistence.size | quote }} +{{- if .Values.persistence.storageClass }} +{{- if (eq "-" .Values.persistence.storageClass) }} + storageClassName: "" +{{- else }} + storageClassName: "{{ .Values.persistence.storageClass }}" +{{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/jenkins/jenkins/5.5.1/templates/jcasc-config.yaml b/charts/jenkins/jenkins/5.5.1/templates/jcasc-config.yaml new file mode 100644 index 000000000..f51444525 --- /dev/null +++ b/charts/jenkins/jenkins/5.5.1/templates/jcasc-config.yaml @@ -0,0 +1,53 @@ +{{- $root := . }} +{{- if .Values.controller.sidecars.configAutoReload.enabled }} +{{- range $key, $val := .Values.controller.JCasC.configScripts }} +{{- if $val }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "jenkins.casc.configName" (list (printf "config-%s" $key) $ )}} + namespace: {{ template "jenkins.namespace" $root }} + labels: + "app.kubernetes.io/name": {{ template "jenkins.name" $root}} + {{- if $root.Values.renderHelmLabels }} + "helm.sh/chart": "{{ $root.Chart.Name }}-{{ $root.Chart.Version }}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ $.Release.Service }}" + "app.kubernetes.io/instance": "{{ $.Release.Name }}" + "app.kubernetes.io/component": "{{ $.Values.controller.componentName }}" + {{ template "jenkins.fullname" $root }}-jenkins-config: "true" +{{- if $root.Values.controller.JCasC.configMapAnnotations }} + annotations: +{{ toYaml $root.Values.controller.JCasC.configMapAnnotations | indent 4 }} +{{- end }} +data: + {{ $key }}.yaml: |- +{{ tpl $val $| indent 4 }} +{{- end }} +{{- end }} +{{- if .Values.controller.JCasC.defaultConfig }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "jenkins.casc.configName" (list "jcasc-config" $ )}} + namespace: {{ template "jenkins.namespace" $root }} + labels: + "app.kubernetes.io/name": {{ template "jenkins.name" $root}} + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ $root.Chart.Name }}-{{ $root.Chart.Version }}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ $.Release.Service }}" + "app.kubernetes.io/instance": "{{ $.Release.Name }}" + "app.kubernetes.io/component": "{{ $.Values.controller.componentName }}" + {{ template "jenkins.fullname" $root }}-jenkins-config: "true" +{{- if $root.Values.controller.JCasC.configMapAnnotations }} + annotations: +{{ toYaml $root.Values.controller.JCasC.configMapAnnotations | indent 4 }} +{{- end }} +data: + jcasc-default-config.yaml: |- + {{- include "jenkins.casc.defaults" . | nindent 4 }} +{{- end}} +{{- end }} diff --git a/charts/jenkins/jenkins/5.5.1/templates/jenkins-agent-svc.yaml b/charts/jenkins/jenkins/5.5.1/templates/jenkins-agent-svc.yaml new file mode 100644 index 000000000..4440b91f8 --- /dev/null +++ b/charts/jenkins/jenkins/5.5.1/templates/jenkins-agent-svc.yaml @@ -0,0 +1,43 @@ +{{- if .Values.controller.agentListenerEnabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "jenkins.fullname" . }}-agent + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" + {{- if .Values.controller.agentListenerServiceAnnotations }} + annotations: + {{- toYaml .Values.controller.agentListenerServiceAnnotations | nindent 4 }} + {{- end }} +spec: + {{- if .Values.controller.agentListenerExternalTrafficPolicy }} + externalTrafficPolicy: {{.Values.controller.agentListenerExternalTrafficPolicy}} + {{- end }} + ports: + - port: {{ .Values.controller.agentListenerPort }} + targetPort: {{ .Values.controller.agentListenerPort }} + {{- if (and (eq .Values.controller.agentListenerServiceType "NodePort") (not (empty .Values.controller.agentListenerNodePort))) }} + nodePort: {{ .Values.controller.agentListenerNodePort }} + {{- end }} + name: agent-listener + selector: + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + type: {{ .Values.controller.agentListenerServiceType }} + {{if eq .Values.controller.agentListenerServiceType "LoadBalancer"}} +{{- if .Values.controller.agentListenerLoadBalancerSourceRanges }} + loadBalancerSourceRanges: +{{ toYaml .Values.controller.agentListenerLoadBalancerSourceRanges | indent 4 }} +{{- end }} + {{- end }} + {{- if and (eq .Values.controller.agentListenerServiceType "LoadBalancer") (.Values.controller.agentListenerLoadBalancerIP) }} + loadBalancerIP: {{ .Values.controller.agentListenerLoadBalancerIP }} + {{- end }} + {{- end }} diff --git a/charts/jenkins/jenkins/5.5.1/templates/jenkins-aws-security-group-policies.yaml b/charts/jenkins/jenkins/5.5.1/templates/jenkins-aws-security-group-policies.yaml new file mode 100644 index 000000000..2f6e7a13d --- /dev/null +++ b/charts/jenkins/jenkins/5.5.1/templates/jenkins-aws-security-group-policies.yaml @@ -0,0 +1,16 @@ +{{- if .Values.awsSecurityGroupPolicies.enabled -}} +{{- range .Values.awsSecurityGroupPolicies.policies -}} +apiVersion: vpcresources.k8s.aws/v1beta1 +kind: SecurityGroupPolicy +metadata: + name: {{ .name }} + namespace: {{ template "jenkins.namespace" $ }} +spec: + podSelector: + {{- toYaml .podSelector | nindent 6}} + securityGroups: + groupIds: + {{- toYaml .securityGroupIds | nindent 6}} +--- +{{- end -}} +{{- end -}} diff --git a/charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-alerting-rules.yaml b/charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-alerting-rules.yaml new file mode 100644 index 000000000..3fd806172 --- /dev/null +++ b/charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-alerting-rules.yaml @@ -0,0 +1,26 @@ +{{- if and .Values.controller.prometheus.enabled .Values.controller.prometheus.alertingrules }} +--- +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ template "jenkins.fullname" . }} +{{- if .Values.controller.prometheus.prometheusRuleNamespace }} + namespace: {{ .Values.controller.prometheus.prometheusRuleNamespace }} +{{- else }} + namespace: {{ template "jenkins.namespace" . }} +{{- end }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" + {{- range $key, $val := .Values.controller.prometheus.alertingRulesAdditionalLabels }} + {{ $key }}: {{ $val | quote }} + {{- end}} +spec: + groups: +{{ toYaml .Values.controller.prometheus.alertingrules | indent 2 }} +{{- end }} diff --git a/charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-backendconfig.yaml b/charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-backendconfig.yaml new file mode 100644 index 000000000..0e8a566fc --- /dev/null +++ b/charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-backendconfig.yaml @@ -0,0 +1,24 @@ +{{- if .Values.controller.backendconfig.enabled }} +apiVersion: {{ .Values.controller.backendconfig.apiVersion }} +kind: BackendConfig +metadata: + name: {{ .Values.controller.backendconfig.name }} + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" +{{- if .Values.controller.backendconfig.labels }} +{{ toYaml .Values.controller.backendconfig.labels | indent 4 }} +{{- end }} +{{- if .Values.controller.backendconfig.annotations }} + annotations: +{{ toYaml .Values.controller.backendconfig.annotations | indent 4 }} +{{- end }} +spec: +{{ toYaml .Values.controller.backendconfig.spec | indent 2 }} +{{- end }} diff --git a/charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-ingress.yaml b/charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-ingress.yaml new file mode 100644 index 000000000..b3b344ff8 --- /dev/null +++ b/charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-ingress.yaml @@ -0,0 +1,77 @@ +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if .Values.controller.ingress.enabled }} +{{- if semverCompare ">=1.19-0" $kubeTargetVersion -}} +apiVersion: networking.k8s.io/v1 +{{- else if semverCompare ">=1.14-0" $kubeTargetVersion -}} +apiVersion: networking.k8s.io/v1beta1 +{{- else -}} +apiVersion: {{ .Values.controller.ingress.apiVersion }} +{{- end }} +kind: Ingress +metadata: + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" +{{- if .Values.controller.ingress.labels }} +{{ toYaml .Values.controller.ingress.labels | indent 4 }} +{{- end }} +{{- if .Values.controller.ingress.annotations }} + annotations: +{{ toYaml .Values.controller.ingress.annotations | indent 4 }} +{{- end }} + name: {{ template "jenkins.fullname" . }} +spec: +{{- if .Values.controller.ingress.ingressClassName }} + ingressClassName: {{ .Values.controller.ingress.ingressClassName | quote }} +{{- end }} + rules: + - http: + paths: +{{- if empty (.Values.controller.ingress.paths) }} + - backend: +{{- if semverCompare ">=1.19-0" $kubeTargetVersion }} + service: + name: {{ template "jenkins.fullname" . }} + port: + number: {{ .Values.controller.servicePort }} + pathType: ImplementationSpecific +{{- else }} + serviceName: {{ template "jenkins.fullname" . }} + servicePort: {{ .Values.controller.servicePort }} +{{- end }} +{{- if .Values.controller.ingress.path }} + path: {{ .Values.controller.ingress.path }} +{{- end -}} +{{- else }} +{{ tpl (toYaml .Values.controller.ingress.paths | indent 6) . }} +{{- end -}} +{{- if .Values.controller.ingress.hostName }} + host: {{ tpl .Values.controller.ingress.hostName . | quote }} +{{- end }} +{{- if .Values.controller.ingress.resourceRootUrl }} + - http: + paths: + - backend: +{{- if semverCompare ">=1.19-0" $kubeTargetVersion }} + service: + name: {{ template "jenkins.fullname" . }} + port: + number: {{ .Values.controller.servicePort }} + pathType: ImplementationSpecific +{{- else }} + serviceName: {{ template "jenkins.fullname" . }} + servicePort: {{ .Values.controller.servicePort }} +{{- end }} + host: {{ tpl .Values.controller.ingress.resourceRootUrl . | quote }} +{{- end }} +{{- if .Values.controller.ingress.tls }} + tls: +{{ tpl (toYaml .Values.controller.ingress.tls ) . | indent 4 }} +{{- end -}} +{{- end }} diff --git a/charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-networkpolicy.yaml b/charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-networkpolicy.yaml new file mode 100644 index 000000000..82835f2bd --- /dev/null +++ b/charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-networkpolicy.yaml @@ -0,0 +1,76 @@ +{{- if .Values.networkPolicy.enabled }} +kind: NetworkPolicy +apiVersion: {{ .Values.networkPolicy.apiVersion }} +metadata: + name: "{{ .Release.Name }}-{{ .Values.controller.componentName }}" + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" +spec: + podSelector: + matchLabels: + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + ingress: + # Allow web access to the UI + - ports: + - port: {{ .Values.controller.targetPort }} + {{- if .Values.controller.agentListenerEnabled }} + # Allow inbound connections from agents + - from: + {{- if .Values.networkPolicy.internalAgents.allowed }} + - podSelector: + matchLabels: + "jenkins/{{ .Release.Name }}-{{ .Values.agent.componentName }}": "true" + {{- range $k,$v:= .Values.networkPolicy.internalAgents.podLabels }} + {{ $k }}: {{ $v }} + {{- end }} + {{- if .Values.networkPolicy.internalAgents.namespaceLabels }} + namespaceSelector: + matchLabels: + {{- range $k,$v:= .Values.networkPolicy.internalAgents.namespaceLabels }} + {{ $k }}: {{ $v }} + {{- end }} + {{- end }} + {{- end }} + {{- if or .Values.networkPolicy.externalAgents.ipCIDR .Values.networkPolicy.externalAgents.except }} + - ipBlock: + cidr: {{ required "ipCIDR is required if you wish to allow external agents to connect to Jenkins Controller." .Values.networkPolicy.externalAgents.ipCIDR }} + {{- if .Values.networkPolicy.externalAgents.except }} + except: + {{- range .Values.networkPolicy.externalAgents.except }} + - {{ . }} + {{- end }} + {{- end }} + {{- end }} + ports: + - port: {{ .Values.controller.agentListenerPort }} + {{- end }} +{{- if .Values.agent.enabled }} +--- +kind: NetworkPolicy +apiVersion: {{ .Values.networkPolicy.apiVersion }} +metadata: + name: "{{ .Release.Name }}-{{ .Values.agent.componentName }}" + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" +spec: + podSelector: + matchLabels: + # DefaultDeny + "jenkins/{{ .Release.Name }}-{{ .Values.agent.componentName }}": "true" +{{- end }} +{{- end }} diff --git a/charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-pdb.yaml b/charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-pdb.yaml new file mode 100644 index 000000000..9dc1fafe2 --- /dev/null +++ b/charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-pdb.yaml @@ -0,0 +1,34 @@ +{{- if .Values.controller.podDisruptionBudget.enabled }} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if semverCompare ">=1.21-0" $kubeTargetVersion -}} +apiVersion: policy/v1 +{{- else if semverCompare ">=1.5-0" $kubeTargetVersion -}} +apiVersion: policy/v1beta1 +{{- else -}} +apiVersion: {{ .Values.controller.podDisruptionBudget.apiVersion }} +{{- end }} +kind: PodDisruptionBudget +metadata: + name: {{ template "jenkins.fullname" . }}-pdb + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" + {{- if .Values.controller.podDisruptionBudget.labels -}} + {{ toYaml .Values.controller.podDisruptionBudget.labels | nindent 4 }} + {{- end }} + {{- if .Values.controller.podDisruptionBudget.annotations }} + annotations: {{ toYaml .Values.controller.podDisruptionBudget.annotations | nindent 4 }} + {{- end }} +spec: + maxUnavailable: {{ .Values.controller.podDisruptionBudget.maxUnavailable }} + selector: + matchLabels: + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' +{{- end }} diff --git a/charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-podmonitor.yaml b/charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-podmonitor.yaml new file mode 100644 index 000000000..9a04019c3 --- /dev/null +++ b/charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-podmonitor.yaml @@ -0,0 +1,30 @@ +{{- if .Values.controller.googlePodMonitor.enabled }} +apiVersion: monitoring.googleapis.com/v1 +kind: PodMonitoring + +metadata: + name: {{ template "jenkins.fullname" . }} +{{- if .Values.controller.googlePodMonitor.serviceMonitorNamespace }} + namespace: {{ .Values.controller.googlePodMonitor.serviceMonitorNamespace }} +{{- else }} + namespace: {{ template "jenkins.namespace" . }} +{{- end }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" + +spec: + endpoints: + - interval: {{ .Values.controller.googlePodMonitor.scrapeInterval }} + port: http + path: {{ .Values.controller.jenkinsUriPrefix }}{{ .Values.controller.googlePodMonitor.scrapeEndpoint }} + selector: + matchLabels: + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" +{{- end }} diff --git a/charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-route.yaml b/charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-route.yaml new file mode 100644 index 000000000..3550380ee --- /dev/null +++ b/charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-route.yaml @@ -0,0 +1,34 @@ +{{- if .Values.controller.route.enabled }} +apiVersion: route.openshift.io/v1 +kind: Route +metadata: + namespace: {{ template "jenkins.namespace" . }} + labels: + app: {{ template "jenkins.fullname" . }} + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + release: "{{ .Release.Name }}" + heritage: "{{ .Release.Service }}" + component: "{{ .Release.Name }}-{{ .Values.controller.componentName }}" +{{- if .Values.controller.route.labels }} +{{ toYaml .Values.controller.route.labels | indent 4 }} +{{- end }} +{{- if .Values.controller.route.annotations }} + annotations: +{{ toYaml .Values.controller.route.annotations | indent 4 }} +{{- end }} + name: {{ template "jenkins.fullname" . }} +spec: + host: {{ .Values.controller.route.path }} + port: + targetPort: http + tls: + insecureEdgeTerminationPolicy: Redirect + termination: edge + to: + kind: Service + name: {{ template "jenkins.fullname" . }} + weight: 100 + wildcardPolicy: None +{{- end }} diff --git a/charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-secondary-ingress.yaml b/charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-secondary-ingress.yaml new file mode 100644 index 000000000..c63e48229 --- /dev/null +++ b/charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-secondary-ingress.yaml @@ -0,0 +1,56 @@ +{{- if .Values.controller.secondaryingress.enabled }} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- $serviceName := include "jenkins.fullname" . -}} +{{- $servicePort := .Values.controller.servicePort -}} +{{- if semverCompare ">=1.19-0" $kubeTargetVersion -}} +apiVersion: networking.k8s.io/v1 +{{- else if semverCompare ">=1.14-0" $kubeTargetVersion -}} +apiVersion: networking.k8s.io/v1beta1 +{{- else -}} +apiVersion: {{ .Values.controller.secondaryingress.apiVersion }} +{{- end }} +kind: Ingress +metadata: + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" + {{- if .Values.controller.secondaryingress.labels -}} + {{ toYaml .Values.controller.secondaryingress.labels | nindent 4 }} + {{- end }} + {{- if .Values.controller.secondaryingress.annotations }} + annotations: {{ toYaml .Values.controller.secondaryingress.annotations | nindent 4 }} + {{- end }} + name: {{ template "jenkins.fullname" . }}-secondary +spec: +{{- if .Values.controller.secondaryingress.ingressClassName }} + ingressClassName: {{ .Values.controller.secondaryingress.ingressClassName | quote }} +{{- end }} + rules: + - host: {{ .Values.controller.secondaryingress.hostName }} + http: + paths: + {{- range .Values.controller.secondaryingress.paths }} + - path: {{ . | quote }} + backend: +{{ if semverCompare ">=1.19-0" $kubeTargetVersion }} + service: + name: {{ $serviceName }} + port: + number: {{ $servicePort }} + pathType: ImplementationSpecific +{{ else }} + serviceName: {{ $serviceName }} + servicePort: {{ $servicePort }} +{{ end }} + {{- end}} +{{- if .Values.controller.secondaryingress.tls }} + tls: +{{ toYaml .Values.controller.secondaryingress.tls | indent 4 }} +{{- end -}} +{{- end }} diff --git a/charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-servicemonitor.yaml b/charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-servicemonitor.yaml new file mode 100644 index 000000000..8710b2bc9 --- /dev/null +++ b/charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-servicemonitor.yaml @@ -0,0 +1,45 @@ +{{- if and .Values.controller.prometheus.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor + +metadata: + name: {{ template "jenkins.fullname" . }} +{{- if .Values.controller.prometheus.serviceMonitorNamespace }} + namespace: {{ .Values.controller.prometheus.serviceMonitorNamespace }} +{{- else }} + namespace: {{ template "jenkins.namespace" . }} +{{- end }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" + {{- range $key, $val := .Values.controller.prometheus.serviceMonitorAdditionalLabels }} + {{ $key }}: {{ $val | quote }} + {{- end}} + +spec: + endpoints: + - interval: {{ .Values.controller.prometheus.scrapeInterval }} + port: http + path: {{ .Values.controller.jenkinsUriPrefix }}{{ .Values.controller.prometheus.scrapeEndpoint }} + {{- with .Values.controller.prometheus.relabelings }} + relabelings: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.controller.prometheus.metricRelabelings }} + metricRelabelings: + {{- toYaml . | nindent 6 }} + {{- end }} + jobLabel: {{ template "jenkins.fullname" . }} + namespaceSelector: + matchNames: + - "{{ template "jenkins.namespace" $ }}" + selector: + matchLabels: + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" +{{- end }} diff --git a/charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-statefulset.yaml b/charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-statefulset.yaml new file mode 100644 index 000000000..50e61acf1 --- /dev/null +++ b/charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-statefulset.yaml @@ -0,0 +1,424 @@ +{{- if .Capabilities.APIVersions.Has "apps/v1" }} +apiVersion: apps/v1 +{{- else }} +apiVersion: apps/v1beta1 +{{- end }} +kind: StatefulSet +metadata: + name: {{ template "jenkins.fullname" . }} + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" + {{- range $key, $val := .Values.controller.statefulSetLabels }} + {{ $key }}: {{ $val | quote }} + {{- end}} + {{- if .Values.controller.statefulSetAnnotations }} + annotations: +{{ toYaml .Values.controller.statefulSetAnnotations | indent 4 }} + {{- end }} +spec: + serviceName: {{ template "jenkins.fullname" . }} + replicas: 1 + selector: + matchLabels: + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + {{- if .Values.controller.updateStrategy }} + updateStrategy: +{{ toYaml .Values.controller.updateStrategy | indent 4 }} + {{- end }} + template: + metadata: + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" + {{- range $key, $val := .Values.controller.podLabels }} + {{ $key }}: {{ $val | quote }} + {{- end}} + annotations: + checksum/config: {{ include (print $.Template.BasePath "/config.yaml") . | sha256sum }} + {{- if .Values.controller.initScripts }} + checksum/config-init-scripts: {{ include (print $.Template.BasePath "/config-init-scripts.yaml") . | sha256sum }} + {{- end }} + {{- if .Values.controller.podAnnotations }} +{{ tpl (toYaml .Values.controller.podAnnotations | indent 8) . }} + {{- end }} + spec: + {{- if .Values.controller.schedulerName }} + schedulerName: {{ .Values.controller.schedulerName }} + {{- end }} + {{- if .Values.controller.nodeSelector }} + nodeSelector: +{{ toYaml .Values.controller.nodeSelector | indent 8 }} + {{- end }} + {{- if .Values.controller.tolerations }} + tolerations: +{{ toYaml .Values.controller.tolerations | indent 8 }} + {{- end }} + {{- if .Values.controller.affinity }} + affinity: +{{ toYaml .Values.controller.affinity | indent 8 }} + {{- end }} + {{- if .Values.controller.topologySpreadConstraints }} + topologySpreadConstraints: +{{ toYaml .Values.controller.topologySpreadConstraints | indent 8 }} + {{- end }} + {{- if quote .Values.controller.terminationGracePeriodSeconds }} + terminationGracePeriodSeconds: {{ .Values.controller.terminationGracePeriodSeconds }} + {{- end }} + {{- if .Values.controller.priorityClassName }} + priorityClassName: {{ .Values.controller.priorityClassName }} + {{- end }} + {{- if .Values.controller.shareProcessNamespace }} + shareProcessNamespace: true + {{- end }} +{{- if .Values.controller.usePodSecurityContext }} + securityContext: + {{- if kindIs "map" .Values.controller.podSecurityContextOverride }} + {{- tpl (toYaml .Values.controller.podSecurityContextOverride | nindent 8) . -}} + {{- else }} + {{/* The rest of this section should be replaced with the contents of this comment one the runAsUser, fsGroup, and securityContextCapabilities Helm chart values have been removed: + runAsUser: 1000 + fsGroup: 1000 + runAsNonRoot: true + */}} + runAsUser: {{ default 0 .Values.controller.runAsUser }} + {{- if and (.Values.controller.runAsUser) (.Values.controller.fsGroup) }} + {{- if not (eq (int .Values.controller.runAsUser) 0) }} + fsGroup: {{ .Values.controller.fsGroup }} + runAsNonRoot: true + {{- end }} + {{- if .Values.controller.securityContextCapabilities }} + capabilities: + {{- toYaml .Values.controller.securityContextCapabilities | nindent 10 }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} + serviceAccountName: "{{ template "jenkins.serviceAccountName" . }}" +{{- if .Values.controller.hostNetworking }} + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet +{{- end }} + {{- if .Values.controller.hostAliases }} + hostAliases: + {{- toYaml .Values.controller.hostAliases | nindent 8 }} + {{- end }} + initContainers: +{{- if .Values.controller.customInitContainers }} +{{ tpl (toYaml .Values.controller.customInitContainers) . | indent 8 }} +{{- end }} + +{{- if .Values.controller.sidecars.configAutoReload.enabled }} +{{- include "jenkins.configReloadContainer" (list $ "config-reload-init" "init") | nindent 8 }} +{{- end}} + + - name: "init" + image: "{{ .Values.controller.image.registry }}/{{ .Values.controller.image.repository }}:{{- include "controller.image.tag" . -}}" + imagePullPolicy: "{{ .Values.controller.image.pullPolicy }}" + {{- if .Values.controller.containerSecurityContext }} + securityContext: {{- toYaml .Values.controller.containerSecurityContext | nindent 12 }} + {{- end }} + command: [ "sh", "/var/jenkins_config/apply_config.sh" ] + {{- if .Values.controller.initContainerEnvFrom }} + envFrom: +{{ (tpl (toYaml .Values.controller.initContainerEnvFrom) .) | indent 12 }} + {{- end }} + {{- if .Values.controller.initContainerEnv }} + env: +{{ (tpl (toYaml .Values.controller.initContainerEnv) .) | indent 12 }} + {{- end }} + resources: +{{- if .Values.controller.initContainerResources }} +{{ toYaml .Values.controller.initContainerResources | indent 12 }} +{{- else }} +{{ toYaml .Values.controller.resources | indent 12 }} +{{- end }} + volumeMounts: + {{- if .Values.persistence.mounts }} +{{ toYaml .Values.persistence.mounts | indent 12 }} + {{- end }} + - mountPath: {{ .Values.controller.jenkinsHome }} + name: jenkins-home + {{- if .Values.persistence.subPath }} + subPath: {{ .Values.persistence.subPath }} + {{- end }} + - mountPath: /var/jenkins_config + name: jenkins-config + {{- if .Values.controller.installPlugins }} + {{- if .Values.controller.overwritePluginsFromImage }} + - mountPath: {{ .Values.controller.jenkinsRef }}/plugins + name: plugins + {{- end }} + - mountPath: /var/jenkins_plugins + name: plugin-dir + - mountPath: /tmp + name: tmp-volume + {{- end }} + {{- if or .Values.controller.initScripts .Values.controller.initConfigMap }} + - mountPath: {{ .Values.controller.jenkinsHome }}/init.groovy.d + name: init-scripts + {{- end }} + {{- if and .Values.controller.httpsKeyStore.enable (not .Values.controller.httpsKeyStore.disableSecretMount) }} + {{- $httpsJKSDirPath := printf "%s" .Values.controller.httpsKeyStore.path }} + - mountPath: {{ $httpsJKSDirPath }} + name: jenkins-https-keystore + {{- end }} + containers: + - name: jenkins + image: "{{ .Values.controller.image.registry }}/{{ .Values.controller.image.repository }}:{{- include "controller.image.tag" . -}}" + imagePullPolicy: "{{ .Values.controller.image.pullPolicy }}" + {{- if .Values.controller.containerSecurityContext }} + securityContext: {{- toYaml .Values.controller.containerSecurityContext | nindent 12 }} + {{- end }} + {{- if .Values.controller.overrideArgs }} + args: [ + {{- range $overrideArg := .Values.controller.overrideArgs }} + "{{- tpl $overrideArg $ }}", + {{- end }} + ] + {{- else if .Values.controller.httpsKeyStore.enable }} + {{- $httpsJKSFilePath := printf "%s/%s" .Values.controller.httpsKeyStore.path .Values.controller.httpsKeyStore.fileName }} + args: [ "--httpPort={{.Values.controller.httpsKeyStore.httpPort}}", "--httpsPort={{.Values.controller.targetPort}}", '--httpsKeyStore={{ $httpsJKSFilePath }}', "--httpsKeyStorePassword=$(JENKINS_HTTPS_KEYSTORE_PASSWORD)" ] + {{- else }} + args: [ "--httpPort={{.Values.controller.targetPort}}"] + {{- end }} + {{- if .Values.controller.lifecycle }} + lifecycle: +{{ toYaml .Values.controller.lifecycle | indent 12 }} + {{- end }} +{{- if .Values.controller.terminationMessagePath }} + terminationMessagePath: {{ .Values.controller.terminationMessagePath }} +{{- end }} +{{- if .Values.controller.terminationMessagePolicy }} + terminationMessagePolicy: {{ .Values.controller.terminationMessagePolicy }} +{{- end }} + {{- if .Values.controller.containerEnvFrom }} + envFrom: +{{ (tpl ( toYaml .Values.controller.containerEnvFrom) .) | indent 12 }} + {{- end }} + env: + {{- if .Values.controller.containerEnv }} +{{ (tpl ( toYaml .Values.controller.containerEnv) .) | indent 12 }} + {{- end }} + {{- if or .Values.controller.additionalSecrets .Values.controller.existingSecret .Values.controller.additionalExistingSecrets .Values.controller.admin.createSecret }} + - name: SECRETS + value: /run/secrets/additional + {{- end }} + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: JAVA_OPTS + value: >- + {{ if .Values.controller.sidecars.configAutoReload.enabled }} -Dcasc.reload.token=$(POD_NAME) {{ end }}{{ default "" .Values.controller.javaOpts }} + - name: JENKINS_OPTS + value: >- + {{ if .Values.controller.jenkinsUriPrefix }}--prefix={{ .Values.controller.jenkinsUriPrefix }} {{ end }} --webroot=/var/jenkins_cache/war {{ default "" .Values.controller.jenkinsOpts}} + - name: JENKINS_SLAVE_AGENT_PORT + value: "{{ .Values.controller.agentListenerPort }}" + {{- if .Values.controller.httpsKeyStore.enable }} + - name: JENKINS_HTTPS_KEYSTORE_PASSWORD + {{- if not .Values.controller.httpsKeyStore.disableSecretMount }} + valueFrom: + secretKeyRef: + name: {{ if .Values.controller.httpsKeyStore.jenkinsHttpsJksPasswordSecretName }} {{ .Values.controller.httpsKeyStore.jenkinsHttpsJksPasswordSecretName }} {{ else if .Values.controller.httpsKeyStore.jenkinsHttpsJksSecretName }} {{ .Values.controller.httpsKeyStore.jenkinsHttpsJksSecretName }} {{ else }} {{ template "jenkins.fullname" . }}-https-jks {{ end }} + key: "{{ .Values.controller.httpsKeyStore.jenkinsHttpsJksPasswordSecretKey }}" + {{- else }} + value: {{ .Values.controller.httpsKeyStore.password }} + {{- end }} + {{- end }} + + - name: CASC_JENKINS_CONFIG + value: {{ .Values.controller.sidecars.configAutoReload.folder | default (printf "%s/casc_configs" (.Values.controller.jenkinsRef)) }}{{- if .Values.controller.JCasC.configUrls }},{{ join "," .Values.controller.JCasC.configUrls }}{{- end }} + ports: + {{- if .Values.controller.httpsKeyStore.enable }} + - containerPort: {{.Values.controller.httpsKeyStore.httpPort}} + {{- else }} + - containerPort: {{.Values.controller.targetPort}} + {{- end }} + name: http + - containerPort: {{ .Values.controller.agentListenerPort }} + name: agent-listener + {{- if .Values.controller.agentListenerHostPort }} + hostPort: {{ .Values.controller.agentListenerHostPort }} + {{- end }} + {{- if .Values.controller.jmxPort }} + - containerPort: {{ .Values.controller.jmxPort }} + name: jmx + {{- end }} +{{- range $index, $port := .Values.controller.extraPorts }} + - containerPort: {{ $port.port }} + name: {{ $port.name }} +{{- end }} +{{- if and .Values.controller.healthProbes .Values.controller.probes}} + {{- if semverCompare ">=1.16-0" .Capabilities.KubeVersion.GitVersion }} + startupProbe: +{{ tpl (toYaml .Values.controller.probes.startupProbe | indent 12) .}} + {{- end }} + livenessProbe: +{{ tpl (toYaml .Values.controller.probes.livenessProbe | indent 12) .}} + readinessProbe: +{{ tpl (toYaml .Values.controller.probes.readinessProbe | indent 12) .}} +{{- end }} + resources: +{{ toYaml .Values.controller.resources | indent 12 }} + volumeMounts: +{{- if .Values.persistence.mounts }} +{{ toYaml .Values.persistence.mounts | indent 12 }} +{{- end }} + {{- if and .Values.controller.httpsKeyStore.enable (not .Values.controller.httpsKeyStore.disableSecretMount) }} + {{- $httpsJKSDirPath := printf "%s" .Values.controller.httpsKeyStore.path }} + - mountPath: {{ $httpsJKSDirPath }} + name: jenkins-https-keystore + {{- end }} + - mountPath: {{ .Values.controller.jenkinsHome }} + name: jenkins-home + readOnly: false + {{- if .Values.persistence.subPath }} + subPath: {{ .Values.persistence.subPath }} + {{- end }} + - mountPath: /var/jenkins_config + name: jenkins-config + readOnly: true + {{- if .Values.controller.installPlugins }} + - mountPath: {{ .Values.controller.jenkinsRef }}/plugins/ + name: plugin-dir + readOnly: false + {{- end }} + {{- if or .Values.controller.initScripts .Values.controller.initConfigMap }} + - mountPath: {{ .Values.controller.jenkinsHome }}/init.groovy.d + name: init-scripts + {{- end }} + {{- if .Values.controller.sidecars.configAutoReload.enabled }} + - name: sc-config-volume + mountPath: {{ .Values.controller.sidecars.configAutoReload.folder | default (printf "%s/casc_configs" (.Values.controller.jenkinsRef)) }} + {{- end }} + {{- if or .Values.controller.additionalSecrets .Values.controller.existingSecret .Values.controller.additionalExistingSecrets .Values.controller.admin.createSecret }} + - name: jenkins-secrets + mountPath: /run/secrets/additional + readOnly: true + {{- end }} + - name: jenkins-cache + mountPath: /var/jenkins_cache + - mountPath: /tmp + name: tmp-volume + +{{- if .Values.controller.sidecars.configAutoReload.enabled }} +{{- include "jenkins.configReloadContainer" (list $ "config-reload" "sidecar") | nindent 8 }} +{{- end}} + + +{{- if .Values.controller.sidecars.additionalSidecarContainers}} +{{ tpl (toYaml .Values.controller.sidecars.additionalSidecarContainers | indent 8) .}} +{{- end }} + + volumes: +{{- if .Values.persistence.volumes }} +{{ tpl (toYaml .Values.persistence.volumes | indent 6) . }} +{{- end }} + {{- if .Values.controller.sidecars.configAutoReload.logging.configuration.override }} + - name: auto-reload-config + configMap: + name: {{ template "jenkins.fullname" . }}-auto-reload-config + - name: auto-reload-config-logs + emptyDir: {} + {{- end }} + {{- if .Values.controller.installPlugins }} + {{- if .Values.controller.overwritePluginsFromImage }} + - name: plugins + emptyDir: {} + {{- end }} + {{- end }} + {{- if and .Values.controller.initScripts .Values.controller.initConfigMap }} + - name: init-scripts + projected: + sources: + - configMap: + name: {{ template "jenkins.fullname" . }}-init-scripts + - configMap: + name: {{ .Values.controller.initConfigMap }} + {{- else if .Values.controller.initConfigMap }} + - name: init-scripts + configMap: + name: {{ .Values.controller.initConfigMap }} + {{- else if .Values.controller.initScripts }} + - name: init-scripts + configMap: + name: {{ template "jenkins.fullname" . }}-init-scripts + {{- end }} + - name: jenkins-config + configMap: + name: {{ template "jenkins.fullname" . }} + {{- if .Values.controller.installPlugins }} + - name: plugin-dir + emptyDir: {} + {{- end }} + {{- if or .Values.controller.additionalSecrets .Values.controller.existingSecret .Values.controller.additionalExistingSecrets .Values.controller.admin.createSecret }} + - name: jenkins-secrets + projected: + sources: + {{- if .Values.controller.additionalSecrets }} + - secret: + name: {{ template "jenkins.fullname" . }}-additional-secrets + {{- end }} + {{- if .Values.controller.additionalExistingSecrets }} + {{- range $key, $value := .Values.controller.additionalExistingSecrets }} + - secret: + name: {{ tpl $value.name $ }} + items: + - key: {{ tpl $value.keyName $ }} + path: {{ tpl $value.name $ }}-{{ tpl $value.keyName $ }} + {{- end }} + {{- end }} + {{- if .Values.controller.admin.createSecret }} + - secret: + name: {{ .Values.controller.admin.existingSecret | default (include "jenkins.fullname" .) }} + items: + - key: {{ .Values.controller.admin.userKey | default "jenkins-admin-user" }} + path: chart-admin-username + - key: {{ .Values.controller.admin.passwordKey | default "jenkins-admin-password" }} + path: chart-admin-password + {{- end }} + {{- if .Values.controller.existingSecret }} + - secret: + name: {{ .Values.controller.existingSecret }} + {{- end }} + {{- end }} + - name: jenkins-cache + emptyDir: {} + {{- if not (contains "jenkins-home" (quote .Values.persistence.volumes)) }} + - name: jenkins-home + {{- if .Values.persistence.enabled }} + persistentVolumeClaim: + claimName: {{ .Values.persistence.existingClaim | default (include "jenkins.fullname" .) }} + {{- else }} + emptyDir: {} + {{- end -}} + {{- end }} + - name: sc-config-volume + emptyDir: {} + - name: tmp-volume + emptyDir: {} + + {{- if and .Values.controller.httpsKeyStore.enable (not .Values.controller.httpsKeyStore.disableSecretMount) }} + - name: jenkins-https-keystore + secret: + secretName: {{ if .Values.controller.httpsKeyStore.jenkinsHttpsJksSecretName }} {{ .Values.controller.httpsKeyStore.jenkinsHttpsJksSecretName }} {{ else }} {{ template "jenkins.fullname" . }}-https-jks {{ end }} + items: + - key: {{ .Values.controller.httpsKeyStore.jenkinsHttpsJksSecretKey }} + path: {{ .Values.controller.httpsKeyStore.fileName }} + {{- end }} + +{{- if .Values.controller.imagePullSecretName }} + imagePullSecrets: + - name: {{ .Values.controller.imagePullSecretName }} +{{- end -}} diff --git a/charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-svc.yaml b/charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-svc.yaml new file mode 100644 index 000000000..a83466ce3 --- /dev/null +++ b/charts/jenkins/jenkins/5.5.1/templates/jenkins-controller-svc.yaml @@ -0,0 +1,56 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{template "jenkins.fullname" . }} + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" + {{- if .Values.controller.serviceLabels }} +{{ toYaml .Values.controller.serviceLabels | indent 4 }} + {{- end }} +{{- if .Values.controller.serviceAnnotations }} + annotations: +{{ toYaml .Values.controller.serviceAnnotations | indent 4 }} +{{- end }} +spec: + {{- if .Values.controller.serviceExternalTrafficPolicy }} + externalTrafficPolicy: {{.Values.controller.serviceExternalTrafficPolicy}} + {{- end }} + {{- if (and (eq .Values.controller.serviceType "ClusterIP") (not (empty .Values.controller.clusterIP))) }} + clusterIP: {{.Values.controller.clusterIP}} + {{- end }} + ports: + - port: {{.Values.controller.servicePort}} + name: http + targetPort: {{ .Values.controller.targetPort }} + {{- if (and (eq .Values.controller.serviceType "NodePort") (not (empty .Values.controller.nodePort))) }} + nodePort: {{.Values.controller.nodePort}} + {{- end }} +{{- range $index, $port := .Values.controller.extraPorts }} + - port: {{ $port.port }} + name: {{ $port.name }} + {{- if $port.targetPort }} + targetPort: {{ $port.targetPort }} + {{- else }} + targetPort: {{ $port.port }} + {{- end -}} +{{- end }} + selector: + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + type: {{.Values.controller.serviceType}} + {{if eq .Values.controller.serviceType "LoadBalancer"}} +{{- if .Values.controller.loadBalancerSourceRanges }} + loadBalancerSourceRanges: +{{ toYaml .Values.controller.loadBalancerSourceRanges | indent 4 }} +{{- end }} + {{if .Values.controller.loadBalancerIP}} + loadBalancerIP: {{.Values.controller.loadBalancerIP}} + {{end}} + {{end}} diff --git a/charts/jenkins/jenkins/5.5.1/templates/rbac.yaml b/charts/jenkins/jenkins/5.5.1/templates/rbac.yaml new file mode 100644 index 000000000..581cb8d48 --- /dev/null +++ b/charts/jenkins/jenkins/5.5.1/templates/rbac.yaml @@ -0,0 +1,149 @@ +{{ if .Values.rbac.create }} +{{- $serviceName := include "jenkins.fullname" . -}} + +# This role is used to allow Jenkins scheduling of agents via Kubernetes plugin. +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ $serviceName }}-schedule-agents + namespace: {{ template "jenkins.agent.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" +rules: +- apiGroups: [""] + resources: ["pods", "pods/exec", "pods/log", "persistentvolumeclaims", "events"] + verbs: ["get", "list", "watch"] +- apiGroups: [""] + resources: ["pods", "pods/exec", "persistentvolumeclaims"] + verbs: ["create", "delete", "deletecollection", "patch", "update"] + +--- + +# We bind the role to the Jenkins service account. The role binding is created in the namespace +# where the agents are supposed to run. +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ $serviceName }}-schedule-agents + namespace: {{ template "jenkins.agent.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ $serviceName }}-schedule-agents +subjects: +- kind: ServiceAccount + name: {{ template "jenkins.serviceAccountName" .}} + namespace: {{ template "jenkins.namespace" . }} + +--- + +{{- if .Values.rbac.readSecrets }} +# This is needed if you want to use https://jenkinsci.github.io/kubernetes-credentials-provider-plugin/ +# as it needs permissions to get/watch/list Secrets +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "jenkins.fullname" . }}-read-secrets + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" +rules: + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "watch", "list"] + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ $serviceName }}-read-secrets + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "jenkins.fullname" . }}-read-secrets +subjects: + - kind: ServiceAccount + name: {{ template "jenkins.serviceAccountName" . }} + namespace: {{ template "jenkins.namespace" . }} + +--- +{{- end}} + +{{- if .Values.controller.sidecars.configAutoReload.enabled }} +# The sidecar container which is responsible for reloading configuration changes +# needs permissions to watch ConfigMaps +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "jenkins.fullname" . }}-casc-reload + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" +rules: +- apiGroups: [""] + resources: ["configmaps"] + verbs: ["get", "watch", "list"] + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ $serviceName }}-watch-configmaps + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "jenkins.fullname" . }}-casc-reload +subjects: +- kind: ServiceAccount + name: {{ template "jenkins.serviceAccountName" . }} + namespace: {{ template "jenkins.namespace" . }} + +{{- end}} + +{{ end }} diff --git a/charts/jenkins/jenkins/5.5.1/templates/secret-additional.yaml b/charts/jenkins/jenkins/5.5.1/templates/secret-additional.yaml new file mode 100644 index 000000000..d1908aa9b --- /dev/null +++ b/charts/jenkins/jenkins/5.5.1/templates/secret-additional.yaml @@ -0,0 +1,21 @@ +{{- if .Values.controller.additionalSecrets -}} +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "jenkins.fullname" . }}-additional-secrets + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" +type: Opaque +data: +{{- range .Values.controller.additionalSecrets }} + {{ .name }}: {{ .value | b64enc }} +{{- end }} +{{- end }} diff --git a/charts/jenkins/jenkins/5.5.1/templates/secret-claims.yaml b/charts/jenkins/jenkins/5.5.1/templates/secret-claims.yaml new file mode 100644 index 000000000..e8b6d6c8e --- /dev/null +++ b/charts/jenkins/jenkins/5.5.1/templates/secret-claims.yaml @@ -0,0 +1,29 @@ +{{- if .Values.controller.secretClaims -}} +{{- $r := .Release -}} +{{- $v := .Values -}} +{{- $chart := printf "%s-%s" .Chart.Name .Chart.Version -}} +{{- $namespace := include "jenkins.namespace" . -}} +{{- $serviceName := include "jenkins.fullname" . -}} +{{ range .Values.controller.secretClaims }} +--- +kind: SecretClaim +apiVersion: vaultproject.io/v1 +metadata: + name: {{ $serviceName }}-{{ .name | default .path | lower }} + namespace: {{ $namespace }} + labels: + "app.kubernetes.io/name": '{{ $serviceName }}' + {{- if $v.renderHelmLabels }} + "helm.sh/chart": "{{ $chart }}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ $r.Service }}" + "app.kubernetes.io/instance": "{{ $r.Name }}" + "app.kubernetes.io/component": "{{ $v.controller.componentName }}" +spec: + type: {{ .type | default "Opaque" }} + path: {{ .path }} +{{- if .renew }} + renew: {{ .renew }} +{{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/jenkins/jenkins/5.5.1/templates/secret-https-jks.yaml b/charts/jenkins/jenkins/5.5.1/templates/secret-https-jks.yaml new file mode 100644 index 000000000..5348de41e --- /dev/null +++ b/charts/jenkins/jenkins/5.5.1/templates/secret-https-jks.yaml @@ -0,0 +1,20 @@ +{{- if and .Values.controller.httpsKeyStore.enable ( not .Values.controller.httpsKeyStore.jenkinsHttpsJksSecretName ) (not .Values.controller.httpsKeyStore.disableSecretMount) -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "jenkins.fullname" . }}-https-jks + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" +type: Opaque +data: + jenkins-jks-file: | +{{ .Values.controller.httpsKeyStore.jenkinsKeyStoreBase64Encoded | indent 4 }} + https-jks-password: {{ .Values.controller.httpsKeyStore.password | b64enc }} +{{- end }} diff --git a/charts/jenkins/jenkins/5.5.1/templates/secret.yaml b/charts/jenkins/jenkins/5.5.1/templates/secret.yaml new file mode 100644 index 000000000..cc6ace179 --- /dev/null +++ b/charts/jenkins/jenkins/5.5.1/templates/secret.yaml @@ -0,0 +1,20 @@ +{{- if and (not .Values.controller.admin.existingSecret) (.Values.controller.admin.createSecret) -}} + +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "jenkins.fullname" . }} + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" +type: Opaque +data: + jenkins-admin-password: {{ template "jenkins.password" . }} + jenkins-admin-user: {{ .Values.controller.admin.username | b64enc | quote }} +{{- end }} diff --git a/charts/jenkins/jenkins/5.5.1/templates/service-account-agent.yaml b/charts/jenkins/jenkins/5.5.1/templates/service-account-agent.yaml new file mode 100644 index 000000000..48f08ba6c --- /dev/null +++ b/charts/jenkins/jenkins/5.5.1/templates/service-account-agent.yaml @@ -0,0 +1,26 @@ +{{ if .Values.serviceAccountAgent.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "jenkins.serviceAccountAgentName" . }} + namespace: {{ template "jenkins.agent.namespace" . }} +{{- if .Values.serviceAccountAgent.annotations }} + annotations: +{{ tpl (toYaml .Values.serviceAccountAgent.annotations) . | indent 4 }} +{{- end }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" +{{- if .Values.serviceAccountAgent.extraLabels }} +{{ tpl (toYaml .Values.serviceAccountAgent.extraLabels) . | indent 4 }} +{{- end }} +{{- if .Values.serviceAccountAgent.imagePullSecretName }} +imagePullSecrets: + - name: {{ .Values.serviceAccountAgent.imagePullSecretName }} +{{- end -}} +{{ end }} diff --git a/charts/jenkins/jenkins/5.5.1/templates/service-account.yaml b/charts/jenkins/jenkins/5.5.1/templates/service-account.yaml new file mode 100644 index 000000000..b44eb488c --- /dev/null +++ b/charts/jenkins/jenkins/5.5.1/templates/service-account.yaml @@ -0,0 +1,26 @@ +{{ if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "jenkins.serviceAccountName" . }} + namespace: {{ template "jenkins.namespace" . }} +{{- if .Values.serviceAccount.annotations }} + annotations: +{{ tpl (toYaml .Values.serviceAccount.annotations) . | indent 4 }} +{{- end }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" +{{- if .Values.serviceAccount.extraLabels }} +{{ tpl (toYaml .Values.serviceAccount.extraLabels) . | indent 4 }} +{{- end }} +{{- if .Values.serviceAccount.imagePullSecretName }} +imagePullSecrets: + - name: {{ .Values.serviceAccount.imagePullSecretName }} +{{- end -}} +{{ end }} diff --git a/charts/jenkins/jenkins/5.5.1/templates/tests/jenkins-test.yaml b/charts/jenkins/jenkins/5.5.1/templates/tests/jenkins-test.yaml new file mode 100644 index 000000000..12a935ecc --- /dev/null +++ b/charts/jenkins/jenkins/5.5.1/templates/tests/jenkins-test.yaml @@ -0,0 +1,49 @@ +{{- if .Values.controller.testEnabled }} +apiVersion: v1 +kind: Pod +metadata: + name: "{{ .Release.Name }}-ui-test-{{ randAlphaNum 5 | lower }}" + namespace: {{ template "jenkins.namespace" . }} + annotations: + "helm.sh/hook": test-success +spec: + {{- if .Values.controller.nodeSelector }} + nodeSelector: +{{ toYaml .Values.controller.nodeSelector | indent 4 }} + {{- end }} + {{- if .Values.controller.tolerations }} + tolerations: +{{ toYaml .Values.controller.tolerations | indent 4 }} + {{- end }} + initContainers: + - name: "test-framework" + image: "{{ .Values.helmtest.bats.image.registry }}/{{ .Values.helmtest.bats.image.repository }}:{{ .Values.helmtest.bats.image.tag }}" + command: + - "bash" + - "-c" + args: + - | + # copy bats to tools dir + set -ex + cp -R /opt/bats /tools/bats/ + volumeMounts: + - mountPath: /tools + name: tools + containers: + - name: {{ .Release.Name }}-ui-test + image: "{{ .Values.controller.image.registry }}/{{ .Values.controller.image.repository }}:{{- include "controller.image.tag" . -}}" + command: ["/tools/bats/bin/bats", "-t", "/tests/run.sh"] + volumeMounts: + - mountPath: /tests + name: tests + readOnly: true + - mountPath: /tools + name: tools + volumes: + - name: tests + configMap: + name: {{ template "jenkins.fullname" . }}-tests + - name: tools + emptyDir: {} + restartPolicy: Never +{{- end }} diff --git a/charts/jenkins/jenkins/5.5.1/templates/tests/test-config.yaml b/charts/jenkins/jenkins/5.5.1/templates/tests/test-config.yaml new file mode 100644 index 000000000..12c5b3a0d --- /dev/null +++ b/charts/jenkins/jenkins/5.5.1/templates/tests/test-config.yaml @@ -0,0 +1,14 @@ +{{- if .Values.controller.testEnabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "jenkins.fullname" . }}-tests + namespace: {{ template "jenkins.namespace" . }} + annotations: + "helm.sh/hook": test +data: + run.sh: |- + @test "Testing Jenkins UI is accessible" { + curl --retry 48 --retry-delay 10 {{ template "jenkins.fullname" . }}:{{ .Values.controller.servicePort }}{{ default "" .Values.controller.jenkinsUriPrefix }}/login + } +{{- end }} diff --git a/charts/jenkins/jenkins/5.5.1/values.yaml b/charts/jenkins/jenkins/5.5.1/values.yaml new file mode 100644 index 000000000..05c0de499 --- /dev/null +++ b/charts/jenkins/jenkins/5.5.1/values.yaml @@ -0,0 +1,1337 @@ +# Default values for jenkins. +# This is a YAML-formatted file. +# Declare name/value pairs to be passed into your templates. +# name: value + +## Overrides for generated resource names +# See templates/_helpers.tpl +# -- Override the resource name prefix +# @default -- `Chart.Name` +nameOverride: +# -- Override the full resource names +# @default -- `jenkins-(release-name)` or `jenkins` if the release-name is `jenkins` +fullnameOverride: +# -- Override the deployment namespace +# @default -- `Release.Namespace` +namespaceOverride: + +# For FQDN resolving of the controller service. Change this value to match your existing configuration. +# ref: https://github.com/kubernetes/dns/blob/master/docs/specification.md +# -- Override the cluster name for FQDN resolving +clusterZone: "cluster.local" + +# -- The URL of the Kubernetes API server +kubernetesURL: "https://kubernetes.default" + +# -- The Jenkins credentials to access the Kubernetes API server. For the default cluster it is not needed. +credentialsId: + +# -- Enables rendering of the helm.sh/chart label to the annotations +renderHelmLabels: true + +controller: + # -- Used for label app.kubernetes.io/component + componentName: "jenkins-controller" + image: + # -- Controller image registry + registry: "docker.io" + # -- Controller image repository + repository: "jenkins/jenkins" + + # -- Controller image tag override; i.e., tag: "2.440.1-jdk17" + tag: + + # -- Controller image tag label + tagLabel: jdk17 + # -- Controller image pull policy + pullPolicy: "Always" + # -- Controller image pull secret + imagePullSecretName: + # -- Lifecycle specification for controller-container + lifecycle: {} + # postStart: + # exec: + # command: + # - "uname" + # - "-a" + + # -- Disable use of remember me + disableRememberMe: false + + # -- Set Number of executors + numExecutors: 0 + + # -- Sets the executor mode of the Jenkins node. Possible values are "NORMAL" or "EXCLUSIVE" + executorMode: "NORMAL" + + # -- Append Jenkins labels to the controller + customJenkinsLabels: [] + + hostNetworking: false + + # When enabling LDAP or another non-Jenkins identity source, the built-in admin account will no longer exist. + # If you disable the non-Jenkins identity store and instead use the Jenkins internal one, + # you should revert controller.admin.username to your preferred admin user: + admin: + + # -- Admin username created as a secret if `controller.admin.createSecret` is true + username: "admin" + # -- Admin password created as a secret if `controller.admin.createSecret` is true + # @default -- + password: + + # -- The key in the existing admin secret containing the username + userKey: jenkins-admin-user + # -- The key in the existing admin secret containing the password + passwordKey: jenkins-admin-password + + # The default configuration uses this secret to configure an admin user + # If you don't need that user or use a different security realm, then you can disable it + # -- Create secret for admin user + createSecret: true + + # -- The name of an existing secret containing the admin credentials + existingSecret: "" + # -- Email address for the administrator of the Jenkins instance + jenkinsAdminEmail: + + # This value should not be changed unless you use your custom image of jenkins or any derived from. + # If you want to use Cloudbees Jenkins Distribution docker, you should set jenkinsHome: "/var/cloudbees-jenkins-distribution" + # -- Custom Jenkins home path + jenkinsHome: "/var/jenkins_home" + + # This value should not be changed unless you use your custom image of jenkins or any derived from. + # If you want to use Cloudbees Jenkins Distribution docker, you should set jenkinsRef: "/usr/share/cloudbees-jenkins-distribution/ref" + # -- Custom Jenkins reference path + jenkinsRef: "/usr/share/jenkins/ref" + + # Path to the jenkins war file which is used by jenkins-plugin-cli. + jenkinsWar: "/usr/share/jenkins/jenkins.war" + # Override the default arguments passed to the war + # overrideArgs: + # - --httpPort=8080 + + # -- Resource allocation (Requests and Limits) + resources: + requests: + cpu: "50m" + memory: "256Mi" + limits: + cpu: "2000m" + memory: "4096Mi" + + # Share process namespace to allow sidecar containers to interact with processes in other containers in the same pod + shareProcessNamespace: false + + # Overrides the init container default values + # -- Resources allocation (Requests and Limits) for Init Container + initContainerResources: {} + # initContainerResources: + # requests: + # cpu: "50m" + # memory: "256Mi" + # limits: + # cpu: "2000m" + # memory: "4096Mi" + # -- Environment variable sources for Init Container + initContainerEnvFrom: [] + + # useful for i.e., http_proxy + # -- Environment variables for Init Container + initContainerEnv: [] + # initContainerEnv: + # - name: http_proxy + # value: "http://192.168.64.1:3128" + + # -- Environment variable sources for Jenkins Container + containerEnvFrom: [] + + # -- Environment variables for Jenkins Container + containerEnv: [] + # - name: http_proxy + # value: "http://192.168.64.1:3128" + + # Set min/max heap here if needed with "-Xms512m -Xmx512m" + # -- Append to `JAVA_OPTS` env var + javaOpts: + # -- Append to `JENKINS_OPTS` env var + jenkinsOpts: + + # If you are using the ingress definitions provided by this chart via the `controller.ingress` block, + # the configured hostname will be the ingress hostname starting with `https://` + # or `http://` depending on the `tls` configuration. + # The Protocol can be overwritten by specifying `controller.jenkinsUrlProtocol`. + # -- Set protocol for Jenkins URL; `https` if `controller.ingress.tls`, `http` otherwise + jenkinsUrlProtocol: + + # -- Set Jenkins URL if you are not using the ingress definitions provided by the chart + jenkinsUrl: + + # If you set this prefix and use ingress controller, then you might want to set the ingress path below + # I.e., "/jenkins" + # -- Root URI Jenkins will be served on + jenkinsUriPrefix: + + # -- Enable pod security context (must be `true` if podSecurityContextOverride, runAsUser or fsGroup are set) + usePodSecurityContext: true + + # Note that `runAsUser`, `fsGroup`, and `securityContextCapabilities` are + # being deprecated and replaced by `podSecurityContextOverride`. + # Set runAsUser to 1000 to let Jenkins run as non-root user 'jenkins', which exists in 'jenkins/jenkins' docker image. + # When configuring runAsUser to a different value than 0 also set fsGroup to the same value: + # -- Deprecated in favor of `controller.podSecurityContextOverride`. uid that jenkins runs with. + runAsUser: 1000 + + # -- Deprecated in favor of `controller.podSecurityContextOverride`. uid that will be used for persistent volume. + fsGroup: 1000 + + # If you have PodSecurityPolicies that require dropping of capabilities as suggested by CIS K8s benchmark, put them here + # securityContextCapabilities: + # drop: + # - NET_RAW + securityContextCapabilities: {} + + # In the case of mounting an ext4 filesystem, it might be desirable to use `supplementalGroups` instead of `fsGroup` in + # the `securityContext` block: https://github.com/kubernetes/kubernetes/issues/67014#issuecomment-589915496 + # podSecurityContextOverride: + # runAsUser: 1000 + # runAsNonRoot: true + # supplementalGroups: [1000] + # capabilities: {} + # -- Completely overwrites the contents of the pod security context, ignoring the values provided for `runAsUser`, `fsGroup`, and `securityContextCapabilities` + podSecurityContextOverride: ~ + + # -- Allow controlling the securityContext for the jenkins container + containerSecurityContext: + runAsUser: 1000 + runAsGroup: 1000 + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + + # For minikube, set this to NodePort, elsewhere uses LoadBalancer + # Use ClusterIP if your setup includes ingress controller + # -- k8s service type + serviceType: ClusterIP + + # -- k8s service clusterIP. Only used if serviceType is ClusterIP + clusterIp: + # -- k8s service port + servicePort: 8080 + # -- k8s target port + targetPort: 8080 + # -- k8s node port. Only used if serviceType is NodePort + nodePort: + + # Use Local to preserve the client source IP and avoids a second hop for LoadBalancer and NodePort type services, + # but risks potentially imbalanced traffic spreading. + serviceExternalTrafficPolicy: + + # -- Jenkins controller service annotations + serviceAnnotations: {} + # -- Jenkins controller custom labels for the StatefulSet + statefulSetLabels: {} + # foo: bar + # bar: foo + # -- Labels for the Jenkins controller-service + serviceLabels: {} + # service.beta.kubernetes.io/aws-load-balancer-backend-protocol: https + + # Put labels on Jenkins controller pod + # -- Custom Pod labels (an object with `label-key: label-value` pairs) + podLabels: {} + + # Enable Kubernetes Startup, Liveness and Readiness Probes + # if Startup Probe is supported, enable it too + # ~ 2 minutes to allow Jenkins to restart when upgrading plugins. Set ReadinessTimeout to be shorter than LivenessTimeout. + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes + # -- Enable Kubernetes Probes configuration configured in `controller.probes` + healthProbes: true + + probes: + startupProbe: + # -- Set the failure threshold for the startup probe + failureThreshold: 12 + httpGet: + # -- Set the Pod's HTTP path for the startup probe + path: '{{ default "" .Values.controller.jenkinsUriPrefix }}/login' + # -- Set the Pod's HTTP port to use for the startup probe + port: http + # -- Set the time interval between two startup probes executions in seconds + periodSeconds: 10 + # -- Set the timeout for the startup probe in seconds + timeoutSeconds: 5 + + livenessProbe: + # -- Set the failure threshold for the liveness probe + failureThreshold: 5 + httpGet: + # -- Set the Pod's HTTP path for the liveness probe + path: '{{ default "" .Values.controller.jenkinsUriPrefix }}/login' + # -- Set the Pod's HTTP port to use for the liveness probe + port: http + # -- Set the time interval between two liveness probes executions in seconds + periodSeconds: 10 + # -- Set the timeout for the liveness probe in seconds + timeoutSeconds: 5 + + # If Startup Probe is not supported on your Kubernetes cluster, you might want to use "initialDelaySeconds" instead. + # It delays the initial liveness probe while Jenkins is starting + # -- Set the initial delay for the liveness probe in seconds + initialDelaySeconds: + + readinessProbe: + # -- Set the failure threshold for the readiness probe + failureThreshold: 3 + httpGet: + # -- Set the Pod's HTTP path for the liveness probe + path: '{{ default "" .Values.controller.jenkinsUriPrefix }}/login' + # -- Set the Pod's HTTP port to use for the readiness probe + port: http + # -- Set the time interval between two readiness probes executions in seconds + periodSeconds: 10 + # -- Set the timeout for the readiness probe in seconds + timeoutSeconds: 5 + + # If Startup Probe is not supported on your Kubernetes cluster, you might want to use "initialDelaySeconds" instead. + # It delays the initial readiness probe while Jenkins is starting + # -- Set the initial delay for the readiness probe in seconds + initialDelaySeconds: + + # PodDisruptionBudget config + podDisruptionBudget: + # ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/ + + # -- Enable Kubernetes Pod Disruption Budget configuration + enabled: false + + # For Kubernetes v1.5+, use 'policy/v1beta1' + # For Kubernetes v1.21+, use 'policy/v1' + # -- Policy API version + apiVersion: "policy/v1beta1" + + annotations: {} + labels: {} + # -- Number of pods that can be unavailable. Either an absolute number or a percentage + maxUnavailable: "0" + + # -- Create Agent listener service + agentListenerEnabled: true + # -- Listening port for agents + agentListenerPort: 50000 + # -- Host port to listen for agents + agentListenerHostPort: + # -- Node port to listen for agents + agentListenerNodePort: + + # ref: https://kubernetes.io/docs/concepts/services-networking/service/#traffic-policies + # -- Traffic Policy of for the agentListener service + agentListenerExternalTrafficPolicy: + # -- Allowed inbound IP for the agentListener service + agentListenerLoadBalancerSourceRanges: + - 0.0.0.0/0 + # -- Disabled agent protocols + disabledAgentProtocols: + - JNLP-connect + - JNLP2-connect + csrf: + defaultCrumbIssuer: + # -- Enable the default CSRF Crumb issuer + enabled: true + # -- Enable proxy compatibility + proxyCompatability: true + + # Kubernetes service type for the JNLP agent service + # agentListenerServiceType is the Kubernetes Service type for the JNLP agent service, + # either 'LoadBalancer', 'NodePort', or 'ClusterIP' + # Note if you set this to 'LoadBalancer', you *must* define annotations to secure it. By default, + # this will be an external load balancer and allowing inbound 0.0.0.0/0, a HUGE + # security risk: https://github.com/kubernetes/charts/issues/1341 + # -- Defines how to expose the agentListener service + agentListenerServiceType: "ClusterIP" + + # -- Annotations for the agentListener service + agentListenerServiceAnnotations: {} + + # Optionally, assign an IP to the LoadBalancer agentListenerService LoadBalancer + # GKE users: only regional static IPs will work for Service Load balancer. + # -- Static IP for the agentListener LoadBalancer + agentListenerLoadBalancerIP: + + # -- Whether legacy remoting security should be enabled + legacyRemotingSecurityEnabled: false + + # Example of a 'LoadBalancer'-type agent listener with annotations securing it + # agentListenerServiceType: LoadBalancer + # agentListenerServiceAnnotations: + # service.beta.kubernetes.io/aws-load-balancer-internal: "True" + # service.beta.kubernetes.io/load-balancer-source-ranges: "172.0.0.0/8, 10.0.0.0/8" + + # LoadBalancerSourcesRange is a list of allowed CIDR values, which are combined with ServicePort to + # set allowed inbound rules on the security group assigned to the controller load balancer + # -- Allowed inbound IP addresses + loadBalancerSourceRanges: + - 0.0.0.0/0 + + # -- Optionally assign a known public LB IP + loadBalancerIP: + + # Optionally configure a JMX port. This requires additional javaOpts, for example, + # javaOpts: > + # -Dcom.sun.management.jmxremote.port=4000 + # -Dcom.sun.management.jmxremote.authenticate=false + # -Dcom.sun.management.jmxremote.ssl=false + # jmxPort: 4000 + # -- Open a port, for JMX stats + jmxPort: + + # -- Optionally configure other ports to expose in the controller container + extraPorts: [] + # - name: BuildInfoProxy + # port: 9000 + # targetPort: 9010 (Optional: Use to explicitly set targetPort if different from port) + + # Plugins will be installed during Jenkins controller start + # -- List of Jenkins plugins to install. If you don't want to install plugins, set it to `false` + installPlugins: + - kubernetes:4265.v78b_d4a_1c864a_ + - workflow-aggregator:600.vb_57cdd26fdd7 + - git:5.2.2 + - configuration-as-code:1836.vccda_4a_122a_a_e + + # If set to false, Jenkins will download the minimum required version of all dependencies. + # -- Download the minimum required version or latest version of all dependencies + installLatestPlugins: true + + # -- Set to true to download the latest version of any plugin that is requested to have the latest version + installLatestSpecifiedPlugins: false + + # -- List of plugins to install in addition to those listed in controller.installPlugins + additionalPlugins: [] + + # Without this; whenever the controller gets restarted (Evicted, etc.) it will fetch plugin updates that have the potential to cause breakage. + # Note that for this to work, `persistence.enabled` needs to be set to `true` + # -- Initialize only on first installation. Ensures plugins do not get updated inadvertently. Requires `persistence.enabled` to be set to `true` + initializeOnce: false + + # Enable to always override the installed plugins with the values of 'controller.installPlugins' on upgrade or redeployment. + # -- Overwrite installed plugins on start + overwritePlugins: false + + # Configures if plugins bundled with `controller.image` should be overwritten with the values of 'controller.installPlugins' on upgrade or redeployment. + # -- Overwrite plugins that are already installed in the controller image + overwritePluginsFromImage: true + + # Configures the restrictions for naming projects. Set this key to null or empty to skip it in the default config. + projectNamingStrategy: standard + + # Useful with ghprb plugin. The OWASP plugin is not installed by default, please update controller.installPlugins. + # -- Enable HTML parsing using OWASP Markup Formatter Plugin (antisamy-markup-formatter) + enableRawHtmlMarkupFormatter: false + + # This is ignored if enableRawHtmlMarkupFormatter is true + # -- Yaml of the markup formatter to use + markupFormatter: plainText + + # Used to approve a list of groovy functions in pipelines used the script-security plugin. Can be viewed under /scriptApproval + # -- List of groovy functions to approve + scriptApproval: [] + # - "method groovy.json.JsonSlurperClassic parseText java.lang.String" + # - "new groovy.json.JsonSlurperClassic" + + # -- Map of groovy init scripts to be executed during Jenkins controller start + initScripts: {} + # test: |- + # print 'adding global pipeline libraries, register properties, bootstrap jobs...' + # -- Name of the existing ConfigMap that contains init scripts + initConfigMap: + + # 'name' is a name of an existing secret in the same namespace as jenkins, + # 'keyName' is the name of one of the keys inside the current secret. + # the 'name' and 'keyName' are concatenated with a '-' in between, so for example: + # an existing secret "secret-credentials" and a key inside it named "github-password" should be used in JCasC as ${secret-credentials-github-password} + # 'name' and 'keyName' must be lowercase RFC 1123 label must consist of lower case alphanumeric characters or '-', + # and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc') + # existingSecret existing secret "secret-credentials" and a key inside it named "github-username" should be used in JCasC as ${github-username} + # When using existingSecret no need to specify the keyName under additionalExistingSecrets. + existingSecret: + + # -- List of additional existing secrets to mount + additionalExistingSecrets: [] + # ref: https://github.com/jenkinsci/configuration-as-code-plugin/blob/master/docs/features/secrets.adoc#kubernetes-secrets + # additionalExistingSecrets: + # - name: secret-name-1 + # keyName: username + # - name: secret-name-1 + # keyName: password + + # -- List of additional secrets to create and mount + additionalSecrets: [] + # ref: https://github.com/jenkinsci/configuration-as-code-plugin/blob/master/docs/features/secrets.adoc#kubernetes-secrets + # additionalSecrets: + # - name: nameOfSecret + # value: secretText + + # Generate SecretClaim resources to create Kubernetes secrets from HashiCorp Vault using kube-vault-controller. + # 'name' is the name of the secret that will be created in Kubernetes. The Jenkins fullname is prepended to this value. + # 'path' is the fully qualified path to the secret in Vault + # 'type' is an optional Kubernetes secret type. The default is 'Opaque' + # 'renew' is an optional secret renewal time in seconds + # -- List of `SecretClaim` resources to create + secretClaims: [] + # - name: secretName # required + # path: testPath # required + # type: kubernetes.io/tls # optional + # renew: 60 # optional + + # -- Name of default cloud configuration. + cloudName: "kubernetes" + + # Below is the implementation of Jenkins Configuration as Code. Add a key under configScripts for each configuration area, + # where each corresponds to a plugin or section of the UI. Each key (prior to | character) is just a label, and can be any value. + # Keys are only used to give the section a meaningful name. The only restriction is they may only contain RFC 1123 \ DNS label + # characters: lowercase letters, numbers, and hyphens. The keys become the name of a configuration yaml file on the controller in + # /var/jenkins_home/casc_configs (by default) and will be processed by the Configuration as Code Plugin. The lines after each | + # become the content of the configuration yaml file. The first line after this is a JCasC root element, e.g., jenkins, credentials, + # etc. Best reference is https:///configuration-as-code/reference. The example below creates a welcome message: + JCasC: + # -- Enables default Jenkins configuration via configuration as code plugin + defaultConfig: true + + # If true, the init container deletes all the plugin config files and Jenkins Config as Code overwrites any existing configuration + # -- Whether Jenkins Config as Code should overwrite any existing configuration + overwriteConfiguration: false + # -- Remote URLs for configuration files. + configUrls: [] + # - https://acme.org/jenkins.yaml + # -- List of Jenkins Config as Code scripts + configScripts: {} + # welcome-message: | + # jenkins: + # systemMessage: Welcome to our CI\CD server. This Jenkins is configured and managed 'as code'. + + # Allows adding to the top-level security JCasC section. For legacy purposes, by default, the chart includes apiToken configurations + # -- Jenkins Config as Code security-section + security: + apiToken: + creationOfLegacyTokenEnabled: false + tokenGenerationOnCreationEnabled: false + usageStatisticsEnabled: true + + # Ignored if securityRealm is defined in controller.JCasC.configScripts + # -- Jenkins Config as Code Security Realm-section + securityRealm: |- + local: + allowsSignup: false + enableCaptcha: false + users: + - id: "${chart-admin-username}" + name: "Jenkins Admin" + password: "${chart-admin-password}" + + # Ignored if authorizationStrategy is defined in controller.JCasC.configScripts + # -- Jenkins Config as Code Authorization Strategy-section + authorizationStrategy: |- + loggedInUsersCanDoAnything: + allowAnonymousRead: false + + # -- Annotations for the JCasC ConfigMap + configMapAnnotations: {} + + # -- Custom init-container specification in raw-yaml format + customInitContainers: [] + # - name: custom-init + # image: "alpine:3" + # imagePullPolicy: Always + # command: [ "uname", "-a" ] + + sidecars: + configAutoReload: + # If enabled: true, Jenkins Configuration as Code will be reloaded on-the-fly without a reboot. + # If false or not-specified, JCasC changes will cause a reboot and will only be applied at the subsequent start-up. + # Auto-reload uses the http:///reload-configuration-as-code endpoint to reapply config when changes to + # the configScripts are detected. + # -- Enables Jenkins Config as Code auto-reload + enabled: true + image: + # -- Registry for the image that triggers the reload + registry: docker.io + # -- Repository of the image that triggers the reload + repository: kiwigrid/k8s-sidecar + # -- Tag for the image that triggers the reload + tag: 1.27.5 + imagePullPolicy: IfNotPresent + resources: {} + # limits: + # cpu: 100m + # memory: 100Mi + # requests: + # cpu: 50m + # memory: 50Mi + # -- Enables additional volume mounts for the config auto-reload container + additionalVolumeMounts: [] + # - name: auto-reload-config + # mountPath: /var/config/logger + # - name: auto-reload-logs + # mountPath: /var/log/auto_reload + # -- Config auto-reload logging settings + logging: + # See default settings https://github.com/kiwigrid/k8s-sidecar/blob/master/src/logger.py + configuration: + # -- Enables custom log config utilizing using the settings below. + override: false + logLevel: INFO + formatter: JSON + logToConsole: true + logToFile: false + maxBytes: 1024 + backupCount: 3 + + # -- The scheme to use when connecting to the Jenkins configuration as code endpoint + scheme: http + # -- Skip TLS verification when connecting to the Jenkins configuration as code endpoint + skipTlsVerify: false + + # -- How many connection-related errors to retry on + reqRetryConnect: 10 + # -- How many seconds to wait before updating config-maps/secrets (sets METHOD=SLEEP on the sidecar) + sleepTime: + + # -- Environment variable sources for the Jenkins Config as Code auto-reload container + envFrom: [] + # -- Environment variables for the Jenkins Config as Code auto-reload container + env: {} + # - name: REQ_TIMEOUT + # value: "30" + + # SSH port value can be set to any unused TCP port. The default, 1044, is a non-standard SSH port that has been chosen at random. + # This is only used to reload JCasC config from the sidecar container running in the Jenkins controller pod. + # This TCP port will not be open in the pod (unless you specifically configure this), so Jenkins will not be + # accessible via SSH from outside the pod. Note if you use non-root pod privileges (runAsUser & fsGroup), + # this must be > 1024: + sshTcpPort: 1044 + # folder in the pod that should hold the collected dashboards: + folder: "/var/jenkins_home/casc_configs" + + # If specified, the sidecar will search for JCasC config-maps inside this namespace. + # Otherwise, the namespace in which the sidecar is running will be used. + # It's also possible to specify ALL to search in all namespaces: + # searchNamespace: + # -- Enable container security context + containerSecurityContext: + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + + # -- Configures additional sidecar container(s) for the Jenkins controller + additionalSidecarContainers: [] + ## The example below runs the client for https://smee.io as sidecar container next to Jenkins, + ## that allows triggering build behind a secure firewall. + ## https://jenkins.io/blog/2019/01/07/webhook-firewalls/#triggering-builds-with-webhooks-behind-a-secure-firewall + ## + ## Note: To use it you should go to https://smee.io/new and update the url to the generated one. + # - name: smee + # image: docker.io/twalter/smee-client:1.0.2 + # args: ["--port", "{{ .Values.controller.servicePort }}", "--path", "/github-webhook/", "--url", "https://smee.io/new"] + # resources: + # limits: + # cpu: 50m + # memory: 128Mi + # requests: + # cpu: 10m + # memory: 32Mi + + # -- Name of the Kubernetes scheduler to use + schedulerName: "" + + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector + # -- Node labels for pod assignment + nodeSelector: {} + + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#taints-and-tolerations-beta-feature + # -- Toleration labels for pod assignment + tolerations: [] + # -- Set TerminationGracePeriodSeconds + terminationGracePeriodSeconds: + # -- Set the termination message path + terminationMessagePath: + # -- Set the termination message policy + terminationMessagePolicy: + + # -- Affinity settings + affinity: {} + + # Leverage a priorityClass to ensure your pods survive resource shortages + # ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/ + # -- The name of a `priorityClass` to apply to the controller pod + priorityClassName: + + # -- Annotations for controller pod + podAnnotations: {} + # -- Annotations for controller StatefulSet + statefulSetAnnotations: {} + + # ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#update-strategies + # -- Update strategy for StatefulSet + updateStrategy: {} + + # -- Topology spread constraints + topologySpreadConstraints: {} + + ingress: + # -- Enables ingress + enabled: false + + # Override for the default paths that map requests to the backend + # -- Override for the default Ingress paths + paths: [] + # - backend: + # serviceName: ssl-redirect + # servicePort: use-annotation + # - backend: + # serviceName: >- + # {{ template "jenkins.fullname" . }} + # # Don't use string here, use only integer value! + # servicePort: 8080 + + # For Kubernetes v1.14+, use 'networking.k8s.io/v1beta1' + # For Kubernetes v1.19+, use 'networking.k8s.io/v1' + # -- Ingress API version + apiVersion: "extensions/v1beta1" + # -- Ingress labels + labels: {} + # -- Ingress annotations + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + # For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName + # See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress + # ingressClassName: nginx + + # Set this path to jenkinsUriPrefix above or use annotations to rewrite path + # -- Ingress path + path: + + # configures the hostname e.g. jenkins.example.com + # -- Ingress hostname + hostName: + # -- Hostname to serve assets from + resourceRootUrl: + # -- Ingress TLS configuration + tls: [] + # - secretName: jenkins.cluster.local + # hosts: + # - jenkins.cluster.local + + # often you want to have your controller all locked down and private, + # but you still want to get webhooks from your SCM + # A secondary ingress will let you expose different urls + # with a different configuration + secondaryingress: + enabled: false + # paths you want forwarded to the backend + # ex /github-webhook + paths: [] + # For Kubernetes v1.14+, use 'networking.k8s.io/v1beta1' + # For Kubernetes v1.19+, use 'networking.k8s.io/v1' + apiVersion: "extensions/v1beta1" + labels: {} + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + # For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName + # See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress + # ingressClassName: nginx + # configures the hostname e.g., jenkins-external.example.com + hostName: + tls: + # - secretName: jenkins-external.example.com + # hosts: + # - jenkins-external.example.com + + # If you're running on GKE and need to configure a backendconfig + # to finish ingress setup, use the following values. + # Docs: https://cloud.google.com/kubernetes-engine/docs/concepts/backendconfig + backendconfig: + # -- Enables backendconfig + enabled: false + # -- backendconfig API version + apiVersion: "extensions/v1beta1" + # -- backendconfig name + name: + # -- backendconfig labels + labels: {} + # -- backendconfig annotations + annotations: {} + # -- backendconfig spec + spec: {} + + # Openshift route + route: + # -- Enables openshift route + enabled: false + # -- Route labels + labels: {} + # -- Route annotations + annotations: {} + # -- Route path + path: + + # -- Allows for adding entries to Pod /etc/hosts + hostAliases: [] + # ref: https://kubernetes.io/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases/ + # hostAliases: + # - ip: 192.168.50.50 + # hostnames: + # - something.local + # - ip: 10.0.50.50 + # hostnames: + # - other.local + + # Expose Prometheus metrics + prometheus: + # If enabled, add the prometheus plugin to the list of plugins to install + # https://plugins.jenkins.io/prometheus + + # -- Enables prometheus service monitor + enabled: false + # -- Additional labels to add to the service monitor object + serviceMonitorAdditionalLabels: {} + # -- Set a custom namespace where to deploy ServiceMonitor resource + serviceMonitorNamespace: + # -- How often prometheus should scrape metrics + scrapeInterval: 60s + + # Defaults to the default endpoint used by the prometheus plugin + # -- The endpoint prometheus should get metrics from + scrapeEndpoint: /prometheus + + # See here: https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/ + # The `groups` root object is added by default, add the rule entries + # -- Array of prometheus alerting rules + alertingrules: [] + # -- Additional labels to add to the PrometheusRule object + alertingRulesAdditionalLabels: {} + # -- Set a custom namespace where to deploy PrometheusRule resource + prometheusRuleNamespace: "" + + # RelabelConfigs to apply to samples before scraping. Prometheus Operator automatically adds + # relabelings for a few standard Kubernetes fields. The original scrape job’s name + # is available via the __tmp_prometheus_job_name label. + # More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + relabelings: [] + # MetricRelabelConfigs to apply to samples before ingestion. + metricRelabelings: [] + + googlePodMonitor: + # If enabled, It creates Google Managed Prometheus scraping config + enabled: false + # Set a custom namespace where to deploy PodMonitoring resource + # serviceMonitorNamespace: "" + scrapeInterval: 60s + # This is the default endpoint used by the prometheus plugin + scrapeEndpoint: /prometheus + + # -- Can be used to disable rendering controller test resources when using helm template + testEnabled: true + + httpsKeyStore: + # -- Enables HTTPS keystore on jenkins controller + enable: false + # -- Name of the secret that already has ssl keystore + jenkinsHttpsJksSecretName: "" + # -- Name of the key in the secret that already has ssl keystore + jenkinsHttpsJksSecretKey: "jenkins-jks-file" + # -- Name of the secret that contains the JKS password, if it is not in the same secret as the JKS file + jenkinsHttpsJksPasswordSecretName: "" + # -- Name of the key in the secret that contains the JKS password + jenkinsHttpsJksPasswordSecretKey: "https-jks-password" + disableSecretMount: false + + # When HTTPS keystore is enabled, servicePort and targetPort will be used as HTTPS port + # -- HTTP Port that Jenkins should listen to along with HTTPS, it also serves as the liveness and readiness probes port. + httpPort: 8081 + # -- Path of HTTPS keystore file + path: "/var/jenkins_keystore" + # -- Jenkins keystore filename which will appear under controller.httpsKeyStore.path + fileName: "keystore.jks" + # -- Jenkins keystore password + password: "password" + + # -- Base64 encoded Keystore content. Keystore must be converted to base64 then being pasted here + jenkinsKeyStoreBase64Encoded: + # Convert keystore.jks files content to base64 > $ cat keystore.jks | base64 +# /u3+7QAAAAIAAAABAAAAAQANamVua2luc2NpLmNvbQAAAW2r/b1ZAAAFATCCBP0wDgYKKwYBBAEq +# AhEBAQUABIIE6QbCqasvoHS0pSwYqSvdydMCB9t+VNfwhFIiiuAelJfO5sSe2SebJbtwHgLcRz1Z +# gMtWgOSFdl3bWSzA7vrW2LED52h+jXLYSWvZzuDuh8hYO85m10ikF6QR+dTi4jra0whIFDvq3pxe +# TnESxEsN+DvbZM3jA3qsjQJSeISNpDjO099dqQvHpnCn18lyk7J4TWJ8sOQQb1EM2zDAfAOSqA/x +# QuPEFl74DlY+5DIk6EBvpmWhaMSvXzWZACGA0sYqa157dq7O0AqmuLG/EI5EkHETO4CrtBW+yLcy +# 2dUCXOMA+j+NjM1BjrQkYE5vtSfNO6lFZcISyKo5pTFlcA7ut0Fx2nZ8GhHTn32CpeWwNcZBn1gR +# pZVt6DxVVkhTAkMLhR4rL2wGIi/1WRs23ZOLGKtyDNvDHnQyDiQEoJGy9nAthA8aNHa3cfdF10vB +# Drb19vtpFHmpvKEEhpk2EBRF4fTi644Fuhu2Ied6118AlaPvEea+n6G4vBz+8RWuVCmZjLU+7h8l +# Hy3/WdUPoIL5eW7Kz+hS+sRTFzfu9C48dMkQH3a6f3wSY+mufizNF9U298r98TnYy+PfDJK0bstG +# Ph6yPWx8DGXKQBwrhWJWXI6JwZDeC5Ny+l8p1SypTmAjpIaSW3ge+KgcL6Wtt1R5hUV1ajVwVSUi +# HF/FachKqPqyLJFZTGjNrxnmNYpt8P1d5JTvJfmfr55Su/P9n7kcyWp7zMcb2Q5nlXt4tWogOHLI +# OzEWKCacbFfVHE+PpdrcvCVZMDzFogIq5EqGTOZe2poPpBVE+1y9mf5+TXBegy5HToLWvmfmJNTO +# NCDuBjgLs2tdw2yMPm4YEr57PnMX5gGTC3f2ZihXCIJDCRCdQ9sVBOjIQbOCzxFXkVITo0BAZhCi +# Yz61wt3Ud8e//zhXWCkCsSV+IZCxxPzhEFd+RFVjW0Nm9hsb2FgAhkXCjsGROgoleYgaZJWvQaAg +# UyBzMmKDPKTllBHyE3Gy1ehBNGPgEBChf17/9M+j8pcm1OmlM434ctWQ4qW7RU56//yq1soFY0Te +# fu2ei03a6m68fYuW6s7XEEK58QisJWRAvEbpwu/eyqfs7PsQ+zSgJHyk2rO95IxdMtEESb2GRuoi +# Bs+AHNdYFTAi+GBWw9dvEgqQ0Mpv0//6bBE/Fb4d7b7f56uUNnnE7mFnjGmGQN+MvC62pfwfvJTT +# EkT1iZ9kjM9FprTFWXT4UmO3XTvesGeE50sV9YPm71X4DCQwc4KE8vyuwj0s6oMNAUACW2ClU9QQ +# y0tRpaF1tzs4N42Q5zl0TzWxbCCjAtC3u6xf+c8MCGrr7DzNhm42LOQiHTa4MwX4x96q7235oiAU +# iQqSI/hyF5yLpWw4etyUvsx2/0/0wkuTU1FozbLoCWJEWcPS7QadMrRRISxHf0YobIeQyz34regl +# t1qSQ3dCU9D6AHLgX6kqllx4X0fnFq7LtfN7fA2itW26v+kAT2QFZ3qZhINGfofCja/pITC1uNAZ +# gsJaTMcQ600krj/ynoxnjT+n1gmeqThac6/Mi3YlVeRtaxI2InL82ZuD+w/dfY9OpPssQjy3xiQa +# jPuaMWXRxz/sS9syOoGVH7XBwKrWpQcpchozWJt40QV5DslJkclcr8aC2AGlzuJMTdEgz1eqV0+H +# bAXG9HRHN/0eJTn1/QAAAAEABVguNTA5AAADjzCCA4swggJzAhRGqVxH4HTLYPGO4rzHcCPeGDKn +# xTANBgkqhkiG9w0BAQsFADCBgTELMAkGA1UEBhMCY2ExEDAOBgNVBAgMB29udGFyaW8xEDAOBgNV +# BAcMB3Rvcm9udG8xFDASBgNVBAoMC2plbmtpbnN0ZXN0MRkwFwYDVQQDDBBqZW5raW5zdGVzdC5p +# bmZvMR0wGwYJKoZIhvcNAQkBFg50ZXN0QHRlc3QuaW5mbzAeFw0xOTEwMDgxNTI5NTVaFw0xOTEx +# MDcxNTI5NTVaMIGBMQswCQYDVQQGEwJjYTEQMA4GA1UECAwHb250YXJpbzEQMA4GA1UEBwwHdG9y +# b250bzEUMBIGA1UECgwLamVua2luc3Rlc3QxGTAXBgNVBAMMEGplbmtpbnN0ZXN0LmluZm8xHTAb +# BgkqhkiG9w0BCQEWDnRlc3RAdGVzdC5pbmZvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +# AQEA02q352JTHGvROMBhSHvSv+vnoOTDKSTz2aLQn0tYrIRqRo+8bfmMjXuhkwZPSnCpvUGNAJ+w +# Jrt/dqMoYUjCBkjylD/qHmnXN5EwS1cMg1Djh65gi5JJLFJ7eNcoSsr/0AJ+TweIal1jJSP3t3PF +# 9Uv21gm6xdm7HnNK66WpUUXLDTKaIs/jtagVY1bLOo9oEVeLN4nT2CYWztpMvdCyEDUzgEdDbmrP +# F5nKUPK5hrFqo1Dc5rUI4ZshL3Lpv398aMxv6n2adQvuL++URMEbXXBhxOrT6rCtYzbcR5fkwS9i +# d3Br45CoWOQro02JAepoU0MQKY5+xQ4Bq9Q7tB9BAwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAe +# 4xc+mSvKkrKBHg9/zpkWgZUiOp4ENJCi8H4tea/PCM439v6y/kfjT/okOokFvX8N5aa1OSz2Vsrl +# m8kjIc6hiA7bKzT6lb0EyjUShFFZ5jmGVP4S7/hviDvgB5yEQxOPpumkdRP513YnEGj/o9Pazi5h +# /MwpRxxazoda9r45kqQpyG+XoM4pB+Fd3JzMc4FUGxfVPxJU4jLawnJJiZ3vqiSyaB0YyUL+Er1Q +# 6NnqtR4gEBF0ZVlQmkycFvD4EC2boP943dLqNUvop+4R3SM1QMM6P5u8iTXtHd/VN4MwMyy1wtog +# hYAzODo1Jt59pcqqKJEas0C/lFJEB3frw4ImNx5fNlJYOpx+ijfQs9m39CevDq0= + +agent: + # -- Enable Kubernetes plugin jnlp-agent podTemplate + enabled: true + # -- The name of the pod template to use for providing default values + defaultsProviderTemplate: "" + + # For connecting to the Jenkins controller + # -- Overrides the Kubernetes Jenkins URL + jenkinsUrl: + + # connects to the specified host and port, instead of connecting directly to the Jenkins controller + # -- Overrides the Kubernetes Jenkins tunnel + jenkinsTunnel: + # -- Disables the verification of the controller certificate on remote connection. This flag correspond to the "Disable https certificate check" flag in kubernetes plugin UI + skipTlsVerify: false + # -- Enable the possibility to restrict the usage of this agent to specific folder. This flag correspond to the "Restrict pipeline support to authorized folders" flag in kubernetes plugin UI + usageRestricted: false + # -- The connection timeout in seconds for connections to Kubernetes API. The minimum value is 5 + kubernetesConnectTimeout: 5 + # -- The read timeout in seconds for connections to Kubernetes API. The minimum value is 15 + kubernetesReadTimeout: 15 + # -- The maximum concurrent connections to Kubernetes API + maxRequestsPerHostStr: "32" + # -- Time in minutes after which the Kubernetes cloud plugin will clean up an idle worker that has not already terminated + retentionTimeout: 5 + # -- Seconds to wait for pod to be running + waitForPodSec: 600 + # -- Namespace in which the Kubernetes agents should be launched + namespace: + # -- Custom Pod labels (an object with `label-key: label-value` pairs) + podLabels: {} + # -- Custom registry used to pull the agent jnlp image from + jnlpregistry: + image: + # -- Repository to pull the agent jnlp image from + repository: "jenkins/inbound-agent" + # -- Tag of the image to pull + tag: "3256.v88a_f6e922152-1" + # -- Configure working directory for default agent + workingDir: "/home/jenkins/agent" + nodeUsageMode: "NORMAL" + # -- Append Jenkins labels to the agent + customJenkinsLabels: [] + # -- Name of the secret to be used to pull the image + imagePullSecretName: + componentName: "jenkins-agent" + # -- Enables agent communication via websockets + websocket: false + directConnection: false + # -- Agent privileged container + privileged: false + # -- Configure container user + runAsUser: + # -- Configure container group + runAsGroup: + # -- Enables the agent to use the host network + hostNetworking: false + # -- Resources allocation (Requests and Limits) + resources: + requests: + cpu: "512m" + memory: "512Mi" + # ephemeralStorage: + limits: + cpu: "512m" + memory: "512Mi" + # ephemeralStorage: + livenessProbe: {} +# execArgs: "cat /tmp/healthy" +# failureThreshold: 3 +# initialDelaySeconds: 0 +# periodSeconds: 10 +# successThreshold: 1 +# timeoutSeconds: 1 + + # You may want to change this to true while testing a new image + # -- Always pull agent container image before build + alwaysPullImage: false + # When using Pod Security Admission in the Agents namespace with the restricted Pod Security Standard, + # the jnlp container cannot be scheduled without overriding its container definition with a securityContext. + # This option allows to automatically inject in the jnlp container a securityContext + # that is suitable for the use of the restricted Pod Security Standard. + # -- Set a restricted securityContext on jnlp containers + restrictedPssSecurityContext: false + # Controls how agent pods are retained after the Jenkins build completes + # Possible values: Always, Never, OnFailure + podRetention: "Never" + # Disable if you do not want the Yaml the agent pod template to show up + # in the job Console Output. This can be helpful for either security reasons + # or simply to clean up the output to make it easier to read. + showRawYaml: true + + # You can define the volumes that you want to mount for this container + # Allowed types are: ConfigMap, EmptyDir, EphemeralVolume, HostPath, Nfs, PVC, Secret + # Configure the attributes as they appear in the corresponding Java class for that type + # https://github.com/jenkinsci/kubernetes-plugin/tree/master/src/main/java/org/csanchez/jenkins/plugins/kubernetes/volumes + # -- Additional volumes + volumes: [] + # - type: ConfigMap + # configMapName: myconfigmap + # mountPath: /var/myapp/myconfigmap + # - type: EmptyDir + # mountPath: /var/myapp/myemptydir + # memory: false + # - type: EphemeralVolume + # mountPath: /var/myapp/myephemeralvolume + # accessModes: ReadWriteOnce + # requestsSize: 10Gi + # storageClassName: mystorageclass + # - type: HostPath + # hostPath: /var/lib/containers + # mountPath: /var/myapp/myhostpath + # - type: Nfs + # mountPath: /var/myapp/mynfs + # readOnly: false + # serverAddress: "192.0.2.0" + # serverPath: /var/lib/containers + # - type: PVC + # claimName: mypvc + # mountPath: /var/myapp/mypvc + # readOnly: false + # - type: Secret + # defaultMode: "600" + # mountPath: /var/myapp/mysecret + # secretName: mysecret + # Pod-wide environment, these vars are visible to any container in the agent pod + + # You can define the workspaceVolume that you want to mount for this container + # Allowed types are: DynamicPVC, EmptyDir, EphemeralVolume, HostPath, Nfs, PVC + # Configure the attributes as they appear in the corresponding Java class for that type + # https://github.com/jenkinsci/kubernetes-plugin/tree/master/src/main/java/org/csanchez/jenkins/plugins/kubernetes/volumes/workspace + # -- Workspace volume (defaults to EmptyDir) + workspaceVolume: {} + ## DynamicPVC example + # - type: DynamicPVC + # configMapName: myconfigmap + ## EmptyDir example + # - type: EmptyDir + # memory: false + ## EphemeralVolume example + # - type: EphemeralVolume + # accessModes: ReadWriteOnce + # requestsSize: 10Gi + # storageClassName: mystorageclass + ## HostPath example + # - type: HostPath + # hostPath: /var/lib/containers + ## NFS example + # - type: Nfs + # readOnly: false + # serverAddress: "192.0.2.0" + # serverPath: /var/lib/containers + ## PVC example + # - type: PVC + # claimName: mypvc + # readOnly: false + + # Pod-wide environment, these vars are visible to any container in the agent pod + # -- Environment variables for the agent Pod + envVars: [] + # - name: PATH + # value: /usr/local/bin + # -- Mount a secret as environment variable + secretEnvVars: [] + # - key: PATH + # optional: false # default: false + # secretKey: MY-K8S-PATH + # secretName: my-k8s-secret + + # -- Node labels for pod assignment + nodeSelector: {} + # Key Value selectors. Ex: + # nodeSelector + # jenkins-agent: v1 + + # -- Command to execute when side container starts + command: + # -- Arguments passed to command to execute + args: "${computer.jnlpmac} ${computer.name}" + # -- Side container name + sideContainerName: "jnlp" + + # Doesn't allocate pseudo TTY by default + # -- Allocate pseudo tty to the side container + TTYEnabled: false + # -- Max number of agents to launch + containerCap: 10 + # -- Agent Pod base name + podName: "default" + + # -- Allows the Pod to remain active for reuse until the configured number of minutes has passed since the last step was executed on it + idleMinutes: 0 + + + # The raw yaml of a Pod API Object, for example, this allows usage of toleration for agent pods. + # https://github.com/jenkinsci/kubernetes-plugin#using-yaml-to-define-pod-templates + # https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ + # -- The raw yaml of a Pod API Object to merge into the agent spec + yamlTemplate: "" + # yamlTemplate: |- + # apiVersion: v1 + # kind: Pod + # spec: + # tolerations: + # - key: "key" + # operator: "Equal" + # value: "value" + + # -- Defines how the raw yaml field gets merged with yaml definitions from inherited pod templates. Possible values: "merge" or "override" + yamlMergeStrategy: "override" + # -- Controls whether the defined yaml merge strategy will be inherited if another defined pod template is configured to inherit from the current one + inheritYamlMergeStrategy: false + # -- Timeout in seconds for an agent to be online + connectTimeout: 100 + # -- Annotations to apply to the pod + annotations: {} + + # Containers specified here are added to all agents. Set key empty to remove container from additional agents. + # -- Add additional containers to the agents + additionalContainers: [] + # - sideContainerName: dind + # image: + # repository: docker + # tag: dind + # command: dockerd-entrypoint.sh + # args: "" + # privileged: true + # resources: + # requests: + # cpu: 500m + # memory: 1Gi + # limits: + # cpu: 1 + # memory: 2Gi + + # Useful when configuring agents only with the podTemplates value, since the default podTemplate populated by values mentioned above will be excluded in the rendered template. + # -- Disable the default Jenkins Agent configuration + disableDefaultAgent: false + + # Below is the implementation of custom pod templates for the default configured kubernetes cloud. + # Add a key under podTemplates for each pod template. Each key (prior to | character) is just a label, and can be any value. + # Keys are only used to give the pod template a meaningful name. The only restriction is they may only contain RFC 1123 \ DNS label + # characters: lowercase letters, numbers, and hyphens. Each pod template can contain multiple containers. + # For this pod templates configuration to be loaded, the following values must be set: + # controller.JCasC.defaultConfig: true + # Best reference is https:///configuration-as-code/reference#Cloud-kubernetes. The example below creates a python pod template. + # -- Configures extra pod templates for the default kubernetes cloud + podTemplates: {} + # python: | + # - name: python + # label: jenkins-python + # serviceAccount: jenkins + # containers: + # - name: python + # image: python:3 + # command: "/bin/sh -c" + # args: "cat" + # ttyEnabled: true + # privileged: true + # resourceRequestCpu: "400m" + # resourceRequestMemory: "512Mi" + # resourceLimitCpu: "1" + # resourceLimitMemory: "1024Mi" + +# Inherits all values from `agent` so you only need to specify values which differ +# -- Configure additional +additionalAgents: {} +# maven: +# podName: maven +# customJenkinsLabels: maven +# # An example of overriding the jnlp container +# # sideContainerName: jnlp +# image: +# repository: jenkins/jnlp-agent-maven +# tag: latest +# python: +# podName: python +# customJenkinsLabels: python +# sideContainerName: python +# image: +# repository: python +# tag: "3" +# command: "/bin/sh -c" +# args: "cat" +# TTYEnabled: true + +# Here you can add additional clouds +# They inherit all values from the default cloud (including the main agent), so +# you only need to specify values which differ. If you want to override +# default additionalAgents with the additionalClouds.additionalAgents set +# additionalAgentsOverride to `true`. +additionalClouds: {} +# remote-cloud-1: +# kubernetesURL: https://api.remote-cloud.com +# additionalAgentsOverride: true +# additionalAgents: +# maven-2: +# podName: maven-2 +# customJenkinsLabels: maven +# # An example of overriding the jnlp container +# # sideContainerName: jnlp +# image: +# repository: jenkins/jnlp-agent-maven +# tag: latest +# namespace: my-other-maven-namespace +# remote-cloud-2: +# kubernetesURL: https://api.remote-cloud.com + +persistence: + # -- Enable the use of a Jenkins PVC + enabled: true + + # A manually managed Persistent Volume and Claim + # Requires persistence.enabled: true + # If defined, PVC must be created manually before volume will be bound + # -- Provide the name of a PVC + existingClaim: + + # jenkins data Persistent Volume Storage Class + # If defined, storageClassName: + # If set to "-", storageClassName: "", which disables dynamic provisioning + # If undefined (the default) or set to null, no storageClassName spec is + # set, choosing the default provisioner (gp2 on AWS, standard on GKE, AWS & OpenStack) + # -- Storage class for the PVC + storageClass: + # -- Annotations for the PVC + annotations: {} + # -- Labels for the PVC + labels: {} + # -- The PVC access mode + accessMode: "ReadWriteOnce" + # -- The size of the PVC + size: "8Gi" + + # ref: https://kubernetes.io/docs/concepts/storage/volume-pvc-datasource/ + # -- Existing data source to clone PVC from + dataSource: {} + # name: PVC-NAME + # kind: PersistentVolumeClaim + + # -- SubPath for jenkins-home mount + subPath: + # -- Additional volumes + volumes: [] + # - name: nothing + # emptyDir: {} + + # -- Additional mounts + mounts: [] + # - mountPath: /var/nothing + # name: nothing + # readOnly: true + +networkPolicy: + # -- Enable the creation of NetworkPolicy resources + enabled: false + + # For Kubernetes v1.4, v1.5 and v1.6, use 'extensions/v1beta1' + # For Kubernetes v1.7, use 'networking.k8s.io/v1' + # -- NetworkPolicy ApiVersion + apiVersion: networking.k8s.io/v1 + # You can allow agents to connect from both within the cluster (from within specific/all namespaces) AND/OR from a given external IP range + internalAgents: + # -- Allow internal agents (from the same cluster) to connect to controller. Agent pods will be filtered based on PodLabels + allowed: true + # -- A map of labels (keys/values) that agent pods must have to be able to connect to controller + podLabels: {} + # -- A map of labels (keys/values) that agents namespaces must have to be able to connect to controller + namespaceLabels: {} + # project: myproject + externalAgents: + # -- The IP range from which external agents are allowed to connect to controller, i.e., 172.17.0.0/16 + ipCIDR: + # -- A list of IP sub-ranges to be excluded from the allowlisted IP range + except: [] + # - 172.17.1.0/24 + +## Install Default RBAC roles and bindings +rbac: + # -- Whether RBAC resources are created + create: true + # -- Whether the Jenkins service account should be able to read Kubernetes secrets + readSecrets: false + +serviceAccount: + # -- Configures if a ServiceAccount with this name should be created + create: true + + # The name of the ServiceAccount is autogenerated by default + # -- The name of the ServiceAccount to be used by access-controlled resources + name: + # -- Configures annotations for the ServiceAccount + annotations: {} + # -- Configures extra labels for the ServiceAccount + extraLabels: {} + # -- Controller ServiceAccount image pull secret + imagePullSecretName: + + +serviceAccountAgent: + # -- Configures if an agent ServiceAccount should be created + create: false + + # If not set and create is true, a name is generated using the fullname template + # -- The name of the agent ServiceAccount to be used by access-controlled resources + name: + # -- Configures annotations for the agent ServiceAccount + annotations: {} + # -- Configures extra labels for the agent ServiceAccount + extraLabels: {} + # -- Agent ServiceAccount image pull secret + imagePullSecretName: + +# -- Checks if any deprecated values are used +checkDeprecation: true + +awsSecurityGroupPolicies: + enabled: false + policies: + - name: "" + securityGroupIds: [] + podSelector: {} + +# Here you can configure unit tests values when executing the helm unittest in the CONTRIBUTING.md +helmtest: + # A testing framework for bash + bats: + # Bash Automated Testing System (BATS) + image: + # -- Registry of the image used to test the framework + registry: "docker.io" + # -- Repository of the image used to test the framework + repository: "bats/bats" + # -- Tag of the image to test the framework + tag: "1.11.0" diff --git a/charts/linux-polska/ezd-backend/1.5.1/.helmignore b/charts/linux-polska/ezd-backend/1.5.1/.helmignore new file mode 100644 index 000000000..0e8a0eb36 --- /dev/null +++ b/charts/linux-polska/ezd-backend/1.5.1/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/charts/linux-polska/ezd-backend/1.5.1/Chart.yaml b/charts/linux-polska/ezd-backend/1.5.1/Chart.yaml new file mode 100644 index 000000000..89ba00ea3 --- /dev/null +++ b/charts/linux-polska/ezd-backend/1.5.1/Chart.yaml @@ -0,0 +1,26 @@ +annotations: + catalog.cattle.io/auto-install: ezd-crd=match + catalog.cattle.io/certified: partner + catalog.cattle.io/display-name: LP Backend for EZD RP + catalog.cattle.io/kube-version: '>=1.19-0' + catalog.cattle.io/os: linux + catalog.cattle.io/release-name: ezd-backend +apiVersion: v2 +appVersion: 1.2024-19.7.45 +description: Services necessary to run EZD RP app +home: https://linuxpolska.com +icon: file://assets/icons/ezd-backend.png +keywords: +- config +kubeVersion: '>=1.19-0' +maintainers: +- email: biuro@linuxpolska.com + name: Linux Polska +- email: support@linuxpolska.com + name: Linux Polska + url: https://linuxpolska.com/en/ +name: ezd-backend +sources: +- https://github.com/linuxpolska/ezd-rp.git +type: application +version: 1.5.1 diff --git a/charts/linux-polska/ezd-backend/1.5.1/README.md b/charts/linux-polska/ezd-backend/1.5.1/README.md new file mode 100644 index 000000000..4dbcf1ff5 --- /dev/null +++ b/charts/linux-polska/ezd-backend/1.5.1/README.md @@ -0,0 +1,75 @@ + +# LP backend for EZD RP + +Services necessary to run EZD RP application provided by NASK. +For more detailed information for EZD-BACKEND chart please check [README](https://github.com/linuxpolska/ezd-rp/blob/main/README.md) + +## TL;DR + +```console +helm repo add lp-ezd https://linuxpolska.github.io/ezd-rp +helm upgrade --install --create-namespace ezd-backend -n ezd-rp lp-ezd/ezd-backend +``` + +## Introduction + +This chart bootstraps a set of operatos and CRDs on a [Kubernetes](https://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + +Linux Polska charts can be served by [Rancher Apps & Marketplace](https://ranchermanager.docs.rancher.com/pages-for-subheaders/helm-charts-in-rancher) for deployment and management of Helm Charts in clusters. + +## Prerequisites + +- Kubernetes 1.19+ +- Helm 3.2.0+ +- PV provisioner support in the underlying infrastructure + +## Installing the Chart + +Add repository necessary for installation: + +```console +helm repo add lp-ezd https://github.com/linuxpolska/ezd-rp +helm repo update +``` + +To install the chart with the release name `my-release`: + +```console +helm upgrade --install --create-namespace ezd-backend -n ezd-rp le-ezd/ezd-backend +``` + +The command deploys postgresql, rabbitmq, redis on the Kubernetes cluster in the default configuration. For more detailed information regarding parameters please check our [README](https://github.com/linuxpolska/ezd-rp/blob/main/README.md). + +> **Tip**: List all releases using `helm list` + +## Uninstalling the Chart + +To uninstall/delete the `ezd-backend` deployment: + +```console +helm -n default uninstall ezd-backed +``` + +> **Note**: Deleting the helm chart will delete all data as well. Please be cautious before doing it. + +> **Note**: Remove helm chart before remove CRDs for LP Backend. + +For more detailed information regarding installation of ezd-backend please refer to [INSTALLATION](https://github.com/linuxpolska/ezd-rp/blob/main/INSTALLATION.md) + +## Compability with NASK ezdrp version + +Chart ezd-crd was tested with chart version up to 19.7.45 (application version up to 1.2024-19.7.45). + +## Configuration and parameters + +See [Customizing the Chart Before Installing](https://helm.sh/docs/intro/using_helm/#customizing-the-chart-before-installing). To see all configurable options with detailed comments: + +```console +helm search repo lp-ezd +helm show values lp-ezd/ezd-backend +``` + +## Components version +- redis: 7.0.13-alpine-3.15-r1 +- rabbitmq: 3.13.16-management-rabbitmq-3.13-r1 +- postgresql: 16.3-postgres-16.3-bullseye-r1 diff --git a/charts/linux-polska/ezd-backend/1.5.1/app-readme.md b/charts/linux-polska/ezd-backend/1.5.1/app-readme.md new file mode 100644 index 000000000..333ced4ed --- /dev/null +++ b/charts/linux-polska/ezd-backend/1.5.1/app-readme.md @@ -0,0 +1,17 @@ +## LP Backend for EZD RP + + +This chart is based off of the some upstream charts postgresql, rabbitmq, redis. The chart deploys set of operators and CRDs, which necessary to configure postgresql, rabbitmq, redis. + +For more information on how to use the feature, refer to our [docs](https://github.com/linuxpolska/ezd-rp). + + +## Prerequisites + +- Kubernetes 1.19+ +- Helm 3.2.0+ +- PV provisioner support in the underlying infrastructure + + + +For more information on how to configure the Helm chart, refer to the Helm Chart README. diff --git a/charts/linux-polska/ezd-backend/1.5.1/questions.yaml b/charts/linux-polska/ezd-backend/1.5.1/questions.yaml new file mode 100644 index 000000000..922ca1bfd --- /dev/null +++ b/charts/linux-polska/ezd-backend/1.5.1/questions.yaml @@ -0,0 +1,279 @@ +categories: +- database +questions: +- variable: global.rabbitmq.deploy + default: "true" + label: Deploy RabbitMQ + type: boolean + group: "Components" + show_subquestion_if: true + subquestions: + - variable: rabbitmqConfig.auth.username + label: Username + description: "RabbitMQ Username" + group: "RabbitMQ Settings" + type: string + min: 6 + required: true + - variable: rabbitmqConfig.auth.password + label: Password + description: "RabbitMQ Password" + group: "RabbitMQ Settings" + type: password + min: 8 + required: true + - variable: rabbitmqConfig.customConfig.replicas + label: Replicas + description: "Amount of replicas rabbitmq. Min 3 replicas for ha" + group: "RabbitMQ Settings" + type: int + default: 1 + - variable: rabbitmqConfig.customConfig.persistence.storageClassName + label: Storage Class for database data + description: "Select storage class for database data" + group: "RabbitMQ Settings" + type: storageclass + - variable: rabbitmqConfig.customConfig.persistence.storage + label: Database size + description: "Size database data" + group: "RabbitMQ Settings" + type: string + default: "2Gi" + - variable: global.rabbitmq.custom.consumption + default: "false" + label: Modify resource consumption + group: "RabbitMQ Settings" + type: boolean + show_subquestion_if: true + subquestions: + - variable: rabbitmqConfig.customConfig.resources.limits.cpu + label: Milicore limit for rabbitmq instance + description: "1000 milicores = 1vCPU" + type: string + default: "2000m" + - variable: rabbitmqConfig.customConfig.resources.requests.cpu + label: Milicore request for rabbitmq instance + description: "1000 milicores = 1vCPU, value must be <= milicore limit" + type: string + default: "2000m" + - variable: rabbitmqConfig.customConfig.resources.limits.memory + label: Memory limit for rabbitmq instance + description: "Memory limit" + type: string + default: "2Gi" + - variable: rabbitmqConfig.customConfig.resources.requests.memory + label: Memory request for rabbitmq instance + description: "Memory request, value must be <= memory limit" + type: string + default: "2Gi" + - variable: rabbitmqConfig.ingress.enabled + default: "false" + label: Enable web console for RabbitMQ + group: "RabbitMQ Settings" + type: boolean + show_subquestion_if: true + subquestions: + - variable: rabbitmqConfig.ingress.hosts.host + label: URL + description: "Configure url for rabbitmq web-ui" + type: string + default: "rabbitmq.my.domain.internal" + +- variable: global.postgresql.deploy + default: "true" + label: Deploy Postgresql + type: boolean + group: "Components" + show_subquestion_if: true + subquestions: + - variable: postgresqlConfig.auth.admPassword + label: SuperUser Password + description: "Password for SuperUser role" + group: "Postgresql Settings" + type: password + min: 8 + required: true + - variable: postgresqlConfig.auth.appPassword + label: Application Password + description: "Password for application role" + group: "Postgresql Settings" + type: password + min: 8 + required: true + - variable: postgresqlConfig.customConfig.instances + label: Replicas + description: "Amount of replicas postgresql. Min 3 replicas for ha" + group: "Postgresql Settings" + type: int + default: 1 + - variable: postgresqlConfig.customConfig.storage.storageClass + label: Storage Class for database data + description: "Select storage class for database data" + group: "Postgresql Settings" + type: storageclass + - variable: postgresqlConfig.customConfig.storage.size + label: Database size + description: "Size database data" + group: "Postgresql Settings" + type: string + default: "2Gi" + - variable: postgresqlConfig.customConfig.walStorage.storageClass + label: Storage Class for database WAL + description: "Select storage class for database WAL" + group: "Postgresql Settings" + type: storageclass + - variable: postgresqlConfig.customConfig.walStorage.size + label: WAL Size + description: "Size database WAL" + group: "Postgresql Settings" + type: string + default: "2Gi" + - variable: global.postgresql.custom.consumption + default: "false" + label: Modify resource consumption + group: "Postgresql Settings" + type: boolean + show_subquestion_if: true + subquestions: + - variable: postgresqlConfig.customConfig.postgresql.parameters.resources.limits.cpu + label: Milicore limit for postgresql instance + description: "1000 milicores = 1vCPU" + type: string + default: "2000m" + - variable: postgresqlConfig.customConfig.postgresql.parameters.resources.requests.cpu + label: Milicore request for postgresql instance + description: "1000 milicores = 1vCPU, value must be <= milicore limit" + type: string + default: "2000m" + - variable: postgresqlConfig.customConfig.postgresql.parameters.resources.limits.memory + label: Memory limit for postgresql instance + description: "Memory limit" + type: string + default: "2Gi" + - variable: postgresqlConfig.customConfig.postgresql.parameters.resources.requests.memory + label: Memory request for postgresql instance + description: "Memory request, value must be <= memory limit" + type: string + default: "2Gi" +- variable: global.redis.deploy + default: "true" + label: Deploy Redis + type: boolean + group: "Components" + show_subquestion_if: true + subquestions: + - variable: redisConfig.auth.password + label: Password + description: "Redis Password" + group: "Redis Settings" + type: password + min: 8 + required: true +# - variable: redisConfig.customConfig.setit +# label: Replicas +# description: "Amount of replicas redis. Min 3 replicas for ha" +# group: "Redis Settings" +# type: int +# default: 1 + - variable: redisConfig.customConfig.storage.volumeClaimTemplate.spec.storageClassName + label: Storage Class for database data + description: "Select storage class for database data" + group: "Redis Settings" + type: storageclass + - variable: redisConfig.customConfig.storage.volumeClaimTemplate.spec.resources.requests.storage + label: Database size + description: "Size database data" + group: "Redis Settings" + type: string + default: "2Gi" + - variable: global.redis.custom.consumption + default: "false" + label: Modify resource consumption + group: "Redis Settings" + type: boolean + show_subquestion_if: true + subquestions: + - variable: redisConfig.customConfig.kubernetesConfig.resources.limits.cpu + label: Milicore limit for redis instance + description: "1000 milicores = 1vCPU" + type: string + default: "128m" + - variable: redisConfig.customConfig.kubernetesConfig.resources.requests.cpu + label: Milicore request for redis instance + description: "1000 milicores = 1vCPU, value must be <= milicore limit" + type: string + default: "128m" + - variable: redisConfig.customConfig.kubernetesConfig.resources.limits.memory + label: Memory limit for redis instance + description: "Memory limit" + type: string + default: "128Mi" + - variable: redisConfig.customConfig.kubernetesConfig.resources.requests.memory + label: Memory request for redis instance + description: "Memory request, value must be <= memory limit" + type: string + default: "128Mi" + +- variable: global.privateRegistry.createSecret + default: "false" + description: "Check if you want authenticate to image registry " + type: boolean + group: "Private Registry Settings" + label: Modify Secret for Private Registry Settings + show_subquestion_if: true + subquestions: + - variable: global.imageCredentials.registry + label: Private registry URL + description: "URL of private registry. For instance: docker.io, ghcr.io" + group: "Private Registry Settings" + type: string + default: "https://index.docker.io/v1/" + - variable: global.imageCredentials.username + label: Private registry user + description: "User used to authenticate to private registry." + type: string + default: "" + - variable: global.imageCredentials.password + label: Private registry password + description: "Password used to authenticate to private registry." + type: password + default: "" + - variable: global.imageCredentials.email + label: Private registry email + description: "Email used to authenticate to private registry" + type: string + default: "" + + +- variable: global.defaultImage + default: false + description: "Check if you have images in a private registry" + label: "Change default image source" + type: boolean + show_subquestion_if: true + group: "Private Registry Settings" + subquestions: + - variable: postgresqlConfig.customConfig.imageName + label: Postgresql Image Name + description: "Postgresql image name." + type: string + default: "quay.io/linuxpolska/ezd-backend_postgresql:16.3-postgres-16.3-bullseye-r1" + show_if: "global.postgresql.deploy=true" + - variable: rabbitmqConfig.customConfig.image + label: RabbitMQ Image Name + description: "RabbitMQ image name." + type: string + default: "quay.io/linuxpolska/ezd-backend_rabbitmq:3.13.16-management-rabbitmq-3.13-r1" + show_if: "global.rabbitmq.deploy=true" + - variable: redisConfig.customConfig.kubernetesConfig.image + label: Redis Image Name + description: "Redis Image Name." + type: string + default: "quay.io/linuxpolska/ezd-backend_redis:7.0.13-alpine-3.15-r1" + show_if: "global.redis.deploy=true" + - variable: redisConfig.customConfig.kubernetesConfig.redisExporter.image + label: Redis Exporter Image Name + description: "Redis Exporter Image Name." + type: string + default: "quay.io/linuxpolska/ezd-backend_redis-exporter:1.44.0" + show_if: "global.redis.deploy=true" diff --git a/charts/linux-polska/ezd-backend/1.5.1/templates/NOTES.txt b/charts/linux-polska/ezd-backend/1.5.1/templates/NOTES.txt new file mode 100644 index 000000000..c996d1e4d --- /dev/null +++ b/charts/linux-polska/ezd-backend/1.5.1/templates/NOTES.txt @@ -0,0 +1,41 @@ + +Congratulation!!! + +Copy it and configure EZDRP app. + +{{- if ( .Values.global.postgresql.deploy ) }} + +Database configuration: + Select database type: POSTGRESQL + External DB connectionstring: Host={{ include "ezd-backend.postgresqlConfig.fullname" . }}-rw;Port=5432;Database=ezdrp;Username={{ default ( "postgres" ) }};Password='{{ include "ezd-backend.password" .Values.postgresqlConfig.auth.admPassword }}' + Select ARCHIWUM database type: POSTGRESQL + External DB connectionstring: Host={{ include "ezd-backend.postgresqlConfig.fullname" . }}-rw;Port=5432;Database=archiwum;Username={{ default ( "postgres" ) }};Password='{{ include "ezd-backend.password" .Values.postgresqlConfig.auth.admPassword }}' + Select KUIP database type: POSTGRESQL + External DB connectionstring: Host={{ include "ezd-backend.postgresqlConfig.fullname" . }}-rw;Port=5432;Database=ezdrp;Username={{ default ( "postgres" ) }};Password='{{ include "ezd-backend.password" .Values.postgresqlConfig.auth.admPassword }}' + Select EZDRP_ODCZYT database type: POSTGRESQL + External DB connectionstring: Host={{ include "ezd-backend.postgresqlConfig.fullname" . }}-rw;Port=5432;Database=ezdrp_odczyt;Username={{ default ( "postgres" ) }};Password='{{ include "ezd-backend.password" .Values.postgresqlConfig.auth.admPassword }}' + + +{{- end }} +{{- if ( .Values.global.redis.deploy ) }} + +Redis Database Configuration: + External RedisDB hostname: {{ include "ezd-backend.redisConfig.fullname" . }} + External RedisDB port: {{ "6379" }} + External RedisDB password: {{ include "ezd-backend.password" .Values.redisConfig.auth.password }} + +Redis-append Database Configuration: + External hostname for RedisDB - append mode: {{ list (include "ezd-backend.redisConfig.fullname" .) "append" | join "-" }} + External port for RedisDB - append mode: {{ "6379" }} + External RedisDB - append mode password: {{ include "ezd-backend.password" .Values.redisConfig.auth.password }} + +{{- end }} +{{- if ( .Values.global.rabbitmq.deploy ) }} + +Rabbit Database Configuration: + Hostname for external RabbitMQ: {{ include "ezd-backend.rabbitmqConfig.fullname" . }} + Port for external RabbitMQ: {{ "5672" }} + Username for external RabbitMQ: {{ include "ezd-backend.username" .Values.rabbitmqConfig.auth.username }} + Password for external RabbitMQ: {{ include "ezd-backend.password" .Values.rabbitmqConfig.auth.password }} + +{{- end }} diff --git a/charts/linux-polska/ezd-backend/1.5.1/templates/_helpers.tpl b/charts/linux-polska/ezd-backend/1.5.1/templates/_helpers.tpl new file mode 100644 index 000000000..d520536fd --- /dev/null +++ b/charts/linux-polska/ezd-backend/1.5.1/templates/_helpers.tpl @@ -0,0 +1,163 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "ezd-backend.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "ezd-backend.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "ezd-backend.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "ezd-backend.labels" -}} +helm.sh/chart: {{ include "ezd-backend.chart" . }} +{{ include "ezd-backend.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "ezd-backend.selectorLabels" -}} +app.kubernetes.io/name: {{ include "ezd-backend.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "ezd-backend.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "ezd-backend.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + + +{{- define "ezd-backend.imagePullSecret" }} +{{- with .Values.global.imageCredentials }} +{{- printf "{\"auths\":{\"%s\":{\"username\":\"%s\",\"password\":\"%s\",\"email\":\"%s\",\"auth\":\"%s\"}}}" .registry .username .password .email (printf "%s:%s" .username .password | b64enc) | b64enc }} +{{- end }} +{{- end }} + +{{/* +Settings for username and password. +*/}} + +{{- define "ezd-backend.username" -}} +{{- $reqInfo := . | required "Username is required." -}} +{{- $reqInfo -}} +{{- end -}} + +{{- define "ezd-backend.password" -}} +{{- $reqInfo := . | required "Password is required." -}} +{{- $reqInfo -}} +{{- end -}} + + + + + +{{/* +Expand the name of the chart. +*/}} +{{- define "ezd-backend.rabbitmqConfig.name" -}} +{{- default .Chart.Name .Values.rabbitmqConfig.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "ezd-backend.rabbitmqConfig.fullname" -}} +{{- if .Values.rabbitmqConfig.fullnameOverride }} +{{- .Values.rabbitmqConfig.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.rabbitmqConfig.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + + +{{/* +Expand the name of the chart. +*/}} +{{- define "ezd-backend.postgresqlConfig.name" -}} +{{- default .Chart.Name .Values.postgresqlConfig.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "ezd-backend.postgresqlConfig.fullname" -}} +{{- if .Values.postgresqlConfig.fullnameOverride }} +{{- .Values.postgresqlConfig.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.postgresqlConfig.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Expand the name of the chart. +*/}} +{{- define "ezd-backend.redisConfig.name" -}} +{{- default .Chart.Name .Values.redisConfig.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "ezd-backend.redisConfig.fullname" -}} +{{- if .Values.redisConfig.fullnameOverride }} +{{- .Values.redisConfig.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.redisConfig.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/linux-polska/ezd-backend/1.5.1/templates/ezdrp-app/rabbitmq-secret.yaml b/charts/linux-polska/ezd-backend/1.5.1/templates/ezdrp-app/rabbitmq-secret.yaml new file mode 100644 index 000000000..7b38813ca --- /dev/null +++ b/charts/linux-polska/ezd-backend/1.5.1/templates/ezdrp-app/rabbitmq-secret.yaml @@ -0,0 +1,17 @@ +{{ if ( .Values.global.rabbitmq.deploy ) }} +apiVersion: v1 +kind: Secret +metadata: + name: rabbit-config + labels: + {{- include "ezd-backend.labels" . | nindent 4 }} +type: Opaque +data: + EZD_INTERNAL_RABBIT_USER: {{ include "ezd-backend.username" .Values.rabbitmqConfig.auth.username | b64enc }} + EZD_INTERNAL_RABBIT_PASSWORD: {{ include "ezd-backend.password" .Values.rabbitmqConfig.auth.password | b64enc }} + EZD_INTERNAL_RABBIT_HOST: {{ include "ezd-backend.rabbitmqConfig.fullname" . | b64enc }} + EZD_INTERNAL_RABBIT_PORT: {{ default ( "5672" ) | b64enc }} + +{{ end }} + + diff --git a/charts/linux-polska/ezd-backend/1.5.1/templates/ezdrp-app/redis-append-secret.yaml b/charts/linux-polska/ezd-backend/1.5.1/templates/ezdrp-app/redis-append-secret.yaml new file mode 100644 index 000000000..4044eb16f --- /dev/null +++ b/charts/linux-polska/ezd-backend/1.5.1/templates/ezdrp-app/redis-append-secret.yaml @@ -0,0 +1,16 @@ +{{ if ( .Values.global.redis.deploy ) }} +apiVersion: v1 +kind: Secret +metadata: + name: redis-append-config + labels: + {{- include "ezd-backend.labels" . | nindent 4 }} +type: Opaque +data: + EZD_REDIS_APPEND_HOST: {{ list (include "ezd-backend.redisConfig.fullname" .) "append" | join "-" | b64enc }} + EZD_REDIS_APPEND_PASSWORD: {{ include "ezd-backend.password" .Values.redisConfig.auth.password | b64enc }} + EZD_REDIS_APPEND_PORT: {{ default ( "6379" ) | b64enc }} + EZD_REDIS_APPEND_SERVICENAME: "" + +{{ end }} + diff --git a/charts/linux-polska/ezd-backend/1.5.1/templates/ezdrp-app/redis-secret.yaml b/charts/linux-polska/ezd-backend/1.5.1/templates/ezdrp-app/redis-secret.yaml new file mode 100644 index 000000000..490b5a824 --- /dev/null +++ b/charts/linux-polska/ezd-backend/1.5.1/templates/ezdrp-app/redis-secret.yaml @@ -0,0 +1,16 @@ +{{ if ( .Values.global.redis.deploy ) }} +apiVersion: v1 +kind: Secret +metadata: + name: redis-config + labels: + {{- include "ezd-backend.labels" . | nindent 4 }} +type: Opaque +data: + EZD_REDIS_HOST: {{ include "ezd-backend.redisConfig.fullname" . | b64enc }} + EZD_REDIS_PASSWORD: {{ include "ezd-backend.password" .Values.redisConfig.auth.password | b64enc }} + EZD_REDIS_PORT: {{ default ( "6379" ) | b64enc }} + EZD_REDIS_SERVICENAME: "" + +{{ end }} + diff --git a/charts/linux-polska/ezd-backend/1.5.1/templates/ezdrp-app/relationaldb-secret.yaml b/charts/linux-polska/ezd-backend/1.5.1/templates/ezdrp-app/relationaldb-secret.yaml new file mode 100644 index 000000000..73dfd308f --- /dev/null +++ b/charts/linux-polska/ezd-backend/1.5.1/templates/ezdrp-app/relationaldb-secret.yaml @@ -0,0 +1,14 @@ +{{- if ( .Values.global.postgresql.deploy ) }} +apiVersion: v1 +kind: Secret +metadata: + name: relationaldb-config + labels: + {{- include "ezd-backend.labels" . | nindent 4 }} +type: Opaque +data: + EZD_INTERNAL_POSTGRES_USER: {{ default ( "postgres" ) | b64enc }} + EZD_INTERNAL_POSTGRES_PASSWORD: {{ include "ezd-backend.password" .Values.postgresqlConfig.auth.admPassword | b64enc }} + EZD_INTERNAL_POSTGRES_HOST: {{ list (include "ezd-backend.postgresqlConfig.fullname" .) "rw" | join "-" | b64enc }} + EZD_INTERNAL_POSTGRES_PORT: {{ default ( "5432" ) | b64enc }} +{{- end }} diff --git a/charts/linux-polska/ezd-backend/1.5.1/templates/global-secret.yaml b/charts/linux-polska/ezd-backend/1.5.1/templates/global-secret.yaml new file mode 100644 index 000000000..e56ffab57 --- /dev/null +++ b/charts/linux-polska/ezd-backend/1.5.1/templates/global-secret.yaml @@ -0,0 +1,13 @@ +{{ if .Values.global.imageCredentials }} +apiVersion: v1 +kind: Secret +metadata: + labels: + {{- include "ezd-backend.labels" . | nindent 4 }} + name: {{ .Values.global.imageCredentials.name }} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ include "ezd-backend.imagePullSecret" . }} +{{- end }} + + diff --git a/charts/linux-polska/ezd-backend/1.5.1/templates/postgresql-cluster.yaml b/charts/linux-polska/ezd-backend/1.5.1/templates/postgresql-cluster.yaml new file mode 100644 index 000000000..19cb96c1a --- /dev/null +++ b/charts/linux-polska/ezd-backend/1.5.1/templates/postgresql-cluster.yaml @@ -0,0 +1,42 @@ +{{- if .Values.global.postgresql.deploy }} +apiVersion: postgresql.cnpg.io/v1 +kind: Cluster +metadata: + name: {{ include "ezd-backend.postgresqlConfig.fullname" . }} + labels: + {{- include "ezd-backend.labels" . | nindent 4 }} +spec: + imagePullSecrets: + - name: {{ .Values.global.imageCredentials.name }} + superuserSecret: + name: credentials-{{ include "ezd-backend.postgresqlConfig.fullname" . }}-adm + bootstrap: + initdb: + database: {{ default ( "ezdrp" ) }} + owner: {{ default ( "ezdrp" ) }} + dataChecksums: true + localeCollate: "en_US.utf8" + localeCType: "en_US.utf8" + secret: + name: credentials-{{ include "ezd-backend.postgresqlConfig.fullname" . }}-app +{{- if (eq "custom" .Values.global.deployment.type) }} +{{- with .Values.postgresqlConfig.customConfig }} + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} + + +{{- end }} + +{{- /* + bootstrap: + initdb: + database: ezdrp + dataChecksums: true + localeCollate: "en_US.utf8" + localeCType: "en_US.utf8" + secret: + name: credentials-{{ include "ezd-backend.postgresqlConfig.fullname" . }}-app + +*/}} + diff --git a/charts/linux-polska/ezd-backend/1.5.1/templates/postgresql-secret.yaml b/charts/linux-polska/ezd-backend/1.5.1/templates/postgresql-secret.yaml new file mode 100644 index 000000000..1cc5ae67c --- /dev/null +++ b/charts/linux-polska/ezd-backend/1.5.1/templates/postgresql-secret.yaml @@ -0,0 +1,25 @@ +{{- if ( .Values.global.postgresql.deploy ) }} +--- +apiVersion: v1 +kind: Secret +metadata: + name: credentials-{{ include "ezd-backend.postgresqlConfig.fullname" . }}-adm + labels: + {{- include "ezd-backend.labels" . | nindent 4 }} +type: kubernetes.io/basic-auth +data: + username: {{ default ( "postgres" ) | b64enc }} + password: {{ include "ezd-backend.password" .Values.postgresqlConfig.auth.admPassword | b64enc }} +--- +apiVersion: v1 +kind: Secret +metadata: + name: credentials-{{ include "ezd-backend.postgresqlConfig.fullname" . }}-app + labels: + {{- include "ezd-backend.labels" . | nindent 4 }} +type: kubernetes.io/basic-auth +data: + username: {{ default ( "ezdrp" ) | b64enc }} + password: {{ include "ezd-backend.password" .Values.postgresqlConfig.auth.appPassword | b64enc }} + +{{- end }} diff --git a/charts/linux-polska/ezd-backend/1.5.1/templates/rabbitmq-ingress.yaml b/charts/linux-polska/ezd-backend/1.5.1/templates/rabbitmq-ingress.yaml new file mode 100644 index 000000000..8dda0b77a --- /dev/null +++ b/charts/linux-polska/ezd-backend/1.5.1/templates/rabbitmq-ingress.yaml @@ -0,0 +1,67 @@ +{{- if .Values.global.rabbitmq.deploy -}} +{{- if .Values.rabbitmqConfig.ingress.enabled -}} +{{- $fullName := include "ezd-backend.rabbitmqConfig.fullname" . -}} +{{- $svcPort := 15672 -}} +{{- if and .Values.rabbitmqConfig.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }} + {{- if not (hasKey .Values.rabbitmqConfig.ingress.annotations "kubernetes.io/ingress.class") }} + {{- $_ := set .Values.rabbitmqConfig.ingress.annotations "kubernetes.io/ingress.class" .Values.rabbitmqConfig.ingress.className}} + {{- end }} +{{- end }} +{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1 +{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1beta1 +{{- else -}} +apiVersion: extensions/v1beta1 +{{- end }} +kind: Ingress +metadata: + name: {{ $fullName }} + labels: + {{- include "ezd-backend.labels" . | nindent 4 }} + {{- with .Values.rabbitmqConfig.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if and .Values.rabbitmqConfig.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }} + ingressClassName: {{ .Values.rabbitmqConfig.ingress.className }} + {{- end }} + {{- if .Values.rabbitmqConfig.ingress.tls }} + tls: + {{- range .Values.rabbitmqConfig.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} + rules: + {{- with .Values.rabbitmqConfig.ingress.hosts }} +{{/* + {{- range .Values.rabbitmqConfig.ingress.hosts }} + - host: {{ .host | quote }} +*/}} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ .path }} + {{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }} + pathType: {{ .pathType }} + {{- end }} + backend: + {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }} + service: + name: {{ $fullName }} + port: + number: {{ $svcPort }} + {{- else }} + serviceName: {{ $fullName }} + servicePort: {{ $svcPort }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/linux-polska/ezd-backend/1.5.1/templates/rabbitmq-rabbitmqcluster.yaml b/charts/linux-polska/ezd-backend/1.5.1/templates/rabbitmq-rabbitmqcluster.yaml new file mode 100644 index 000000000..560412486 --- /dev/null +++ b/charts/linux-polska/ezd-backend/1.5.1/templates/rabbitmq-rabbitmqcluster.yaml @@ -0,0 +1,27 @@ +{{- if .Values.global.rabbitmq.deploy }} +apiVersion: rabbitmq.com/v1beta1 +kind: RabbitmqCluster +metadata: + name: {{ include "ezd-backend.rabbitmqConfig.fullname" . }} + labels: + {{- include "ezd-backend.labels" . | nindent 4 }} +spec: + imagePullSecrets: + - name: {{ .Values.global.imageCredentials.name }} + secretBackend: + externalSecret: + name: "credentials-{{ include "ezd-backend.rabbitmqConfig.fullname" . }}" +{{- if (eq "custom" .Values.global.deployment.type) }} +{{- with .Values.rabbitmqConfig.customConfig }} + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} + + +{{- end }} + +{{- /* + +*/}} + + diff --git a/charts/linux-polska/ezd-backend/1.5.1/templates/rabbitmq-secret.yaml b/charts/linux-polska/ezd-backend/1.5.1/templates/rabbitmq-secret.yaml new file mode 100644 index 000000000..635f6280b --- /dev/null +++ b/charts/linux-polska/ezd-backend/1.5.1/templates/rabbitmq-secret.yaml @@ -0,0 +1,19 @@ +{{ if ( .Values.global.rabbitmq.deploy ) }} +apiVersion: v1 +kind: Secret +metadata: + name: "credentials-{{ include "ezd-backend.rabbitmqConfig.fullname" . }}" + labels: + {{- include "ezd-backend.labels" . | nindent 4 }} +type: Opaque +stringData: + default_user.conf: | + default_user = {{ include "ezd-backend.username" .Values.rabbitmqConfig.auth.username }} + default_pass = {{ include "ezd-backend.password" .Values.rabbitmqConfig.auth.password }} + username: {{ include "ezd-backend.username" .Values.rabbitmqConfig.auth.username }} + password: {{ include "ezd-backend.password" .Values.rabbitmqConfig.auth.password }} + port: {{ default ( "5672" ) | quote }} + provider: {{ default ( "rabbitmq" ) }} + type: {{ default ( "rabbitmq" ) }} + host: {{ printf "%s.%s.%s" ( include "ezd-backend.rabbitmqConfig.fullname" . ) .Release.Namespace "svc" }} +{{ end }} diff --git a/charts/linux-polska/ezd-backend/1.5.1/templates/redis-redis.yaml b/charts/linux-polska/ezd-backend/1.5.1/templates/redis-redis.yaml new file mode 100644 index 000000000..54ecf7028 --- /dev/null +++ b/charts/linux-polska/ezd-backend/1.5.1/templates/redis-redis.yaml @@ -0,0 +1,47 @@ +{{- if .Values.global.redis.deploy }} +apiVersion: redis.redis.opstreelabs.in/v1beta1 +kind: Redis +metadata: + name: {{ include "ezd-backend.redisConfig.fullname" . }} + labels: + {{- include "ezd-backend.labels" . | nindent 4 }} +spec: + kubernetesConfig: + imagePullSecrets: + - name: {{ .Values.global.imageCredentials.name }} + redisSecret: + name: credentials-{{ include "ezd-backend.redisConfig.fullname" . }} + key: password +{{- if (eq "custom" .Values.global.deployment.type) }} +{{- with .Values.redisConfig.customConfig }} + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} +--- +apiVersion: redis.redis.opstreelabs.in/v1beta1 +kind: Redis +metadata: + name: {{ include "ezd-backend.redisConfig.fullname" . }}-append + labels: + {{- include "ezd-backend.labels" . | nindent 4 }} +spec: + kubernetesConfig: + imagePullSecrets: + - name: {{ .Values.global.imageCredentials.name }} + redisSecret: + name: credentials-{{ include "ezd-backend.redisConfig.fullname" . }} + key: password +{{- if (eq "custom" .Values.global.deployment.type) }} +{{- with .Values.redisConfig.customConfig }} + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} + + + +{{- end }} + +{{- /* + +*/}} + diff --git a/charts/linux-polska/ezd-backend/1.5.1/templates/redis-secret.yaml b/charts/linux-polska/ezd-backend/1.5.1/templates/redis-secret.yaml new file mode 100644 index 000000000..39beaf1c2 --- /dev/null +++ b/charts/linux-polska/ezd-backend/1.5.1/templates/redis-secret.yaml @@ -0,0 +1,13 @@ +{{- if ( .Values.global.redis.deploy ) }} +--- +apiVersion: v1 +kind: Secret +metadata: + name: credentials-{{ include "ezd-backend.redisConfig.fullname" . }} + labels: + {{- include "ezd-backend.labels" . | nindent 4 }} +type: kubernetes.io/basic-auth +data: + password: {{ include "ezd-backend.password" .Values.redisConfig.auth.password | b64enc }} +{{- end }} + diff --git a/charts/linux-polska/ezd-backend/1.5.1/values.yaml b/charts/linux-polska/ezd-backend/1.5.1/values.yaml new file mode 100644 index 000000000..899675d2f --- /dev/null +++ b/charts/linux-polska/ezd-backend/1.5.1/values.yaml @@ -0,0 +1,205 @@ +# Default values for ezd-backend. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + + +global: + imageCredentials: + name: credentials-registry-app + registry: "https://index.docker.io/v1/" + username: "" + password: "" + email: "" + deployment: + platform: 'kubernetes' + type: 'custom' + rabbitmq: + deploy: true + custom: + consumpion: false + postgresql: + deploy: true + custom: + consumpion: false + redis: + deploy: true + custom: + consumpion: false + +rabbitmqConfig: + fullnameOverride: "lp-backend-rabbitmq" + nameOverride: "" + auth: + username: "" + password: "" + ingress: + enabled: false + className: "" + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + hosts: + host: "" + paths: + - path: / + pathType: ImplementationSpecific + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + customConfig: + image: quay.io/linuxpolska/ezd-backend_rabbitmq:3.13.16-management-rabbitmq-3.13-r1 + replicas: 2 + rabbitmq: + additionalConfig: | + cluster_partition_handling = pause_minority + vm_memory_high_watermark_paging_ratio = 0.99 + disk_free_limit.relative = 1.0 + collect_statistics_interval = 10000 + persistence: + storage: "10Gi" + resources: + requests: + cpu: 1000m + memory: 2Gi + limits: + cpu: 2000m + memory: 2Gi + override: + statefulSet: + spec: + template: + spec: + containers: + - name: rabbitmq + imagePullPolicy: Always + initContainers: + - name: setup-container + imagePullPolicy: Always + +postgresqlConfig: + fullnameOverride: "lp-backend-postgresql" + nameOverride: "" + auth: + admPassword: "" + appPassword: "" + customConfig: + instances: 3 + minSyncReplicas: 1 + maxSyncReplicas: 2 + replicationSlots: + highAvailability: + enabled: true + env: + - name: TZ + value: Europe/Warsaw + primaryUpdateStrategy: unsupervised + storage: + size: 2Gi + resizeInUseVolumes: True + walStorage: + size: 2Gi + resizeInUseVolumes: True + imageName: quay.io/linuxpolska/ezd-backend_postgresql:16.3-postgres-16.3-bullseye-r1 + postgresql: + parameters: + pg_stat_statements.max: "10000" + pg_stat_statements.track: all + pgaudit.log: "all, -misc" + pgaudit.log_catalog: "off" + pgaudit.log_parameter: "on" + pgaudit.log_relation: "on" + + max_connections: "100" + superuser_reserved_connections: "3" + + shared_buffers: "512 MB" + work_mem: "32 MB" + maintenance_work_mem: "320 MB" + huge_pages: "off" + effective_cache_size: "1 GB" + effective_io_concurrency: "100" # concurrent IO only really activated if OS supports posix_fadvise function + random_page_cost: "1.25" # speed of random disk access relative to sequential access (1.0) + + # Monitoring + track_io_timing: "on" # measure exact block IO times + track_functions: "pl" # track execution times of pl-language procedures if any + + # Checkpointing: + checkpoint_timeout : "15 min " + checkpoint_completion_target: "0.9" + max_wal_size: "1024 MB" + min_wal_size: "512 MB" + + # WAL writing + wal_compression: "on" + wal_buffers: "-1" # auto-tuned by Postgres till maximum of segment size (16MB by default) + wal_writer_delay: "200ms" + wal_writer_flush_after: "1MB" + wal_keep_size: "3650 MB" + + + # Background writer + bgwriter_delay: "200ms" + bgwriter_lru_maxpages: "100" + bgwriter_lru_multiplier: "2.0" + bgwriter_flush_after: "0" + + # Parallel queries: + max_worker_processes: "2" + max_parallel_workers_per_gather: "1" + max_parallel_maintenance_workers: "1" + max_parallel_workers: "2" + parallel_leader_participation: "on" + + # Advanced features + enable_partitionwise_join: "on" + enable_partitionwise_aggregate: "on" + jit: "on" + max_slot_wal_keep_size: "1000 MB" + track_wal_io_timing: "on" + + pg_hba: + - host all all all trust + resources: + requests: + memory: "2Gi" + cpu: "2" + limits: + memory: "2Gi" + cpu: "2" + +redisConfig: + fullnameOverride: "lp-backend-redis" + nameOverride: "" + auth: + password: "" + customConfig: + kubernetesConfig: + image: quay.io/linuxpolska/ezd-backend_redis:7.0.13-alpine-3.15-r1 + imagePullPolicy: Always + imagePullSecrets: + - name: credentials-registry-app + redisSecret: + name: credentials-lp-backend-redis + key: password + resources: + requests: + cpu: 101m + memory: 128Mi + limits: + cpu: 101m + memory: 128Mi + storage: + volumeClaimTemplate: + spec: + accessModes: ["ReadWriteOnce"] + resources: + requests: + storage: 1Gi + redisExporter: + enabled: false + image: quay.io/linuxpolska/ezd-backend_redis-exporter:1.44.0 + securityContext: + runAsUser: 0 + fsGroup: 1001 diff --git a/charts/linux-polska/ezd-crd/1.5.1/.helmignore b/charts/linux-polska/ezd-crd/1.5.1/.helmignore new file mode 100644 index 000000000..0e8a0eb36 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/charts/linux-polska/ezd-crd/1.5.1/Chart.lock b/charts/linux-polska/ezd-crd/1.5.1/Chart.lock new file mode 100644 index 000000000..45d19f7b4 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/Chart.lock @@ -0,0 +1,12 @@ +dependencies: +- name: rabbitmq-cluster-operator + repository: https://charts.bitnami.com/bitnami + version: 4.3.16 +- name: cloudnative-pg + repository: https://cloudnative-pg.github.io/charts + version: 0.21.5 +- name: redis-operator + repository: https://ot-container-kit.github.io/helm-charts + version: 0.18.0 +digest: sha256:452d86d0d29ecfd1b417895649d33ba60b28d113d578739730afab0df59bb9af +generated: "2024-07-30T11:30:06.54299445+02:00" diff --git a/charts/linux-polska/ezd-crd/1.5.1/Chart.yaml b/charts/linux-polska/ezd-crd/1.5.1/Chart.yaml new file mode 100644 index 000000000..bfa7c4423 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/Chart.yaml @@ -0,0 +1,45 @@ +annotations: + catalog.cattle.io/certified: partner + catalog.cattle.io/display-name: CRDs for LP Backend + catalog.cattle.io/hidden: "true" + catalog.cattle.io/kube-version: '>=1.19-0' + catalog.cattle.io/namespace: default + catalog.cattle.io/os: linux + catalog.cattle.io/release-name: ezd-crd +apiVersion: v2 +appVersion: 1.2024-19.7.45 +dependencies: +- alias: rabbitmq-operator + condition: global.rabbitmq.deploy + name: rabbitmq-cluster-operator + repository: file://./charts/rabbitmq-cluster-operator + version: 4.3.16 +- condition: global.postgresql.deploy + name: cloudnative-pg + repository: file://./charts/cloudnative-pg + version: 0.21.5 +- condition: global.redis.deploy + name: redis-operator + repository: file://./charts/redis-operator + version: 0.18.0 +description: Set of operators and CRDs for LP Backend +home: https://linuxpolska.com +icon: file://assets/icons/ezd-crd.png +keywords: +- ezd +- ezdrp +- ezd-rp +- backend +- databases +kubeVersion: '>=1.19-0' +maintainers: +- email: biuro@linuxpolska.com + name: Linux Polska +- email: support@linuxpolska.com + name: Linux Polska + url: https://linuxpolska.com/en/ +name: ezd-crd +sources: +- https://github.com/linuxpolska/ezd-rp.git +type: application +version: 1.5.1 diff --git a/charts/linux-polska/ezd-crd/1.5.1/README.md b/charts/linux-polska/ezd-crd/1.5.1/README.md new file mode 100644 index 000000000..e8c36cdc0 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/README.md @@ -0,0 +1,84 @@ + +# CRDs for EZD backend Helm Chart + +Helm chart necessary for installtion of EZD backend chart. +For more detailed information for EZD-CRD chart please check [README](https://github.com/linuxpolska/ezd-rp/blob/main/README.md) + +## TL;DR + +```console +helm repo add lp-ezd https://linuxpolska.github.io/ezd-rp +helm upgrade --install --create-namespace ezd-crd -n default lp-ezd/ezd-crd +``` + +## Introduction + +This chart bootstraps a set of operatos and CRDs on a [Kubernetes](https://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + +Linux Polska charts can be served by [Rancher Apps & Marketplace](https://ranchermanager.docs.rancher.com/pages-for-subheaders/helm-charts-in-rancher) for deployment and management of Helm Charts in clusters. + +## Prerequisites + +- Kubernetes 1.19+ +- Helm 3.2.0+ +- PV provisioner support in the underlying infrastructure + +## Installing the Chart + +Add repository necessary for installation: + +```console +helm repo add lp-ezd https://linuxpolska.github.io/ezd-rp +helm repo update +``` + +To install the chart with the release name `my-release`: + +```console +helm upgrade --install --create-namespace ezd-crd -n default lp-ezd/ezd-crd +``` + +The command deploys operators on the Kubernetes cluster in the default configuration. For more detailed information regarding parameters please check our [README](https://github.com/linuxpolska/ezd-rp/blob/main/README.md). + +> **Tip**: List all releases using `helm list` + +## Uninstalling the Chart + +To uninstall/delete the `my-release` deployment: + +```console +helm uninstall ezd-crd +``` + +The command removes all the Kubernetes components but no CRDs + +To delete the CRDs associated with `my-release`: + +```console + +kubectl get crd -o name | grep -E "(postgresql.cnpg.io|rabbitmqclusters.rabbitmq.com)" | xargs kubectl delete + +``` + +> **Note**: Deleting the CRDs will delete all data as well. Please be cautious before doing it. + +For more detailed information regarding installation of ezd-crd please refer to [INSTALLATION](https://github.com/linuxpolska/ezd-rp/blob/main/INSTALLATION.md) + +## Compability with NASK ezdrp version + +Chart ezd-crd was tested with chart version up to 19.7.45 (application version up to 1.2024-19.7.45). + +## Configuration and parameters + +See [Customizing the Chart Before Installing](https://helm.sh/docs/intro/using_helm/#customizing-the-chart-before-installing). To see all configurable options with detailed comments: + +```console +helm search repo lp-ezd +helm show values lp-ezd/ezd-crd +``` + +## Components version +- redis_operator: 0.18.0-golang-1.21-r1 +- cluster_operator: 2.9.0-golang-1.22-r1 +- cloudnative-pg: 1.23.0-debian-12-r1 + diff --git a/charts/linux-polska/ezd-crd/1.5.1/app-readme.md b/charts/linux-polska/ezd-crd/1.5.1/app-readme.md new file mode 100644 index 000000000..9985b80fa --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/app-readme.md @@ -0,0 +1,22 @@ +## CRDs for LP Backend + +The chart deploys set of operators and CRDs, which necessary to configure postgresql, rabbitmq, redis. + + +## Prerequisites + +- Kubernetes 1.19+ +- Helm 3.2.0+ +- PV provisioner support in the underlying infrastructure + +## CRDs +This Chart create following crds, and do not remove them after operator remove by defult + +- `backups.postgresql.cnpg.io` +- `clusters.postgresql.cnpg.io` +- `poolers.postgresql.cnpg.io` +- `rabbitmqclusters.rabbitmq.com` +- `scheduledbackups.postgresql.cnpg.io` + +For more information on how to configure the Helm chart, refer to the Helm README. + diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/.helmignore b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/.helmignore new file mode 100644 index 000000000..0e8a0eb36 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/Chart.lock b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/Chart.lock new file mode 100644 index 000000000..610070fb7 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: cluster + repository: https://cloudnative-pg.github.io/grafana-dashboards + version: 0.0.2 +digest: sha256:fcf16ad357c17be3dd79c138723e78e9e101fecc5d07d9371299c32b9f85dbd9 +generated: "2024-04-25T12:32:36.61779032-04:00" diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/Chart.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/Chart.yaml new file mode 100644 index 000000000..285a127ec --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/Chart.yaml @@ -0,0 +1,25 @@ +apiVersion: v2 +appVersion: 1.23.2 +dependencies: +- alias: monitoring + condition: monitoring.grafanaDashboard.create + name: cluster + repository: https://cloudnative-pg.github.io/grafana-dashboards + version: "0.0" +description: CloudNativePG Operator Helm Chart +home: https://cloudnative-pg.io +icon: https://raw.githubusercontent.com/cloudnative-pg/artwork/main/cloudnativepg-logo.svg +keywords: +- operator +- controller +- postgresql +- postgres +- database +maintainers: +- email: p.scorsolini@gmail.com + name: phisco +name: cloudnative-pg +sources: +- https://github.com/cloudnative-pg/charts +type: application +version: 0.21.5 diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/LICENSE b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/README.md b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/README.md new file mode 100644 index 000000000..2aa7853ab --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/README.md @@ -0,0 +1,73 @@ +# cloudnative-pg + +![Version: 0.21.5](https://img.shields.io/badge/Version-0.21.5-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.23.2](https://img.shields.io/badge/AppVersion-1.23.2-informational?style=flat-square) + +CloudNativePG Operator Helm Chart + +**Homepage:** + +## Maintainers + +| Name | Email | Url | +| ---- | ------ | --- | +| phisco | | | + +## Source Code + +* + +## Requirements + +| Repository | Name | Version | +|------------|------|---------| +| https://cloudnative-pg.github.io/grafana-dashboards | monitoring(cluster) | 0.0 | + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| additionalArgs | list | `[]` | Additinal arguments to be added to the operator's args list. | +| additionalEnv | list | `[]` | Array containing extra environment variables which can be templated. For example: - name: RELEASE_NAME value: "{{ .Release.Name }}" - name: MY_VAR value: "mySpecialKey" | +| affinity | object | `{}` | Affinity for the operator to be installed. | +| commonAnnotations | object | `{}` | Annotations to be added to all other resources. | +| config | object | `{"create":true,"data":{},"name":"cnpg-controller-manager-config","secret":false}` | Operator configuration. | +| config.create | bool | `true` | Specifies whether the secret should be created. | +| config.data | object | `{}` | The content of the configmap/secret, see https://cloudnative-pg.io/documentation/current/operator_conf/#available-options for all the available options. | +| config.name | string | `"cnpg-controller-manager-config"` | The name of the configmap/secret to use. | +| config.secret | bool | `false` | Specifies whether it should be stored in a secret, instead of a configmap. | +| containerSecurityContext | object | `{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"readOnlyRootFilesystem":true,"runAsGroup":10001,"runAsUser":10001,"seccompProfile":{"type":"RuntimeDefault"}}` | Container Security Context. | +| crds.create | bool | `true` | Specifies whether the CRDs should be created when installing the chart. | +| fullnameOverride | string | `""` | | +| image.pullPolicy | string | `"IfNotPresent"` | | +| image.repository | string | `"ghcr.io/cloudnative-pg/cloudnative-pg"` | | +| image.tag | string | `""` | Overrides the image tag whose default is the chart appVersion. | +| imagePullSecrets | list | `[]` | | +| monitoring.grafanaDashboard.annotations | object | `{}` | Annotations that ConfigMaps can have to get configured in Grafana. | +| monitoring.grafanaDashboard.configMapName | string | `"cnpg-grafana-dashboard"` | The name of the ConfigMap containing the dashboard. | +| monitoring.grafanaDashboard.create | bool | `false` | | +| monitoring.grafanaDashboard.labels | object | `{}` | Labels that ConfigMaps should have to get configured in Grafana. | +| monitoring.grafanaDashboard.namespace | string | `""` | Allows overriding the namespace where the ConfigMap will be created, defaulting to the same one as the Release. | +| monitoring.grafanaDashboard.sidecarLabel | string | `"grafana_dashboard"` | Label that ConfigMaps should have to be loaded as dashboards. DEPRECATED: Use labels instead. | +| monitoring.grafanaDashboard.sidecarLabelValue | string | `"1"` | Label value that ConfigMaps should have to be loaded as dashboards. DEPRECATED: Use labels instead. | +| monitoring.podMonitorAdditionalLabels | object | `{}` | Additional labels for the podMonitor | +| monitoring.podMonitorEnabled | bool | `false` | Specifies whether the monitoring should be enabled. Requires Prometheus Operator CRDs. | +| monitoringQueriesConfigMap.name | string | `"cnpg-default-monitoring"` | The name of the default monitoring configmap. | +| monitoringQueriesConfigMap.queries | string | `"backends:\n query: |\n SELECT sa.datname\n , sa.usename\n , sa.application_name\n , states.state\n , COALESCE(sa.count, 0) AS total\n , COALESCE(sa.max_tx_secs, 0) AS max_tx_duration_seconds\n FROM ( VALUES ('active')\n , ('idle')\n , ('idle in transaction')\n , ('idle in transaction (aborted)')\n , ('fastpath function call')\n , ('disabled')\n ) AS states(state)\n LEFT JOIN (\n SELECT datname\n , state\n , usename\n , COALESCE(application_name, '') AS application_name\n , COUNT(*)\n , COALESCE(EXTRACT (EPOCH FROM (max(now() - xact_start))), 0) AS max_tx_secs\n FROM pg_catalog.pg_stat_activity\n GROUP BY datname, state, usename, application_name\n ) sa ON states.state = sa.state\n WHERE sa.usename IS NOT NULL\n metrics:\n - datname:\n usage: \"LABEL\"\n description: \"Name of the database\"\n - usename:\n usage: \"LABEL\"\n description: \"Name of the user\"\n - application_name:\n usage: \"LABEL\"\n description: \"Name of the application\"\n - state:\n usage: \"LABEL\"\n description: \"State of the backend\"\n - total:\n usage: \"GAUGE\"\n description: \"Number of backends\"\n - max_tx_duration_seconds:\n usage: \"GAUGE\"\n description: \"Maximum duration of a transaction in seconds\"\n\nbackends_waiting:\n query: |\n SELECT count(*) AS total\n FROM pg_catalog.pg_locks blocked_locks\n JOIN pg_catalog.pg_locks blocking_locks\n ON blocking_locks.locktype = blocked_locks.locktype\n AND blocking_locks.database IS NOT DISTINCT FROM blocked_locks.database\n AND blocking_locks.relation IS NOT DISTINCT FROM blocked_locks.relation\n AND blocking_locks.page IS NOT DISTINCT FROM blocked_locks.page\n AND blocking_locks.tuple IS NOT DISTINCT FROM blocked_locks.tuple\n AND blocking_locks.virtualxid IS NOT DISTINCT FROM blocked_locks.virtualxid\n AND blocking_locks.transactionid IS NOT DISTINCT FROM blocked_locks.transactionid\n AND blocking_locks.classid IS NOT DISTINCT FROM blocked_locks.classid\n AND blocking_locks.objid IS NOT DISTINCT FROM blocked_locks.objid\n AND blocking_locks.objsubid IS NOT DISTINCT FROM blocked_locks.objsubid\n AND blocking_locks.pid != blocked_locks.pid\n JOIN pg_catalog.pg_stat_activity blocking_activity ON blocking_activity.pid = blocking_locks.pid\n WHERE NOT blocked_locks.granted\n metrics:\n - total:\n usage: \"GAUGE\"\n description: \"Total number of backends that are currently waiting on other queries\"\n\npg_database:\n query: |\n SELECT datname\n , pg_catalog.pg_database_size(datname) AS size_bytes\n , pg_catalog.age(datfrozenxid) AS xid_age\n , pg_catalog.mxid_age(datminmxid) AS mxid_age\n FROM pg_catalog.pg_database\n metrics:\n - datname:\n usage: \"LABEL\"\n description: \"Name of the database\"\n - size_bytes:\n usage: \"GAUGE\"\n description: \"Disk space used by the database\"\n - xid_age:\n usage: \"GAUGE\"\n description: \"Number of transactions from the frozen XID to the current one\"\n - mxid_age:\n usage: \"GAUGE\"\n description: \"Number of multiple transactions (Multixact) from the frozen XID to the current one\"\n\npg_postmaster:\n query: |\n SELECT EXTRACT(EPOCH FROM pg_postmaster_start_time) AS start_time\n FROM pg_catalog.pg_postmaster_start_time()\n metrics:\n - start_time:\n usage: \"GAUGE\"\n description: \"Time at which postgres started (based on epoch)\"\n\npg_replication:\n query: \"SELECT CASE WHEN (\n NOT pg_catalog.pg_is_in_recovery()\n OR pg_catalog.pg_last_wal_receive_lsn() = pg_catalog.pg_last_wal_replay_lsn())\n THEN 0\n ELSE GREATEST (0,\n EXTRACT(EPOCH FROM (now() - pg_catalog.pg_last_xact_replay_timestamp())))\n END AS lag,\n pg_catalog.pg_is_in_recovery() AS in_recovery,\n EXISTS (TABLE pg_stat_wal_receiver) AS is_wal_receiver_up,\n (SELECT count(*) FROM pg_catalog.pg_stat_replication) AS streaming_replicas\"\n metrics:\n - lag:\n usage: \"GAUGE\"\n description: \"Replication lag behind primary in seconds\"\n - in_recovery:\n usage: \"GAUGE\"\n description: \"Whether the instance is in recovery\"\n - is_wal_receiver_up:\n usage: \"GAUGE\"\n description: \"Whether the instance wal_receiver is up\"\n - streaming_replicas:\n usage: \"GAUGE\"\n description: \"Number of streaming replicas connected to the instance\"\n\npg_replication_slots:\n query: |\n SELECT slot_name,\n slot_type,\n database,\n active,\n (CASE pg_catalog.pg_is_in_recovery()\n WHEN TRUE THEN pg_catalog.pg_wal_lsn_diff(pg_catalog.pg_last_wal_receive_lsn(), restart_lsn)\n ELSE pg_catalog.pg_wal_lsn_diff(pg_catalog.pg_current_wal_lsn(), restart_lsn)\n END) as pg_wal_lsn_diff\n FROM pg_catalog.pg_replication_slots\n WHERE NOT temporary\n metrics:\n - slot_name:\n usage: \"LABEL\"\n description: \"Name of the replication slot\"\n - slot_type:\n usage: \"LABEL\"\n description: \"Type of the replication slot\"\n - database:\n usage: \"LABEL\"\n description: \"Name of the database\"\n - active:\n usage: \"GAUGE\"\n description: \"Flag indicating whether the slot is active\"\n - pg_wal_lsn_diff:\n usage: \"GAUGE\"\n description: \"Replication lag in bytes\"\n\npg_stat_archiver:\n query: |\n SELECT archived_count\n , failed_count\n , COALESCE(EXTRACT(EPOCH FROM (now() - last_archived_time)), -1) AS seconds_since_last_archival\n , COALESCE(EXTRACT(EPOCH FROM (now() - last_failed_time)), -1) AS seconds_since_last_failure\n , COALESCE(EXTRACT(EPOCH FROM last_archived_time), -1) AS last_archived_time\n , COALESCE(EXTRACT(EPOCH FROM last_failed_time), -1) AS last_failed_time\n , COALESCE(CAST(CAST('x'||pg_catalog.right(pg_catalog.split_part(last_archived_wal, '.', 1), 16) AS pg_catalog.bit(64)) AS pg_catalog.int8), -1) AS last_archived_wal_start_lsn\n , COALESCE(CAST(CAST('x'||pg_catalog.right(pg_catalog.split_part(last_failed_wal, '.', 1), 16) AS pg_catalog.bit(64)) AS pg_catalog.int8), -1) AS last_failed_wal_start_lsn\n , EXTRACT(EPOCH FROM stats_reset) AS stats_reset_time\n FROM pg_catalog.pg_stat_archiver\n metrics:\n - archived_count:\n usage: \"COUNTER\"\n description: \"Number of WAL files that have been successfully archived\"\n - failed_count:\n usage: \"COUNTER\"\n description: \"Number of failed attempts for archiving WAL files\"\n - seconds_since_last_archival:\n usage: \"GAUGE\"\n description: \"Seconds since the last successful archival operation\"\n - seconds_since_last_failure:\n usage: \"GAUGE\"\n description: \"Seconds since the last failed archival operation\"\n - last_archived_time:\n usage: \"GAUGE\"\n description: \"Epoch of the last time WAL archiving succeeded\"\n - last_failed_time:\n usage: \"GAUGE\"\n description: \"Epoch of the last time WAL archiving failed\"\n - last_archived_wal_start_lsn:\n usage: \"GAUGE\"\n description: \"Archived WAL start LSN\"\n - last_failed_wal_start_lsn:\n usage: \"GAUGE\"\n description: \"Last failed WAL LSN\"\n - stats_reset_time:\n usage: \"GAUGE\"\n description: \"Time at which these statistics were last reset\"\n\npg_stat_bgwriter:\n runonserver: \"<17.0.0\"\n query: |\n SELECT checkpoints_timed\n , checkpoints_req\n , checkpoint_write_time\n , checkpoint_sync_time\n , buffers_checkpoint\n , buffers_clean\n , maxwritten_clean\n , buffers_backend\n , buffers_backend_fsync\n , buffers_alloc\n FROM pg_catalog.pg_stat_bgwriter\n metrics:\n - checkpoints_timed:\n usage: \"COUNTER\"\n description: \"Number of scheduled checkpoints that have been performed\"\n - checkpoints_req:\n usage: \"COUNTER\"\n description: \"Number of requested checkpoints that have been performed\"\n - checkpoint_write_time:\n usage: \"COUNTER\"\n description: \"Total amount of time that has been spent in the portion of checkpoint processing where files are written to disk, in milliseconds\"\n - checkpoint_sync_time:\n usage: \"COUNTER\"\n description: \"Total amount of time that has been spent in the portion of checkpoint processing where files are synchronized to disk, in milliseconds\"\n - buffers_checkpoint:\n usage: \"COUNTER\"\n description: \"Number of buffers written during checkpoints\"\n - buffers_clean:\n usage: \"COUNTER\"\n description: \"Number of buffers written by the background writer\"\n - maxwritten_clean:\n usage: \"COUNTER\"\n description: \"Number of times the background writer stopped a cleaning scan because it had written too many buffers\"\n - buffers_backend:\n usage: \"COUNTER\"\n description: \"Number of buffers written directly by a backend\"\n - buffers_backend_fsync:\n usage: \"COUNTER\"\n description: \"Number of times a backend had to execute its own fsync call (normally the background writer handles those even when the backend does its own write)\"\n - buffers_alloc:\n usage: \"COUNTER\"\n description: \"Number of buffers allocated\"\n\npg_stat_database:\n query: |\n SELECT datname\n , xact_commit\n , xact_rollback\n , blks_read\n , blks_hit\n , tup_returned\n , tup_fetched\n , tup_inserted\n , tup_updated\n , tup_deleted\n , conflicts\n , temp_files\n , temp_bytes\n , deadlocks\n , blk_read_time\n , blk_write_time\n FROM pg_catalog.pg_stat_database\n metrics:\n - datname:\n usage: \"LABEL\"\n description: \"Name of this database\"\n - xact_commit:\n usage: \"COUNTER\"\n description: \"Number of transactions in this database that have been committed\"\n - xact_rollback:\n usage: \"COUNTER\"\n description: \"Number of transactions in this database that have been rolled back\"\n - blks_read:\n usage: \"COUNTER\"\n description: \"Number of disk blocks read in this database\"\n - blks_hit:\n usage: \"COUNTER\"\n description: \"Number of times disk blocks were found already in the buffer cache, so that a read was not necessary (this only includes hits in the PostgreSQL buffer cache, not the operating system's file system cache)\"\n - tup_returned:\n usage: \"COUNTER\"\n description: \"Number of rows returned by queries in this database\"\n - tup_fetched:\n usage: \"COUNTER\"\n description: \"Number of rows fetched by queries in this database\"\n - tup_inserted:\n usage: \"COUNTER\"\n description: \"Number of rows inserted by queries in this database\"\n - tup_updated:\n usage: \"COUNTER\"\n description: \"Number of rows updated by queries in this database\"\n - tup_deleted:\n usage: \"COUNTER\"\n description: \"Number of rows deleted by queries in this database\"\n - conflicts:\n usage: \"COUNTER\"\n description: \"Number of queries canceled due to conflicts with recovery in this database\"\n - temp_files:\n usage: \"COUNTER\"\n description: \"Number of temporary files created by queries in this database\"\n - temp_bytes:\n usage: \"COUNTER\"\n description: \"Total amount of data written to temporary files by queries in this database\"\n - deadlocks:\n usage: \"COUNTER\"\n description: \"Number of deadlocks detected in this database\"\n - blk_read_time:\n usage: \"COUNTER\"\n description: \"Time spent reading data file blocks by backends in this database, in milliseconds\"\n - blk_write_time:\n usage: \"COUNTER\"\n description: \"Time spent writing data file blocks by backends in this database, in milliseconds\"\n\npg_stat_replication:\n primary: true\n query: |\n SELECT usename\n , COALESCE(application_name, '') AS application_name\n , COALESCE(client_addr::text, '') AS client_addr\n , COALESCE(client_port::text, '') AS client_port\n , EXTRACT(EPOCH FROM backend_start) AS backend_start\n , COALESCE(pg_catalog.age(backend_xmin), 0) AS backend_xmin_age\n , pg_catalog.pg_wal_lsn_diff(pg_catalog.pg_current_wal_lsn(), sent_lsn) AS sent_diff_bytes\n , pg_catalog.pg_wal_lsn_diff(pg_catalog.pg_current_wal_lsn(), write_lsn) AS write_diff_bytes\n , pg_catalog.pg_wal_lsn_diff(pg_catalog.pg_current_wal_lsn(), flush_lsn) AS flush_diff_bytes\n , COALESCE(pg_catalog.pg_wal_lsn_diff(pg_catalog.pg_current_wal_lsn(), replay_lsn),0) AS replay_diff_bytes\n , COALESCE((EXTRACT(EPOCH FROM write_lag)),0)::float AS write_lag_seconds\n , COALESCE((EXTRACT(EPOCH FROM flush_lag)),0)::float AS flush_lag_seconds\n , COALESCE((EXTRACT(EPOCH FROM replay_lag)),0)::float AS replay_lag_seconds\n FROM pg_catalog.pg_stat_replication\n metrics:\n - usename:\n usage: \"LABEL\"\n description: \"Name of the replication user\"\n - application_name:\n usage: \"LABEL\"\n description: \"Name of the application\"\n - client_addr:\n usage: \"LABEL\"\n description: \"Client IP address\"\n - client_port:\n usage: \"LABEL\"\n description: \"Client TCP port\"\n - backend_start:\n usage: \"COUNTER\"\n description: \"Time when this process was started\"\n - backend_xmin_age:\n usage: \"COUNTER\"\n description: \"The age of this standby's xmin horizon\"\n - sent_diff_bytes:\n usage: \"GAUGE\"\n description: \"Difference in bytes from the last write-ahead log location sent on this connection\"\n - write_diff_bytes:\n usage: \"GAUGE\"\n description: \"Difference in bytes from the last write-ahead log location written to disk by this standby server\"\n - flush_diff_bytes:\n usage: \"GAUGE\"\n description: \"Difference in bytes from the last write-ahead log location flushed to disk by this standby server\"\n - replay_diff_bytes:\n usage: \"GAUGE\"\n description: \"Difference in bytes from the last write-ahead log location replayed into the database on this standby server\"\n - write_lag_seconds:\n usage: \"GAUGE\"\n description: \"Time elapsed between flushing recent WAL locally and receiving notification that this standby server has written it\"\n - flush_lag_seconds:\n usage: \"GAUGE\"\n description: \"Time elapsed between flushing recent WAL locally and receiving notification that this standby server has written and flushed it\"\n - replay_lag_seconds:\n usage: \"GAUGE\"\n description: \"Time elapsed between flushing recent WAL locally and receiving notification that this standby server has written, flushed and applied it\"\n\npg_settings:\n query: |\n SELECT name,\n CASE setting WHEN 'on' THEN '1' WHEN 'off' THEN '0' ELSE setting END AS setting\n FROM pg_catalog.pg_settings\n WHERE vartype IN ('integer', 'real', 'bool')\n ORDER BY 1\n metrics:\n - name:\n usage: \"LABEL\"\n description: \"Name of the setting\"\n - setting:\n usage: \"GAUGE\"\n description: \"Setting value\"\n"` | A string representation of a YAML defining monitoring queries. | +| nameOverride | string | `""` | | +| nodeSelector | object | `{}` | Nodeselector for the operator to be installed. | +| podAnnotations | object | `{}` | Annotations to be added to the pod. | +| podLabels | object | `{}` | Labels to be added to the pod. | +| podSecurityContext | object | `{"runAsNonRoot":true,"seccompProfile":{"type":"RuntimeDefault"}}` | Security Context for the whole pod. | +| priorityClassName | string | `""` | Priority indicates the importance of a Pod relative to other Pods. | +| rbac.aggregateClusterRoles | bool | `false` | Aggregate ClusterRoles to Kubernetes default user-facing roles. Ref: https://kubernetes.io/docs/reference/access-authn-authz/rbac/#user-facing-roles | +| rbac.create | bool | `true` | Specifies whether ClusterRole and ClusterRoleBinding should be created. | +| replicaCount | int | `1` | | +| resources | object | `{}` | | +| service.name | string | `"cnpg-webhook-service"` | DO NOT CHANGE THE SERVICE NAME as it is currently used to generate the certificate and can not be configured | +| service.port | int | `443` | | +| service.type | string | `"ClusterIP"` | | +| serviceAccount.create | bool | `true` | Specifies whether the service account should be created. | +| serviceAccount.name | string | `""` | The name of the service account to use. If not set and create is true, a name is generated using the fullname template. | +| tolerations | list | `[]` | Tolerations for the operator to be installed. | +| webhook | object | `{"livenessProbe":{"initialDelaySeconds":3},"mutating":{"create":true,"failurePolicy":"Fail"},"port":9443,"readinessProbe":{"initialDelaySeconds":3},"validating":{"create":true,"failurePolicy":"Fail"}}` | The webhook configuration. | + diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/charts/cluster/.helmignore b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/charts/cluster/.helmignore new file mode 100644 index 000000000..0e8a0eb36 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/charts/cluster/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/charts/cluster/Chart.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/charts/cluster/Chart.yaml new file mode 100644 index 000000000..86c48e5dc --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/charts/cluster/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +appVersion: 1.16.0 +description: CloudNativePG Grafana Cluster Dashboard. +name: cluster +type: application +version: 0.0.2 diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/charts/cluster/README.md b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/charts/cluster/README.md new file mode 100644 index 000000000..825b030e2 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/charts/cluster/README.md @@ -0,0 +1,59 @@ + + +# cluster + +![Version: 0.0.2](https://img.shields.io/badge/Version-0.0.2-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.16.0](https://img.shields.io/badge/AppVersion-1.16.0-informational?style=flat-square) + +![Grafana CloudNativePG Cluster Overview](../../images/overview.png) + +Getting Started +--------------- + +_**Note,** this dashboard is already included in the [CloudNativePG Operator Helm Chart][operator]._ + +There are 4 ways to use the CloudNativePG Grafana Cluster Dashboard: + +0. Install the [CloudNativePG Operator Helm Chart][operator] + +1. Install manually via [Grafana.com](https://grafana.com/grafana/dashboards/20417-cloudnativepg/). + +2. Install manually via the [Grafana JSON](https://github.com/cloudnative-pg/grafana-dashboards/blob/main/charts/cluster/grafana-dashboard.json): + +``` +https://raw.githubusercontent.com/cloudnative-pg/grafana-dashboards/main/charts/cluster/grafana-dashboard.json +``` + +3. Install directly in your cluster as a Helm Chart: + +```bash +helm repo add cnpg-grafana https://cloudnative-pg.github.io/grafana-dashboards +helm upgrade + --install \ + --namespace monitoring \ + cnpg-grafana-cluster cnpg-grafana/cluster +``` + +2. As as a dependency to an existing chart: + +```yaml +dependencies: + - name: cluster + alias: cnpg-grafana-cluster-dashboard + version: "0.0" + repository: https://cloudnative-pg.github.io/grafana-dashboards +``` + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| fullnameOverride | string | `""` | | +| grafanaDashboard.annotations | object | `{}` | Annotations that ConfigMaps can have to get configured in Grafana. | +| grafanaDashboard.configMapName | string | `"cnpg-grafana-dashboard"` | The name of the ConfigMap containing the dashboard. | +| grafanaDashboard.labels | object | `{}` | Labels that ConfigMaps should have to get configured in Grafana. | +| grafanaDashboard.namespace | string | `""` | Allows overriding the namespace where the ConfigMap will be created, defaulting to the same one as the Release. | +| grafanaDashboard.sidecarLabel | string | `"grafana_dashboard"` | Label that ConfigMaps should have to be loaded as dashboards. DEPRECATED: Use labels instead. | +| grafanaDashboard.sidecarLabelValue | string | `"1"` | Label value that ConfigMaps should have to be loaded as dashboards. DEPRECATED: Use labels instead. | +| nameOverride | string | `""` | | + +[operator]: https://github.com/cloudnative-pg/charts/tree/main/charts/cloudnative-pg diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/charts/cluster/README.md.gotmpl b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/charts/cluster/README.md.gotmpl new file mode 100644 index 000000000..e759b120f --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/charts/cluster/README.md.gotmpl @@ -0,0 +1,59 @@ + + +{{ template "chart.header" . }} + +{{ template "chart.deprecationWarning" . }} + +{{ template "chart.badgesSection" . }} + +![Grafana CloudNativePG Cluster Overview](../../images/overview.png) + +Getting Started +--------------- + +_**Note,** this dashboard is already included in the [CloudNativePG Operator Helm Chart][operator]._ + +There are 4 ways to use the CloudNativePG Grafana Cluster Dashboard: + +0. Install the [CloudNativePG Operator Helm Chart][operator] + +1. Install manually via [Grafana.com](https://grafana.com/grafana/dashboards/20417-cloudnativepg/). + +2. Install manually via the [Grafana JSON](https://github.com/cloudnative-pg/grafana-dashboards/blob/main/charts/cluster/grafana-dashboard.json): + +``` +https://raw.githubusercontent.com/cloudnative-pg/grafana-dashboards/main/charts/cluster/grafana-dashboard.json +``` + +3. Install directly in your cluster as a Helm Chart: + +```bash +helm repo add cnpg-grafana https://cloudnative-pg.github.io/grafana-dashboards +helm upgrade + --install \ + --namespace monitoring \ + cnpg-grafana-cluster cnpg-grafana/cluster +``` + +2. As as a dependency to an existing chart: + +```yaml +dependencies: + - name: cluster + alias: cnpg-grafana-cluster-dashboard + version: "0.0" + repository: https://cloudnative-pg.github.io/grafana-dashboards +``` + + +{{ template "chart.requirementsSection" . }} + + +{{ template "chart.valuesSection" . }} + + +{{ template "chart.maintainersSection" . }} + +{{ template "helm-docs.versionFooter" . }} + +[operator]: https://github.com/cloudnative-pg/charts/tree/main/charts/cloudnative-pg diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/charts/cluster/grafana-dashboard.json b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/charts/cluster/grafana-dashboard.json new file mode 100644 index 000000000..536e520f5 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/charts/cluster/grafana-dashboard.json @@ -0,0 +1,9189 @@ +{ + "__inputs": [ + { + "name": "DS_PROMETHEUS", + "label": "Prometheus", + "description": "", + "type": "datasource", + "pluginId": "prometheus", + "pluginName": "Prometheus" + }, + { + "name": "DS_EXPRESSION", + "label": "Expression", + "description": "", + "type": "datasource", + "pluginId": "__expr__" + } + ], + "__elements": {}, + "__requires": [ + { + "type": "datasource", + "id": "__expr__", + "version": "1.0.0" + }, + { + "type": "panel", + "id": "alertlist", + "name": "Alert list", + "version": "" + }, + { + "type": "panel", + "id": "bargauge", + "name": "Bar gauge", + "version": "" + }, + { + "type": "panel", + "id": "gauge", + "name": "Gauge", + "version": "" + }, + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "10.3.3" + }, + { + "type": "panel", + "id": "heatmap", + "name": "Heatmap", + "version": "" + }, + { + "type": "datasource", + "id": "prometheus", + "name": "Prometheus", + "version": "1.0.0" + }, + { + "type": "panel", + "id": "stat", + "name": "Stat", + "version": "" + }, + { + "type": "panel", + "id": "table", + "name": "Table", + "version": "" + }, + { + "type": "panel", + "id": "text", + "name": "Text", + "version": "" + }, + { + "type": "panel", + "id": "timeseries", + "name": "Time series", + "version": "" + } + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "target": { + "limit": 100, + "matchAny": false, + "tags": [], + "type": "dashboard" + }, + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 1, + "id": null, + "links": [ + { + "asDropdown": false, + "icon": "external link", + "includeVars": false, + "keepTime": false, + "tags": [ + "cloudnativepg" + ], + "targetBlank": false, + "title": "Related Dashboards", + "tooltip": "", + "type": "dashboards", + "url": "" + } + ], + "liveNow": false, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "h": 7, + "w": 3, + "x": 0, + "y": 0 + }, + "id": 676, + "options": { + "alertInstanceLabelFilter": "{namespace=~\"$namespace\",pod=~\"$instances\"}", + "alertName": "", + "dashboardAlerts": false, + "folder": "", + "groupBy": [], + "groupMode": "default", + "maxItems": 20, + "sortOrder": 1, + "stateFilter": { + "error": true, + "firing": true, + "noData": false, + "normal": true, + "pending": true + }, + "viewMode": "list" + }, + "title": "Alerts", + "type": "alertlist" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "h": 1, + "w": 4, + "x": 3, + "y": 0 + }, + "id": 586, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "", + "mode": "markdown" + }, + "pluginVersion": "10.3.3", + "title": "Health", + "type": "text" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "h": 1, + "w": 12, + "x": 7, + "y": 0 + }, + "id": 336, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "", + "mode": "markdown" + }, + "pluginVersion": "10.3.3", + "title": "Overview", + "type": "text" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "h": 1, + "w": 2, + "x": 19, + "y": 0 + }, + "id": 352, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "", + "mode": "markdown" + }, + "pluginVersion": "10.3.3", + "title": "Storage", + "type": "text" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "h": 1, + "w": 3, + "x": 21, + "y": 0 + }, + "id": 354, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "", + "mode": "markdown" + }, + "pluginVersion": "10.3.3", + "title": "Backups", + "type": "text" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "Cluster Replication Health represents the availability of replica servers available to replace the primary in case of a failure.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "0": { + "color": "red", + "index": 2, + "text": "None" + }, + "1": { + "color": "orange", + "index": 1, + "text": "Degraded" + } + }, + "type": "value" + }, + { + "options": { + "from": 2, + "result": { + "color": "green", + "index": 0, + "text": "Healthy" + }, + "to": 999 + }, + "type": "range" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 2, + "x": 3, + "y": 1 + }, + "id": 585, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "max(cnpg_pg_replication_streaming_replicas{namespace=~\"$namespace\", pod=~\"$instances\"} - cnpg_pg_replication_is_wal_receiver_up{namespace=~\"$namespace\", pod=~\"$instances\"})", + "legendFormat": "Replication", + "range": true, + "refId": "A" + } + ], + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "High lag indicates issue with replication. Network or storage interfaces may not have enough bandwidth to handle incoming traffic and replication at the same time.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "color": "text", + "index": 0, + "text": "No data" + } + }, + "type": "special" + }, + { + "options": { + "from": 0, + "result": { + "color": "green", + "index": 1, + "text": "Healthy" + }, + "to": 0.1 + }, + "type": "range" + }, + { + "options": { + "from": 0.1, + "result": { + "color": "yellow", + "index": 2, + "text": "Sub-second" + }, + "to": 1 + }, + "type": "range" + }, + { + "options": { + "from": 1, + "result": { + "color": "orange", + "index": 3, + "text": "Delayed" + }, + "to": 5 + }, + "type": "range" + }, + { + "options": { + "from": 5, + "result": { + "color": "red", + "index": 4, + "text": "High" + }, + "to": 4294967295 + }, + "type": "range" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 1, + "x": 5, + "y": 1 + }, + "id": 590, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "value_and_name", + "wideLayout": true + }, + "pluginVersion": "10.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "max(cnpg_pg_replication_lag{namespace=~\"$namespace\",pod=~\"$instances\"}) + max(cnpg_pg_stat_replication_write_lag_seconds{namespace=~\"$namespace\",pod=~\"$instances\"}) + max(cnpg_pg_stat_replication_flush_lag_seconds{namespace=~\"$namespace\",pod=~\"$instances\"}) + max(cnpg_pg_stat_replication_replay_lag_seconds{namespace=~\"$namespace\",pod=~\"$instances\"})", + "hide": false, + "instant": false, + "legendFormat": "Lag", + "range": true, + "refId": "LAG" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "expr": "", + "hide": false, + "instant": false, + "range": true, + "refId": "A" + } + ], + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "Low disk space or low inode count will result in data loss.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "color": "text", + "index": 0, + "text": "No data" + } + }, + "type": "special" + }, + { + "options": { + "from": 0, + "result": { + "color": "green", + "index": 1, + "text": "Healthy" + }, + "to": 0.8 + }, + "type": "range" + }, + { + "options": { + "from": 0.8, + "result": { + "color": "orange", + "index": 2, + "text": "Warning" + }, + "to": 0.9 + }, + "type": "range" + }, + { + "options": { + "from": 0.9, + "result": { + "color": "red", + "index": 3, + "text": "Critical" + }, + "to": 0.98 + }, + "type": "range" + }, + { + "options": { + "from": 0.98, + "result": { + "color": "red", + "index": 4, + "text": "Data Loss" + }, + "to": 1 + }, + "type": "range" + }, + { + "options": { + "from": 1, + "result": { + "color": "red", + "index": 5, + "text": "Full" + }, + "to": 4294967295 + }, + "type": "range" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 1, + "x": 6, + "y": 1 + }, + "id": 613, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "value_and_name", + "wideLayout": true + }, + "pluginVersion": "10.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "max((max(max by(persistentvolumeclaim) (1 - kubelet_volume_stats_available_bytes{namespace=\"$namespace\", persistentvolumeclaim=~\"$instances\"} / kubelet_volume_stats_capacity_bytes{namespace=\"$namespace\", persistentvolumeclaim=~\"$instances\"}))) OR (max by(persistentvolumeclaim) (kubelet_volume_stats_inodes_used{namespace=\"$namespace\", persistentvolumeclaim=~\"$instances\"} / kubelet_volume_stats_inodes{namespace=\"$namespace\", persistentvolumeclaim=~\"$instances\"})))", + "hide": false, + "legendFormat": "Storage", + "range": true, + "refId": "STORAGE" + } + ], + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "dark-blue", + "value": null + } + ] + }, + "unit": "dateTimeFromNow", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 2, + "x": 7, + "y": 1 + }, + "id": 338, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "text": {}, + "textMode": "value", + "wideLayout": true + }, + "pluginVersion": "10.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "max(cnpg_pg_postmaster_start_time{namespace=~\"$namespace\",pod=~\"$instances\"})*1000", + "format": "time_series", + "hide": false, + "instant": true, + "interval": "", + "intervalFactor": 1, + "legendFormat": "", + "refId": "A" + } + ], + "title": "Last failover", + "transformations": [], + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 2, + "x": 9, + "y": 1 + }, + "id": 342, + "interval": "1m", + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": true, + "expr": "sum(rate(cnpg_pg_stat_database_xact_commit{namespace=~\"$namespace\",pod=~\"$instances\"}[$__interval])) + sum(rate(cnpg_pg_stat_database_xact_rollback{namespace=~\"$namespace\",pod=~\"$instances\"}[$__interval]))", + "interval": "", + "legendFormat": "TPS", + "range": true, + "refId": "TPS" + } + ], + "title": "TPS", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "CPU Utilisation from Requests", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "color": "text", + "index": 0, + "text": "Missing request" + } + }, + "type": "special" + } + ], + "max": 1, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "orange", + "value": 0.8 + }, + { + "color": "red", + "value": 0.9 + } + ] + }, + "unit": "percentunit", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 2, + "x": 11, + "y": 1 + }, + "id": 344, + "interval": "1m", + "links": [], + "options": { + "minVizHeight": 75, + "minVizWidth": 75, + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "sizing": "auto" + }, + "pluginVersion": "10.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{namespace=\"$namespace\", pod=~\"$instances\"}) / sum(kube_pod_container_resource_requests{job=\"kube-state-metrics\", namespace=\"$namespace\", resource=\"cpu\", pod=~\"$instances\"})", + "format": "time_series", + "instant": true, + "intervalFactor": 2, + "refId": "A" + } + ], + "title": "CPU Utilisation", + "type": "gauge" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "Memory Utilisation from Requests", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "color": "text", + "index": 0, + "text": "Missing request" + } + }, + "type": "special" + } + ], + "max": 1, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "orange", + "value": 0.8 + }, + { + "color": "red", + "value": 0.9 + } + ] + }, + "unit": "percentunit", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 2, + "x": 13, + "y": 1 + }, + "id": 348, + "interval": "1m", + "links": [], + "options": { + "minVizHeight": 75, + "minVizWidth": 75, + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "sizing": "auto" + }, + "pluginVersion": "10.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(container_memory_working_set_bytes{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", namespace=\"$namespace\",container!=\"\", image!=\"\", pod=~\"$instances\"}) / sum(max by(pod) (kube_pod_container_resource_requests{job=\"kube-state-metrics\", namespace=\"$namespace\", resource=\"memory\", pod=~\"$instances\"}))", + "format": "time_series", + "instant": true, + "intervalFactor": 2, + "refId": "A" + } + ], + "title": "Memory Utilisation", + "type": "gauge" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "max": 30, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 1 + }, + { + "color": "orange", + "value": 10 + }, + { + "color": "red", + "value": 20 + } + ] + }, + "unit": "s", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 2, + "x": 15, + "y": 1 + }, + "id": 465, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "max(cnpg_pg_replication_lag{namespace=~\"$namespace\",pod=~\"$instances\"})", + "instant": true, + "legendFormat": "__auto", + "range": false, + "refId": "A" + } + ], + "title": "Replication Lag", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 1 + }, + { + "color": "orange", + "value": 10 + }, + { + "color": "red", + "value": 20 + } + ] + }, + "unit": "s", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 2, + "x": 17, + "y": 1 + }, + "id": 467, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "max(cnpg_pg_stat_replication_write_lag_seconds{namespace=~\"$namespace\",pod=~\"$instances\"})", + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Write Lag", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "max": 1, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "orange", + "value": 0.8 + }, + { + "color": "red", + "value": 0.9 + } + ] + }, + "unit": "percentunit", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 2, + "x": 19, + "y": 1 + }, + "id": 356, + "options": { + "minVizHeight": 75, + "minVizWidth": 75, + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "sizing": "auto" + }, + "pluginVersion": "10.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "max(max by(persistentvolumeclaim) (1 - kubelet_volume_stats_available_bytes{namespace=\"$namespace\", persistentvolumeclaim=~\"$instances\"} / kubelet_volume_stats_capacity_bytes{namespace=\"$namespace\", persistentvolumeclaim=~\"$instances\"}))", + "format": "time_series", + "instant": true, + "interval": "", + "legendFormat": "DATA", + "range": false, + "refId": "DATA" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "max(max by(persistentvolumeclaim) (1 - kubelet_volume_stats_available_bytes{namespace=\"$namespace\", persistentvolumeclaim=~\"(${instances})-wal\"} / kubelet_volume_stats_capacity_bytes{namespace=\"$namespace\", persistentvolumeclaim=~\"(${instances})-wal\"}))", + "format": "time_series", + "instant": true, + "interval": "", + "legendFormat": "WAL", + "range": false, + "refId": "WAL" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "max(\n sum by (namespace,persistentvolumeclaim) (kubelet_volume_stats_used_bytes{namespace=\"$namespace\", persistentvolumeclaim=~\"(${instances})-tbs.*\"}) \n /\n sum by (namespace,persistentvolumeclaim) (kubelet_volume_stats_capacity_bytes{namespace=\"$namespace\", persistentvolumeclaim=~\"(${instances})-tbs.*\"}) \n *\n on(namespace, persistentvolumeclaim) group_left(volume)\n kube_pod_spec_volumes_persistentvolumeclaims_info{pod=~\"$instances\"}\n)", + "hide": false, + "instant": true, + "legendFormat": "Tablespaces (max)", + "range": false, + "refId": "Max Tablespace" + } + ], + "title": "Volume Space Usage", + "type": "gauge" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "Elapsed time since the last successful base backup.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "from": 1, + "result": { + "color": "semi-dark-orange", + "index": 0, + "text": "Invalid date" + }, + "to": 1e+42 + }, + "type": "range" + }, + { + "options": { + "from": -2147483648, + "result": { + "color": "red", + "index": 1, + "text": "N/A" + }, + "to": -1577847600 + }, + "type": "range" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "semi-dark-red", + "value": -108000 + }, + { + "color": "semi-dark-orange", + "value": -107999 + }, + { + "color": "#EAB839", + "value": -89999 + }, + { + "color": "green", + "value": -86399 + } + ] + }, + "unit": "dtdurations", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 3, + "x": 21, + "y": 1 + }, + "id": 360, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "-(time() - max(cnpg_collector_last_available_backup_timestamp{namespace=\"$namespace\",pod=~\"$instances\"}))", + "instant": true, + "legendFormat": "__auto", + "range": false, + "refId": "A" + } + ], + "title": "Last Base Backup", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "High resource usage (CPU, Memory, DB Connections)", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "color": "text", + "index": 0, + "text": "No data" + } + }, + "type": "special" + }, + { + "options": { + "from": 0, + "result": { + "color": "green", + "index": 1, + "text": "Healthy" + }, + "to": 0.8 + }, + "type": "range" + }, + { + "options": { + "from": 0.8, + "result": { + "color": "orange", + "index": 2, + "text": "Warning" + }, + "to": 0.9 + }, + "type": "range" + }, + { + "options": { + "from": 0.9, + "result": { + "color": "red", + "index": 3, + "text": "Critical" + }, + "to": 0.98 + }, + "type": "range" + }, + { + "options": { + "from": 0.98, + "result": { + "color": "red", + "index": 4, + "text": "Data Loss" + }, + "to": 999 + }, + "type": "range" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 4, + "x": 3, + "y": 3 + }, + "id": 591, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "value_and_name", + "wideLayout": true + }, + "pluginVersion": "10.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "(sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{ namespace=\"$namespace\", pod=~\"$instances\"}) / sum(kube_pod_container_resource_requests{job=\"kube-state-metrics\", namespace=\"$namespace\", resource=\"cpu\", pod=~\"$instances\"}))", + "hide": false, + "legendFormat": "CPU", + "range": true, + "refId": "CPU" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "(sum(container_memory_working_set_bytes{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", namespace=\"$namespace\",container!=\"\", image!=\"\", pod=~\"$instances\"}) / sum(max by(pod) (kube_pod_container_resource_requests{job=\"kube-state-metrics\", namespace=\"$namespace\", resource=\"memory\", pod=~\"$instances\"})))", + "hide": false, + "instant": false, + "legendFormat": "Memory", + "range": true, + "refId": "MEM" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": " (max(sum by (pod) (cnpg_backends_total{namespace=~\"$namespace\", pod=~\"$instances\"}) / sum by (pod) (cnpg_pg_settings_setting{name=\"max_connections\", namespace=~\"$namespace\", pod=~\"$instances\"})))", + "hide": false, + "instant": false, + "legendFormat": "Connections", + "range": true, + "refId": "CONNS" + } + ], + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "Computes the time since the last known WAL archival in the primary.\nWe ensure to ignore the metric in the replicas by using (1 - cnpg_pg_replication_in_recovery ) as a multiplicative factor. It will be 0 for replicas, 1 for the primary.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "color": "red", + "index": 0, + "text": "No backups" + } + }, + "type": "special" + }, + { + "options": { + "from": -1e+22, + "result": { + "color": "text", + "index": 1, + "text": "No data" + }, + "to": 0 + }, + "type": "range" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "dtdurations", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 3, + "x": 21, + "y": 3 + }, + "id": 362, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "max((1 - cnpg_pg_replication_in_recovery{namespace=~\"$namespace\",pod=~\"$instances\"}) * (time() - timestamp(cnpg_pg_stat_archiver_seconds_since_last_archival{namespace=~\"$namespace\",pod=~\"$instances\"}) +\ncnpg_pg_stat_archiver_seconds_since_last_archival{namespace=~\"$namespace\",pod=~\"$instances\"}))", + "format": "time_series", + "instant": true, + "interval": "", + "legendFormat": "__auto", + "range": false, + "refId": "A" + } + ], + "title": "Last archived WAL", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "dark-blue", + "value": null + } + ] + }, + "unit": "string", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 2, + "x": 7, + "y": 4 + }, + "id": 340, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "/^full$/", + "values": false + }, + "showPercentChange": false, + "text": {}, + "textMode": "value", + "wideLayout": true + }, + "pluginVersion": "10.3.3", + "repeatDirection": "v", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "exemplar": false, + "expr": "cnpg_collector_postgres_version{namespace=~\"$namespace\",pod=~\"$instances\"}", + "format": "table", + "hide": false, + "instant": true, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{pod}}", + "range": false, + "refId": "A" + } + ], + "title": "Version", + "transformations": [], + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 1 + }, + { + "color": "orange", + "value": 10 + }, + { + "color": "red", + "value": 20 + } + ] + }, + "unit": "s", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 2, + "x": 15, + "y": 4 + }, + "id": 466, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "max(cnpg_pg_stat_replication_flush_lag_seconds{namespace=~\"$namespace\",pod=~\"$instances\"})", + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Flush Lag", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 1 + }, + { + "color": "orange", + "value": 10 + }, + { + "color": "red", + "value": 20 + } + ] + }, + "unit": "s", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 2, + "x": 17, + "y": 4 + }, + "id": 468, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "max(cnpg_pg_stat_replication_replay_lag_seconds{namespace=~\"$namespace\",pod=~\"$instances\"})", + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Replay Lag", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "Base Backups are considered healthy when there has been at least one base backup in the last 24 hours.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "color": "orange", + "index": 0, + "text": "None" + } + }, + "type": "special" + }, + { + "options": { + "from": 0, + "result": { + "color": "green", + "index": 1, + "text": "Healthy" + }, + "to": 90000 + }, + "type": "range" + }, + { + "options": { + "from": 90000, + "result": { + "color": "orange", + "index": 2, + "text": "Degraded" + }, + "to": 108000 + }, + "type": "range" + }, + { + "options": { + "from": 108000, + "result": { + "color": "red", + "index": 3, + "text": "None recent" + }, + "to": 4294967295 + }, + "type": "range" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unitScale": true + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "WAL" + }, + "properties": [ + { + "id": "mappings", + "value": [ + { + "options": { + "match": "null", + "result": { + "color": "orange", + "index": 0, + "text": "None" + } + }, + "type": "special" + }, + { + "options": { + "from": 0, + "result": { + "color": "green", + "index": 1, + "text": "Healthy" + }, + "to": 360 + }, + "type": "range" + }, + { + "options": { + "from": 360, + "result": { + "color": "orange", + "index": 2, + "text": "Delayed" + }, + "to": 900 + }, + "type": "range" + }, + { + "options": { + "from": 900, + "result": { + "color": "red", + "index": 3, + "text": "Unsynced" + }, + "to": 4294967295 + }, + "type": "range" + } + ] + } + ] + } + ] + }, + "gridPos": { + "h": 2, + "w": 1, + "x": 3, + "y": 5 + }, + "id": 588, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "value_and_name", + "wideLayout": true + }, + "pluginVersion": "10.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "time() - max(cnpg_collector_last_available_backup_timestamp{namespace=\"$namespace\", pod=~\"$instances\"})", + "legendFormat": "Backups", + "range": true, + "refId": "BACKUPS" + } + ], + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "Base Backups are considered healthy when there has been at least one base backup in the last 24 hours.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "color": "orange", + "index": 0, + "text": "None" + } + }, + "type": "special" + }, + { + "options": { + "from": 0, + "result": { + "color": "green", + "index": 1, + "text": "Healthy" + }, + "to": 360 + }, + "type": "range" + }, + { + "options": { + "from": 360, + "result": { + "color": "orange", + "index": 2, + "text": "Delayed" + }, + "to": 900 + }, + "type": "range" + }, + { + "options": { + "from": 900, + "result": { + "color": "red", + "index": 3, + "text": "Unsynced" + }, + "to": 4294967295 + }, + "type": "range" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unitScale": true + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "WAL" + }, + "properties": [ + { + "id": "mappings", + "value": [ + { + "options": { + "match": "null", + "result": { + "color": "orange", + "index": 0, + "text": "None" + } + }, + "type": "special" + }, + { + "options": { + "from": 0, + "result": { + "color": "green", + "index": 1, + "text": "Healthy" + }, + "to": 360 + }, + "type": "range" + }, + { + "options": { + "from": 360, + "result": { + "color": "orange", + "index": 2, + "text": "Delayed" + }, + "to": 900 + }, + "type": "range" + }, + { + "options": { + "from": 900, + "result": { + "color": "red", + "index": 3, + "text": "Unsynced" + }, + "to": 4294967295 + }, + "type": "range" + } + ] + } + ] + } + ] + }, + "gridPos": { + "h": 2, + "w": 1, + "x": 4, + "y": 5 + }, + "id": 612, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "value_and_name", + "wideLayout": true + }, + "pluginVersion": "10.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "max((1 - cnpg_pg_replication_in_recovery{namespace=~\"$namespace\", pod=~\"$instances\"}) * (time() - timestamp(cnpg_pg_stat_archiver_seconds_since_last_archival{namespace=~\"$namespace\", pod=~\"$instances\"}) +\ncnpg_pg_stat_archiver_seconds_since_last_archival{namespace=~\"$namespace\", pod=~\"$instances\"}))", + "hide": false, + "instant": false, + "legendFormat": "WAL", + "range": true, + "refId": "WAL" + } + ], + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "Online if there is at least one ready operator pod", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "0": { + "color": "red", + "index": 0, + "text": "Failure" + } + }, + "type": "value" + }, + { + "options": { + "from": 1, + "result": { + "color": "green", + "index": 1, + "text": "Online" + }, + "to": 99 + }, + "type": "range" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unitScale": true + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "A" + }, + "properties": [ + { + "id": "displayName", + "value": "Reconcile errors" + } + ] + } + ] + }, + "gridPos": { + "h": 2, + "w": 1, + "x": 5, + "y": 5 + }, + "id": 589, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "value_and_name", + "wideLayout": true + }, + "pluginVersion": "10.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum by (label_app_kubernetes_io_name) (kube_pod_status_ready{namespace=\"$operatorNamespace\"} * on (pod) group_left( label_app_kubernetes_io_name ) kube_pod_labels{label_app_kubernetes_io_name=~\"cloudnative-pg\"})", + "hide": false, + "instant": false, + "legendFormat": "Operator Status", + "range": true, + "refId": "A" + } + ], + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "The operator reconcile errors don't distinguish between database cluster or namespaces.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "0": { + "color": "green", + "index": 0, + "text": "None" + } + }, + "type": "value" + }, + { + "options": { + "from": 1, + "result": { + "color": "red", + "index": 1, + "text": "Backup" + }, + "to": 9 + }, + "type": "range" + }, + { + "options": { + "from": 10, + "result": { + "color": "red", + "index": 2, + "text": "Cluster" + }, + "to": 99 + }, + "type": "range" + }, + { + "options": { + "from": 100, + "result": { + "color": "red", + "index": 3, + "text": "Pooler" + }, + "to": 999 + }, + "type": "range" + }, + { + "options": { + "from": 1000, + "result": { + "color": "red", + "index": 4, + "text": "Scheduled Backup" + }, + "to": 9999 + }, + "type": "range" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unitScale": true + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "A" + }, + "properties": [ + { + "id": "displayName", + "value": "Reconcile errors" + } + ] + } + ] + }, + "gridPos": { + "h": 2, + "w": 1, + "x": 6, + "y": 5 + }, + "id": 655, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "value_and_name", + "wideLayout": true + }, + "pluginVersion": "10.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "clamp_max(max(controller_runtime_reconcile_total{namespace=~\"$operatorNamespace\", result=\"error\", controller=\"backup\"}), 1)", + "hide": true, + "legendFormat": "__auto", + "range": true, + "refId": "RECONCILE_ERRORS_BACKUP" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "clamp_max(max(controller_runtime_reconcile_total{namespace=~\"$operatorNamespace\", result=\"error\", controller=\"cluster\"}), 1)", + "hide": true, + "legendFormat": "__auto", + "range": true, + "refId": "RECONCILE_ERRORS_CLUSTER" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "clamp_max(max(controller_runtime_reconcile_total{namespace=~\"$operatorNamespace\", result=\"error\", controller=\"pooler\"}), 1)", + "hide": true, + "legendFormat": "__auto", + "range": true, + "refId": "RECONCILE_ERRORS_POOLER" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "clamp_max(max(controller_runtime_reconcile_total{namespace=~\"$operatorNamespace\", result=\"error\", controller=\"scheduledbackup\"}), 1)", + "hide": true, + "legendFormat": "__auto", + "range": true, + "refId": "RECONCILE_ERRORS_SCHEDULED_BACKUP" + }, + { + "datasource": { + "type": "__expr__", + "uid": "${DS_EXPRESSION}" + }, + "expression": "$RECONCILE_ERRORS_BACKUP + $RECONCILE_ERRORS_CLUSTER * 10 + $RECONCILE_ERRORS_POOLER * 100 + $RECONCILE_ERRORS_SCHEDULED_BACKUP * 1000", + "hide": false, + "refId": "A", + "type": "math" + } + ], + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 2, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "#EAB839", + "value": 80000000000 + }, + { + "color": "red", + "value": 90000000000 + } + ] + }, + "unit": "none", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 2, + "x": 11, + "y": 5 + }, + "id": 346, + "links": [], + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "center", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": true, + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{namespace=\"$namespace\", pod=~\"$instances\"})", + "hide": false, + "interval": "", + "legendFormat": "Total", + "range": true, + "refId": "B" + } + ], + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "Excluding cache", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "#EAB839", + "value": 80000000000 + }, + { + "color": "red", + "value": 90000000000 + } + ] + }, + "unit": "bytes", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 2, + "x": 13, + "y": 5 + }, + "id": 350, + "links": [], + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "center", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": true, + "expr": "sum(container_memory_working_set_bytes{pod=~\"$instances\", namespace=\"$namespace\", container!=\"\", image!=\"\"})", + "hide": false, + "interval": "", + "legendFormat": "Total", + "range": true, + "refId": "B" + } + ], + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 2, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "#EAB839", + "value": 60000000000 + }, + { + "color": "red", + "value": 80000000000 + } + ] + }, + "unit": "decbytes", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 2, + "x": 19, + "y": 5 + }, + "id": 358, + "links": [], + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "sum" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "value", + "wideLayout": true + }, + "pluginVersion": "10.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "cnpg_pg_database_size_bytes{namespace=\"$namespace\"}", + "format": "table", + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Database Size", + "transformations": [ + { + "id": "groupBy", + "options": { + "fields": { + "Value": { + "aggregations": [ + "max" + ], + "operation": "aggregate" + }, + "datname": { + "aggregations": [], + "operation": "groupby" + } + } + } + } + ], + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "0": { + "color": "red", + "index": 1, + "text": "N/A" + } + }, + "type": "value" + }, + { + "options": { + "match": "null", + "result": { + "color": "red", + "index": 0, + "text": "No backups" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "dateTimeAsIso", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 3, + "x": 21, + "y": 5 + }, + "id": 364, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "max(cnpg_collector_first_recoverability_point{namespace=~\"$namespace\",pod=~\"$instances\"})*1000", + "format": "time_series", + "instant": true, + "interval": "", + "legendFormat": "{{pod}}", + "range": false, + "refId": "A" + } + ], + "title": "First Recoverability Point", + "type": "stat" + }, + { + "collapsed": false, + "datasource": { + "uid": "prometheus" + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 7 + }, + "id": 12, + "panels": [], + "targets": [ + { + "datasource": { + "uid": "prometheus" + }, + "refId": "A" + } + ], + "title": "Server Health", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "h": 1, + "w": 3, + "x": 0, + "y": 8 + }, + "id": 191, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "", + "mode": "html" + }, + "pluginVersion": "10.3.3", + "repeatDirection": "v", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "kube_pod_container_status_ready{container=\"postgres\",namespace=~\"$namespace\",pod=~\"$instances\"}", + "instant": true, + "interval": "", + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "title": "Instance", + "transparent": true, + "type": "text" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "h": 1, + "w": 2, + "x": 3, + "y": 8 + }, + "id": 192, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "", + "mode": "html" + }, + "pluginVersion": "10.3.3", + "repeatDirection": "v", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "kube_pod_container_status_ready{container=\"postgres\",namespace=~\"$namespace\",pod=~\"$instances\"}", + "instant": true, + "interval": "", + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "title": "Status", + "type": "text" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "h": 1, + "w": 3, + "x": 5, + "y": 8 + }, + "id": 193, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "", + "mode": "html" + }, + "pluginVersion": "10.3.3", + "repeatDirection": "v", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "kube_pod_container_status_ready{container=\"postgres\",namespace=~\"$namespace\",pod=~\"$instances\"}", + "instant": true, + "interval": "", + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "title": "Clustering / replicas", + "type": "text" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "h": 1, + "w": 2, + "x": 8, + "y": 8 + }, + "id": 384, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "", + "mode": "html" + }, + "pluginVersion": "10.3.3", + "repeatDirection": "v", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "kube_pod_container_status_ready{container=\"postgres\",namespace=~\"$namespace\",pod=~\"$instances\"}", + "instant": true, + "interval": "", + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "title": "Zone", + "type": "text" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "h": 1, + "w": 4, + "x": 10, + "y": 8 + }, + "id": 195, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "", + "mode": "html" + }, + "pluginVersion": "10.3.3", + "repeatDirection": "v", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "kube_pod_container_status_ready{container=\"postgres\",namespace=~\"$namespace\",pod=~\"$instances\"}", + "instant": true, + "interval": "", + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "title": "Connections", + "type": "text" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "h": 1, + "w": 3, + "x": 14, + "y": 8 + }, + "id": 196, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "", + "mode": "html" + }, + "pluginVersion": "10.3.3", + "repeatDirection": "v", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "kube_pod_container_status_ready{container=\"postgres\",namespace=~\"$namespace\",pod=~\"$instances\"}", + "instant": true, + "interval": "", + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "title": "Max Connections", + "type": "text" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "gridPos": { + "h": 1, + "w": 3, + "x": 17, + "y": 8 + }, + "id": 197, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "", + "mode": "html" + }, + "pluginVersion": "10.3.3", + "repeatDirection": "v", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "kube_pod_container_status_ready{container=\"postgres\",namespace=~\"$namespace\",pod=~\"$instances\"}", + "instant": true, + "interval": "", + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "title": "Wraparound", + "type": "text" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "h": 1, + "w": 2, + "x": 20, + "y": 8 + }, + "id": 313, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "", + "mode": "html" + }, + "pluginVersion": "10.3.3", + "repeatDirection": "v", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "kube_pod_container_status_ready{container=\"postgres\",namespace=~\"$namespace\",pod=~\"$instances\"}", + "instant": true, + "interval": "", + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "title": "Started", + "type": "text" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "h": 1, + "w": 2, + "x": 22, + "y": 8 + }, + "id": 198, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "", + "mode": "html" + }, + "pluginVersion": "10.3.3", + "repeatDirection": "v", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "kube_pod_container_status_ready{container=\"postgres\",namespace=~\"$namespace\",pod=~\"$instances\"}", + "instant": true, + "interval": "", + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "title": "Version", + "type": "text" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 0, + "y": 9 + }, + "id": 61, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "\n \n

$instances

\n
", + "mode": "html" + }, + "pluginVersion": "10.3.3", + "repeat": "instances", + "repeatDirection": "v", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "kube_pod_container_status_ready{container=\"postgres\",namespace=~\"$namespace\",pod=~\"$instances\"}", + "instant": true, + "interval": "", + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "type": "text" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "0": { + "index": 0, + "text": "Down" + }, + "1": { + "index": 1, + "text": "Up" + } + }, + "type": "value" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "dark-red", + "value": null + }, + { + "color": "green", + "value": 1 + } + ] + }, + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 2, + "x": 3, + "y": 9 + }, + "id": 33, + "options": { + "colorMode": "background", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "text": {}, + "textMode": "value", + "wideLayout": true + }, + "pluginVersion": "10.3.3", + "repeat": "instances", + "repeatDirection": "v", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": true, + "expr": "min(kube_pod_container_status_ready{container=\"postgres\",namespace=~\"$namespace\",pod=~\"$instances\"})", + "instant": true, + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "0": { + "color": "red", + "index": 1, + "text": "No" + }, + "1": { + "color": "green", + "index": 0, + "text": "Yes" + } + }, + "type": "value" + } + ], + "noValue": "-", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 2, + "x": 5, + "y": 9 + }, + "id": 60, + "options": { + "colorMode": "background", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "text": {}, + "textMode": "value", + "wideLayout": true + }, + "pluginVersion": "10.3.3", + "repeat": "instances", + "repeatDirection": "v", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "1 - cnpg_pg_replication_in_recovery{namespace=~\"$namespace\",pod=~\"$instances\"} + cnpg_pg_replication_is_wal_receiver_up{namespace=~\"$namespace\",pod=~\"$instances\"}", + "instant": true, + "interval": "", + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "transformations": [], + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "noValue": "-", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 1, + "x": 7, + "y": 9 + }, + "id": 229, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "text": {}, + "textMode": "value", + "wideLayout": true + }, + "pluginVersion": "10.3.3", + "repeat": "instances", + "repeatDirection": "v", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": true, + "expr": "cnpg_pg_replication_streaming_replicas{namespace=~\"$namespace\", pod=~\"$instances\"}", + "instant": true, + "interval": "", + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "transformations": [], + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "This metric depends on exporting the: `topology.kubernetes.io/zone` label through kube-state-metrics (not enabled by default). Can be added by changing its configuration with:\n\n```yaml\nmetricLabelsAllowlist:\n - nodes=[topology.kubernetes.io/zone]\n```", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "blue", + "value": null + } + ] + }, + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 2, + "x": 8, + "y": 9 + }, + "id": 386, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "/^label_topology_kubernetes_io_zone$/", + "values": false + }, + "showPercentChange": false, + "text": { + "valueSize": 18 + }, + "textMode": "value", + "wideLayout": true + }, + "pluginVersion": "10.3.3", + "repeat": "instances", + "repeatDirection": "v", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": true, + "expr": "kube_pod_info{namespace=~\"$namespace\", pod=~\"$instances\"} * on(node,instance) group_left(label_topology_kubernetes_io_zone) kube_node_labels", + "format": "table", + "instant": true, + "interval": "", + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "transformations": [], + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "short", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 10, + "y": 9 + }, + "id": 58, + "options": { + "legend": { + "calcs": [ + "last", + "mean" + ], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "8.2.1", + "repeat": "instances", + "repeatDirection": "v", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": true, + "expr": "sum by (pod) (cnpg_backends_total{namespace=~\"$namespace\", pod=~\"$instances\"})", + "instant": false, + "interval": "", + "legendFormat": "-", + "refId": "A" + } + ], + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 0, + "mappings": [], + "max": 100, + "min": 0, + "noValue": "<1%", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "#EAB839", + "value": 75 + }, + { + "color": "red", + "value": 90 + } + ] + }, + "unit": "percent", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 14, + "y": 9 + }, + "id": 32, + "options": { + "minVizHeight": 75, + "minVizWidth": 75, + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "last" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "sizing": "auto", + "text": {} + }, + "pluginVersion": "10.3.3", + "repeat": "instances", + "repeatDirection": "v", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": true, + "expr": "100 * sum by (pod) (cnpg_backends_total{namespace=~\"$namespace\", pod=~\"$instances\"}) / sum by (pod) (cnpg_pg_settings_setting{name=\"max_connections\", namespace=~\"$namespace\", pod=~\"$instances\"})", + "instant": true, + "interval": "", + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "type": "gauge" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "max": 2147483647, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "#EAB839", + "value": 200000000 + }, + { + "color": "red", + "value": 1000000000 + } + ] + }, + "unit": "none", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 17, + "y": 9 + }, + "id": 8, + "options": { + "displayMode": "lcd", + "maxVizHeight": 300, + "minVizHeight": 10, + "minVizWidth": 0, + "namePlacement": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showUnfilled": true, + "sizing": "auto", + "text": {}, + "valueMode": "color" + }, + "pluginVersion": "10.3.3", + "repeat": "instances", + "repeatDirection": "v", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": true, + "expr": "max by (pod) (cnpg_pg_database_xid_age{namespace=~\"$namespace\", pod=~\"$instances\"})", + "instant": true, + "interval": "", + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "type": "bargauge" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "dark-blue", + "value": null + } + ] + }, + "unit": "dateTimeFromNow", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 2, + "x": 20, + "y": 9 + }, + "id": 314, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "text": {}, + "textMode": "value", + "wideLayout": true + }, + "pluginVersion": "10.3.3", + "repeat": "instances", + "repeatDirection": "v", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "cnpg_pg_postmaster_start_time{namespace=~\"$namespace\", pod=~\"$instances\"}*1000", + "format": "time_series", + "hide": false, + "instant": true, + "interval": "", + "intervalFactor": 1, + "legendFormat": "", + "refId": "A" + } + ], + "transformations": [], + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "dark-blue", + "value": null + } + ] + }, + "unit": "string", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 2, + "x": 22, + "y": 9 + }, + "id": 42, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "/^full$/", + "values": false + }, + "showPercentChange": false, + "text": {}, + "textMode": "value", + "wideLayout": true + }, + "pluginVersion": "10.3.3", + "repeat": "instances", + "repeatDirection": "v", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "cnpg_collector_postgres_version{namespace=~\"$namespace\", pod=~\"$instances\"}", + "format": "table", + "hide": false, + "instant": true, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "transformations": [], + "type": "stat" + }, + { + "collapsed": true, + "datasource": { + "uid": "prometheus" + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 18 + }, + "id": 41, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "h": 1, + "w": 3, + "x": 0, + "y": 25 + }, + "id": 187, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "", + "mode": "html" + }, + "pluginVersion": "10.3.1", + "repeatDirection": "v", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "kube_pod_container_status_ready{container=\"postgres\",namespace=~\"$namespace\",pod=~\"$instances\"}", + "instant": true, + "interval": "", + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "title": "Instance", + "transparent": true, + "type": "text" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "h": 1, + "w": 3, + "x": 3, + "y": 25 + }, + "id": 183, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "", + "mode": "html" + }, + "pluginVersion": "10.3.1", + "repeatDirection": "v", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "kube_pod_container_status_ready{container=\"postgres\",namespace=~\"$namespace\",pod=~\"$instances\"}", + "instant": true, + "interval": "", + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "title": "Max Connections", + "type": "text" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "h": 1, + "w": 3, + "x": 6, + "y": 25 + }, + "id": 184, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "", + "mode": "html" + }, + "pluginVersion": "10.3.1", + "repeatDirection": "v", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "kube_pod_container_status_ready{container=\"postgres\",namespace=~\"$namespace\",pod=~\"$instances\"}", + "instant": true, + "interval": "", + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "title": "Shared Buffers", + "type": "text" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "h": 1, + "w": 3, + "x": 9, + "y": 25 + }, + "id": 185, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "", + "mode": "html" + }, + "pluginVersion": "10.3.1", + "repeatDirection": "v", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "kube_pod_container_status_ready{container=\"postgres\",namespace=~\"$namespace\",pod=~\"$instances\"}", + "instant": true, + "interval": "", + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "title": "Effective Cache Size", + "type": "text" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "h": 1, + "w": 3, + "x": 12, + "y": 25 + }, + "id": 186, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "", + "mode": "html" + }, + "pluginVersion": "10.3.1", + "repeatDirection": "v", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "kube_pod_container_status_ready{container=\"postgres\",namespace=~\"$namespace\",pod=~\"$instances\"}", + "instant": true, + "interval": "", + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "title": "Work Mem", + "type": "text" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "h": 1, + "w": 3, + "x": 15, + "y": 25 + }, + "id": 188, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "", + "mode": "html" + }, + "pluginVersion": "10.3.1", + "repeatDirection": "v", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "kube_pod_container_status_ready{container=\"postgres\",namespace=~\"$namespace\",pod=~\"$instances\"}", + "instant": true, + "interval": "", + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "title": "Maintenance Work Mem", + "type": "text" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "h": 1, + "w": 3, + "x": 18, + "y": 25 + }, + "id": 189, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "", + "mode": "html" + }, + "pluginVersion": "10.3.1", + "repeatDirection": "v", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "kube_pod_container_status_ready{container=\"postgres\",namespace=~\"$namespace\",pod=~\"$instances\"}", + "instant": true, + "interval": "", + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "title": "Random Page Cost", + "type": "text" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "h": 1, + "w": 3, + "x": 21, + "y": 25 + }, + "id": 190, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "", + "mode": "html" + }, + "pluginVersion": "10.3.1", + "repeatDirection": "v", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "kube_pod_container_status_ready{container=\"postgres\",namespace=~\"$namespace\",pod=~\"$instances\"}", + "instant": true, + "interval": "", + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "title": "Sequential Page Cost", + "type": "text" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 0, + "y": 26 + }, + "id": 86, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "\n \n

$instances

\n
", + "mode": "html" + }, + "pluginVersion": "10.3.1", + "repeat": "instances", + "repeatDirection": "v", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "kube_pod_container_status_ready{container=\"postgres\",namespace=~\"$namespace\",pod=~\"$instances\"}", + "instant": true, + "interval": "", + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "type": "text" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "dark-purple" + } + ] + }, + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 3, + "y": 26 + }, + "id": 30, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "text": {}, + "textMode": "value", + "wideLayout": true + }, + "pluginVersion": "10.3.1", + "repeat": "instances", + "repeatDirection": "v", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "cnpg_pg_settings_setting{name=\"max_connections\",namespace=~\"$namespace\",pod=~\"$instances\"}", + "instant": true, + "interval": "", + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "dark-purple" + } + ] + }, + "unit": "bytes", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 6, + "y": 26 + }, + "id": 24, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "text": {}, + "textMode": "value", + "wideLayout": true + }, + "pluginVersion": "10.3.1", + "repeat": "instances", + "repeatDirection": "v", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "max by (pod) (cnpg_pg_settings_setting{name=\"shared_buffers\",namespace=~\"$namespace\",pod=~\"$instances\"}) * max by (pod) (cnpg_pg_settings_setting{name=\"block_size\",namespace=~\"$namespace\",pod=~\"$instances\"})", + "instant": true, + "interval": "", + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "dark-purple" + } + ] + }, + "unit": "bytes", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 9, + "y": 26 + }, + "id": 57, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "text": {}, + "textMode": "value", + "wideLayout": true + }, + "pluginVersion": "10.3.1", + "repeat": "instances", + "repeatDirection": "v", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "max by (pod) (cnpg_pg_settings_setting{name=\"effective_cache_size\",namespace=~\"$namespace\",pod=~\"$instances\"}) * max by (pod) (cnpg_pg_settings_setting{name=\"block_size\",namespace=~\"$namespace\",pod=~\"$instances\"})", + "instant": true, + "interval": "", + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "dark-purple" + } + ] + }, + "unit": "bytes", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 12, + "y": 26 + }, + "id": 26, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "text": {}, + "textMode": "value", + "wideLayout": true + }, + "pluginVersion": "10.3.1", + "repeat": "instances", + "repeatDirection": "v", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "cnpg_pg_settings_setting{name=\"work_mem\",namespace=~\"$namespace\",pod=~\"$instances\"} * 1024", + "instant": true, + "interval": "", + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "dark-purple" + } + ] + }, + "unit": "bytes", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 15, + "y": 26 + }, + "id": 47, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "text": {}, + "textMode": "value", + "wideLayout": true + }, + "pluginVersion": "10.3.1", + "repeat": "instances", + "repeatDirection": "v", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "cnpg_pg_settings_setting{name=\"maintenance_work_mem\",namespace=~\"$namespace\",pod=~\"$instances\"}", + "instant": true, + "interval": "", + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "dark-purple" + } + ] + }, + "unit": "none", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 18, + "y": 26 + }, + "id": 48, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "text": {}, + "textMode": "value", + "wideLayout": true + }, + "pluginVersion": "10.3.1", + "repeat": "instances", + "repeatDirection": "v", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "cnpg_pg_settings_setting{name=\"random_page_cost\",namespace=~\"$namespace\",pod=~\"$instances\"}", + "instant": true, + "interval": "", + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "dark-purple" + } + ] + }, + "unit": "none", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 21, + "y": 26 + }, + "id": 56, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "text": {}, + "textMode": "value", + "wideLayout": true + }, + "pluginVersion": "10.3.1", + "repeat": "instances", + "repeatDirection": "v", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "cnpg_pg_settings_setting{name=\"seq_page_cost\",namespace=~\"$namespace\",pod=~\"$instances\"}", + "instant": true, + "interval": "", + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "auto", + "cellOptions": { + "type": "auto" + }, + "filterable": true, + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "dark-purple" + } + ] + }, + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 24, + "x": 0, + "y": 32 + }, + "id": 150, + "options": { + "cellHeight": "sm", + "footer": { + "countRows": false, + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true, + "sortBy": [] + }, + "pluginVersion": "10.3.1", + "repeatDirection": "v", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "cnpg_pg_settings_setting{namespace=~\"$namespace\",pod=~\"$instances\"}", + "format": "table", + "instant": true, + "interval": "", + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "title": "Configurations", + "transformations": [ + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true, + "__name__": true, + "container": true, + "endpoint": true, + "instance": true, + "job": true, + "name": false, + "namespace": true, + "pod": false + }, + "indexByName": { + "Time": 0, + "Value": 9, + "__name__": 1, + "container": 2, + "endpoint": 3, + "instance": 4, + "job": 5, + "name": 7, + "namespace": 8, + "pod": 6 + }, + "renameByName": { + "__name__": "", + "name": "parameter" + } + } + }, + { + "id": "groupingToMatrix", + "options": { + "columnField": "pod", + "rowField": "parameter", + "valueField": "Value" + } + }, + { + "id": "organize", + "options": { + "excludeByName": {}, + "indexByName": {}, + "renameByName": { + "parameter\\pod": "parameter" + } + } + } + ], + "type": "table" + } + ], + "targets": [ + { + "datasource": { + "uid": "prometheus" + }, + "refId": "A" + } + ], + "title": "Configuration", + "type": "row" + }, + { + "collapsed": false, + "datasource": { + "uid": "prometheus" + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 19 + }, + "id": 10, + "panels": [], + "targets": [ + { + "datasource": { + "uid": "prometheus" + }, + "refId": "A" + } + ], + "title": "Operational Stats", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 100, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "log": 10, + "type": "log" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "normal" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 20 + }, + "id": 273, + "links": [], + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "10.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{pod=~\"$instances\", namespace=~\"$namespace\"}) by (pod)", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{pod}}", + "refId": "A", + "step": 10 + } + ], + "title": "CPU Usage", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 100, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "bytes", + "unitScale": true + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "quota - requests" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "#F2495C", + "mode": "fixed" + } + }, + { + "id": "custom.fillOpacity", + "value": 0 + }, + { + "id": "custom.lineWidth", + "value": 2 + }, + { + "id": "custom.stacking", + "value": { + "group": "A", + "mode": "none" + } + }, + { + "id": "custom.lineStyle", + "value": { + "dash": [ + 10, + 10 + ], + "fill": "dash" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "quota - limits" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "#FF9830", + "mode": "fixed" + } + }, + { + "id": "custom.fillOpacity", + "value": 0 + }, + { + "id": "custom.lineWidth", + "value": 2 + }, + { + "id": "custom.stacking", + "value": { + "group": "A", + "mode": "none" + } + }, + { + "id": "custom.lineStyle", + "value": { + "dash": [ + 10, + 10 + ], + "fill": "dash" + } + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 20 + }, + "id": 275, + "links": [], + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "10.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "sum(container_memory_working_set_bytes{pod=~\"$instances\", namespace=\"$namespace\", container!=\"\", image!=\"\"}) by (pod)", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{pod}}", + "refId": "A", + "step": 10 + } + ], + "title": "Memory Usage (w/o cache)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 27 + }, + "id": 39, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "sum(cnpg_backends_total{namespace=~\"$namespace\",pod=~\"$instances\"}) by (pod)", + "hide": false, + "interval": "", + "legendFormat": "total ({{pod}})", + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "sum(cnpg_backends_total{namespace=~\"$namespace\",pod=~\"$instances\"}) by (state, pod)", + "interval": "", + "legendFormat": "{{state}} ({{pod}})", + "refId": "A" + } + ], + "title": "Session States", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 35 + }, + "id": 50, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": true, + "expr": "sum(rate(cnpg_pg_stat_database_xact_commit{namespace=~\"$namespace\",pod=~\"$instances\"}[5m])) by (pod)", + "interval": "", + "legendFormat": "committed ({{pod}})", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "sum(rate(cnpg_pg_stat_database_xact_rollback{namespace=~\"$namespace\",pod=~\"$instances\"}[5m])) by (pod)", + "hide": false, + "interval": "", + "legendFormat": "rolled back ({{pod}})", + "refId": "B" + } + ], + "title": "Transactions [5m]", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 35 + }, + "id": 4, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "max by (pod) (cnpg_backends_max_tx_duration_seconds{namespace=~\"$namespace\",pod=~\"$instances\"})", + "interval": "", + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "title": "Longest Transaction", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 43 + }, + "id": 55, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "rate(cnpg_pg_stat_database_deadlocks{datname=\"\",namespace=~\"$namespace\",pod=~\"$instances\"}[5m])", + "hide": false, + "instant": false, + "interval": "", + "legendFormat": "count ({{pod}})", + "refId": "B" + } + ], + "title": "Deadlocks [5m]", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 43 + }, + "id": 54, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "cnpg_backends_waiting_total{namespace=~\"$namespace\",pod=~\"$instances\"}", + "interval": "", + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "title": "Blocked Queries", + "type": "timeseries" + }, + { + "collapsed": true, + "datasource": { + "uid": "prometheus" + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 51 + }, + "id": 35, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "max": 1, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "#EAB839", + "value": 0.7 + }, + { + "color": "red", + "value": 0.8 + } + ] + }, + "unit": "percentunit", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 52 + }, + "id": 424, + "options": { + "minVizHeight": 75, + "minVizWidth": 75, + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "sizing": "auto", + "text": {} + }, + "pluginVersion": "10.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "max by(persistentvolumeclaim) (1 - kubelet_volume_stats_available_bytes{namespace=\"$namespace\", persistentvolumeclaim=~\"$instances\"} / kubelet_volume_stats_capacity_bytes{namespace=\"$namespace\", persistentvolumeclaim=~\"$instances\"})", + "format": "time_series", + "interval": "", + "legendFormat": "{{persistentvolumeclaim}}", + "range": true, + "refId": "FREE_SPACE" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "max by(persistentvolumeclaim) (1 - kubelet_volume_stats_available_bytes{namespace=\"$namespace\", persistentvolumeclaim=~\"(${instances})-wal\"} / kubelet_volume_stats_capacity_bytes{namespace=\"$namespace\", persistentvolumeclaim=~\"(${instances})-wal\"})", + "format": "time_series", + "interval": "", + "legendFormat": "{{persistentvolumeclaim}}", + "range": true, + "refId": "FREE_SPACE_WAL" + } + ], + "title": "Volume Space Usage: PGDATA and WAL", + "transformations": [], + "type": "gauge" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 2, + "mappings": [], + "max": 1, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "#EAB839", + "value": 0.8 + }, + { + "color": "red", + "value": 0.9 + } + ] + }, + "unit": "percentunit", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 52 + }, + "id": 426, + "options": { + "minVizHeight": 75, + "minVizWidth": 75, + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "sizing": "auto" + }, + "pluginVersion": "10.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "max by(persistentvolumeclaim) (kubelet_volume_stats_inodes_used{namespace=\"$namespace\", persistentvolumeclaim=~\"$instances\"} / kubelet_volume_stats_inodes{namespace=\"$namespace\", persistentvolumeclaim=~\"$instances\"})", + "format": "time_series", + "interval": "", + "legendFormat": "{{persistentvolumeclaim}}", + "range": true, + "refId": "FREE_INODES" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "max by(persistentvolumeclaim) (kubelet_volume_stats_inodes_used{namespace=\"$namespace\", persistentvolumeclaim=~\"(${instances})-wal\"} / kubelet_volume_stats_inodes{namespace=\"$namespace\", persistentvolumeclaim=~\"(${instances})-wal\"})", + "format": "time_series", + "interval": "", + "legendFormat": "{{persistentvolumeclaim}}", + "range": true, + "refId": "FREE_INODES_WAL" + } + ], + "title": "Volume Inode Usage: PGDATA and WAL", + "transformations": [], + "type": "gauge" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "max": 1, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "#EAB839", + "value": 0.7 + }, + { + "color": "red", + "value": 0.8 + } + ] + }, + "unit": "percentunit", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 60 + }, + "id": 564, + "options": { + "minVizHeight": 75, + "minVizWidth": 75, + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "sizing": "auto", + "text": {} + }, + "pluginVersion": "10.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum by (namespace,persistentvolumeclaim) (kubelet_volume_stats_used_bytes{namespace=\"$namespace\", persistentvolumeclaim=~\"(${instances})-tbs.*\"}) \n/\nsum by (namespace,persistentvolumeclaim) (kubelet_volume_stats_capacity_bytes{namespace=\"$namespace\", persistentvolumeclaim=~\"(${instances})-tbs.*\"}) \n*\non(namespace, persistentvolumeclaim) group_left(volume,pod)\nkube_pod_spec_volumes_persistentvolumeclaims_info{pod=~\"$instances\"}", + "format": "time_series", + "interval": "", + "legendFormat": "{{volume}}-{{pod}}", + "range": true, + "refId": "FREE_SPACE" + } + ], + "title": "Volume Space Usage: Tablespaces", + "transformations": [], + "type": "gauge" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 67 + }, + "id": 44, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": true, + "expr": "sum(rate(cnpg_pg_stat_database_tup_deleted{datname=\"\",namespace=~\"$namespace\",pod=~\"$instances\"}[5m]))", + "interval": "", + "legendFormat": "deleted", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": true, + "expr": "sum(rate(cnpg_pg_stat_database_tup_inserted{datname=\"\",namespace=~\"$namespace\",pod=~\"$instances\"}[5m]))", + "hide": false, + "interval": "", + "legendFormat": "inserted", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": true, + "expr": "sum(rate(cnpg_pg_stat_database_tup_fetched{datname=\"\",namespace=~\"$namespace\",pod=~\"$instances\"}[5m]))", + "hide": false, + "interval": "", + "legendFormat": "fetched", + "range": true, + "refId": "C" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": true, + "expr": "sum(rate(cnpg_pg_stat_database_tup_returned{datname=\"\",namespace=~\"$namespace\",pod=~\"$instances\"}[5m]))", + "hide": false, + "interval": "", + "legendFormat": "returned", + "range": true, + "refId": "D" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": true, + "expr": "sum(rate(cnpg_pg_stat_database_tup_updated{datname=\"\",namespace=~\"$namespace\",pod=~\"$instances\"}[5m]))", + "hide": false, + "interval": "", + "legendFormat": "updated", + "range": true, + "refId": "E" + } + ], + "title": "Tuple I/O [5m]", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 67 + }, + "id": 46, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": true, + "expr": "rate(cnpg_pg_stat_database_blks_hit{datname=\"\",namespace=~\"$namespace\",pod=~\"$instances\"}[5m])", + "interval": "", + "legendFormat": "hit ({{pod}})", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": true, + "expr": "rate(cnpg_pg_stat_database_blks_read{datname=\"\",namespace=~\"$namespace\",pod=~\"$instances\"}[5m])", + "hide": false, + "interval": "", + "legendFormat": "read ({{pod}})", + "range": true, + "refId": "B" + } + ], + "title": "Block I/O [5m]", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + }, + "unit": "decbytes", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 75 + }, + "id": 22, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "8.0.5", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": true, + "expr": "max by (datname) (cnpg_pg_database_size_bytes{datname!~\"template.*\",datname!=\"postgres\",namespace=~\"$namespace\",pod=~\"$instances\"})", + "interval": "", + "legendFormat": " {{pod}}: {{datname}}", + "range": true, + "refId": "A" + } + ], + "title": "Database Size", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "decbytes", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 75 + }, + "id": 2, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "rate(cnpg_pg_stat_database_temp_bytes{datname=\"\",namespace=~\"$namespace\",pod=~\"$instances\"}[5m])", + "instant": false, + "interval": "", + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "title": "Temp Bytes [5m]", + "type": "timeseries" + } + ], + "targets": [ + { + "datasource": { + "uid": "prometheus" + }, + "refId": "A" + } + ], + "title": "Storage & I/O", + "type": "row" + }, + { + "collapsed": true, + "datasource": { + "uid": "prometheus" + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 52 + }, + "id": 37, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 53 + }, + "id": 6, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "cnpg_collector_pg_wal_archive_status{value=\"ready\",namespace=~\"$namespace\",pod=~\"$instances\"}", + "interval": "", + "legendFormat": "ready ({{pod}})", + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "cnpg_collector_pg_wal_archive_status{value=\"done\",namespace=~\"$namespace\",pod=~\"$instances\"}", + "hide": false, + "interval": "", + "legendFormat": "done ({{pod}})", + "refId": "B" + } + ], + "title": "WAL Segment Archive Status", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 53 + }, + "id": 52, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "rate(cnpg_pg_stat_archiver_archived_count{namespace=~\"$namespace\",pod=~\"$instances\"}[5m])", + "interval": "", + "legendFormat": "archived ({{pod}})", + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "rate(cnpg_pg_stat_archiver_failed_count{namespace=~\"$namespace\",pod=~\"$instances\"}[5m])", + "hide": false, + "interval": "", + "legendFormat": "failed ({{pod}})", + "refId": "B" + } + ], + "title": "Archiver Status [5m]", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 16, + "y": 53 + }, + "id": 53, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "cnpg_pg_stat_archiver_seconds_since_last_archival{namespace=~\"$namespace\",pod=~\"$instances\"}", + "interval": "", + "legendFormat": "age ({{pod}})", + "refId": "A" + } + ], + "title": "Last Archive Age", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 61 + }, + "id": 725, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "cnpg_collector_pg_wal{pod=~\"$instances\", namespace=~\"$namespace\", value=\"count\"}", + "instant": false, + "legendFormat": "{{pod}}", + "range": true, + "refId": "A" + } + ], + "title": "WAL Count", + "type": "timeseries" + } + ], + "targets": [ + { + "datasource": { + "uid": "prometheus" + }, + "refId": "A" + } + ], + "title": "Write Ahead Log", + "type": "row" + }, + { + "collapsed": true, + "datasource": { + "uid": "prometheus" + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 53 + }, + "id": 18, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "line" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "#EAB839", + "value": 600 + }, + { + "color": "dark-red", + "value": 3600 + } + ] + }, + "unit": "s", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 6, + "x": 0, + "y": 59 + }, + "id": 16, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "cnpg_pg_replication_lag{namespace=~\"$namespace\",pod=~\"$instances\"}", + "instant": false, + "interval": "", + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "title": "Replication Lag", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 6, + "x": 6, + "y": 59 + }, + "id": 14, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": true, + "expr": "cnpg_pg_stat_replication_write_lag_seconds{namespace=~\"$namespace\",pod=~\"$instances\"}", + "instant": false, + "interval": "", + "legendFormat": "{{pod}} -> {{application_name}}", + "refId": "A" + } + ], + "title": "Write Lag", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 6, + "x": 12, + "y": 59 + }, + "id": 59, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": true, + "expr": "cnpg_pg_stat_replication_flush_lag_seconds{namespace=~\"$namespace\",pod=~\"$instances\"}", + "instant": false, + "interval": "", + "legendFormat": "{{pod}} -> {{application_name}}", + "refId": "A" + } + ], + "title": "Flush Lag", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 6, + "x": 18, + "y": 59 + }, + "id": 20, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": true, + "expr": "cnpg_pg_stat_replication_replay_lag_seconds{namespace=~\"$namespace\",pod=~\"$instances\"}", + "interval": "", + "legendFormat": "{{pod}} -> {{application_name}}", + "range": true, + "refId": "A" + } + ], + "title": "Replay Lag", + "type": "timeseries" + } + ], + "targets": [ + { + "datasource": { + "uid": "prometheus" + }, + "refId": "A" + } + ], + "title": "Replication", + "type": "row" + }, + { + "collapsed": true, + "datasource": { + "uid": "prometheus" + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 54 + }, + "id": 231, + "panels": [ + { + "cards": {}, + "color": { + "cardColor": "#b4ff00", + "colorScale": "sqrt", + "colorScheme": "interpolateOranges", + "exponent": 0.5, + "mode": "spectrum" + }, + "dataFormat": "timeseries", + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "custom": { + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "scaleDistribution": { + "type": "linear" + } + }, + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 55 + }, + "heatmap": {}, + "hideZeroBuckets": false, + "highlightCards": true, + "id": 233, + "legend": { + "show": false + }, + "options": { + "calculate": true, + "calculation": {}, + "cellGap": 2, + "cellValues": {}, + "color": { + "exponent": 0.5, + "fill": "#b4ff00", + "mode": "scheme", + "reverse": false, + "scale": "exponential", + "scheme": "Oranges", + "steps": 128 + }, + "exemplars": { + "color": "rgba(255,0,255,0.7)" + }, + "filterValues": { + "le": 1e-9 + }, + "legend": { + "show": false + }, + "rowsFrame": { + "layout": "auto" + }, + "showValue": "never", + "tooltip": { + "mode": "single", + "showColorScale": false, + "yHistogram": false + }, + "yAxis": { + "axisPlacement": "left", + "reverse": false, + "unit": "s" + } + }, + "pluginVersion": "10.3.3", + "reverseYBuckets": false, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "cnpg_collector_collection_duration_seconds{namespace=~\"$namespace\",pod=~\"$instances\"}", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "title": "Collection Duration", + "tooltip": { + "show": true, + "showHistogram": false + }, + "type": "heatmap", + "xAxis": { + "show": true + }, + "yAxis": { + "format": "s", + "logBase": 1, + "show": true + }, + "yBucketBound": "auto" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 55 + }, + "id": 235, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "cnpg_collector_last_collection_error{namespace=~\"$namespace\",pod=~\"$instances\"}", + "interval": "", + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "title": "Errors", + "type": "timeseries" + } + ], + "targets": [ + { + "datasource": { + "uid": "prometheus" + }, + "refId": "A" + } + ], + "title": "Collector Stats", + "type": "row" + }, + { + "collapsed": true, + "datasource": { + "uid": "prometheus" + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 55 + }, + "id": 239, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "dateTimeAsIso", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 8, + "x": 0, + "y": 56 + }, + "id": 237, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "cnpg_collector_first_recoverability_point{namespace=~\"$namespace\",pod=~\"$instances\"}*1000 > 0", + "format": "time_series", + "interval": "", + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "title": "First Recoverability Point", + "type": "timeseries" + } + ], + "targets": [ + { + "datasource": { + "uid": "prometheus" + }, + "refId": "A" + } + ], + "title": "Backups", + "type": "row" + }, + { + "collapsed": true, + "datasource": { + "uid": "prometheus" + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 56 + }, + "id": 293, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": -1, + "drawStyle": "line", + "fillOpacity": 8, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "none", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 5, + "x": 0, + "y": 57 + }, + "id": 295, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "8.2.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "cnpg_pg_stat_bgwriter_checkpoints_req{namespace=~\"$namespace\",pod=~\"$instances\"}", + "format": "time_series", + "hide": false, + "instant": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "req/{{pod}}", + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "cnpg_pg_stat_bgwriter_checkpoints_timed{namespace=~\"$namespace\",pod=~\"$instances\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "legendFormat": "timed/{{pod}}", + "refId": "A" + } + ], + "title": "Requested/Timed", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": -1, + "drawStyle": "line", + "fillOpacity": 8, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "ms", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 5, + "x": 5, + "y": 57 + }, + "id": 296, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "8.2.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "cnpg_pg_stat_bgwriter_checkpoint_write_time{namespace=~\"$namespace\",pod=~\"$instances\"}", + "format": "time_series", + "hide": false, + "instant": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "write/{{pod}}", + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "cnpg_pg_stat_bgwriter_checkpoint_sync_time{namespace=~\"$namespace\",pod=~\"$instances\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "legendFormat": "sync/{{pod}}", + "refId": "A" + } + ], + "title": "Write/Sync time", + "type": "timeseries" + } + ], + "targets": [ + { + "datasource": { + "uid": "prometheus" + }, + "refId": "A" + } + ], + "title": "Checkpoints", + "type": "row" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 57 + }, + "id": 696, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "0": { + "color": "red", + "index": 0, + "text": "No Ready pods" + } + }, + "type": "value" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + }, + "unitScale": true + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "A" + }, + "properties": [ + { + "id": "displayName", + "value": "Reconcile errors" + } + ] + } + ] + }, + "gridPos": { + "h": 2, + "w": 4, + "x": 0, + "y": 64 + }, + "id": 697, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "value_and_name", + "wideLayout": true + }, + "pluginVersion": "10.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum(kube_pod_status_ready{namespace=\"$operatorNamespace\"} * on (pod) group_left( label_app_kubernetes_io_name ) kube_pod_labels{label_app_kubernetes_io_name=~\"cloudnative-pg\"})", + "hide": false, + "instant": true, + "legendFormat": "Ready Operator Pods", + "range": false, + "refId": "A" + } + ], + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "The operator reconcile errors don't distinguish between database cluster or namespaces.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "0": { + "color": "green", + "index": 0, + "text": "None" + } + }, + "type": "value" + }, + { + "options": { + "from": 1, + "result": { + "color": "red", + "index": 1 + }, + "to": 4294967295 + }, + "type": "range" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + }, + "unitScale": true + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "A" + }, + "properties": [ + { + "id": "displayName", + "value": "Reconcile errors" + } + ] + } + ] + }, + "gridPos": { + "h": 2, + "w": 4, + "x": 4, + "y": 64 + }, + "id": 702, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "value_and_name", + "wideLayout": true + }, + "pluginVersion": "10.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "max(controller_runtime_reconcile_total{namespace=~\"$operatorNamespace\", result=\"error\", controller=\"cluster\"})", + "hide": false, + "instant": true, + "legendFormat": "Cluster Reconcile Errors", + "range": false, + "refId": "RECONCILE_ERRORS_BACKUP" + } + ], + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "The operator reconcile errors don't distinguish between database cluster or namespaces.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "0": { + "color": "green", + "index": 0, + "text": "None" + } + }, + "type": "value" + }, + { + "options": { + "from": 1, + "result": { + "color": "red", + "index": 1 + }, + "to": 4294967295 + }, + "type": "range" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + }, + "unitScale": true + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "A" + }, + "properties": [ + { + "id": "displayName", + "value": "Reconcile errors" + } + ] + } + ] + }, + "gridPos": { + "h": 2, + "w": 4, + "x": 8, + "y": 64 + }, + "id": 698, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "value_and_name", + "wideLayout": true + }, + "pluginVersion": "10.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "max(controller_runtime_reconcile_total{namespace=~\"$operatorNamespace\", result=\"error\", controller=\"backup\"})", + "hide": false, + "instant": true, + "legendFormat": "Backup Reconcile Errors", + "range": false, + "refId": "RECONCILE_ERRORS_BACKUP" + } + ], + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "The operator reconcile errors don't distinguish between database cluster or namespaces.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "0": { + "color": "green", + "index": 0, + "text": "None" + } + }, + "type": "value" + }, + { + "options": { + "from": 1, + "result": { + "color": "red", + "index": 1 + }, + "to": 4294967295 + }, + "type": "range" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + }, + "unitScale": true + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "A" + }, + "properties": [ + { + "id": "displayName", + "value": "Reconcile errors" + } + ] + } + ] + }, + "gridPos": { + "h": 2, + "w": 4, + "x": 12, + "y": 64 + }, + "id": 704, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "value_and_name", + "wideLayout": true + }, + "pluginVersion": "10.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "max(controller_runtime_reconcile_total{namespace=~\"$operatorNamespace\", result=\"error\", controller=\"scheduledbackup\"})", + "hide": false, + "instant": true, + "legendFormat": "Scheduled Backup Reconcile Errors", + "range": false, + "refId": "RECONCILE_ERRORS_BACKUP" + } + ], + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "The operator reconcile errors don't distinguish between database cluster or namespaces.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "0": { + "color": "green", + "index": 0, + "text": "None" + } + }, + "type": "value" + }, + { + "options": { + "from": 1, + "result": { + "color": "red", + "index": 1 + }, + "to": 4294967295 + }, + "type": "range" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + }, + "unitScale": true + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "A" + }, + "properties": [ + { + "id": "displayName", + "value": "Reconcile errors" + } + ] + } + ] + }, + "gridPos": { + "h": 2, + "w": 4, + "x": 16, + "y": 64 + }, + "id": 703, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "value_and_name", + "wideLayout": true + }, + "pluginVersion": "10.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "max(controller_runtime_reconcile_total{namespace=~\"$operatorNamespace\", result=\"error\", controller=\"pooler\"})", + "hide": false, + "instant": true, + "legendFormat": "Pooler Reconcile Errors", + "range": false, + "refId": "RECONCILE_ERRORS_BACKUP" + } + ], + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [ + { + "options": { + "0": { + "color": "red", + "index": 0, + "text": "No Ready pods" + } + }, + "type": "value" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + }, + "unitScale": true + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "A" + }, + "properties": [ + { + "id": "displayName", + "value": "Reconcile errors" + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 4, + "x": 0, + "y": 66 + }, + "id": 746, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "10.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(kube_pod_status_ready{namespace=\"$operatorNamespace\"} * on (pod) group_left( label_app_kubernetes_io_name ) kube_pod_labels{label_app_kubernetes_io_name=~\"cloudnative-pg\"})", + "hide": false, + "instant": false, + "legendFormat": "Ready Operator Pods", + "range": true, + "refId": "A" + } + ], + "title": "Ready Operator Pods", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "The operator reconcile errors don't distinguish between database cluster or namespaces.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [ + { + "options": { + "0": { + "color": "green", + "index": 0, + "text": "None" + } + }, + "type": "value" + }, + { + "options": { + "from": 1, + "result": { + "color": "red", + "index": 1 + }, + "to": 4294967295 + }, + "type": "range" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + }, + "unitScale": true + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "A" + }, + "properties": [ + { + "id": "displayName", + "value": "Reconcile errors" + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 4, + "x": 4, + "y": 66 + }, + "id": 767, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "10.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "max(controller_runtime_reconcile_total{namespace=~\"$operatorNamespace\", result=\"error\", controller=\"cluster\"})", + "hide": false, + "legendFormat": "Cluster Reconcile Errors", + "range": true, + "refId": "RECONCILE_ERRORS_BACKUP" + } + ], + "title": "Cluster Reconcile Errors", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "The operator reconcile errors don't distinguish between database cluster or namespaces.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [ + { + "options": { + "0": { + "color": "green", + "index": 0, + "text": "None" + } + }, + "type": "value" + }, + { + "options": { + "from": 1, + "result": { + "color": "red", + "index": 1 + }, + "to": 4294967295 + }, + "type": "range" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + }, + "unitScale": true + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "A" + }, + "properties": [ + { + "id": "displayName", + "value": "Reconcile errors" + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 4, + "x": 8, + "y": 66 + }, + "id": 768, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "10.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "max(controller_runtime_reconcile_total{namespace=~\"$operatorNamespace\", result=\"error\", controller=\"backup\"})", + "hide": false, + "legendFormat": "Backup Reconcile Errors", + "range": true, + "refId": "RECONCILE_ERRORS_BACKUP" + } + ], + "title": "Backup Reconcile Errors", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "The operator reconcile errors don't distinguish between database cluster or namespaces.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [ + { + "options": { + "0": { + "color": "green", + "index": 0, + "text": "None" + } + }, + "type": "value" + }, + { + "options": { + "from": 1, + "result": { + "color": "red", + "index": 1 + }, + "to": 4294967295 + }, + "type": "range" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + }, + "unitScale": true + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "A" + }, + "properties": [ + { + "id": "displayName", + "value": "Reconcile errors" + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 4, + "x": 12, + "y": 66 + }, + "id": 790, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "10.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "max(controller_runtime_reconcile_total{namespace=~\"$operatorNamespace\", result=\"error\", controller=\"scheduledbackup\"})", + "hide": false, + "instant": false, + "legendFormat": "Scheduled Backup Reconcile Errors", + "range": true, + "refId": "RECONCILE_ERRORS_BACKUP" + } + ], + "title": "Scheduled Backup Reconcile Errors", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "The operator reconcile errors don't distinguish between database cluster or namespaces.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [ + { + "options": { + "0": { + "color": "green", + "index": 0, + "text": "None" + } + }, + "type": "value" + }, + { + "options": { + "from": 1, + "result": { + "color": "red", + "index": 1 + }, + "to": 4294967295 + }, + "type": "range" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + }, + "unitScale": true + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "A" + }, + "properties": [ + { + "id": "displayName", + "value": "Reconcile errors" + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 4, + "x": 16, + "y": 66 + }, + "id": 769, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "10.3.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "max(controller_runtime_reconcile_total{namespace=~\"$operatorNamespace\", result=\"error\", controller=\"pooler\"})", + "hide": false, + "legendFormat": "Pooler Reconcile Errors", + "range": true, + "refId": "RECONCILE_ERRORS_BACKUP" + } + ], + "title": "Pooler Reconcile Errors", + "type": "timeseries" + } + ], + "title": "Operator", + "type": "row" + } + ], + "refresh": "30s", + "revision": 1, + "schemaVersion": 39, + "tags": [ + "cloudnativepg" + ], + "templating": { + "list": [ + { + "current": { + "selected": false, + "text": "Prometheus", + "value": "prometheus" + }, + "hide": 0, + "includeAll": false, + "label": "Datasource", + "multi": false, + "name": "DS_PROMETHEUS", + "options": [], + "query": "prometheus", + "queryValue": "", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + }, + { + "current": {}, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "definition": "label_values(controller_runtime_active_workers,namespace)", + "description": "Namespace where the CNPG operator is located", + "hide": 0, + "includeAll": false, + "label": "Operator Namespace", + "multi": false, + "name": "operatorNamespace", + "options": [], + "query": { + "qryType": 1, + "query": "label_values(controller_runtime_active_workers,namespace)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "type": "query" + }, + { + "current": {}, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "definition": "cnpg_collector_up", + "description": "Namespace where the database cluster is located", + "hide": 0, + "includeAll": false, + "label": "Database Namespace", + "multi": false, + "name": "namespace", + "options": [], + "query": { + "query": "cnpg_collector_up", + "refId": "StandardVariableQuery" + }, + "refresh": 2, + "regex": "/namespace=\"(?[^\"]+)/g", + "skipUrlSync": false, + "sort": 0, + "type": "query" + }, + { + "current": {}, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "definition": "cnpg_collector_up{namespace=~\"$namespace\"}", + "description": "CNPG Cluster", + "hide": 0, + "includeAll": false, + "label": "Cluster", + "multi": false, + "name": "cluster", + "options": [], + "query": { + "query": "cnpg_collector_up{namespace=~\"$namespace\"}", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 2, + "regex": "/\\bcluster\\b=\"(?[^\"]+)/g", + "skipUrlSync": false, + "sort": 1, + "type": "query" + }, + { + "allValue": "$cluster-([1-9][0-9]*)$", + "current": {}, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "definition": "cnpg_collector_up{namespace=~\"$namespace\",pod=~\"$cluster-([1-9][0-9]*)$\"}", + "description": "Database cluster instances", + "hide": 0, + "includeAll": true, + "label": "Instances", + "multi": true, + "name": "instances", + "options": [], + "query": { + "qryType": 4, + "query": "cnpg_collector_up{namespace=~\"$namespace\",pod=~\"$cluster-([1-9][0-9]*)$\"}", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 2, + "regex": "/pod=\"(?[^\"]+)/g", + "skipUrlSync": false, + "sort": 1, + "type": "query" + } + ] + }, + "time": { + "from": "now-7d", + "to": "now" + }, + "timepicker": { + "nowDelay": "" + }, + "timezone": "", + "title": "CloudNativePG", + "uid": "cloudnative-pg", + "version": 2, + "weekStart": "" +} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/charts/cluster/templates/NOTES.txt b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/charts/cluster/templates/NOTES.txt new file mode 100644 index 000000000..2432b4615 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/charts/cluster/templates/NOTES.txt @@ -0,0 +1,5 @@ +CloudNativePG Grafana Dashboard installed successfully. + +{{- if (or .Values.grafanaDashboard.sidecarLabel .Values.grafanaDashboard.sidecarLabelValue) }} +DEPRECATION NOTICE: The grafanaDashboard.sidecarLabel is deprecated and will be removed in a future release. Use the grafanaDashboard.labels instead. +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/charts/cluster/templates/sidecar-configmap.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/charts/cluster/templates/sidecar-configmap.yaml new file mode 100644 index 000000000..85a38e244 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/charts/cluster/templates/sidecar-configmap.yaml @@ -0,0 +1,21 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Values.grafanaDashboard.configMapName }} + namespace: {{ default .Release.Namespace .Values.grafanaDashboard.namespace }} + {{- if (or .Values.grafanaDashboard.labels .Values.grafanaDashboard.sidecarLabel) }} + labels: + {{- if .Values.grafanaDashboard.sidecarLabel }} + {{ .Values.grafanaDashboard.sidecarLabel }}: {{ .Values.grafanaDashboard.sidecarLabelValue | quote }} + {{- end }} + {{- with .Values.grafanaDashboard.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} + {{- with .Values.grafanaDashboard.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +data: + cnp.json: |- +{{ .Files.Get "grafana-dashboard.json" | indent 6 }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/charts/cluster/values.schema.json b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/charts/cluster/values.schema.json new file mode 100644 index 000000000..88825967e --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/charts/cluster/values.schema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/schema#", + "type": "object", + "properties": { + "fullnameOverride": { + "type": "string" + }, + "grafanaDashboard": { + "type": "object", + "properties": { + "annotations": { + "type": "object" + }, + "configMapName": { + "type": "string" + }, + "labels": { + "type": "object" + }, + "namespace": { + "type": "string" + }, + "sidecarLabel": { + "type": "string" + }, + "sidecarLabelValue": { + "type": "string" + } + } + }, + "nameOverride": { + "type": "string" + } + } +} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/charts/cluster/values.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/charts/cluster/values.yaml new file mode 100644 index 000000000..362b66060 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/charts/cluster/values.yaml @@ -0,0 +1,20 @@ +# Default values for cluster. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +nameOverride: "" +fullnameOverride: "" + +grafanaDashboard: + # -- Allows overriding the namespace where the ConfigMap will be created, defaulting to the same one as the Release. + namespace: "" + # -- The name of the ConfigMap containing the dashboard. + configMapName: "cnpg-grafana-dashboard" + # -- Label that ConfigMaps should have to be loaded as dashboards. DEPRECATED: Use labels instead. + sidecarLabel: "grafana_dashboard" + # -- Label value that ConfigMaps should have to be loaded as dashboards. DEPRECATED: Use labels instead. + sidecarLabelValue: "1" + # -- Labels that ConfigMaps should have to get configured in Grafana. + labels: {} + # -- Annotations that ConfigMaps can have to get configured in Grafana. + annotations: {} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/monitoring/grafana-dashboard.json b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/monitoring/grafana-dashboard.json new file mode 100644 index 000000000..8c4813056 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/monitoring/grafana-dashboard.json @@ -0,0 +1,3 @@ +The JSON file has been moved to a dedicated repository for CloudNativePG dashboards located at: + +https://github.com/cloudnative-pg/grafana-dashboards/blob/main/charts/cluster/grafana-dashboard.json diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/templates/NOTES.txt b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/templates/NOTES.txt new file mode 100644 index 000000000..0f79fe0dc --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/templates/NOTES.txt @@ -0,0 +1,18 @@ + +CloudNativePG operator should be installed in namespace "{{ .Release.Namespace }}". +You can now create a PostgreSQL cluster with 3 nodes in the current namespace as follows: + +cat < matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + additionalPodAntiAffinity: + description: |- + AdditionalPodAntiAffinity allows to specify pod anti-affinity terms to be added to the ones generated + by the operator if EnablePodAntiAffinity is set to true (default) or to be used exclusively if set to false. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + enablePodAntiAffinity: + description: |- + Activates anti-affinity for the pods. The operator will define pods + anti-affinity unless this field is explicitly set to false + type: boolean + nodeAffinity: + description: |- + NodeAffinity describes node affinity scheduling rules for the pod. + More info: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. + items: + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated with the + corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching the corresponding + nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + nodeSelector: + additionalProperties: + type: string + description: |- + NodeSelector is map of key-value pairs used to define the nodes on which + the pods can run. + More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + type: object + podAntiAffinityType: + description: |- + PodAntiAffinityType allows the user to decide whether pod anti-affinity between cluster instance has to be + considered a strong requirement during scheduling or not. Allowed values are: "preferred" (default if empty) or + "required". Setting it to "required", could lead to instances remaining pending until new kubernetes nodes are + added if all the existing nodes don't match the required pod anti-affinity rule. + More info: + https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity + type: string + tolerations: + description: |- + Tolerations is a list of Tolerations that should be set for all the pods, in order to allow them to run + on tainted nodes. + More info: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/ + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + topologyKey: + description: |- + TopologyKey to use for anti-affinity configuration. See k8s documentation + for more info on that + type: string + type: object + backup: + description: The configuration to be used for backups + properties: + barmanObjectStore: + description: The configuration for the barman-cloud tool suite + properties: + azureCredentials: + description: The credentials to use to upload data to Azure + Blob Storage + properties: + connectionString: + description: The connection string to be used + properties: + key: + description: The key to select + type: string + name: + description: Name of the referent. + type: string + required: + - key + - name + type: object + inheritFromAzureAD: + description: Use the Azure AD based authentication without + providing explicitly the keys. + type: boolean + storageAccount: + description: The storage account where to upload data + properties: + key: + description: The key to select + type: string + name: + description: Name of the referent. + type: string + required: + - key + - name + type: object + storageKey: + description: |- + The storage account key to be used in conjunction + with the storage account name + properties: + key: + description: The key to select + type: string + name: + description: Name of the referent. + type: string + required: + - key + - name + type: object + storageSasToken: + description: |- + A shared-access-signature to be used in conjunction with + the storage account name + properties: + key: + description: The key to select + type: string + name: + description: Name of the referent. + type: string + required: + - key + - name + type: object + type: object + data: + description: |- + The configuration to be used to backup the data files + When not defined, base backups files will be stored uncompressed and may + be unencrypted in the object store, according to the bucket default + policy. + properties: + additionalCommandArgs: + description: |- + AdditionalCommandArgs represents additional arguments that can be appended + to the 'barman-cloud-backup' command-line invocation. These arguments + provide flexibility to customize the backup process further according to + specific requirements or configurations. + + + Example: + In a scenario where specialized backup options are required, such as setting + a specific timeout or defining custom behavior, users can use this field + to specify additional command arguments. + + + Note: + It's essential to ensure that the provided arguments are valid and supported + by the 'barman-cloud-backup' command, to avoid potential errors or unintended + behavior during execution. + items: + type: string + type: array + compression: + description: |- + Compress a backup file (a tar file per tablespace) while streaming it + to the object store. Available options are empty string (no + compression, default), `gzip`, `bzip2` or `snappy`. + enum: + - gzip + - bzip2 + - snappy + type: string + encryption: + description: |- + Whenever to force the encryption of files (if the bucket is + not already configured for that). + Allowed options are empty string (use the bucket policy, default), + `AES256` and `aws:kms` + enum: + - AES256 + - aws:kms + type: string + immediateCheckpoint: + description: |- + Control whether the I/O workload for the backup initial checkpoint will + be limited, according to the `checkpoint_completion_target` setting on + the PostgreSQL server. If set to true, an immediate checkpoint will be + used, meaning PostgreSQL will complete the checkpoint as soon as + possible. `false` by default. + type: boolean + jobs: + description: |- + The number of parallel jobs to be used to upload the backup, defaults + to 2 + format: int32 + minimum: 1 + type: integer + type: object + destinationPath: + description: |- + The path where to store the backup (i.e. s3://bucket/path/to/folder) + this path, with different destination folders, will be used for WALs + and for data + minLength: 1 + type: string + endpointCA: + description: |- + EndpointCA store the CA bundle of the barman endpoint. + Useful when using self-signed certificates to avoid + errors with certificate issuer and barman-cloud-wal-archive + properties: + key: + description: The key to select + type: string + name: + description: Name of the referent. + type: string + required: + - key + - name + type: object + endpointURL: + description: |- + Endpoint to be used to upload data to the cloud, + overriding the automatic endpoint discovery + type: string + googleCredentials: + description: The credentials to use to upload data to Google + Cloud Storage + properties: + applicationCredentials: + description: The secret containing the Google Cloud Storage + JSON file with the credentials + properties: + key: + description: The key to select + type: string + name: + description: Name of the referent. + type: string + required: + - key + - name + type: object + gkeEnvironment: + description: |- + If set to true, will presume that it's running inside a GKE environment, + default to false. + type: boolean + type: object + historyTags: + additionalProperties: + type: string + description: |- + HistoryTags is a list of key value pairs that will be passed to the + Barman --history-tags option. + type: object + s3Credentials: + description: The credentials to use to upload data to S3 + properties: + accessKeyId: + description: The reference to the access key id + properties: + key: + description: The key to select + type: string + name: + description: Name of the referent. + type: string + required: + - key + - name + type: object + inheritFromIAMRole: + description: Use the role based authentication without + providing explicitly the keys. + type: boolean + region: + description: The reference to the secret containing the + region name + properties: + key: + description: The key to select + type: string + name: + description: Name of the referent. + type: string + required: + - key + - name + type: object + secretAccessKey: + description: The reference to the secret access key + properties: + key: + description: The key to select + type: string + name: + description: Name of the referent. + type: string + required: + - key + - name + type: object + sessionToken: + description: The references to the session key + properties: + key: + description: The key to select + type: string + name: + description: Name of the referent. + type: string + required: + - key + - name + type: object + type: object + serverName: + description: |- + The server name on S3, the cluster name is used if this + parameter is omitted + type: string + tags: + additionalProperties: + type: string + description: |- + Tags is a list of key value pairs that will be passed to the + Barman --tags option. + type: object + wal: + description: |- + The configuration for the backup of the WAL stream. + When not defined, WAL files will be stored uncompressed and may be + unencrypted in the object store, according to the bucket default policy. + properties: + compression: + description: |- + Compress a WAL file before sending it to the object store. Available + options are empty string (no compression, default), `gzip`, `bzip2` or `snappy`. + enum: + - gzip + - bzip2 + - snappy + type: string + encryption: + description: |- + Whenever to force the encryption of files (if the bucket is + not already configured for that). + Allowed options are empty string (use the bucket policy, default), + `AES256` and `aws:kms` + enum: + - AES256 + - aws:kms + type: string + maxParallel: + description: |- + Number of WAL files to be either archived in parallel (when the + PostgreSQL instance is archiving to a backup object store) or + restored in parallel (when a PostgreSQL standby is fetching WAL + files from a recovery object store). If not specified, WAL files + will be processed one at a time. It accepts a positive integer as a + value - with 1 being the minimum accepted value. + minimum: 1 + type: integer + type: object + required: + - destinationPath + type: object + retentionPolicy: + description: |- + RetentionPolicy is the retention policy to be used for backups + and WALs (i.e. '60d'). The retention policy is expressed in the form + of `XXu` where `XX` is a positive integer and `u` is in `[dwm]` - + days, weeks, months. + It's currently only applicable when using the BarmanObjectStore method. + pattern: ^[1-9][0-9]*[dwm]$ + type: string + target: + default: prefer-standby + description: |- + The policy to decide which instance should perform backups. Available + options are empty string, which will default to `prefer-standby` policy, + `primary` to have backups run always on primary instances, `prefer-standby` + to have backups run preferably on the most updated standby, if available. + enum: + - primary + - prefer-standby + type: string + volumeSnapshot: + description: VolumeSnapshot provides the configuration for the + execution of volume snapshot backups. + properties: + annotations: + additionalProperties: + type: string + description: Annotations key-value pairs that will be added + to .metadata.annotations snapshot resources. + type: object + className: + description: |- + ClassName specifies the Snapshot Class to be used for PG_DATA PersistentVolumeClaim. + It is the default class for the other types if no specific class is present + type: string + labels: + additionalProperties: + type: string + description: Labels are key-value pairs that will be added + to .metadata.labels snapshot resources. + type: object + online: + default: true + description: |- + Whether the default type of backup with volume snapshots is + online/hot (`true`, default) or offline/cold (`false`) + type: boolean + onlineConfiguration: + default: + immediateCheckpoint: false + waitForArchive: true + description: Configuration parameters to control the online/hot + backup with volume snapshots + properties: + immediateCheckpoint: + description: |- + Control whether the I/O workload for the backup initial checkpoint will + be limited, according to the `checkpoint_completion_target` setting on + the PostgreSQL server. If set to true, an immediate checkpoint will be + used, meaning PostgreSQL will complete the checkpoint as soon as + possible. `false` by default. + type: boolean + waitForArchive: + default: true + description: |- + If false, the function will return immediately after the backup is completed, + without waiting for WAL to be archived. + This behavior is only useful with backup software that independently monitors WAL archiving. + Otherwise, WAL required to make the backup consistent might be missing and make the backup useless. + By default, or when this parameter is true, pg_backup_stop will wait for WAL to be archived when archiving is + enabled. + On a standby, this means that it will wait only when archive_mode = always. + If write activity on the primary is low, it may be useful to run pg_switch_wal on the primary in order to trigger + an immediate segment switch. + type: boolean + type: object + snapshotOwnerReference: + default: none + description: SnapshotOwnerReference indicates the type of + owner reference the snapshot should have + enum: + - none + - cluster + - backup + type: string + tablespaceClassName: + additionalProperties: + type: string + description: |- + TablespaceClassName specifies the Snapshot Class to be used for the tablespaces. + defaults to the PGDATA Snapshot Class, if set + type: object + walClassName: + description: WalClassName specifies the Snapshot Class to + be used for the PG_WAL PersistentVolumeClaim. + type: string + type: object + type: object + bootstrap: + description: Instructions to bootstrap this cluster + properties: + initdb: + description: Bootstrap the cluster via initdb + properties: + dataChecksums: + description: |- + Whether the `-k` option should be passed to initdb, + enabling checksums on data pages (default: `false`) + type: boolean + database: + description: 'Name of the database used by the application. + Default: `app`.' + type: string + encoding: + description: The value to be passed as option `--encoding` + for initdb (default:`UTF8`) + type: string + import: + description: |- + Bootstraps the new cluster by importing data from an existing PostgreSQL + instance using logical backup (`pg_dump` and `pg_restore`) + properties: + databases: + description: The databases to import + items: + type: string + type: array + postImportApplicationSQL: + description: |- + List of SQL queries to be executed as a superuser in the application + database right after is imported - to be used with extreme care + (by default empty). Only available in microservice type. + items: + type: string + type: array + roles: + description: The roles to import + items: + type: string + type: array + schemaOnly: + description: |- + When set to true, only the `pre-data` and `post-data` sections of + `pg_restore` are invoked, avoiding data import. Default: `false`. + type: boolean + source: + description: The source of the import + properties: + externalCluster: + description: The name of the externalCluster used + for import + type: string + required: + - externalCluster + type: object + type: + description: The import type. Can be `microservice` or + `monolith`. + enum: + - microservice + - monolith + type: string + required: + - databases + - source + - type + type: object + localeCType: + description: The value to be passed as option `--lc-ctype` + for initdb (default:`C`) + type: string + localeCollate: + description: The value to be passed as option `--lc-collate` + for initdb (default:`C`) + type: string + options: + description: |- + The list of options that must be passed to initdb when creating the cluster. + Deprecated: This could lead to inconsistent configurations, + please use the explicit provided parameters instead. + If defined, explicit values will be ignored. + items: + type: string + type: array + owner: + description: |- + Name of the owner of the database in the instance to be used + by applications. Defaults to the value of the `database` key. + type: string + postInitApplicationSQL: + description: |- + List of SQL queries to be executed as a superuser in the application + database right after is created - to be used with extreme care + (by default empty) + items: + type: string + type: array + postInitApplicationSQLRefs: + description: |- + PostInitApplicationSQLRefs points references to ConfigMaps or Secrets which + contain SQL files, the general implementation order to these references is + from all Secrets to all ConfigMaps, and inside Secrets or ConfigMaps, + the implementation order is same as the order of each array + (by default empty) + properties: + configMapRefs: + description: ConfigMapRefs holds a list of references + to ConfigMaps + items: + description: |- + ConfigMapKeySelector contains enough information to let you locate + the key of a ConfigMap + properties: + key: + description: The key to select + type: string + name: + description: Name of the referent. + type: string + required: + - key + - name + type: object + type: array + secretRefs: + description: SecretRefs holds a list of references to + Secrets + items: + description: |- + SecretKeySelector contains enough information to let you locate + the key of a Secret + properties: + key: + description: The key to select + type: string + name: + description: Name of the referent. + type: string + required: + - key + - name + type: object + type: array + type: object + postInitSQL: + description: |- + List of SQL queries to be executed as a superuser immediately + after the cluster has been created - to be used with extreme care + (by default empty) + items: + type: string + type: array + postInitTemplateSQL: + description: |- + List of SQL queries to be executed as a superuser in the `template1` + after the cluster has been created - to be used with extreme care + (by default empty) + items: + type: string + type: array + secret: + description: |- + Name of the secret containing the initial credentials for the + owner of the user database. If empty a new secret will be + created from scratch + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + walSegmentSize: + description: |- + The value in megabytes (1 to 1024) to be passed to the `--wal-segsize` + option for initdb (default: empty, resulting in PostgreSQL default: 16MB) + maximum: 1024 + minimum: 1 + type: integer + type: object + pg_basebackup: + description: |- + Bootstrap the cluster taking a physical backup of another compatible + PostgreSQL instance + properties: + database: + description: 'Name of the database used by the application. + Default: `app`.' + type: string + owner: + description: |- + Name of the owner of the database in the instance to be used + by applications. Defaults to the value of the `database` key. + type: string + secret: + description: |- + Name of the secret containing the initial credentials for the + owner of the user database. If empty a new secret will be + created from scratch + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + source: + description: The name of the server of which we need to take + a physical backup + minLength: 1 + type: string + required: + - source + type: object + recovery: + description: Bootstrap the cluster from a backup + properties: + backup: + description: |- + The backup object containing the physical base backup from which to + initiate the recovery procedure. + Mutually exclusive with `source` and `volumeSnapshots`. + properties: + endpointCA: + description: |- + EndpointCA store the CA bundle of the barman endpoint. + Useful when using self-signed certificates to avoid + errors with certificate issuer and barman-cloud-wal-archive. + properties: + key: + description: The key to select + type: string + name: + description: Name of the referent. + type: string + required: + - key + - name + type: object + name: + description: Name of the referent. + type: string + required: + - name + type: object + database: + description: 'Name of the database used by the application. + Default: `app`.' + type: string + owner: + description: |- + Name of the owner of the database in the instance to be used + by applications. Defaults to the value of the `database` key. + type: string + recoveryTarget: + description: |- + By default, the recovery process applies all the available + WAL files in the archive (full recovery). However, you can also + end the recovery as soon as a consistent state is reached or + recover to a point-in-time (PITR) by specifying a `RecoveryTarget` object, + as expected by PostgreSQL (i.e., timestamp, transaction Id, LSN, ...). + More info: https://www.postgresql.org/docs/current/runtime-config-wal.html#RUNTIME-CONFIG-WAL-RECOVERY-TARGET + properties: + backupID: + description: |- + The ID of the backup from which to start the recovery process. + If empty (default) the operator will automatically detect the backup + based on targetTime or targetLSN if specified. Otherwise use the + latest available backup in chronological order. + type: string + exclusive: + description: |- + Set the target to be exclusive. If omitted, defaults to false, so that + in Postgres, `recovery_target_inclusive` will be true + type: boolean + targetImmediate: + description: End recovery as soon as a consistent state + is reached + type: boolean + targetLSN: + description: The target LSN (Log Sequence Number) + type: string + targetName: + description: |- + The target name (to be previously created + with `pg_create_restore_point`) + type: string + targetTLI: + description: The target timeline ("latest" or a positive + integer) + type: string + targetTime: + description: The target time as a timestamp in the RFC3339 + standard + type: string + targetXID: + description: The target transaction ID + type: string + type: object + secret: + description: |- + Name of the secret containing the initial credentials for the + owner of the user database. If empty a new secret will be + created from scratch + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + source: + description: |- + The external cluster whose backup we will restore. This is also + used as the name of the folder under which the backup is stored, + so it must be set to the name of the source cluster + Mutually exclusive with `backup`. + type: string + volumeSnapshots: + description: |- + The static PVC data source(s) from which to initiate the + recovery procedure. Currently supporting `VolumeSnapshot` + and `PersistentVolumeClaim` resources that map an existing + PVC group, compatible with CloudNativePG, and taken with + a cold backup copy on a fenced Postgres instance (limitation + which will be removed in the future when online backup + will be implemented). + Mutually exclusive with `backup`. + properties: + storage: + description: Configuration of the storage of the instances + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + tablespaceStorage: + additionalProperties: + description: |- + TypedLocalObjectReference contains enough information to let you locate the + typed referenced object inside the same namespace. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + description: Configuration of the storage for PostgreSQL + tablespaces + type: object + walStorage: + description: Configuration of the storage for PostgreSQL + WAL (Write-Ahead Log) + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + required: + - storage + type: object + type: object + type: object + certificates: + description: The configuration for the CA and related certificates + properties: + clientCASecret: + description: |- + The secret containing the Client CA certificate. If not defined, a new secret will be created + with a self-signed CA and will be used to generate all the client certificates.
+
+ Contains:
+
+ - `ca.crt`: CA that should be used to validate the client certificates, + used as `ssl_ca_file` of all the instances.
+ - `ca.key`: key used to generate client certificates, if ReplicationTLSSecret is provided, + this can be omitted.
+ type: string + replicationTLSSecret: + description: |- + The secret of type kubernetes.io/tls containing the client certificate to authenticate as + the `streaming_replica` user. + If not defined, ClientCASecret must provide also `ca.key`, and a new secret will be + created using the provided CA. + type: string + serverAltDNSNames: + description: The list of the server alternative DNS names to be + added to the generated server TLS certificates, when required. + items: + type: string + type: array + serverCASecret: + description: |- + The secret containing the Server CA certificate. If not defined, a new secret will be created + with a self-signed CA and will be used to generate the TLS certificate ServerTLSSecret.
+
+ Contains:
+
+ - `ca.crt`: CA that should be used to validate the server certificate, + used as `sslrootcert` in client connection strings.
+ - `ca.key`: key used to generate Server SSL certs, if ServerTLSSecret is provided, + this can be omitted.
+ type: string + serverTLSSecret: + description: |- + The secret of type kubernetes.io/tls containing the server TLS certificate and key that will be set as + `ssl_cert_file` and `ssl_key_file` so that clients can connect to postgres securely. + If not defined, ServerCASecret must provide also `ca.key` and a new secret will be + created using the provided CA. + type: string + type: object + description: + description: Description of this PostgreSQL cluster + type: string + enablePDB: + default: true + description: |- + Manage the `PodDisruptionBudget` resources within the cluster. When + configured as `true` (default setting), the pod disruption budgets + will safeguard the primary node from being terminated. Conversely, + setting it to `false` will result in the absence of any + `PodDisruptionBudget` resource, permitting the shutdown of all nodes + hosting the PostgreSQL cluster. This latter configuration is + advisable for any PostgreSQL cluster employed for + development/staging purposes. + type: boolean + enableSuperuserAccess: + default: false + description: |- + When this option is enabled, the operator will use the `SuperuserSecret` + to update the `postgres` user password (if the secret is + not present, the operator will automatically create one). When this + option is disabled, the operator will ignore the `SuperuserSecret` content, delete + it when automatically created, and then blank the password of the `postgres` + user by setting it to `NULL`. Disabled by default. + type: boolean + env: + description: |- + Env follows the Env format to pass environment variables + to the pods created in the cluster + items: + description: EnvVar represents an environment variable present in + a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's value. Cannot + be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + optional: + description: Specify whether the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath is + written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified + API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed + resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + description: |- + EnvFrom follows the EnvFrom format to pass environment variables + sources to the pods to be used by Env + items: + description: EnvFromSource represents the source of a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + optional: + description: Specify whether the ConfigMap must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: An optional identifier to prepend to each key in + the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + optional: + description: Specify whether the Secret must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + ephemeralVolumeSource: + description: EphemeralVolumeSource allows the user to configure the + source of ephemeral volumes. + properties: + volumeClaimTemplate: + description: |- + Will be used to create a stand-alone PVC to provision the volume. + The pod in which this EphemeralVolumeSource is embedded will be the + owner of the PVC, i.e. the PVC will be deleted together with the + pod. The name of the PVC will be `-` where + `` is the name from the `PodSpec.Volumes` array + entry. Pod validation will reject the pod if the concatenated name + is not valid for a PVC (for example, too long). + + + An existing PVC with that name that is not owned by the pod + will *not* be used for the pod to avoid using an unrelated + volume by mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created PVC is + meant to be used by the pod, the PVC has to updated with an + owner reference to the pod once the pod exists. Normally + this should not be necessary, but it may be useful when + manually reconstructing a broken cluster. + + + This field is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. + + + Required, must not be nil. + properties: + metadata: + description: |- + May contain labels and annotations that will be copied into the PVC + when creating it. No other fields are allowed and will be rejected during + validation. + type: object + spec: + description: |- + The specification for the PersistentVolumeClaim. The entire content is + copied unchanged into the PVC that gets created from this + template. The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over volumes to + consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ + (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to the + PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + ephemeralVolumesSizeLimit: + description: |- + EphemeralVolumesSizeLimit allows the user to set the limits for the ephemeral + volumes + properties: + shm: + anyOf: + - type: integer + - type: string + description: Shm is the size limit of the shared memory volume + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + temporaryData: + anyOf: + - type: integer + - type: string + description: TemporaryData is the size limit of the temporary + data volume + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + externalClusters: + description: The list of external clusters which are used in the configuration + items: + description: |- + ExternalCluster represents the connection parameters to an + external cluster which is used in the other sections of the configuration + properties: + barmanObjectStore: + description: The configuration for the barman-cloud tool suite + properties: + azureCredentials: + description: The credentials to use to upload data to Azure + Blob Storage + properties: + connectionString: + description: The connection string to be used + properties: + key: + description: The key to select + type: string + name: + description: Name of the referent. + type: string + required: + - key + - name + type: object + inheritFromAzureAD: + description: Use the Azure AD based authentication without + providing explicitly the keys. + type: boolean + storageAccount: + description: The storage account where to upload data + properties: + key: + description: The key to select + type: string + name: + description: Name of the referent. + type: string + required: + - key + - name + type: object + storageKey: + description: |- + The storage account key to be used in conjunction + with the storage account name + properties: + key: + description: The key to select + type: string + name: + description: Name of the referent. + type: string + required: + - key + - name + type: object + storageSasToken: + description: |- + A shared-access-signature to be used in conjunction with + the storage account name + properties: + key: + description: The key to select + type: string + name: + description: Name of the referent. + type: string + required: + - key + - name + type: object + type: object + data: + description: |- + The configuration to be used to backup the data files + When not defined, base backups files will be stored uncompressed and may + be unencrypted in the object store, according to the bucket default + policy. + properties: + additionalCommandArgs: + description: |- + AdditionalCommandArgs represents additional arguments that can be appended + to the 'barman-cloud-backup' command-line invocation. These arguments + provide flexibility to customize the backup process further according to + specific requirements or configurations. + + + Example: + In a scenario where specialized backup options are required, such as setting + a specific timeout or defining custom behavior, users can use this field + to specify additional command arguments. + + + Note: + It's essential to ensure that the provided arguments are valid and supported + by the 'barman-cloud-backup' command, to avoid potential errors or unintended + behavior during execution. + items: + type: string + type: array + compression: + description: |- + Compress a backup file (a tar file per tablespace) while streaming it + to the object store. Available options are empty string (no + compression, default), `gzip`, `bzip2` or `snappy`. + enum: + - gzip + - bzip2 + - snappy + type: string + encryption: + description: |- + Whenever to force the encryption of files (if the bucket is + not already configured for that). + Allowed options are empty string (use the bucket policy, default), + `AES256` and `aws:kms` + enum: + - AES256 + - aws:kms + type: string + immediateCheckpoint: + description: |- + Control whether the I/O workload for the backup initial checkpoint will + be limited, according to the `checkpoint_completion_target` setting on + the PostgreSQL server. If set to true, an immediate checkpoint will be + used, meaning PostgreSQL will complete the checkpoint as soon as + possible. `false` by default. + type: boolean + jobs: + description: |- + The number of parallel jobs to be used to upload the backup, defaults + to 2 + format: int32 + minimum: 1 + type: integer + type: object + destinationPath: + description: |- + The path where to store the backup (i.e. s3://bucket/path/to/folder) + this path, with different destination folders, will be used for WALs + and for data + minLength: 1 + type: string + endpointCA: + description: |- + EndpointCA store the CA bundle of the barman endpoint. + Useful when using self-signed certificates to avoid + errors with certificate issuer and barman-cloud-wal-archive + properties: + key: + description: The key to select + type: string + name: + description: Name of the referent. + type: string + required: + - key + - name + type: object + endpointURL: + description: |- + Endpoint to be used to upload data to the cloud, + overriding the automatic endpoint discovery + type: string + googleCredentials: + description: The credentials to use to upload data to Google + Cloud Storage + properties: + applicationCredentials: + description: The secret containing the Google Cloud + Storage JSON file with the credentials + properties: + key: + description: The key to select + type: string + name: + description: Name of the referent. + type: string + required: + - key + - name + type: object + gkeEnvironment: + description: |- + If set to true, will presume that it's running inside a GKE environment, + default to false. + type: boolean + type: object + historyTags: + additionalProperties: + type: string + description: |- + HistoryTags is a list of key value pairs that will be passed to the + Barman --history-tags option. + type: object + s3Credentials: + description: The credentials to use to upload data to S3 + properties: + accessKeyId: + description: The reference to the access key id + properties: + key: + description: The key to select + type: string + name: + description: Name of the referent. + type: string + required: + - key + - name + type: object + inheritFromIAMRole: + description: Use the role based authentication without + providing explicitly the keys. + type: boolean + region: + description: The reference to the secret containing + the region name + properties: + key: + description: The key to select + type: string + name: + description: Name of the referent. + type: string + required: + - key + - name + type: object + secretAccessKey: + description: The reference to the secret access key + properties: + key: + description: The key to select + type: string + name: + description: Name of the referent. + type: string + required: + - key + - name + type: object + sessionToken: + description: The references to the session key + properties: + key: + description: The key to select + type: string + name: + description: Name of the referent. + type: string + required: + - key + - name + type: object + type: object + serverName: + description: |- + The server name on S3, the cluster name is used if this + parameter is omitted + type: string + tags: + additionalProperties: + type: string + description: |- + Tags is a list of key value pairs that will be passed to the + Barman --tags option. + type: object + wal: + description: |- + The configuration for the backup of the WAL stream. + When not defined, WAL files will be stored uncompressed and may be + unencrypted in the object store, according to the bucket default policy. + properties: + compression: + description: |- + Compress a WAL file before sending it to the object store. Available + options are empty string (no compression, default), `gzip`, `bzip2` or `snappy`. + enum: + - gzip + - bzip2 + - snappy + type: string + encryption: + description: |- + Whenever to force the encryption of files (if the bucket is + not already configured for that). + Allowed options are empty string (use the bucket policy, default), + `AES256` and `aws:kms` + enum: + - AES256 + - aws:kms + type: string + maxParallel: + description: |- + Number of WAL files to be either archived in parallel (when the + PostgreSQL instance is archiving to a backup object store) or + restored in parallel (when a PostgreSQL standby is fetching WAL + files from a recovery object store). If not specified, WAL files + will be processed one at a time. It accepts a positive integer as a + value - with 1 being the minimum accepted value. + minimum: 1 + type: integer + type: object + required: + - destinationPath + type: object + connectionParameters: + additionalProperties: + type: string + description: The list of connection parameters, such as dbname, + host, username, etc + type: object + name: + description: The server name, required + type: string + password: + description: |- + The reference to the password to be used to connect to the server. + If a password is provided, CloudNativePG creates a PostgreSQL + passfile at `/controller/external/NAME/pass` (where "NAME" is the + cluster's name). This passfile is automatically referenced in the + connection string when establishing a connection to the remote + PostgreSQL server from the current PostgreSQL `Cluster`. This ensures + secure and efficient password management for external clusters. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + sslCert: + description: |- + The reference to an SSL certificate to be used to connect to this + instance + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + sslKey: + description: |- + The reference to an SSL private key to be used to connect to this + instance + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + sslRootCert: + description: |- + The reference to an SSL CA public key to be used to connect to this + instance + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + required: + - name + type: object + type: array + failoverDelay: + default: 0 + description: |- + The amount of time (in seconds) to wait before triggering a failover + after the primary PostgreSQL instance in the cluster was detected + to be unhealthy + format: int32 + type: integer + imageCatalogRef: + description: Defines the major PostgreSQL version we want to use within + an ImageCatalog + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + major: + description: The major version of PostgreSQL we want to use from + the ImageCatalog + type: integer + x-kubernetes-validations: + - message: Major is immutable + rule: self == oldSelf + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - major + - name + type: object + x-kubernetes-map-type: atomic + x-kubernetes-validations: + - message: Only image catalogs are supported + rule: self.kind == 'ImageCatalog' || self.kind == 'ClusterImageCatalog' + - message: Only image catalogs are supported + rule: self.apiGroup == 'postgresql.cnpg.io' + imageName: + description: |- + Name of the container image, supporting both tags (`:`) + and digests for deterministic and repeatable deployments + (`:@sha256:`) + type: string + imagePullPolicy: + description: |- + Image pull policy. + One of `Always`, `Never` or `IfNotPresent`. + If not defined, it defaults to `IfNotPresent`. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + type: string + imagePullSecrets: + description: The list of pull secrets to be used to pull the images + items: + description: |- + LocalObjectReference contains enough information to let you locate a + local object with a known type inside the same namespace + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + type: array + inheritedMetadata: + description: Metadata that will be inherited by all objects related + to the Cluster + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + instances: + default: 1 + description: Number of instances required in the cluster + minimum: 1 + type: integer + livenessProbeTimeout: + description: |- + LivenessProbeTimeout is the time (in seconds) that is allowed for a PostgreSQL instance + to successfully respond to the liveness probe (default 30). + The Liveness probe failure threshold is derived from this value using the formula: + ceiling(livenessProbe / 10). + format: int32 + type: integer + logLevel: + default: info + description: 'The instances'' log level, one of the following values: + error, warning, info (default), debug, trace' + enum: + - error + - warning + - info + - debug + - trace + type: string + managed: + description: The configuration that is used by the portions of PostgreSQL + that are managed by the instance manager + properties: + roles: + description: Database roles managed by the `Cluster` + items: + description: |- + RoleConfiguration is the representation, in Kubernetes, of a PostgreSQL role + with the additional field Ensure specifying whether to ensure the presence or + absence of the role in the database + + + The defaults of the CREATE ROLE command are applied + Reference: https://www.postgresql.org/docs/current/sql-createrole.html + properties: + bypassrls: + description: |- + Whether a role bypasses every row-level security (RLS) policy. + Default is `false`. + type: boolean + comment: + description: Description of the role + type: string + connectionLimit: + default: -1 + description: |- + If the role can log in, this specifies how many concurrent + connections the role can make. `-1` (the default) means no limit. + format: int64 + type: integer + createdb: + description: |- + When set to `true`, the role being defined will be allowed to create + new databases. Specifying `false` (default) will deny a role the + ability to create databases. + type: boolean + createrole: + description: |- + Whether the role will be permitted to create, alter, drop, comment + on, change the security label for, and grant or revoke membership in + other roles. Default is `false`. + type: boolean + disablePassword: + description: DisablePassword indicates that a role's password + should be set to NULL in Postgres + type: boolean + ensure: + default: present + description: Ensure the role is `present` or `absent` - + defaults to "present" + enum: + - present + - absent + type: string + inRoles: + description: |- + List of one or more existing roles to which this role will be + immediately added as a new member. Default empty. + items: + type: string + type: array + inherit: + default: true + description: |- + Whether a role "inherits" the privileges of roles it is a member of. + Defaults is `true`. + type: boolean + login: + description: |- + Whether the role is allowed to log in. A role having the `login` + attribute can be thought of as a user. Roles without this attribute + are useful for managing database privileges, but are not users in + the usual sense of the word. Default is `false`. + type: boolean + name: + description: Name of the role + type: string + passwordSecret: + description: |- + Secret containing the password of the role (if present) + If null, the password will be ignored unless DisablePassword is set + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + replication: + description: |- + Whether a role is a replication role. A role must have this + attribute (or be a superuser) in order to be able to connect to the + server in replication mode (physical or logical replication) and in + order to be able to create or drop replication slots. A role having + the `replication` attribute is a very highly privileged role, and + should only be used on roles actually used for replication. Default + is `false`. + type: boolean + superuser: + description: |- + Whether the role is a `superuser` who can override all access + restrictions within the database - superuser status is dangerous and + should be used only when really needed. You must yourself be a + superuser to create a new superuser. Defaults is `false`. + type: boolean + validUntil: + description: |- + Date and time after which the role's password is no longer valid. + When omitted, the password will never expire (default). + format: date-time + type: string + required: + - name + type: object + type: array + type: object + maxSyncReplicas: + default: 0 + description: |- + The target value for the synchronous replication quorum, that can be + decreased if the number of ready standbys is lower than this. + Undefined or 0 disable synchronous replication. + minimum: 0 + type: integer + minSyncReplicas: + default: 0 + description: |- + Minimum number of instances required in synchronous replication with the + primary. Undefined or 0 allow writes to complete when no standby is + available. + minimum: 0 + type: integer + monitoring: + description: The configuration of the monitoring infrastructure of + this cluster + properties: + customQueriesConfigMap: + description: The list of config maps containing the custom queries + items: + description: |- + ConfigMapKeySelector contains enough information to let you locate + the key of a ConfigMap + properties: + key: + description: The key to select + type: string + name: + description: Name of the referent. + type: string + required: + - key + - name + type: object + type: array + customQueriesSecret: + description: The list of secrets containing the custom queries + items: + description: |- + SecretKeySelector contains enough information to let you locate + the key of a Secret + properties: + key: + description: The key to select + type: string + name: + description: Name of the referent. + type: string + required: + - key + - name + type: object + type: array + disableDefaultQueries: + default: false + description: |- + Whether the default queries should be injected. + Set it to `true` if you don't want to inject default queries into the cluster. + Default: false. + type: boolean + enablePodMonitor: + default: false + description: Enable or disable the `PodMonitor` + type: boolean + podMonitorMetricRelabelings: + description: The list of metric relabelings for the `PodMonitor`. + Applied to samples before ingestion. + items: + description: |- + RelabelConfig allows dynamic rewriting of the label set for targets, alerts, + scraped samples and remote write samples. + + + More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + properties: + action: + default: replace + description: |- + Action to perform based on the regex matching. + + + `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0. + `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0. + + + Default: "Replace" + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + description: |- + Modulus to take of the hash of the source label values. + + + Only applicable when the action is `HashMod`. + format: int64 + type: integer + regex: + description: Regular expression against which the extracted + value is matched. + type: string + replacement: + description: |- + Replacement value against which a Replace action is performed if the + regular expression matches. + + + Regex capture groups are available. + type: string + separator: + description: Separator is the string between concatenated + SourceLabels. + type: string + sourceLabels: + description: |- + The source labels select values from existing labels. Their content is + concatenated using the configured Separator and matched against the + configured regular expression. + items: + description: |- + LabelName is a valid Prometheus label name which may only contain ASCII + letters, numbers, as well as underscores. + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + description: |- + Label to which the resulting string is written in a replacement. + + + It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`, + `KeepEqual` and `DropEqual` actions. + + + Regex capture groups are available. + type: string + type: object + type: array + podMonitorRelabelings: + description: The list of relabelings for the `PodMonitor`. Applied + to samples before scraping. + items: + description: |- + RelabelConfig allows dynamic rewriting of the label set for targets, alerts, + scraped samples and remote write samples. + + + More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + properties: + action: + default: replace + description: |- + Action to perform based on the regex matching. + + + `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0. + `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0. + + + Default: "Replace" + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + description: |- + Modulus to take of the hash of the source label values. + + + Only applicable when the action is `HashMod`. + format: int64 + type: integer + regex: + description: Regular expression against which the extracted + value is matched. + type: string + replacement: + description: |- + Replacement value against which a Replace action is performed if the + regular expression matches. + + + Regex capture groups are available. + type: string + separator: + description: Separator is the string between concatenated + SourceLabels. + type: string + sourceLabels: + description: |- + The source labels select values from existing labels. Their content is + concatenated using the configured Separator and matched against the + configured regular expression. + items: + description: |- + LabelName is a valid Prometheus label name which may only contain ASCII + letters, numbers, as well as underscores. + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + description: |- + Label to which the resulting string is written in a replacement. + + + It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`, + `KeepEqual` and `DropEqual` actions. + + + Regex capture groups are available. + type: string + type: object + type: array + type: object + nodeMaintenanceWindow: + description: Define a maintenance window for the Kubernetes nodes + properties: + inProgress: + default: false + description: Is there a node maintenance activity in progress? + type: boolean + reusePVC: + default: true + description: |- + Reuse the existing PVC (wait for the node to come + up again) or not (recreate it elsewhere - when `instances` >1) + type: boolean + type: object + plugins: + description: |- + The plugins configuration, containing + any plugin to be loaded with the corresponding configuration + items: + description: |- + PluginConfiguration specifies a plugin that need to be loaded for this + cluster to be reconciled + properties: + name: + description: Name is the plugin name + type: string + parameters: + additionalProperties: + type: string + description: Parameters is the configuration of the plugin + type: object + required: + - name + type: object + type: array + postgresGID: + default: 26 + description: The GID of the `postgres` user inside the image, defaults + to `26` + format: int64 + type: integer + postgresUID: + default: 26 + description: The UID of the `postgres` user inside the image, defaults + to `26` + format: int64 + type: integer + postgresql: + description: Configuration of the PostgreSQL server + properties: + enableAlterSystem: + description: |- + If this parameter is true, the user will be able to invoke `ALTER SYSTEM` + on this CloudNativePG Cluster. + This should only be used for debugging and troubleshooting. + Defaults to false. + type: boolean + ldap: + description: Options to specify LDAP configuration + properties: + bindAsAuth: + description: Bind as authentication configuration + properties: + prefix: + description: Prefix for the bind authentication option + type: string + suffix: + description: Suffix for the bind authentication option + type: string + type: object + bindSearchAuth: + description: Bind+Search authentication configuration + properties: + baseDN: + description: Root DN to begin the user search + type: string + bindDN: + description: DN of the user to bind to the directory + type: string + bindPassword: + description: Secret with the password for the user to + bind to the directory + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + searchAttribute: + description: Attribute to match against the username + type: string + searchFilter: + description: Search filter to use when doing the search+bind + authentication + type: string + type: object + port: + description: LDAP server port + type: integer + scheme: + description: LDAP schema to be used, possible options are + `ldap` and `ldaps` + enum: + - ldap + - ldaps + type: string + server: + description: LDAP hostname or IP address + type: string + tls: + description: Set to 'true' to enable LDAP over TLS. 'false' + is default + type: boolean + type: object + parameters: + additionalProperties: + type: string + description: PostgreSQL configuration options (postgresql.conf) + type: object + pg_hba: + description: |- + PostgreSQL Host Based Authentication rules (lines to be appended + to the pg_hba.conf file) + items: + type: string + type: array + pg_ident: + description: |- + PostgreSQL User Name Maps rules (lines to be appended + to the pg_ident.conf file) + items: + type: string + type: array + promotionTimeout: + description: |- + Specifies the maximum number of seconds to wait when promoting an instance to primary. + Default value is 40000000, greater than one year in seconds, + big enough to simulate an infinite timeout + format: int32 + type: integer + shared_preload_libraries: + description: Lists of shared preload libraries to add to the default + ones + items: + type: string + type: array + syncReplicaElectionConstraint: + description: |- + Requirements to be met by sync replicas. This will affect how the "synchronous_standby_names" parameter will be + set up. + properties: + enabled: + description: This flag enables the constraints for sync replicas + type: boolean + nodeLabelsAntiAffinity: + description: A list of node labels values to extract and compare + to evaluate if the pods reside in the same topology or not + items: + type: string + type: array + required: + - enabled + type: object + type: object + primaryUpdateMethod: + default: restart + description: |- + Method to follow to upgrade the primary server during a rolling + update procedure, after all replicas have been successfully updated: + it can be with a switchover (`switchover`) or in-place (`restart` - default) + enum: + - switchover + - restart + type: string + primaryUpdateStrategy: + default: unsupervised + description: |- + Deployment strategy to follow to upgrade the primary server during a rolling + update procedure, after all replicas have been successfully updated: + it can be automated (`unsupervised` - default) or manual (`supervised`) + enum: + - unsupervised + - supervised + type: string + priorityClassName: + description: |- + Name of the priority class which will be used in every generated Pod, if the PriorityClass + specified does not exist, the pod will not be able to schedule. Please refer to + https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/#priorityclass + for more information + type: string + projectedVolumeTemplate: + description: |- + Template to be used to define projected volumes, projected volumes will be mounted + under `/projected` base folder + properties: + defaultMode: + description: |- + defaultMode are the mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume projections + items: + description: Projection that may be projected along with other + supported volume types + properties: + clusterTrustBundle: + description: |- + ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field + of ClusterTrustBundle objects in an auto-updating file. + + + Alpha, gated by the ClusterTrustBundleProjection feature gate. + + + ClusterTrustBundle objects can either be selected by name, or by the + combination of signer name and a label selector. + + + Kubelet performs aggressive normalization of the PEM contents written + into the pod filesystem. Esoteric PEM features such as inter-block + comments and block headers are stripped. Certificates are deduplicated. + The ordering of certificates within the file is arbitrary, and Kubelet + may change the order over time. + properties: + labelSelector: + description: |- + Select all ClusterTrustBundles that match this label selector. Only has + effect if signerName is set. Mutually-exclusive with name. If unset, + interpreted as "match nothing". If set but empty, interpreted as "match + everything". + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + name: + description: |- + Select a single ClusterTrustBundle by object name. Mutually-exclusive + with signerName and labelSelector. + type: string + optional: + description: |- + If true, don't block pod startup if the referenced ClusterTrustBundle(s) + aren't available. If using name, then the named ClusterTrustBundle is + allowed not to exist. If using signerName, then the combination of + signerName and labelSelector is allowed to match zero + ClusterTrustBundles. + type: boolean + path: + description: Relative path from the volume root to write + the bundle. + type: string + signerName: + description: |- + Select all ClusterTrustBundles that match this signer name. + Mutually-exclusive with name. The contents of all selected + ClusterTrustBundles will be unified and deduplicated. + type: string + required: + - path + type: object + configMap: + description: configMap information about the configMap data + to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a + volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + description: downwardAPI information about the downwardAPI + data to project + properties: + items: + description: Items is a list of DownwardAPIVolume file + items: + description: DownwardAPIVolumeFile represents information + to create the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects a field of the + pod: only annotations, labels, name, namespace + and uid are supported.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. Must not + be absolute or contain the ''..'' path. Must + be utf-8 encoded. The first item of the relative + path must not start with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + secret: + description: secret information about the secret data to + project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a + volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + optional: + description: optional field specify whether the Secret + or its key must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + description: serviceAccountToken is information about the + serviceAccountToken data to project + properties: + audience: + description: |- + audience is the intended audience of the token. A recipient of a token + must identify itself with an identifier specified in the audience of the + token, and otherwise should reject the token. The audience defaults to the + identifier of the apiserver. + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service + account token. As the token approaches expiration, the kubelet volume + plugin will proactively rotate the service account token. The kubelet will + start trying to rotate the token if the token is older than 80 percent of + its time to live or if the token is older than 24 hours.Defaults to 1 hour + and must be at least 10 minutes. + format: int64 + type: integer + path: + description: |- + path is the path relative to the mount point of the file to project the + token into. + type: string + required: + - path + type: object + type: object + type: array + x-kubernetes-list-type: atomic + type: object + replica: + description: Replica cluster configuration + properties: + enabled: + description: |- + If replica mode is enabled, this cluster will be a replica of an + existing cluster. Replica cluster can be created from a recovery + object store or via streaming through pg_basebackup. + Refer to the Replica clusters page of the documentation for more information. + type: boolean + source: + description: The name of the external cluster which is the replication + origin + minLength: 1 + type: string + required: + - enabled + - source + type: object + replicationSlots: + default: + highAvailability: + enabled: true + description: Replication slots management configuration + properties: + highAvailability: + default: + enabled: true + description: Replication slots for high availability configuration + properties: + enabled: + default: true + description: |- + If enabled (default), the operator will automatically manage replication slots + on the primary instance and use them in streaming replication + connections with all the standby instances that are part of the HA + cluster. If disabled, the operator will not take advantage + of replication slots in streaming connections with the replicas. + This feature also controls replication slots in replica cluster, + from the designated primary to its cascading replicas. + type: boolean + slotPrefix: + default: _cnpg_ + description: |- + Prefix for replication slots managed by the operator for HA. + It may only contain lower case letters, numbers, and the underscore character. + This can only be set at creation time. By default set to `_cnpg_`. + pattern: ^[0-9a-z_]*$ + type: string + type: object + synchronizeReplicas: + description: Configures the synchronization of the user defined + physical replication slots + properties: + enabled: + default: true + description: When set to true, every replication slot that + is on the primary is synchronized on each standby + type: boolean + excludePatterns: + description: List of regular expression patterns to match + the names of replication slots to be excluded (by default + empty) + items: + type: string + type: array + required: + - enabled + type: object + updateInterval: + default: 30 + description: |- + Standby will update the status of the local replication slots + every `updateInterval` seconds (default 30). + minimum: 1 + type: integer + type: object + resources: + description: |- + Resources requirements of every generated Pod. Please refer to + https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + for more information. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + schedulerName: + description: |- + If specified, the pod will be dispatched by specified Kubernetes + scheduler. If not specified, the pod will be dispatched by the default + scheduler. More info: + https://kubernetes.io/docs/concepts/scheduling-eviction/kube-scheduler/ + type: string + seccompProfile: + description: |- + The SeccompProfile applied to every Pod and Container. + Defaults to: `RuntimeDefault` + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + serviceAccountTemplate: + description: Configure the generation of the service account + properties: + metadata: + description: |- + Metadata are the metadata to be used for the generated + service account + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: http://kubernetes.io/docs/user-guide/annotations + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: http://kubernetes.io/docs/user-guide/labels + type: object + type: object + required: + - metadata + type: object + smartShutdownTimeout: + default: 180 + description: |- + The time in seconds that controls the window of time reserved for the smart shutdown of Postgres to complete. + Make sure you reserve enough time for the operator to request a fast shutdown of Postgres + (that is: `stopDelay` - `smartShutdownTimeout`). + format: int32 + type: integer + startDelay: + default: 3600 + description: |- + The time in seconds that is allowed for a PostgreSQL instance to + successfully start up (default 3600). + The startup probe failure threshold is derived from this value using the formula: + ceiling(startDelay / 10). + format: int32 + type: integer + stopDelay: + default: 1800 + description: |- + The time in seconds that is allowed for a PostgreSQL instance to + gracefully shutdown (default 1800) + format: int32 + type: integer + storage: + description: Configuration of the storage of the instances + properties: + pvcTemplate: + description: Template to be used to generate the Persistent Volume + Claim + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over volumes to consider + for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ + (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to the PersistentVolume + backing this claim. + type: string + type: object + resizeInUseVolumes: + default: true + description: Resize existent PVCs, defaults to true + type: boolean + size: + description: |- + Size of the storage. Required if not already specified in the PVC template. + Changes to this field are automatically reapplied to the created PVCs. + Size cannot be decreased. + type: string + storageClass: + description: |- + StorageClass to use for PVCs. Applied after + evaluating the PVC template, if available. + If not specified, the generated PVCs will use the + default storage class + type: string + type: object + superuserSecret: + description: |- + The secret containing the superuser password. If not defined a new + secret will be created with a randomly generated password + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + switchoverDelay: + default: 3600 + description: |- + The time in seconds that is allowed for a primary PostgreSQL instance + to gracefully shutdown during a switchover. + Default value is 3600 seconds (1 hour). + format: int32 + type: integer + tablespaces: + description: The tablespaces configuration + items: + description: |- + TablespaceConfiguration is the configuration of a tablespace, and includes + the storage specification for the tablespace + properties: + name: + description: The name of the tablespace + type: string + owner: + description: Owner is the PostgreSQL user owning the tablespace + properties: + name: + type: string + type: object + storage: + description: The storage configuration for the tablespace + properties: + pvcTemplate: + description: Template to be used to generate the Persistent + Volume Claim + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over volumes + to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ + (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to + the PersistentVolume backing this claim. + type: string + type: object + resizeInUseVolumes: + default: true + description: Resize existent PVCs, defaults to true + type: boolean + size: + description: |- + Size of the storage. Required if not already specified in the PVC template. + Changes to this field are automatically reapplied to the created PVCs. + Size cannot be decreased. + type: string + storageClass: + description: |- + StorageClass to use for PVCs. Applied after + evaluating the PVC template, if available. + If not specified, the generated PVCs will use the + default storage class + type: string + type: object + temporary: + default: false + description: |- + When set to true, the tablespace will be added as a `temp_tablespaces` + entry in PostgreSQL, and will be available to automatically house temp + database objects, or other temporary files. Please refer to PostgreSQL + documentation for more information on the `temp_tablespaces` GUC. + type: boolean + required: + - name + - storage + type: object + type: array + topologySpreadConstraints: + description: |- + TopologySpreadConstraints specifies how to spread matching pods among the given topology. + More info: + https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ + items: + description: TopologySpreadConstraint specifies how to spread matching + pods among the given topology. + properties: + labelSelector: + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods + in their corresponding topology domain. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + + + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. + format: int32 + type: integer + minDomains: + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + + + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + format: int32 + type: integer + nodeAffinityPolicy: + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + + + If this value is nil, the behavior is equivalent to the Honor policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + nodeTaintsPolicy: + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + + + If this value is nil, the behavior is equivalent to the Ignore policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + topologyKey: + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. + type: string + whenUnsatisfiable: + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + walStorage: + description: Configuration of the storage for PostgreSQL WAL (Write-Ahead + Log) + properties: + pvcTemplate: + description: Template to be used to generate the Persistent Volume + Claim + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over volumes to consider + for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ + (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to the PersistentVolume + backing this claim. + type: string + type: object + resizeInUseVolumes: + default: true + description: Resize existent PVCs, defaults to true + type: boolean + size: + description: |- + Size of the storage. Required if not already specified in the PVC template. + Changes to this field are automatically reapplied to the created PVCs. + Size cannot be decreased. + type: string + storageClass: + description: |- + StorageClass to use for PVCs. Applied after + evaluating the PVC template, if available. + If not specified, the generated PVCs will use the + default storage class + type: string + type: object + required: + - instances + type: object + x-kubernetes-validations: + - message: imageName and imageCatalogRef are mutually exclusive + rule: '!(has(self.imageCatalogRef) && has(self.imageName))' + status: + description: |- + Most recently observed status of the cluster. This data may not be up + to date. Populated by the system. Read-only. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + availableArchitectures: + description: AvailableArchitectures reports the available architectures + of a cluster + items: + description: AvailableArchitecture represents the state of a cluster's + architecture + properties: + goArch: + description: GoArch is the name of the executable architecture + type: string + hash: + description: Hash is the hash of the executable + type: string + required: + - goArch + - hash + type: object + type: array + azurePVCUpdateEnabled: + description: AzurePVCUpdateEnabled shows if the PVC online upgrade + is enabled for this cluster + type: boolean + certificates: + description: The configuration for the CA and related certificates, + initialized with defaults. + properties: + clientCASecret: + description: |- + The secret containing the Client CA certificate. If not defined, a new secret will be created + with a self-signed CA and will be used to generate all the client certificates.
+
+ Contains:
+
+ - `ca.crt`: CA that should be used to validate the client certificates, + used as `ssl_ca_file` of all the instances.
+ - `ca.key`: key used to generate client certificates, if ReplicationTLSSecret is provided, + this can be omitted.
+ type: string + expirations: + additionalProperties: + type: string + description: Expiration dates for all certificates. + type: object + replicationTLSSecret: + description: |- + The secret of type kubernetes.io/tls containing the client certificate to authenticate as + the `streaming_replica` user. + If not defined, ClientCASecret must provide also `ca.key`, and a new secret will be + created using the provided CA. + type: string + serverAltDNSNames: + description: The list of the server alternative DNS names to be + added to the generated server TLS certificates, when required. + items: + type: string + type: array + serverCASecret: + description: |- + The secret containing the Server CA certificate. If not defined, a new secret will be created + with a self-signed CA and will be used to generate the TLS certificate ServerTLSSecret.
+
+ Contains:
+
+ - `ca.crt`: CA that should be used to validate the server certificate, + used as `sslrootcert` in client connection strings.
+ - `ca.key`: key used to generate Server SSL certs, if ServerTLSSecret is provided, + this can be omitted.
+ type: string + serverTLSSecret: + description: |- + The secret of type kubernetes.io/tls containing the server TLS certificate and key that will be set as + `ssl_cert_file` and `ssl_key_file` so that clients can connect to postgres securely. + If not defined, ServerCASecret must provide also `ca.key` and a new secret will be + created using the provided CA. + type: string + type: object + cloudNativePGCommitHash: + description: The commit hash number of which this operator running + type: string + cloudNativePGOperatorHash: + description: The hash of the binary of the operator + type: string + conditions: + description: Conditions for cluster object + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + configMapResourceVersion: + description: |- + The list of resource versions of the configmaps, + managed by the operator. Every change here is done in the + interest of the instance manager, which will refresh the + configmap data + properties: + metrics: + additionalProperties: + type: string + description: |- + A map with the versions of all the config maps used to pass metrics. + Map keys are the config map names, map values are the versions + type: object + type: object + currentPrimary: + description: Current primary instance + type: string + currentPrimaryFailingSinceTimestamp: + description: |- + The timestamp when the primary was detected to be unhealthy + This field is reported when `.spec.failoverDelay` is populated or during online upgrades + type: string + currentPrimaryTimestamp: + description: The timestamp when the last actual promotion to primary + has occurred + type: string + danglingPVC: + description: |- + List of all the PVCs created by this cluster and still available + which are not attached to a Pod + items: + type: string + type: array + firstRecoverabilityPoint: + description: |- + The first recoverability point, stored as a date in RFC3339 format. + This field is calculated from the content of FirstRecoverabilityPointByMethod + type: string + firstRecoverabilityPointByMethod: + additionalProperties: + format: date-time + type: string + description: The first recoverability point, stored as a date in RFC3339 + format, per backup method type + type: object + healthyPVC: + description: List of all the PVCs not dangling nor initializing + items: + type: string + type: array + image: + description: Image contains the image name used by the pods + type: string + initializingPVC: + description: List of all the PVCs that are being initialized by this + cluster + items: + type: string + type: array + instanceNames: + description: List of instance names in the cluster + items: + type: string + type: array + instances: + description: The total number of PVC Groups detected in the cluster. + It may differ from the number of existing instance pods. + type: integer + instancesReportedState: + additionalProperties: + description: InstanceReportedState describes the last reported state + of an instance during a reconciliation loop + properties: + isPrimary: + description: indicates if an instance is the primary one + type: boolean + timeLineID: + description: indicates on which TimelineId the instance is + type: integer + required: + - isPrimary + type: object + description: The reported state of the instances during the last reconciliation + loop + type: object + instancesStatus: + additionalProperties: + items: + type: string + type: array + description: InstancesStatus indicates in which status the instances + are + type: object + jobCount: + description: How many Jobs have been created by this cluster + format: int32 + type: integer + lastFailedBackup: + description: Stored as a date in RFC3339 format + type: string + lastSuccessfulBackup: + description: |- + Last successful backup, stored as a date in RFC3339 format + This field is calculated from the content of LastSuccessfulBackupByMethod + type: string + lastSuccessfulBackupByMethod: + additionalProperties: + format: date-time + type: string + description: Last successful backup, stored as a date in RFC3339 format, + per backup method type + type: object + latestGeneratedNode: + description: ID of the latest generated node (used to avoid node name + clashing) + type: integer + managedRolesStatus: + description: ManagedRolesStatus reports the state of the managed roles + in the cluster + properties: + byStatus: + additionalProperties: + items: + type: string + type: array + description: ByStatus gives the list of roles in each state + type: object + cannotReconcile: + additionalProperties: + items: + type: string + type: array + description: |- + CannotReconcile lists roles that cannot be reconciled in PostgreSQL, + with an explanation of the cause + type: object + passwordStatus: + additionalProperties: + description: PasswordState represents the state of the password + of a managed RoleConfiguration + properties: + resourceVersion: + description: the resource version of the password secret + type: string + transactionID: + description: the last transaction ID to affect the role + definition in PostgreSQL + format: int64 + type: integer + type: object + description: PasswordStatus gives the last transaction id and + password secret version for each managed role + type: object + type: object + onlineUpdateEnabled: + description: OnlineUpdateEnabled shows if the online upgrade is enabled + inside the cluster + type: boolean + phase: + description: Current phase of the cluster + type: string + phaseReason: + description: Reason for the current phase + type: string + pluginStatus: + description: PluginStatus is the status of the loaded plugins + items: + description: PluginStatus is the status of a loaded plugin + properties: + backupCapabilities: + description: |- + BackupCapabilities are the list of capabilities of the + plugin regarding the Backup management + items: + type: string + type: array + capabilities: + description: |- + Capabilities are the list of capabilities of the + plugin + items: + type: string + type: array + name: + description: Name is the name of the plugin + type: string + operatorCapabilities: + description: |- + OperatorCapabilities are the list of capabilities of the + plugin regarding the reconciler + items: + type: string + type: array + version: + description: |- + Version is the version of the plugin loaded by the + latest reconciliation loop + type: string + walCapabilities: + description: |- + WALCapabilities are the list of capabilities of the + plugin regarding the WAL management + items: + type: string + type: array + required: + - name + - version + type: object + type: array + poolerIntegrations: + description: The integration needed by poolers referencing the cluster + properties: + pgBouncerIntegration: + description: PgBouncerIntegrationStatus encapsulates the needed + integration for the pgbouncer poolers referencing the cluster + properties: + secrets: + items: + type: string + type: array + type: object + type: object + pvcCount: + description: How many PVCs have been created by this cluster + format: int32 + type: integer + readService: + description: Current list of read pods + type: string + readyInstances: + description: The total number of ready instances in the cluster. It + is equal to the number of ready instance pods. + type: integer + resizingPVC: + description: List of all the PVCs that have ResizingPVC condition. + items: + type: string + type: array + secretsResourceVersion: + description: |- + The list of resource versions of the secrets + managed by the operator. Every change here is done in the + interest of the instance manager, which will refresh the + secret data + properties: + applicationSecretVersion: + description: The resource version of the "app" user secret + type: string + barmanEndpointCA: + description: The resource version of the Barman Endpoint CA if + provided + type: string + caSecretVersion: + description: Unused. Retained for compatibility with old versions. + type: string + clientCaSecretVersion: + description: The resource version of the PostgreSQL client-side + CA secret version + type: string + externalClusterSecretVersion: + additionalProperties: + type: string + description: The resource versions of the external cluster secrets + type: object + managedRoleSecretVersion: + additionalProperties: + type: string + description: The resource versions of the managed roles secrets + type: object + metrics: + additionalProperties: + type: string + description: |- + A map with the versions of all the secrets used to pass metrics. + Map keys are the secret names, map values are the versions + type: object + replicationSecretVersion: + description: The resource version of the "streaming_replica" user + secret + type: string + serverCaSecretVersion: + description: The resource version of the PostgreSQL server-side + CA secret version + type: string + serverSecretVersion: + description: The resource version of the PostgreSQL server-side + secret version + type: string + superuserSecretVersion: + description: The resource version of the "postgres" user secret + type: string + type: object + switchReplicaClusterStatus: + description: SwitchReplicaClusterStatus is the status of the switch + to replica cluster + properties: + inProgress: + description: InProgress indicates if there is an ongoing procedure + of switching a cluster to a replica cluster. + type: boolean + type: object + tablespacesStatus: + description: TablespacesStatus reports the state of the declarative + tablespaces in the cluster + items: + description: TablespaceState represents the state of a tablespace + in a cluster + properties: + error: + description: Error is the reconciliation error, if any + type: string + name: + description: Name is the name of the tablespace + type: string + owner: + description: Owner is the PostgreSQL user owning the tablespace + type: string + state: + description: State is the latest reconciliation state + type: string + required: + - name + - state + type: object + type: array + targetPrimary: + description: |- + Target primary instance, this is different from the previous one + during a switchover or a failover + type: string + targetPrimaryTimestamp: + description: The timestamp when the last request for a new primary + has occurred + type: string + timelineID: + description: The timeline of the Postgres cluster + type: integer + topology: + description: Instances topology. + properties: + instances: + additionalProperties: + additionalProperties: + type: string + description: PodTopologyLabels represent the topology of a Pod. + map[labelName]labelValue + type: object + description: Instances contains the pod topology of the instances + type: object + nodesUsed: + description: |- + NodesUsed represents the count of distinct nodes accommodating the instances. + A value of '1' suggests that all instances are hosted on a single node, + implying the absence of High Availability (HA). Ideally, this value should + be the same as the number of instances in the Postgres HA cluster, implying + shared nothing architecture on the compute side. + format: int32 + type: integer + successfullyExtracted: + description: |- + SuccessfullyExtracted indicates if the topology data was extract. It is useful to enact fallback behaviors + in synchronous replica election in case of failures + type: boolean + type: object + unusablePVC: + description: List of all the PVCs that are unusable because another + PVC is missing + items: + type: string + type: array + writeService: + description: Current write pod + type: string + type: object + required: + - metadata + - spec + type: object + served: true + storage: true + subresources: + scale: + specReplicasPath: .spec.instances + statusReplicasPath: .status.instances + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + helm.sh/resource-policy: keep + name: imagecatalogs.postgresql.cnpg.io +spec: + group: postgresql.cnpg.io + names: + kind: ImageCatalog + listKind: ImageCatalogList + plural: imagecatalogs + singular: imagecatalog + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: ImageCatalog is the Schema for the imagecatalogs API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: |- + Specification of the desired behavior of the ImageCatalog. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + images: + description: List of CatalogImages available in the catalog + items: + description: CatalogImage defines the image and major version + properties: + image: + description: The image reference + type: string + major: + description: The PostgreSQL major version of the image. Must + be unique within the catalog. + minimum: 10 + type: integer + required: + - image + - major + type: object + maxItems: 8 + minItems: 1 + type: array + x-kubernetes-validations: + - message: Images must have unique major versions + rule: self.all(e, self.filter(f, f.major==e.major).size() == 1) + required: + - images + type: object + required: + - metadata + - spec + type: object + served: true + storage: true + subresources: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + helm.sh/resource-policy: keep + name: poolers.postgresql.cnpg.io +spec: + group: postgresql.cnpg.io + names: + kind: Pooler + listKind: PoolerList + plural: poolers + singular: pooler + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .spec.cluster.name + name: Cluster + type: string + - jsonPath: .spec.type + name: Type + type: string + name: v1 + schema: + openAPIV3Schema: + description: Pooler is the Schema for the poolers API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: |- + Specification of the desired behavior of the Pooler. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + cluster: + description: |- + This is the cluster reference on which the Pooler will work. + Pooler name should never match with any cluster name within the same namespace. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + deploymentStrategy: + description: The deployment strategy to use for pgbouncer to replace + existing pods with new ones + properties: + rollingUpdate: + description: |- + Rolling update config params. Present only if DeploymentStrategyType = + RollingUpdate. + --- + TODO: Update this to follow our convention for oneOf, whatever we decide it + to be. + properties: + maxSurge: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of pods that can be scheduled above the desired number of + pods. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up. + Defaults to 25%. + Example: when this is set to 30%, the new ReplicaSet can be scaled up immediately when + the rolling update starts, such that the total number of old and new pods do not exceed + 130% of desired pods. Once old pods have been killed, + new ReplicaSet can be scaled up further, ensuring that total number of pods running + at any time during the update is at most 130% of desired pods. + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of pods that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + Absolute number is calculated from percentage by rounding down. + This can not be 0 if MaxSurge is 0. + Defaults to 25%. + Example: when this is set to 30%, the old ReplicaSet can be scaled down to 70% of desired pods + immediately when the rolling update starts. Once new pods are ready, old ReplicaSet + can be scaled down further, followed by scaling up the new ReplicaSet, ensuring + that the total number of pods available at all times during the update is at + least 70% of desired pods. + x-kubernetes-int-or-string: true + type: object + type: + description: Type of deployment. Can be "Recreate" or "RollingUpdate". + Default is RollingUpdate. + type: string + type: object + instances: + default: 1 + description: 'The number of replicas we want. Default: 1.' + format: int32 + type: integer + monitoring: + description: The configuration of the monitoring infrastructure of + this pooler. + properties: + enablePodMonitor: + default: false + description: Enable or disable the `PodMonitor` + type: boolean + podMonitorMetricRelabelings: + description: The list of metric relabelings for the `PodMonitor`. + Applied to samples before ingestion. + items: + description: |- + RelabelConfig allows dynamic rewriting of the label set for targets, alerts, + scraped samples and remote write samples. + + + More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + properties: + action: + default: replace + description: |- + Action to perform based on the regex matching. + + + `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0. + `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0. + + + Default: "Replace" + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + description: |- + Modulus to take of the hash of the source label values. + + + Only applicable when the action is `HashMod`. + format: int64 + type: integer + regex: + description: Regular expression against which the extracted + value is matched. + type: string + replacement: + description: |- + Replacement value against which a Replace action is performed if the + regular expression matches. + + + Regex capture groups are available. + type: string + separator: + description: Separator is the string between concatenated + SourceLabels. + type: string + sourceLabels: + description: |- + The source labels select values from existing labels. Their content is + concatenated using the configured Separator and matched against the + configured regular expression. + items: + description: |- + LabelName is a valid Prometheus label name which may only contain ASCII + letters, numbers, as well as underscores. + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + description: |- + Label to which the resulting string is written in a replacement. + + + It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`, + `KeepEqual` and `DropEqual` actions. + + + Regex capture groups are available. + type: string + type: object + type: array + podMonitorRelabelings: + description: The list of relabelings for the `PodMonitor`. Applied + to samples before scraping. + items: + description: |- + RelabelConfig allows dynamic rewriting of the label set for targets, alerts, + scraped samples and remote write samples. + + + More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + properties: + action: + default: replace + description: |- + Action to perform based on the regex matching. + + + `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0. + `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0. + + + Default: "Replace" + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + description: |- + Modulus to take of the hash of the source label values. + + + Only applicable when the action is `HashMod`. + format: int64 + type: integer + regex: + description: Regular expression against which the extracted + value is matched. + type: string + replacement: + description: |- + Replacement value against which a Replace action is performed if the + regular expression matches. + + + Regex capture groups are available. + type: string + separator: + description: Separator is the string between concatenated + SourceLabels. + type: string + sourceLabels: + description: |- + The source labels select values from existing labels. Their content is + concatenated using the configured Separator and matched against the + configured regular expression. + items: + description: |- + LabelName is a valid Prometheus label name which may only contain ASCII + letters, numbers, as well as underscores. + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + description: |- + Label to which the resulting string is written in a replacement. + + + It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`, + `KeepEqual` and `DropEqual` actions. + + + Regex capture groups are available. + type: string + type: object + type: array + type: object + pgbouncer: + description: The PgBouncer configuration + properties: + authQuery: + description: |- + The query that will be used to download the hash of the password + of a certain user. Default: "SELECT usename, passwd FROM public.user_search($1)". + In case it is specified, also an AuthQuerySecret has to be specified and + no automatic CNPG Cluster integration will be triggered. + type: string + authQuerySecret: + description: |- + The credentials of the user that need to be used for the authentication + query. In case it is specified, also an AuthQuery + (e.g. "SELECT usename, passwd FROM pg_catalog.pg_shadow WHERE usename=$1") + has to be specified and no automatic CNPG Cluster integration will be triggered. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + parameters: + additionalProperties: + type: string + description: |- + Additional parameters to be passed to PgBouncer - please check + the CNPG documentation for a list of options you can configure + type: object + paused: + default: false + description: |- + When set to `true`, PgBouncer will disconnect from the PostgreSQL + server, first waiting for all queries to complete, and pause all new + client connections until this value is set to `false` (default). Internally, + the operator calls PgBouncer's `PAUSE` and `RESUME` commands. + type: boolean + pg_hba: + description: |- + PostgreSQL Host Based Authentication rules (lines to be appended + to the pg_hba.conf file) + items: + type: string + type: array + poolMode: + default: session + description: 'The pool mode. Default: `session`.' + enum: + - session + - transaction + type: string + type: object + serviceTemplate: + description: Template for the Service to be created + properties: + metadata: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: http://kubernetes.io/docs/user-guide/annotations + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: http://kubernetes.io/docs/user-guide/labels + type: object + type: object + spec: + description: |- + Specification of the desired behavior of the service. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + allocateLoadBalancerNodePorts: + description: |- + allocateLoadBalancerNodePorts defines if NodePorts will be automatically + allocated for services with type LoadBalancer. Default is "true". It + may be set to "false" if the cluster load-balancer does not rely on + NodePorts. If the caller requests specific NodePorts (by specifying a + value), those requests will be respected, regardless of this field. + This field may only be set for services with type LoadBalancer and will + be cleared if the type is changed to any other type. + type: boolean + clusterIP: + description: |- + clusterIP is the IP address of the service and is usually assigned + randomly. If an address is specified manually, is in-range (as per + system configuration), and is not in use, it will be allocated to the + service; otherwise creation of the service will fail. This field may not + be changed through updates unless the type field is also being changed + to ExternalName (which requires this field to be blank) or the type + field is being changed from ExternalName (in which case this field may + optionally be specified, as describe above). Valid values are "None", + empty string (""), or a valid IP address. Setting this to "None" makes a + "headless service" (no virtual IP), which is useful when direct endpoint + connections are preferred and proxying is not required. Only applies to + types ClusterIP, NodePort, and LoadBalancer. If this field is specified + when creating a Service of type ExternalName, creation will fail. This + field will be wiped when updating a Service to type ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + clusterIPs: + description: |- + ClusterIPs is a list of IP addresses assigned to this service, and are + usually assigned randomly. If an address is specified manually, is + in-range (as per system configuration), and is not in use, it will be + allocated to the service; otherwise creation of the service will fail. + This field may not be changed through updates unless the type field is + also being changed to ExternalName (which requires this field to be + empty) or the type field is being changed from ExternalName (in which + case this field may optionally be specified, as describe above). Valid + values are "None", empty string (""), or a valid IP address. Setting + this to "None" makes a "headless service" (no virtual IP), which is + useful when direct endpoint connections are preferred and proxying is + not required. Only applies to types ClusterIP, NodePort, and + LoadBalancer. If this field is specified when creating a Service of type + ExternalName, creation will fail. This field will be wiped when updating + a Service to type ExternalName. If this field is not specified, it will + be initialized from the clusterIP field. If this field is specified, + clients must ensure that clusterIPs[0] and clusterIP have the same + value. + + + This field may hold a maximum of two entries (dual-stack IPs, in either order). + These IPs must correspond to the values of the ipFamilies field. Both + clusterIPs and ipFamilies are governed by the ipFamilyPolicy field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + description: |- + externalIPs is a list of IP addresses for which nodes in the cluster + will also accept traffic for this service. These IPs are not managed by + Kubernetes. The user is responsible for ensuring that traffic arrives + at a node with this IP. A common example is external load-balancers + that are not part of the Kubernetes system. + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalName: + description: |- + externalName is the external reference that discovery mechanisms will + return as an alias for this service (e.g. a DNS CNAME record). No + proxying will be involved. Must be a lowercase RFC-1123 hostname + (https://tools.ietf.org/html/rfc1123) and requires `type` to be "ExternalName". + type: string + externalTrafficPolicy: + description: |- + externalTrafficPolicy describes how nodes distribute service traffic they + receive on one of the Service's "externally-facing" addresses (NodePorts, + ExternalIPs, and LoadBalancer IPs). If set to "Local", the proxy will configure + the service in a way that assumes that external load balancers will take care + of balancing the service traffic between nodes, and so each node will deliver + traffic only to the node-local endpoints of the service, without masquerading + the client source IP. (Traffic mistakenly sent to a node with no endpoints will + be dropped.) The default value, "Cluster", uses the standard behavior of + routing to all endpoints evenly (possibly modified by topology and other + features). Note that traffic sent to an External IP or LoadBalancer IP from + within the cluster will always get "Cluster" semantics, but clients sending to + a NodePort from within the cluster may need to take traffic policy into account + when picking a node. + type: string + healthCheckNodePort: + description: |- + healthCheckNodePort specifies the healthcheck nodePort for the service. + This only applies when type is set to LoadBalancer and + externalTrafficPolicy is set to Local. If a value is specified, is + in-range, and is not in use, it will be used. If not specified, a value + will be automatically allocated. External systems (e.g. load-balancers) + can use this port to determine if a given node holds endpoints for this + service or not. If this field is specified when creating a Service + which does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing type). + This field cannot be updated once set. + format: int32 + type: integer + internalTrafficPolicy: + description: |- + InternalTrafficPolicy describes how nodes distribute service traffic they + receive on the ClusterIP. If set to "Local", the proxy will assume that pods + only want to talk to endpoints of the service on the same node as the pod, + dropping the traffic if there are no local endpoints. The default value, + "Cluster", uses the standard behavior of routing to all endpoints evenly + (possibly modified by topology and other features). + type: string + ipFamilies: + description: |- + IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this + service. This field is usually assigned automatically based on cluster + configuration and the ipFamilyPolicy field. If this field is specified + manually, the requested family is available in the cluster, + and ipFamilyPolicy allows it, it will be used; otherwise creation of + the service will fail. This field is conditionally mutable: it allows + for adding or removing a secondary IP family, but it does not allow + changing the primary IP family of the Service. Valid values are "IPv4" + and "IPv6". This field only applies to Services of types ClusterIP, + NodePort, and LoadBalancer, and does apply to "headless" services. + This field will be wiped when updating a Service to type ExternalName. + + + This field may hold a maximum of two entries (dual-stack families, in + either order). These families must correspond to the values of the + clusterIPs field, if specified. Both clusterIPs and ipFamilies are + governed by the ipFamilyPolicy field. + items: + description: |- + IPFamily represents the IP Family (IPv4 or IPv6). This type is used + to express the family of an IP expressed by a type (e.g. service.spec.ipFamilies). + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by + this Service. If there is no value provided, then this field will be set + to SingleStack. Services can be "SingleStack" (a single IP family), + "PreferDualStack" (two IP families on dual-stack configured clusters or + a single IP family on single-stack clusters), or "RequireDualStack" + (two IP families on dual-stack configured clusters, otherwise fail). The + ipFamilies and clusterIPs fields depend on the value of this field. This + field will be wiped when updating a service to type ExternalName. + type: string + loadBalancerClass: + description: |- + loadBalancerClass is the class of the load balancer implementation this Service belongs to. + If specified, the value of this field must be a label-style identifier, with an optional prefix, + e.g. "internal-vip" or "example.com/internal-vip". Unprefixed names are reserved for end-users. + This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load + balancer implementation is used, today this is typically done through the cloud provider integration, + but should apply for any default implementation. If set, it is assumed that a load balancer + implementation is watching for Services with a matching class. Any default load balancer + implementation (e.g. cloud providers) should ignore Services that set this field. + This field can only be set when creating or updating a Service to type 'LoadBalancer'. + Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type. + type: string + loadBalancerIP: + description: |- + Only applies to Service Type: LoadBalancer. + This feature depends on whether the underlying cloud-provider supports specifying + the loadBalancerIP when a load balancer is created. + This field will be ignored if the cloud-provider does not support the feature. + Deprecated: This field was under-specified and its meaning varies across implementations. + Using it is non-portable and it may not support dual-stack. + Users are encouraged to use implementation-specific annotations when available. + type: string + loadBalancerSourceRanges: + description: |- + If specified and supported by the platform, this will restrict traffic through the cloud-provider + load-balancer will be restricted to the specified client IPs. This field will be ignored if the + cloud-provider does not support the feature." + More info: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ + items: + type: string + type: array + x-kubernetes-list-type: atomic + ports: + description: |- + The list of ports that are exposed by this service. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + items: + description: ServicePort contains information on service's + port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses indicates that any agent which deals with endpoints for this + Service should disregard any indications of ready/not-ready. + The primary use case for setting this field is for a StatefulSet's Headless Service to + propagate SRV DNS records for its Pods for the purpose of peer discovery. + The Kubernetes controllers that generate Endpoints and EndpointSlice resources for + Services interpret this to mean that all endpoints are considered "ready" even if the + Pods themselves are not. Agents which consume only Kubernetes generated endpoints + through the Endpoints or EndpointSlice resources can safely assume this behavior. + type: boolean + selector: + additionalProperties: + type: string + description: |- + Route service traffic to pods with label keys and values matching this + selector. If empty or not present, the service is assumed to have an + external process managing its endpoints, which Kubernetes will not + modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. + Ignored if type is ExternalName. + More info: https://kubernetes.io/docs/concepts/services-networking/service/ + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + description: |- + Supports "ClientIP" and "None". Used to maintain session affinity. + Enable client IP based session affinity. + Must be ClientIP or None. + Defaults to None. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + type: string + sessionAffinityConfig: + description: sessionAffinityConfig contains the configurations + of session affinity. + properties: + clientIP: + description: clientIP contains the configurations of Client + IP based session affinity. + properties: + timeoutSeconds: + description: |- + timeoutSeconds specifies the seconds of ClientIP type session sticky time. + The value must be >0 && <=86400(for 1 day) if ServiceAffinity == "ClientIP". + Default value is 10800(for 3 hours). + format: int32 + type: integer + type: object + type: object + trafficDistribution: + description: |- + TrafficDistribution offers a way to express preferences for how traffic is + distributed to Service endpoints. Implementations can use this field as a + hint, but are not required to guarantee strict adherence. If the field is + not set, the implementation will apply its default routing strategy. If set + to "PreferClose", implementations should prioritize endpoints that are + topologically close (e.g., same zone). + This is an alpha field and requires enabling ServiceTrafficDistribution feature. + type: string + type: + description: |- + type determines how the Service is exposed. Defaults to ClusterIP. Valid + options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + "ClusterIP" allocates a cluster-internal IP address for load-balancing + to endpoints. Endpoints are determined by the selector or if that is not + specified, by manual construction of an Endpoints object or + EndpointSlice objects. If clusterIP is "None", no virtual IP is + allocated and the endpoints are published as a set of endpoints rather + than a virtual IP. + "NodePort" builds on ClusterIP and allocates a port on every node which + routes to the same endpoints as the clusterIP. + "LoadBalancer" builds on NodePort and creates an external load-balancer + (if supported in the current cloud) which routes to the same endpoints + as the clusterIP. + "ExternalName" aliases this service to the specified externalName. + Several other fields do not apply to ExternalName services. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: string + type: object + type: object + template: + description: The template of the Pod to be created + properties: + metadata: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: http://kubernetes.io/docs/user-guide/annotations + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: http://kubernetes.io/docs/user-guide/labels + type: object + type: object + spec: + description: |- + Specification of the desired behavior of the pod. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + activeDeadlineSeconds: + description: |- + Optional duration in seconds the pod may be active on the node relative to + StartTime before the system will actively try to mark it failed and kill associated containers. + Value must be a positive integer. + format: int64 + type: integer + affinity: + description: If specified, the pod's scheduling constraints + properties: + nodeAffinity: + description: Describes node affinity scheduling rules + for the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. + items: + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated + with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching + the corresponding nodeSelectorTerm, in the + range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector + terms. The terms are ORed. + items: + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. + co-locate this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules + (e.g. avoid putting this pod in the same node, zone, + etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + automountServiceAccountToken: + description: AutomountServiceAccountToken indicates whether + a service account token should be automatically mounted. + type: boolean + containers: + description: |- + List of containers belonging to the pod. + Containers cannot currently be added or removed. + There must be at least one container in a Pod. + Cannot be updated. + items: + description: A single application container that you want + to run within a pod. + properties: + args: + description: |- + Arguments to the entrypoint. + The container image's CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + description: |- + Entrypoint array. Not executed within a shell. + The container image's ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + description: |- + List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in + the pod's namespace + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + description: |- + List of sources to populate environment variables in the container. + The keys defined within a source must be a C_IDENTIFIER. All invalid keys + will be reported as an event when the container is starting. When a key exists in multiple + sources, the value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will take precedence. + Cannot be updated. + items: + description: EnvFromSource represents the source of + a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + optional: + description: Specify whether the ConfigMap + must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: An optional identifier to prepend + to each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + optional: + description: Specify whether the Secret must + be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + description: |- + Container image name. + More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management to default or override + container images in workload controllers like Deployments and StatefulSets. + type: string + imagePullPolicy: + description: |- + Image pull policy. + One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + type: string + lifecycle: + description: |- + Actions that the management system should take in response to container lifecycle events. + Cannot be updated. + properties: + postStart: + description: |- + PostStart is called immediately after a container is created. If the handler fails, + the container is terminated and restarted according to its restart policy. + Other management of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration that + the container should sleep before being terminated. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: |- + PreStop is called immediately before a container is terminated due to an + API request or management event such as liveness/startup probe failure, + preemption, resource contention, etc. The handler is not called if the + container crashes or exits. The Pod's termination grace period countdown begins before the + PreStop hook is executed. Regardless of the outcome of the handler, the + container will eventually terminate within the Pod's termination grace + period (unless delayed by finalizers). Other management of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration that + the container should sleep before being terminated. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: |- + Periodic probe of container liveness. + Container will be restarted if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + name: + description: |- + Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: |- + List of ports to expose from the container. Not specifying a port here + DOES NOT prevent that port from being exposed. Any port which is + listening on the default "0.0.0.0" address inside a container will be + accessible from the network. + Modifying this array with strategic merge patch may corrupt the data. + For more information See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. + items: + description: ContainerPort represents a network port + in a single container. + properties: + containerPort: + description: |- + Number of port to expose on the pod's IP address. + This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external + port to. + type: string + hostPort: + description: |- + Number of port to expose on the host. + If specified, this must be a valid port number, 0 < x < 65536. + If HostNetwork is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: |- + If specified, this must be an IANA_SVC_NAME and unique within the pod. Each + named port in a pod must have a unique name. Name for the port that can be + referred to by services. + type: string + protocol: + default: TCP + description: |- + Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: |- + Periodic probe of container service readiness. + Container will be removed from service endpoints if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: |- + Name of the resource to which this resource resize policy applies. + Supported values: cpu, memory. + type: string + restartPolicy: + description: |- + Restart policy to apply when specified resource is resized. + If not specified, it defaults to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: |- + Compute Resources required by this container. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry + in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + RestartPolicy defines the restart behavior of individual containers in a pod. + This field may only be set for init containers, and the only allowed value is "Always". + For non-init containers or when this field is not specified, + the restart behavior is defined by the Pod's restart policy and the container type. + Setting the RestartPolicy as "Always" for the init container will have the following effect: + this init container will be continually restarted on + exit until all regular containers have terminated. Once all regular + containers have completed, all init containers with restartPolicy "Always" + will be shut down. This lifecycle differs from normal init containers and + is often referred to as a "sidecar" container. Although this init + container still starts in the init container sequence, it does not wait + for the container to complete before proceeding to the next init + container. Instead, the next init container starts immediately after this + init container is started, or after any startupProbe has successfully + completed. + type: string + securityContext: + description: |- + SecurityContext defines the security options the container should be run with. + If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + x-kubernetes-list-type: atomic + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that + applies to the container. + type: string + role: + description: Role is a SELinux role label that + applies to the container. + type: string + type: + description: Type is a SELinux type label that + applies to the container. + type: string + user: + description: User is a SELinux user label that + applies to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: |- + StartupProbe indicates that the Pod has successfully initialized. + If specified, no other probes are executed until this completes successfully. + If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. + This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, + when it might take a long time to load data or warm a cache, than during steady-state operation. + This cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + stdin: + description: |- + Whether this container should allocate a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will always result in EOF. + Default is false. + type: boolean + stdinOnce: + description: |- + Whether the container runtime should close the stdin channel after it has been opened by + a single attach. When stdin is true the stdin stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + first client attaches to stdin, and then remains open and accepts data until the client disconnects, + at which time stdin is closed and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin will never receive an EOF. + Default is false + type: boolean + terminationMessagePath: + description: |- + Optional: Path at which the file to which the container's termination message + will be written is mounted into the container's filesystem. + Message written is intended to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. The total message length across + all containers will be limited to 12kb. + Defaults to /dev/termination-log. + Cannot be updated. + type: string + terminationMessagePolicy: + description: |- + Indicate how the termination message should be populated. File will use the contents of + terminationMessagePath to populate the container status message on both success and failure. + FallbackToLogsOnError will use the last chunk of container log output if the termination + message file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + Defaults to File. + Cannot be updated. + type: string + tty: + description: |- + Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of a + raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of + the container that the device will be mapped + to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + description: |- + Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a + Volume within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified + (which defaults to None). + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + recursiveReadOnly: + description: |- + RecursiveReadOnly specifies whether read-only mounts should be handled + recursively. + + + If ReadOnly is false, this field has no meaning and must be unspecified. + + + If ReadOnly is true, and this field is set to Disabled, the mount is not made + recursively read-only. If this field is set to IfPossible, the mount is made + recursively read-only, if it is supported by the container runtime. If this + field is set to Enabled, the mount is made recursively read-only if it is + supported by the container runtime, otherwise the pod will not be started and + an error will be generated to indicate the reason. + + + If this field is set to IfPossible or Enabled, MountPropagation must be set to + None (or be unspecified, which defaults to None). + + + If this field is not specified, it is treated as an equivalent of Disabled. + type: string + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + description: |- + Container's working directory. + If not specified, the container runtime's default will be used, which + might be configured in the container image. + Cannot be updated. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + dnsConfig: + description: |- + Specifies the DNS parameters of a pod. + Parameters specified here will be merged to the generated DNS + configuration based on DNSPolicy. + properties: + nameservers: + description: |- + A list of DNS name server IP addresses. + This will be appended to the base nameservers generated from DNSPolicy. + Duplicated nameservers will be removed. + items: + type: string + type: array + x-kubernetes-list-type: atomic + options: + description: |- + A list of DNS resolver options. + This will be merged with the base options generated from DNSPolicy. + Duplicated entries will be removed. Resolution options given in Options + will override those that appear in the base DNSPolicy. + items: + description: PodDNSConfigOption defines DNS resolver + options of a pod. + properties: + name: + description: Required. + type: string + value: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + searches: + description: |- + A list of DNS search domains for host-name lookup. + This will be appended to the base search paths generated from DNSPolicy. + Duplicated search paths will be removed. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + dnsPolicy: + description: |- + Set DNS policy for the pod. + Defaults to "ClusterFirst". + Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', 'Default' or 'None'. + DNS parameters given in DNSConfig will be merged with the policy selected with DNSPolicy. + To have DNS options set along with hostNetwork, you have to specify DNS policy + explicitly to 'ClusterFirstWithHostNet'. + type: string + enableServiceLinks: + description: |- + EnableServiceLinks indicates whether information about services should be injected into pod's + environment variables, matching the syntax of Docker links. + Optional: Defaults to true. + type: boolean + ephemeralContainers: + description: |- + List of ephemeral containers run in this pod. Ephemeral containers may be run in an existing + pod to perform user-initiated actions such as debugging. This list cannot be specified when + creating a pod, and it cannot be modified by updating the pod spec. In order to add an + ephemeral container to an existing pod, use the pod's ephemeralcontainers subresource. + items: + description: |- + An EphemeralContainer is a temporary container that you may add to an existing Pod for + user-initiated activities such as debugging. Ephemeral containers have no resource or + scheduling guarantees, and they will not be restarted when they exit or when a Pod is + removed or restarted. The kubelet may evict a Pod if an ephemeral container causes the + Pod to exceed its resource allocation. + + + To add an ephemeral container, use the ephemeralcontainers subresource of an existing + Pod. Ephemeral containers may not be removed or restarted. + properties: + args: + description: |- + Arguments to the entrypoint. + The image's CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + description: |- + Entrypoint array. Not executed within a shell. + The image's ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + description: |- + List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in + the pod's namespace + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + description: |- + List of sources to populate environment variables in the container. + The keys defined within a source must be a C_IDENTIFIER. All invalid keys + will be reported as an event when the container is starting. When a key exists in multiple + sources, the value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will take precedence. + Cannot be updated. + items: + description: EnvFromSource represents the source of + a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + optional: + description: Specify whether the ConfigMap + must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: An optional identifier to prepend + to each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + optional: + description: Specify whether the Secret must + be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + description: |- + Container image name. + More info: https://kubernetes.io/docs/concepts/containers/images + type: string + imagePullPolicy: + description: |- + Image pull policy. + One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + type: string + lifecycle: + description: Lifecycle is not allowed for ephemeral + containers. + properties: + postStart: + description: |- + PostStart is called immediately after a container is created. If the handler fails, + the container is terminated and restarted according to its restart policy. + Other management of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration that + the container should sleep before being terminated. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: |- + PreStop is called immediately before a container is terminated due to an + API request or management event such as liveness/startup probe failure, + preemption, resource contention, etc. The handler is not called if the + container crashes or exits. The Pod's termination grace period countdown begins before the + PreStop hook is executed. Regardless of the outcome of the handler, the + container will eventually terminate within the Pod's termination grace + period (unless delayed by finalizers). Other management of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration that + the container should sleep before being terminated. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: Probes are not allowed for ephemeral containers. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + name: + description: |- + Name of the ephemeral container specified as a DNS_LABEL. + This name must be unique among all containers, init containers and ephemeral containers. + type: string + ports: + description: Ports are not allowed for ephemeral containers. + items: + description: ContainerPort represents a network port + in a single container. + properties: + containerPort: + description: |- + Number of port to expose on the pod's IP address. + This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external + port to. + type: string + hostPort: + description: |- + Number of port to expose on the host. + If specified, this must be a valid port number, 0 < x < 65536. + If HostNetwork is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: |- + If specified, this must be an IANA_SVC_NAME and unique within the pod. Each + named port in a pod must have a unique name. Name for the port that can be + referred to by services. + type: string + protocol: + default: TCP + description: |- + Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: Probes are not allowed for ephemeral containers. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: |- + Name of the resource to which this resource resize policy applies. + Supported values: cpu, memory. + type: string + restartPolicy: + description: |- + Restart policy to apply when specified resource is resized. + If not specified, it defaults to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: |- + Resources are not allowed for ephemeral containers. Ephemeral containers use spare resources + already allocated to the pod. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry + in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + Restart policy for the container to manage the restart behavior of each + container within a pod. + This may only be set for init containers. You cannot set this field on + ephemeral containers. + type: string + securityContext: + description: |- + Optional: SecurityContext defines the security options the ephemeral container should be run with. + If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + x-kubernetes-list-type: atomic + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that + applies to the container. + type: string + role: + description: Role is a SELinux role label that + applies to the container. + type: string + type: + description: Type is a SELinux type label that + applies to the container. + type: string + user: + description: User is a SELinux user label that + applies to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: Probes are not allowed for ephemeral containers. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + stdin: + description: |- + Whether this container should allocate a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will always result in EOF. + Default is false. + type: boolean + stdinOnce: + description: |- + Whether the container runtime should close the stdin channel after it has been opened by + a single attach. When stdin is true the stdin stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + first client attaches to stdin, and then remains open and accepts data until the client disconnects, + at which time stdin is closed and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin will never receive an EOF. + Default is false + type: boolean + targetContainerName: + description: |- + If set, the name of the container from PodSpec that this ephemeral container targets. + The ephemeral container will be run in the namespaces (IPC, PID, etc) of this container. + If not set then the ephemeral container uses the namespaces configured in the Pod spec. + + + The container runtime must implement support for this feature. If the runtime does not + support namespace targeting then the result of setting this field is undefined. + type: string + terminationMessagePath: + description: |- + Optional: Path at which the file to which the container's termination message + will be written is mounted into the container's filesystem. + Message written is intended to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. The total message length across + all containers will be limited to 12kb. + Defaults to /dev/termination-log. + Cannot be updated. + type: string + terminationMessagePolicy: + description: |- + Indicate how the termination message should be populated. File will use the contents of + terminationMessagePath to populate the container status message on both success and failure. + FallbackToLogsOnError will use the last chunk of container log output if the termination + message file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + Defaults to File. + Cannot be updated. + type: string + tty: + description: |- + Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of a + raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of + the container that the device will be mapped + to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + description: |- + Pod volumes to mount into the container's filesystem. Subpath mounts are not allowed for ephemeral containers. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a + Volume within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified + (which defaults to None). + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + recursiveReadOnly: + description: |- + RecursiveReadOnly specifies whether read-only mounts should be handled + recursively. + + + If ReadOnly is false, this field has no meaning and must be unspecified. + + + If ReadOnly is true, and this field is set to Disabled, the mount is not made + recursively read-only. If this field is set to IfPossible, the mount is made + recursively read-only, if it is supported by the container runtime. If this + field is set to Enabled, the mount is made recursively read-only if it is + supported by the container runtime, otherwise the pod will not be started and + an error will be generated to indicate the reason. + + + If this field is set to IfPossible or Enabled, MountPropagation must be set to + None (or be unspecified, which defaults to None). + + + If this field is not specified, it is treated as an equivalent of Disabled. + type: string + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + description: |- + Container's working directory. + If not specified, the container runtime's default will be used, which + might be configured in the container image. + Cannot be updated. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + hostAliases: + description: |- + HostAliases is an optional list of hosts and IPs that will be injected into the pod's hosts + file if specified. + items: + description: |- + HostAlias holds the mapping between IP and hostnames that will be injected as an entry in the + pod's hosts file. + properties: + hostnames: + description: Hostnames for the above IP address. + items: + type: string + type: array + x-kubernetes-list-type: atomic + ip: + description: IP address of the host file entry. + type: string + required: + - ip + type: object + type: array + x-kubernetes-list-map-keys: + - ip + x-kubernetes-list-type: map + hostIPC: + description: |- + Use the host's ipc namespace. + Optional: Default to false. + type: boolean + hostNetwork: + description: |- + Host networking requested for this pod. Use the host's network namespace. + If this option is set, the ports that will be used must be specified. + Default to false. + type: boolean + hostPID: + description: |- + Use the host's pid namespace. + Optional: Default to false. + type: boolean + hostUsers: + description: |- + Use the host's user namespace. + Optional: Default to true. + If set to true or not present, the pod will be run in the host user namespace, useful + for when the pod needs a feature only available to the host user namespace, such as + loading a kernel module with CAP_SYS_MODULE. + When set to false, a new userns is created for the pod. Setting false is useful for + mitigating container breakout vulnerabilities even allowing users to run their + containers as root without actually having root privileges on the host. + This field is alpha-level and is only honored by servers that enable the UserNamespacesSupport feature. + type: boolean + hostname: + description: |- + Specifies the hostname of the Pod + If not specified, the pod's hostname will be set to a system-defined value. + type: string + imagePullSecrets: + description: |- + ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. + If specified, these secrets will be passed to individual puller implementations for them to use. + More info: https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod + items: + description: |- + LocalObjectReference contains enough information to let you locate the + referenced object inside the same namespace. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + initContainers: + description: |- + List of initialization containers belonging to the pod. + Init containers are executed in order prior to containers being started. If any + init container fails, the pod is considered to have failed and is handled according + to its restartPolicy. The name for an init container or normal container must be + unique among all containers. + Init containers may not have Lifecycle actions, Readiness probes, Liveness probes, or Startup probes. + The resourceRequirements of an init container are taken into account during scheduling + by finding the highest request/limit for each resource type, and then using the max of + of that value or the sum of the normal containers. Limits are applied to init containers + in a similar fashion. + Init containers cannot currently be added or removed. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ + items: + description: A single application container that you want + to run within a pod. + properties: + args: + description: |- + Arguments to the entrypoint. + The container image's CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + description: |- + Entrypoint array. Not executed within a shell. + The container image's ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + description: |- + List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable + present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in + the pod's namespace + properties: + key: + description: The key of the secret to + select from. Must be a valid secret + key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + description: |- + List of sources to populate environment variables in the container. + The keys defined within a source must be a C_IDENTIFIER. All invalid keys + will be reported as an event when the container is starting. When a key exists in multiple + sources, the value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will take precedence. + Cannot be updated. + items: + description: EnvFromSource represents the source of + a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + optional: + description: Specify whether the ConfigMap + must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: An optional identifier to prepend + to each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + optional: + description: Specify whether the Secret must + be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + description: |- + Container image name. + More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management to default or override + container images in workload controllers like Deployments and StatefulSets. + type: string + imagePullPolicy: + description: |- + Image pull policy. + One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + type: string + lifecycle: + description: |- + Actions that the management system should take in response to container lifecycle events. + Cannot be updated. + properties: + postStart: + description: |- + PostStart is called immediately after a container is created. If the handler fails, + the container is terminated and restarted according to its restart policy. + Other management of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration that + the container should sleep before being terminated. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: |- + PreStop is called immediately before a container is terminated due to an + API request or management event such as liveness/startup probe failure, + preemption, resource contention, etc. The handler is not called if the + container crashes or exits. The Pod's termination grace period countdown begins before the + PreStop hook is executed. Regardless of the outcome of the handler, the + container will eventually terminate within the Pod's termination grace + period (unless delayed by finalizers). Other management of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration that + the container should sleep before being terminated. + properties: + seconds: + description: Seconds is the number of seconds + to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: |- + Periodic probe of container liveness. + Container will be restarted if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + name: + description: |- + Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: |- + List of ports to expose from the container. Not specifying a port here + DOES NOT prevent that port from being exposed. Any port which is + listening on the default "0.0.0.0" address inside a container will be + accessible from the network. + Modifying this array with strategic merge patch may corrupt the data. + For more information See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. + items: + description: ContainerPort represents a network port + in a single container. + properties: + containerPort: + description: |- + Number of port to expose on the pod's IP address. + This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external + port to. + type: string + hostPort: + description: |- + Number of port to expose on the host. + If specified, this must be a valid port number, 0 < x < 65536. + If HostNetwork is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: |- + If specified, this must be an IANA_SVC_NAME and unique within the pod. Each + named port in a pod must have a unique name. Name for the port that can be + referred to by services. + type: string + protocol: + default: TCP + description: |- + Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: |- + Periodic probe of container service readiness. + Container will be removed from service endpoints if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource + resize policy for the container. + properties: + resourceName: + description: |- + Name of the resource to which this resource resize policy applies. + Supported values: cpu, memory. + type: string + restartPolicy: + description: |- + Restart policy to apply when specified resource is resized. + If not specified, it defaults to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: |- + Compute Resources required by this container. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry + in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + RestartPolicy defines the restart behavior of individual containers in a pod. + This field may only be set for init containers, and the only allowed value is "Always". + For non-init containers or when this field is not specified, + the restart behavior is defined by the Pod's restart policy and the container type. + Setting the RestartPolicy as "Always" for the init container will have the following effect: + this init container will be continually restarted on + exit until all regular containers have terminated. Once all regular + containers have completed, all init containers with restartPolicy "Always" + will be shut down. This lifecycle differs from normal init containers and + is often referred to as a "sidecar" container. Although this init + container still starts in the init container sequence, it does not wait + for the container to complete before proceeding to the next init + container. Instead, the next init container starts immediately after this + init container is started, or after any startupProbe has successfully + completed. + type: string + securityContext: + description: |- + SecurityContext defines the security options the container should be run with. + If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + x-kubernetes-list-type: atomic + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that + applies to the container. + type: string + role: + description: Role is a SELinux role label that + applies to the container. + type: string + type: + description: Type is a SELinux type label that + applies to the container. + type: string + user: + description: User is a SELinux user label that + applies to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: |- + StartupProbe indicates that the Pod has successfully initialized. + If specified, no other probes are executed until this completes successfully. + If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. + This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, + when it might take a long time to load data or warm a cache, than during steady-state operation. + This cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + stdin: + description: |- + Whether this container should allocate a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will always result in EOF. + Default is false. + type: boolean + stdinOnce: + description: |- + Whether the container runtime should close the stdin channel after it has been opened by + a single attach. When stdin is true the stdin stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + first client attaches to stdin, and then remains open and accepts data until the client disconnects, + at which time stdin is closed and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin will never receive an EOF. + Default is false + type: boolean + terminationMessagePath: + description: |- + Optional: Path at which the file to which the container's termination message + will be written is mounted into the container's filesystem. + Message written is intended to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. The total message length across + all containers will be limited to 12kb. + Defaults to /dev/termination-log. + Cannot be updated. + type: string + terminationMessagePolicy: + description: |- + Indicate how the termination message should be populated. File will use the contents of + terminationMessagePath to populate the container status message on both success and failure. + FallbackToLogsOnError will use the last chunk of container log output if the termination + message file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + Defaults to File. + Cannot be updated. + type: string + tty: + description: |- + Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices + to be used by the container. + items: + description: volumeDevice describes a mapping of a + raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of + the container that the device will be mapped + to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + description: |- + Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a + Volume within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified + (which defaults to None). + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + recursiveReadOnly: + description: |- + RecursiveReadOnly specifies whether read-only mounts should be handled + recursively. + + + If ReadOnly is false, this field has no meaning and must be unspecified. + + + If ReadOnly is true, and this field is set to Disabled, the mount is not made + recursively read-only. If this field is set to IfPossible, the mount is made + recursively read-only, if it is supported by the container runtime. If this + field is set to Enabled, the mount is made recursively read-only if it is + supported by the container runtime, otherwise the pod will not be started and + an error will be generated to indicate the reason. + + + If this field is set to IfPossible or Enabled, MountPropagation must be set to + None (or be unspecified, which defaults to None). + + + If this field is not specified, it is treated as an equivalent of Disabled. + type: string + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + description: |- + Container's working directory. + If not specified, the container runtime's default will be used, which + might be configured in the container image. + Cannot be updated. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + nodeName: + description: |- + NodeName is a request to schedule this pod onto a specific node. If it is non-empty, + the scheduler simply schedules this pod onto that node, assuming that it fits resource + requirements. + type: string + nodeSelector: + additionalProperties: + type: string + description: |- + NodeSelector is a selector which must be true for the pod to fit on a node. + Selector which must match a node's labels for the pod to be scheduled on that node. + More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + type: object + x-kubernetes-map-type: atomic + os: + description: |- + Specifies the OS of the containers in the pod. + Some pod and container fields are restricted if this is set. + + + If the OS field is set to linux, the following fields must be unset: + -securityContext.windowsOptions + + + If the OS field is set to windows, following fields must be unset: + - spec.hostPID + - spec.hostIPC + - spec.hostUsers + - spec.securityContext.appArmorProfile + - spec.securityContext.seLinuxOptions + - spec.securityContext.seccompProfile + - spec.securityContext.fsGroup + - spec.securityContext.fsGroupChangePolicy + - spec.securityContext.sysctls + - spec.shareProcessNamespace + - spec.securityContext.runAsUser + - spec.securityContext.runAsGroup + - spec.securityContext.supplementalGroups + - spec.containers[*].securityContext.appArmorProfile + - spec.containers[*].securityContext.seLinuxOptions + - spec.containers[*].securityContext.seccompProfile + - spec.containers[*].securityContext.capabilities + - spec.containers[*].securityContext.readOnlyRootFilesystem + - spec.containers[*].securityContext.privileged + - spec.containers[*].securityContext.allowPrivilegeEscalation + - spec.containers[*].securityContext.procMount + - spec.containers[*].securityContext.runAsUser + - spec.containers[*].securityContext.runAsGroup + properties: + name: + description: |- + Name is the name of the operating system. The currently supported values are linux and windows. + Additional value may be defined in future and can be one of: + https://github.com/opencontainers/runtime-spec/blob/master/config.md#platform-specific-configuration + Clients should expect to handle additional values and treat unrecognized values in this field as os: null + type: string + required: + - name + type: object + overhead: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Overhead represents the resource overhead associated with running a pod for a given RuntimeClass. + This field will be autopopulated at admission time by the RuntimeClass admission controller. If + the RuntimeClass admission controller is enabled, overhead must not be set in Pod create requests. + The RuntimeClass admission controller will reject Pod create requests which have the overhead already + set. If RuntimeClass is configured and selected in the PodSpec, Overhead will be set to the value + defined in the corresponding RuntimeClass, otherwise it will remain unset and treated as zero. + More info: https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead/README.md + type: object + preemptionPolicy: + description: |- + PreemptionPolicy is the Policy for preempting pods with lower priority. + One of Never, PreemptLowerPriority. + Defaults to PreemptLowerPriority if unset. + type: string + priority: + description: |- + The priority value. Various system components use this field to find the + priority of the pod. When Priority Admission Controller is enabled, it + prevents users from setting this field. The admission controller populates + this field from PriorityClassName. + The higher the value, the higher the priority. + format: int32 + type: integer + priorityClassName: + description: |- + If specified, indicates the pod's priority. "system-node-critical" and + "system-cluster-critical" are two special keywords which indicate the + highest priorities with the former being the highest priority. Any other + name must be defined by creating a PriorityClass object with that name. + If not specified, the pod priority will be default or zero if there is no + default. + type: string + readinessGates: + description: |- + If specified, all readiness gates will be evaluated for pod readiness. + A pod is ready when all its containers are ready AND + all conditions specified in the readiness gates have status equal to "True" + More info: https://git.k8s.io/enhancements/keps/sig-network/580-pod-readiness-gates + items: + description: PodReadinessGate contains the reference to + a pod condition + properties: + conditionType: + description: ConditionType refers to a condition in + the pod's condition list with matching type. + type: string + required: + - conditionType + type: object + type: array + x-kubernetes-list-type: atomic + resourceClaims: + description: |- + ResourceClaims defines which ResourceClaims must be allocated + and reserved before the Pod is allowed to start. The resources + will be made available to those containers which consume them + by name. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. + items: + description: |- + PodResourceClaim references exactly one ResourceClaim through a ClaimSource. + It adds a name to it that uniquely identifies the ResourceClaim inside the Pod. + Containers that need access to the ResourceClaim reference it with this name. + properties: + name: + description: |- + Name uniquely identifies this resource claim inside the pod. + This must be a DNS_LABEL. + type: string + source: + description: Source describes where to find the ResourceClaim. + properties: + resourceClaimName: + description: |- + ResourceClaimName is the name of a ResourceClaim object in the same + namespace as this pod. + type: string + resourceClaimTemplateName: + description: |- + ResourceClaimTemplateName is the name of a ResourceClaimTemplate + object in the same namespace as this pod. + + + The template will be used to create a new ResourceClaim, which will + be bound to this pod. When this pod is deleted, the ResourceClaim + will also be deleted. The pod name and resource name, along with a + generated component, will be used to form a unique name for the + ResourceClaim, which will be recorded in pod.status.resourceClaimStatuses. + + + This field is immutable and no changes will be made to the + corresponding ResourceClaim by the control plane after creating the + ResourceClaim. + type: string + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + restartPolicy: + description: |- + Restart policy for all containers within the pod. + One of Always, OnFailure, Never. In some contexts, only a subset of those values may be permitted. + Default to Always. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy + type: string + runtimeClassName: + description: |- + RuntimeClassName refers to a RuntimeClass object in the node.k8s.io group, which should be used + to run this pod. If no RuntimeClass resource matches the named class, the pod will not be run. + If unset or empty, the "legacy" RuntimeClass will be used, which is an implicit class with an + empty definition that uses the default runtime handler. + More info: https://git.k8s.io/enhancements/keps/sig-node/585-runtime-class + type: string + schedulerName: + description: |- + If specified, the pod will be dispatched by specified scheduler. + If not specified, the pod will be dispatched by default scheduler. + type: string + schedulingGates: + description: |- + SchedulingGates is an opaque list of values that if specified will block scheduling the pod. + If schedulingGates is not empty, the pod will stay in the SchedulingGated state and the + scheduler will not attempt to schedule the pod. + + + SchedulingGates can only be set at pod creation time, and be removed only afterwards. + items: + description: PodSchedulingGate is associated to a Pod to + guard its scheduling. + properties: + name: + description: |- + Name of the scheduling gate. + Each scheduling gate must have a unique name field. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + securityContext: + description: |- + SecurityContext holds pod-level security attributes and common container settings. + Optional: Defaults to empty. See type description for default values of each field. + properties: + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object + fsGroup: + description: |- + A special supplemental group that applies to all containers in a pod. + Some volume types allow the Kubelet to change the ownership of that volume + to be owned by the pod: + + + 1. The owning GID will be the FSGroup + 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) + 3. The permission bits are OR'd with rw-rw---- + + + If unset, the Kubelet will not modify the ownership and permissions of any volume. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + fsGroupChangePolicy: + description: |- + fsGroupChangePolicy defines behavior of changing ownership and permission of the volume + before being exposed inside Pod. This field will only apply to + volume types which support fsGroup based ownership(and permissions). + It will have no effect on ephemeral volume types such as: secret, configmaps + and emptydir. + Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used. + Note that this field cannot be set when spec.os.name is windows. + type: string + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in SecurityContext. If set in + both SecurityContext and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + supplementalGroups: + description: |- + A list of groups applied to the first process run in each container, in addition + to the container's primary GID, the fsGroup (if specified), and group memberships + defined in the container image for the uid of the container process. If unspecified, + no additional groups are added to any container. Note that group memberships + defined in the container image for the uid of the container process are still effective, + even if they are not included in this list. + Note that this field cannot be set when spec.os.name is windows. + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + sysctls: + description: |- + Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported + sysctls (by the container runtime) might fail to launch. + Note that this field cannot be set when spec.os.name is windows. + items: + description: Sysctl defines a kernel parameter to be + set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options within a container's SecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of + the GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + serviceAccount: + description: |- + DeprecatedServiceAccount is a deprecated alias for ServiceAccountName. + Deprecated: Use serviceAccountName instead. + type: string + serviceAccountName: + description: |- + ServiceAccountName is the name of the ServiceAccount to use to run this pod. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ + type: string + setHostnameAsFQDN: + description: |- + If true the pod's hostname will be configured as the pod's FQDN, rather than the leaf name (the default). + In Linux containers, this means setting the FQDN in the hostname field of the kernel (the nodename field of struct utsname). + In Windows containers, this means setting the registry value of hostname for the registry key HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters to FQDN. + If a pod does not have FQDN, this has no effect. + Default to false. + type: boolean + shareProcessNamespace: + description: |- + Share a single process namespace between all of the containers in a pod. + When this is set containers will be able to view and signal processes from other containers + in the same pod, and the first process in each container will not be assigned PID 1. + HostPID and ShareProcessNamespace cannot both be set. + Optional: Default to false. + type: boolean + subdomain: + description: |- + If specified, the fully qualified Pod hostname will be "...svc.". + If not specified, the pod will not have a domainname at all. + type: string + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + If this value is nil, the default grace period will be used instead. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + Defaults to 30 seconds. + format: int64 + type: integer + tolerations: + description: If specified, the pod's tolerations. + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + x-kubernetes-list-type: atomic + topologySpreadConstraints: + description: |- + TopologySpreadConstraints describes how a group of pods ought to spread across topology + domains. Scheduler will schedule pods in a way which abides by the constraints. + All topologySpreadConstraints are ANDed. + items: + description: TopologySpreadConstraint specifies how to spread + matching pods among the given topology. + properties: + labelSelector: + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods + in their corresponding topology domain. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + + + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. + format: int32 + type: integer + minDomains: + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + + + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + format: int32 + type: integer + nodeAffinityPolicy: + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + + + If this value is nil, the behavior is equivalent to the Honor policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + nodeTaintsPolicy: + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + + + If this value is nil, the behavior is equivalent to the Ignore policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + topologyKey: + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. + type: string + whenUnsatisfiable: + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + x-kubernetes-list-map-keys: + - topologyKey + - whenUnsatisfiable + x-kubernetes-list-type: map + volumes: + description: |- + List of volumes that can be mounted by containers belonging to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes + items: + description: Volume represents a named volume in a pod that + may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: |- + awsElasticBlockStore represents an AWS Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + format: int32 + type: integer + readOnly: + description: |- + readOnly value true will force the readOnly setting in VolumeMounts. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: boolean + volumeID: + description: |- + volumeID is unique ID of the persistent disk resource in AWS (Amazon EBS volume). + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data Disk + mount on the host and bind mount to the pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching mode: + None, Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data disk + in the blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in + the blob storage + type: string + fsType: + description: |- + fsType is Filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: multiple + blob disks per storage account Dedicated: single + blob disk per storage account Managed: azure + managed data disk (only in managed availability + set). defaults to shared' + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File Service + mount on the host and bind mount to the pod. + properties: + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret that + contains Azure Storage Account Name and Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount on the + host that shares a pod's lifetime + properties: + monitors: + description: |- + monitors is Required: Monitors is a collection of Ceph monitors + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + items: + type: string + type: array + x-kubernetes-list-type: atomic + path: + description: 'path is Optional: Used as the mounted + root, rather than the full Ceph tree, default + is /' + type: string + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: boolean + secretFile: + description: |- + secretFile is Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + secretRef: + description: |- + secretRef is Optional: SecretRef is reference to the authentication secret for User, default is empty. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + type: object + x-kubernetes-map-type: atomic + user: + description: |- + user is optional: User is the rados user name, default is admin + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + required: + - monitors + type: object + cinder: + description: |- + cinder represents a cinder volume attached and mounted on kubelets host machine. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: boolean + secretRef: + description: |- + secretRef is optional: points to a secret object containing parameters used to connect + to OpenStack. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + description: |- + volumeID used to identify the volume in cinder. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that should + populate this volume + properties: + defaultMode: + description: |- + defaultMode is optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + description: csi (Container Storage Interface) represents + ephemeral storage that is handled by certain external + CSI drivers (Beta feature). + properties: + driver: + description: |- + driver is the name of the CSI driver that handles this volume. + Consult with your admin for the correct name as registered in the cluster. + type: string + fsType: + description: |- + fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the associated CSI driver + which will determine the default filesystem to apply. + type: string + nodePublishSecretRef: + description: |- + nodePublishSecretRef is a reference to the secret object containing + sensitive information to pass to the CSI driver to complete the CSI + NodePublishVolume and NodeUnpublishVolume calls. + This field is optional, and may be empty if no secret is required. If the + secret object contains more than one secret, all secret references are passed. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + description: |- + readOnly specifies a read-only configuration for the volume. + Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: |- + volumeAttributes stores driver-specific properties that are passed to the CSI + driver. Consult your driver's documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about + the pod that should populate this volume + properties: + defaultMode: + description: |- + Optional: mode bits to use on created files by default. Must be a + Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: Items is a list of downward API volume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing the + pod field + properties: + fieldRef: + description: 'Required: Selects a field of + the pod: only annotations, labels, name, + namespace and uid are supported.' + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. Must + not be absolute or contain the ''..'' path. + Must be utf-8 encoded. The first item of + the relative path must not start with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + emptyDir: + description: |- + emptyDir represents a temporary directory that shares a pod's lifetime. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + properties: + medium: + description: |- + medium represents what type of storage medium should back this directory. + The default is "" which means to use the node's default medium. + Must be an empty string (default) or Memory. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: |- + sizeLimit is the total amount of local storage required for this EmptyDir volume. + The size limit is also applicable for memory medium. + The maximum usage on memory medium EmptyDir would be the minimum value between + the SizeLimit specified here and the sum of memory limits of all containers in a pod. + The default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: |- + ephemeral represents a volume that is handled by a cluster storage driver. + The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, + and deleted when the pod is removed. + + + Use this if: + a) the volume is only needed while the pod runs, + b) features of normal volumes like restoring from snapshot or capacity + tracking are needed, + c) the storage driver is specified through a storage class, and + d) the storage driver supports dynamic volume provisioning through + a PersistentVolumeClaim (see EphemeralVolumeSource for more + information on the connection between this volume type + and PersistentVolumeClaim). + + + Use PersistentVolumeClaim or one of the vendor-specific + APIs for volumes that persist for longer than the lifecycle + of an individual pod. + + + Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to + be used that way - see the documentation of the driver for + more information. + + + A pod can use both types of ephemeral volumes and + persistent volumes at the same time. + properties: + volumeClaimTemplate: + description: |- + Will be used to create a stand-alone PVC to provision the volume. + The pod in which this EphemeralVolumeSource is embedded will be the + owner of the PVC, i.e. the PVC will be deleted together with the + pod. The name of the PVC will be `-` where + `` is the name from the `PodSpec.Volumes` array + entry. Pod validation will reject the pod if the concatenated name + is not valid for a PVC (for example, too long). + + + An existing PVC with that name that is not owned by the pod + will *not* be used for the pod to avoid using an unrelated + volume by mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created PVC is + meant to be used by the pod, the PVC has to updated with an + owner reference to the pod once the pod exists. Normally + this should not be necessary, but it may be useful when + manually reconstructing a broken cluster. + + + This field is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. + + + Required, must not be nil. + properties: + metadata: + description: |- + May contain labels and annotations that will be copied into the PVC + when creating it. No other fields are allowed and will be rejected during + validation. + type: object + spec: + description: |- + The specification for the PersistentVolumeClaim. The entire content is + copied unchanged into the PVC that gets created from this + template. The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over + volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/ + (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference + to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource + that is attached to a kubelet's host machine and then + exposed to the pod. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target + worldwide names (WWNs)' + items: + type: string + type: array + x-kubernetes-list-type: atomic + wwids: + description: |- + wwids Optional: FC volume world wide identifiers (wwids) + Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously. + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + flexVolume: + description: |- + flexVolume represents a generic volume resource that is + provisioned/attached using an exec based plugin. + properties: + driver: + description: driver is the name of the driver to + use for this volume. + type: string + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". The default filesystem depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field holds + extra command options if any.' + type: object + readOnly: + description: |- + readOnly is Optional: defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef is Optional: secretRef is reference to the secret object containing + sensitive information to pass to the plugin scripts. This may be + empty if no secret object is specified. If the secret object + contains more than one secret, all secrets are passed to the plugin + scripts. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume attached + to a kubelet's host machine. This depends on the Flocker + control service being running + properties: + datasetName: + description: |- + datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker + should be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. + This is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: |- + gcePersistentDisk represents a GCE Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + properties: + fsType: + description: |- + fsType is filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + format: int32 + type: integer + pdName: + description: |- + pdName is unique name of the PD resource in GCE. Used to identify the disk in GCE. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: boolean + required: + - pdName + type: object + gitRepo: + description: |- + gitRepo represents a git repository at a particular revision. + DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an + EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir + into the Pod's container. + properties: + directory: + description: |- + directory is the target directory name. + Must not contain or start with '..'. If '.' is supplied, the volume directory will be the + git repository. Otherwise, if specified, the volume will contain the git repository in + the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the + specified revision. + type: string + required: + - repository + type: object + glusterfs: + description: |- + glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/glusterfs/README.md + properties: + endpoints: + description: |- + endpoints is the endpoint name that details Glusterfs topology. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + path: + description: |- + path is the Glusterfs volume path. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + readOnly: + description: |- + readOnly here will force the Glusterfs volume to be mounted with read-only permissions. + Defaults to false. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: |- + hostPath represents a pre-existing file or directory on the host + machine that is directly exposed to the container. This is generally + used for system agents or other privileged things that are allowed + to see the host machine. Most containers will NOT need this. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- + TODO(jonesdl) We need to restrict who can use host directory mounts and who can/can not + mount host directories as read/write. + properties: + path: + description: |- + path of the directory on the host. + If the path is a symlink, it will follow the link to the real path. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + type: + description: |- + type for HostPath Volume + Defaults to "" + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + required: + - path + type: object + iscsi: + description: |- + iscsi represents an ISCSI Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://examples.k8s.io/volumes/iscsi/README.md + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether support + iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support + iSCSI Session CHAP authentication + type: boolean + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + initiatorName: + description: |- + initiatorName is the custom iSCSI Initiator Name. + If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface + : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified Name. + type: string + iscsiInterface: + description: |- + iscsiInterface is the interface Name that uses an iSCSI transport. + Defaults to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: |- + portals is the iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + x-kubernetes-list-type: atomic + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for iSCSI + target and initiator authentication + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + description: |- + targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: |- + name of the volume. + Must be a DNS_LABEL and unique within the pod. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + nfs: + description: |- + nfs represents an NFS mount on the host that shares a pod's lifetime + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + properties: + path: + description: |- + path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + readOnly: + description: |- + readOnly here will force the NFS export to be mounted with read-only permissions. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: boolean + server: + description: |- + server is the hostname or IP address of the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: |- + persistentVolumeClaimVolumeSource represents a reference to a + PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + claimName: + description: |- + claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + type: string + readOnly: + description: |- + readOnly Will force the ReadOnly setting in VolumeMounts. + Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents a PhotonController + persistent disk attached and mounted on kubelets host + machine + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon + Controller persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx volume + attached and mounted on kubelets host machine + properties: + fsType: + description: |- + fSType represents the filesystem type to mount + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx + volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources + secrets, configmaps, and downward API + properties: + defaultMode: + description: |- + defaultMode are the mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume projections + items: + description: Projection that may be projected + along with other supported volume types + properties: + clusterTrustBundle: + description: |- + ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field + of ClusterTrustBundle objects in an auto-updating file. + + + Alpha, gated by the ClusterTrustBundleProjection feature gate. + + + ClusterTrustBundle objects can either be selected by name, or by the + combination of signer name and a label selector. + + + Kubelet performs aggressive normalization of the PEM contents written + into the pod filesystem. Esoteric PEM features such as inter-block + comments and block headers are stripped. Certificates are deduplicated. + The ordering of certificates within the file is arbitrary, and Kubelet + may change the order over time. + properties: + labelSelector: + description: |- + Select all ClusterTrustBundles that match this label selector. Only has + effect if signerName is set. Mutually-exclusive with name. If unset, + interpreted as "match nothing". If set but empty, interpreted as "match + everything". + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + name: + description: |- + Select a single ClusterTrustBundle by object name. Mutually-exclusive + with signerName and labelSelector. + type: string + optional: + description: |- + If true, don't block pod startup if the referenced ClusterTrustBundle(s) + aren't available. If using name, then the named ClusterTrustBundle is + allowed not to exist. If using signerName, then the combination of + signerName and labelSelector is allowed to match zero + ClusterTrustBundles. + type: boolean + path: + description: Relative path from the volume + root to write the bundle. + type: string + signerName: + description: |- + Select all ClusterTrustBundles that match this signer name. + Mutually-exclusive with name. The contents of all selected + ClusterTrustBundles will be unified and deduplicated. + type: string + required: + - path + type: object + configMap: + description: configMap information about the + configMap data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a + path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + optional: + description: optional specify whether + the ConfigMap or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + description: downwardAPI information about + the downwardAPI data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects + a field of the pod: only annotations, + labels, name, namespace and uid + are supported.' + properties: + apiVersion: + description: Version of the + schema the FieldPath is written + in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field + to select in the specified + API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the + relative path name of the file + to be created. Must not be absolute + or contain the ''..'' path. Must + be utf-8 encoded. The first item + of the relative path must not + start with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: + required for volumes, optional + for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource + to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + secret: + description: secret information about the + secret data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a + path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + optional: + description: optional field specify whether + the Secret or its key must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + description: serviceAccountToken is information + about the serviceAccountToken data to project + properties: + audience: + description: |- + audience is the intended audience of the token. A recipient of a token + must identify itself with an identifier specified in the audience of the + token, and otherwise should reject the token. The audience defaults to the + identifier of the apiserver. + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service + account token. As the token approaches expiration, the kubelet volume + plugin will proactively rotate the service account token. The kubelet will + start trying to rotate the token if the token is older than 80 percent of + its time to live or if the token is older than 24 hours.Defaults to 1 hour + and must be at least 10 minutes. + format: int64 + type: integer + path: + description: |- + path is the path relative to the mount point of the file to project the + token into. + type: string + required: + - path + type: object + type: object + type: array + x-kubernetes-list-type: atomic + type: object + quobyte: + description: quobyte represents a Quobyte mount on the + host that shares a pod's lifetime + properties: + group: + description: |- + group to map volume access to + Default is no group + type: string + readOnly: + description: |- + readOnly here will force the Quobyte volume to be mounted with read-only permissions. + Defaults to false. + type: boolean + registry: + description: |- + registry represents a single or multiple Quobyte Registry services + specified as a string as host:port pair (multiple entries are separated with commas) + which acts as the central registry for volumes + type: string + tenant: + description: |- + tenant owning the given Quobyte volume in the Backend + Used with dynamically provisioned Quobyte volumes, value is set by the plugin + type: string + user: + description: |- + user to map volume access to + Defaults to serivceaccount user + type: string + volume: + description: volume is a string that references + an already created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: |- + rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/rbd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + image: + description: |- + image is the rados image name. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + keyring: + description: |- + keyring is the path to key ring for RBDUser. + Default is /etc/ceph/keyring. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + monitors: + description: |- + monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + items: + type: string + type: array + x-kubernetes-list-type: atomic + pool: + description: |- + pool is the rados pool name. + Default is rbd. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: boolean + secretRef: + description: |- + secretRef is name of the authentication secret for RBDUser. If provided + overrides keyring. + Default is nil. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + type: object + x-kubernetes-map-type: atomic + user: + description: |- + user is the rados user name. + Default is admin. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent + volume attached and mounted on Kubernetes nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". + Default is "xfs". + type: string + gateway: + description: gateway is the host address of the + ScaleIO API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the + ScaleIO Protection Domain for the configured storage. + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef references to the secret for ScaleIO user and other + sensitive information. If this is not provided, Login operation will fail. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + description: sslEnabled Flag enable/disable SSL + communication with Gateway, default false + type: boolean + storageMode: + description: |- + storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage + Pool associated with the protection domain. + type: string + system: + description: system is the name of the storage system + as configured in ScaleIO. + type: string + volumeName: + description: |- + volumeName is the name of a volume already created in the ScaleIO system + that is associated with this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: |- + secret represents a secret that should populate this volume. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + properties: + defaultMode: + description: |- + defaultMode is Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values + for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items If unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + description: optional field specify whether the + Secret or its keys must be defined + type: boolean + secretName: + description: |- + secretName is the name of the secret in the pod's namespace to use. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + type: string + type: object + storageos: + description: storageOS represents a StorageOS volume + attached and mounted on Kubernetes nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef specifies the secret to use for obtaining the StorageOS API + credentials. If not specified, default values will be attempted. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + description: |- + volumeName is the human-readable name of the StorageOS volume. Volume + names are only unique within a namespace. + type: string + volumeNamespace: + description: |- + volumeNamespace specifies the scope of the volume within StorageOS. If no + namespace is specified then the Pod's namespace will be used. This allows the + Kubernetes name scoping to be mirrored within StorageOS for tighter integration. + Set VolumeName to any name to override the default behaviour. + Set to "default" if you are not using namespaces within StorageOS. + Namespaces that do not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere volume + attached and mounted on kubelets host machine + properties: + fsType: + description: |- + fsType is filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy + Based Management (SPBM) profile ID associated + with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage Policy + Based Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies + vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + required: + - containers + type: object + type: object + type: + default: rw + description: 'Type of service to forward traffic to. Default: `rw`.' + enum: + - rw + - ro + type: string + required: + - cluster + - pgbouncer + type: object + status: + description: |- + Most recently observed status of the Pooler. This data may not be up to + date. Populated by the system. Read-only. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + instances: + description: The number of pods trying to be scheduled + format: int32 + type: integer + secrets: + description: The resource version of the config object + properties: + clientCA: + description: The client CA secret version + properties: + name: + description: The name of the secret + type: string + version: + description: The ResourceVersion of the secret + type: string + type: object + pgBouncerSecrets: + description: The version of the secrets used by PgBouncer + properties: + authQuery: + description: The auth query secret version + properties: + name: + description: The name of the secret + type: string + version: + description: The ResourceVersion of the secret + type: string + type: object + type: object + serverCA: + description: The server CA secret version + properties: + name: + description: The name of the secret + type: string + version: + description: The ResourceVersion of the secret + type: string + type: object + serverTLS: + description: The server TLS secret version + properties: + name: + description: The name of the secret + type: string + version: + description: The ResourceVersion of the secret + type: string + type: object + type: object + type: object + required: + - metadata + - spec + type: object + served: true + storage: true + subresources: + scale: + specReplicasPath: .spec.instances + statusReplicasPath: .status.instances + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + helm.sh/resource-policy: keep + name: scheduledbackups.postgresql.cnpg.io +spec: + group: postgresql.cnpg.io + names: + kind: ScheduledBackup + listKind: ScheduledBackupList + plural: scheduledbackups + singular: scheduledbackup + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .spec.cluster.name + name: Cluster + type: string + - jsonPath: .status.lastScheduleTime + name: Last Backup + type: date + name: v1 + schema: + openAPIV3Schema: + description: ScheduledBackup is the Schema for the scheduledbackups API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: |- + Specification of the desired behavior of the ScheduledBackup. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + backupOwnerReference: + default: none + description: |- + Indicates which ownerReference should be put inside the created backup resources.
+ - none: no owner reference for created backup objects (same behavior as before the field was introduced)
+ - self: sets the Scheduled backup object as owner of the backup
+ - cluster: set the cluster as owner of the backup
+ enum: + - none + - self + - cluster + type: string + cluster: + description: The cluster to backup + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + immediate: + description: If the first backup has to be immediately start after + creation or not + type: boolean + method: + default: barmanObjectStore + description: |- + The backup method to be used, possible options are `barmanObjectStore` + and `volumeSnapshot`. Defaults to: `barmanObjectStore`. + enum: + - barmanObjectStore + - volumeSnapshot + type: string + online: + description: |- + Whether the default type of backup with volume snapshots is + online/hot (`true`, default) or offline/cold (`false`) + Overrides the default setting specified in the cluster field '.spec.backup.volumeSnapshot.online' + type: boolean + onlineConfiguration: + description: |- + Configuration parameters to control the online/hot backup with volume snapshots + Overrides the default settings specified in the cluster '.backup.volumeSnapshot.onlineConfiguration' stanza + properties: + immediateCheckpoint: + description: |- + Control whether the I/O workload for the backup initial checkpoint will + be limited, according to the `checkpoint_completion_target` setting on + the PostgreSQL server. If set to true, an immediate checkpoint will be + used, meaning PostgreSQL will complete the checkpoint as soon as + possible. `false` by default. + type: boolean + waitForArchive: + default: true + description: |- + If false, the function will return immediately after the backup is completed, + without waiting for WAL to be archived. + This behavior is only useful with backup software that independently monitors WAL archiving. + Otherwise, WAL required to make the backup consistent might be missing and make the backup useless. + By default, or when this parameter is true, pg_backup_stop will wait for WAL to be archived when archiving is + enabled. + On a standby, this means that it will wait only when archive_mode = always. + If write activity on the primary is low, it may be useful to run pg_switch_wal on the primary in order to trigger + an immediate segment switch. + type: boolean + type: object + pluginConfiguration: + description: Configuration parameters passed to the plugin managing + this backup + properties: + name: + description: Name is the name of the plugin managing this backup + type: string + parameters: + additionalProperties: + type: string + description: |- + Parameters are the configuration parameters passed to the backup + plugin for this backup + type: object + required: + - name + type: object + schedule: + description: |- + The schedule does not follow the same format used in Kubernetes CronJobs + as it includes an additional seconds specifier, + see https://pkg.go.dev/github.com/robfig/cron#hdr-CRON_Expression_Format + type: string + suspend: + description: If this backup is suspended or not + type: boolean + target: + description: |- + The policy to decide which instance should perform this backup. If empty, + it defaults to `cluster.spec.backup.target`. + Available options are empty string, `primary` and `prefer-standby`. + `primary` to have backups run always on primary instances, + `prefer-standby` to have backups run preferably on the most updated + standby, if available. + enum: + - primary + - prefer-standby + type: string + required: + - cluster + - schedule + type: object + status: + description: |- + Most recently observed status of the ScheduledBackup. This data may not be up + to date. Populated by the system. Read-only. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + lastCheckTime: + description: The latest time the schedule + format: date-time + type: string + lastScheduleTime: + description: Information when was the last time that backup was successfully + scheduled. + format: date-time + type: string + nextScheduleTime: + description: Next time we will run a backup + format: date-time + type: string + type: object + required: + - metadata + - spec + type: object + served: true + storage: true + subresources: + status: {} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/templates/deployment.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/templates/deployment.yaml new file mode 100644 index 000000000..515d52ecc --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/templates/deployment.yaml @@ -0,0 +1,141 @@ +# +# Copyright The CloudNativePG Contributors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "cloudnative-pg.fullname" . }} + labels: + {{- include "cloudnative-pg.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + {{- include "cloudnative-pg.selectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + checksum/config: {{ include (print $.Template.BasePath "/config.yaml") . | sha256sum }} + {{- with .Values.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "cloudnative-pg.selectorLabels" . | nindent 8 }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - args: + - controller + - --leader-elect + {{- if .Values.config.name }} + {{- if not .Values.config.secret }} + - --config-map-name={{ .Values.config.name }} + {{- else }} + - --secret-name={{ .Values.config.name }} + {{- end }} + {{- end }} + - --webhook-port={{ .Values.webhook.port }} + {{- range .Values.additionalArgs }} + - {{ . }} + {{- end }} + command: + - /manager + env: + - name: OPERATOR_IMAGE_NAME + value: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + - name: OPERATOR_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: MONITORING_QUERIES_CONFIGMAP + value: "{{ .Values.monitoringQueriesConfigMap.name }}" + {{- if .Values.additionalEnv }} + {{- tpl (.Values.additionalEnv | toYaml) . | nindent 8 }} + {{- end }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + livenessProbe: + httpGet: + path: /readyz + port: {{ .Values.webhook.port }} + scheme: HTTPS + {{- if .Values.webhook.livenessProbe.initialDelaySeconds }} + initialDelaySeconds: {{ .Values.webhook.livenessProbe.initialDelaySeconds }} + {{- end }} + name: manager + ports: + - containerPort: 8080 + name: metrics + protocol: TCP + - containerPort: {{ .Values.webhook.port }} + name: webhook-server + protocol: TCP + readinessProbe: + httpGet: + path: /readyz + port: {{ .Values.webhook.port }} + scheme: HTTPS + {{- if .Values.webhook.readinessProbe.initialDelaySeconds }} + initialDelaySeconds: {{ .Values.webhook.readinessProbe.initialDelaySeconds }} + {{- end }} + resources: + {{- toYaml .Values.resources | nindent 10 }} + securityContext: + {{- toYaml .Values.containerSecurityContext | nindent 10 }} + volumeMounts: + - mountPath: /controller + name: scratch-data + - mountPath: /run/secrets/cnpg.io/webhook + name: webhook-certificates + {{- if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName }} + {{- end }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + serviceAccountName: {{ include "cloudnative-pg.serviceAccountName" . }} + terminationGracePeriodSeconds: 10 + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - emptyDir: {} + name: scratch-data + - name: webhook-certificates + secret: + defaultMode: 420 + optional: true + secretName: cnpg-webhook-cert + + diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/templates/monitoring-configmap.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/templates/monitoring-configmap.yaml new file mode 100644 index 000000000..a987f0797 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/templates/monitoring-configmap.yaml @@ -0,0 +1,29 @@ +# +# Copyright The CloudNativePG Contributors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Values.monitoringQueriesConfigMap.name }} + labels: + {{- include "cloudnative-pg.labels" . | nindent 4 }} + cnpg.io/reload: "" + {{- with .Values.commonAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +data: + queries: {{- toYaml .Values.monitoringQueriesConfigMap.queries | nindent 4 }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/templates/mutatingwebhookconfiguration.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/templates/mutatingwebhookconfiguration.yaml new file mode 100644 index 000000000..200695b14 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/templates/mutatingwebhookconfiguration.yaml @@ -0,0 +1,92 @@ +# +# Copyright The CloudNativePG Contributors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +{{- if .Values.webhook.mutating.create }} +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + name: cnpg-mutating-webhook-configuration + {{- with .Values.commonAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "cloudnative-pg.labels" . | nindent 4 }} +webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: {{ .Values.service.name }} + namespace: {{ .Release.Namespace }} + path: /mutate-postgresql-cnpg-io-v1-backup + port: {{ .Values.service.port }} + failurePolicy: {{ .Values.webhook.mutating.failurePolicy }} + name: mbackup.cnpg.io + rules: + - apiGroups: + - postgresql.cnpg.io + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - backups + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: {{ .Values.service.name }} + namespace: {{ .Release.Namespace }} + path: /mutate-postgresql-cnpg-io-v1-cluster + port: {{ .Values.service.port }} + failurePolicy: {{ .Values.webhook.mutating.failurePolicy }} + name: mcluster.cnpg.io + rules: + - apiGroups: + - postgresql.cnpg.io + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - clusters + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: {{ .Values.service.name }} + namespace: {{ .Release.Namespace }} + path: /mutate-postgresql-cnpg-io-v1-scheduledbackup + port: {{ .Values.service.port }} + failurePolicy: {{ .Values.webhook.mutating.failurePolicy }} + name: mscheduledbackup.cnpg.io + rules: + - apiGroups: + - postgresql.cnpg.io + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - scheduledbackups + sideEffects: None +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/templates/podmonitor.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/templates/podmonitor.yaml new file mode 100644 index 000000000..bae86ca8d --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/templates/podmonitor.yaml @@ -0,0 +1,21 @@ +{{- if .Values.monitoring.podMonitorEnabled }} +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + name: {{ include "cloudnative-pg.fullname" . }} + labels: + {{- include "cloudnative-pg.labels" . | nindent 4 }} + {{- with .Values.monitoring.podMonitorAdditionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end}} + {{- with .Values.commonAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + selector: + matchLabels: + {{- include "cloudnative-pg.selectorLabels" . | nindent 6 }} + podMetricsEndpoints: + - port: metrics +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/templates/rbac.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/templates/rbac.yaml new file mode 100644 index 000000000..f2bf0e805 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/templates/rbac.yaml @@ -0,0 +1,451 @@ +# +# Copyright The CloudNativePG Contributors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +{{- if .Values.serviceAccount.create }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "cloudnative-pg.serviceAccountName" . }} + labels: + {{- include "cloudnative-pg.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} + +{{- if .Values.rbac.create }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "cloudnative-pg.fullname" . }} + labels: + {{- include "cloudnative-pg.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +rules: +- apiGroups: + - "" + resources: + - configmaps + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - "" + resources: + - configmaps/status + verbs: + - get + - patch + - update +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +- apiGroups: + - "" + resources: + - nodes + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - persistentvolumeclaims + verbs: + - create + - delete + - get + - list + - patch + - watch +- apiGroups: + - "" + resources: + - pods + verbs: + - create + - delete + - get + - list + - patch + - watch +- apiGroups: + - "" + resources: + - pods/exec + verbs: + - create + - delete + - get + - list + - patch + - watch +- apiGroups: + - "" + resources: + - pods/status + verbs: + - get +- apiGroups: + - "" + resources: + - secrets + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - "" + resources: + - secrets/status + verbs: + - get + - patch + - update +- apiGroups: + - "" + resources: + - serviceaccounts + verbs: + - create + - get + - list + - patch + - update + - watch +- apiGroups: + - "" + resources: + - services + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - admissionregistration.k8s.io + resources: + - mutatingwebhookconfigurations + verbs: + - get + - list + - patch + - update +- apiGroups: + - admissionregistration.k8s.io + resources: + - validatingwebhookconfigurations + verbs: + - get + - list + - patch + - update +- apiGroups: + - apiextensions.k8s.io + resources: + - customresourcedefinitions + verbs: + - get + - list + - update +- apiGroups: + - apps + resources: + - deployments + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - batch + resources: + - jobs + verbs: + - create + - delete + - get + - list + - patch + - watch +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - create + - get + - update +- apiGroups: + - monitoring.coreos.com + resources: + - podmonitors + verbs: + - create + - delete + - get + - list + - patch + - watch +- apiGroups: + - policy + resources: + - poddisruptionbudgets + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - postgresql.cnpg.io + resources: + - backups + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - postgresql.cnpg.io + resources: + - backups/status + verbs: + - get + - patch + - update +- apiGroups: + - postgresql.cnpg.io + resources: + - clusterimagecatalogs + verbs: + - get + - list + - watch +- apiGroups: + - postgresql.cnpg.io + resources: + - clusters + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - postgresql.cnpg.io + resources: + - clusters/finalizers + verbs: + - update +- apiGroups: + - postgresql.cnpg.io + resources: + - clusters/status + verbs: + - get + - patch + - update + - watch +- apiGroups: + - postgresql.cnpg.io + resources: + - imagecatalogs + verbs: + - get + - list + - watch +- apiGroups: + - postgresql.cnpg.io + resources: + - poolers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - postgresql.cnpg.io + resources: + - poolers/finalizers + verbs: + - update +- apiGroups: + - postgresql.cnpg.io + resources: + - poolers/status + verbs: + - get + - patch + - update + - watch +- apiGroups: + - postgresql.cnpg.io + resources: + - scheduledbackups + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - postgresql.cnpg.io + resources: + - scheduledbackups/status + verbs: + - get + - patch + - update +- apiGroups: + - rbac.authorization.k8s.io + resources: + - rolebindings + verbs: + - create + - get + - list + - patch + - update + - watch +- apiGroups: + - rbac.authorization.k8s.io + resources: + - roles + verbs: + - create + - get + - list + - patch + - update + - watch +- apiGroups: + - snapshot.storage.k8s.io + resources: + - volumesnapshots + verbs: + - create + - get + - list + - patch + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "cloudnative-pg.fullname" . }} + labels: + {{- include "cloudnative-pg.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "cloudnative-pg.fullname" . }} +subjects: +- kind: ServiceAccount + name: {{ include "cloudnative-pg.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "cloudnative-pg.fullname" . }}-view + labels: + {{- include "cloudnative-pg.labels" . | nindent 4 }} + {{- if .Values.rbac.aggregateClusterRoles }} + rbac.authorization.k8s.io/aggregate-to-view: "true" + rbac.authorization.k8s.io/aggregate-to-edit: "true" + rbac.authorization.k8s.io/aggregate-to-admin: "true" + {{- end }} +rules: +- apiGroups: + - postgresql.cnpg.io + resources: + - backups + - clusters + - poolers + - scheduledbackups + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "cloudnative-pg.fullname" . }}-edit + labels: + {{- include "cloudnative-pg.labels" . | nindent 4 }} + {{- if .Values.rbac.aggregateClusterRoles }} + rbac.authorization.k8s.io/aggregate-to-edit: "true" + rbac.authorization.k8s.io/aggregate-to-admin: "true" + {{- end }} +rules: +- apiGroups: + - postgresql.cnpg.io + resources: + - backups + - clusters + - poolers + - scheduledbackups + verbs: + - create + - delete + - deletecollection + - patch + - update +--- +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/templates/service.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/templates/service.yaml new file mode 100644 index 000000000..fc8a4127e --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/templates/service.yaml @@ -0,0 +1,34 @@ +# +# Copyright The CloudNativePG Contributors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ .Values.service.name }} + labels: + {{- include "cloudnative-pg.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: webhook-server + name: webhook-server + selector: + {{- include "cloudnative-pg.selectorLabels" . | nindent 4 }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/templates/validatingwebhookconfiguration.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/templates/validatingwebhookconfiguration.yaml new file mode 100644 index 000000000..be9fff18e --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/templates/validatingwebhookconfiguration.yaml @@ -0,0 +1,113 @@ +# +# Copyright The CloudNativePG Contributors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +{{- if .Values.webhook.validating.create }} +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: cnpg-validating-webhook-configuration + labels: + {{- include "cloudnative-pg.labels" . | nindent 4 }} + {{- with .Values.rbac.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: {{ .Values.service.name }} + namespace: {{ .Release.Namespace }} + path: /validate-postgresql-cnpg-io-v1-backup + port: {{ .Values.service.port }} + failurePolicy: {{ .Values.webhook.validating.failurePolicy }} + name: vbackup.cnpg.io + rules: + - apiGroups: + - postgresql.cnpg.io + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - backups + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: {{ .Values.service.name }} + namespace: {{ .Release.Namespace }} + path: /validate-postgresql-cnpg-io-v1-cluster + port: {{ .Values.service.port }} + failurePolicy: {{ .Values.webhook.validating.failurePolicy }} + name: vcluster.cnpg.io + rules: + - apiGroups: + - postgresql.cnpg.io + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - clusters + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: {{ .Values.service.name }} + namespace: {{ .Release.Namespace }} + path: /validate-postgresql-cnpg-io-v1-scheduledbackup + port: {{ .Values.service.port }} + failurePolicy: {{ .Values.webhook.validating.failurePolicy }} + name: vscheduledbackup.cnpg.io + rules: + - apiGroups: + - postgresql.cnpg.io + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - scheduledbackups + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: {{ .Values.service.name }} + namespace: {{ .Release.Namespace }} + path: /validate-postgresql-cnpg-io-v1-pooler + port: {{ .Values.service.port }} + failurePolicy: {{ .Values.webhook.validating.failurePolicy }} + name: vpooler.cnpg.io + rules: + - apiGroups: + - postgresql.cnpg.io + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - poolers + sideEffects: None +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/values.schema.json b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/values.schema.json new file mode 100644 index 000000000..6c3779ac2 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/values.schema.json @@ -0,0 +1,269 @@ +{ + "$schema": "http://json-schema.org/schema#", + "type": "object", + "properties": { + "additionalArgs": { + "type": "array" + }, + "additionalEnv": { + "type": "array" + }, + "affinity": { + "type": "object" + }, + "commonAnnotations": { + "type": "object" + }, + "config": { + "type": "object", + "properties": { + "create": { + "type": "boolean" + }, + "data": { + "type": "object" + }, + "name": { + "type": "string" + }, + "secret": { + "type": "boolean" + } + } + }, + "containerSecurityContext": { + "type": "object", + "properties": { + "allowPrivilegeEscalation": { + "type": "boolean" + }, + "capabilities": { + "type": "object", + "properties": { + "drop": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "readOnlyRootFilesystem": { + "type": "boolean" + }, + "runAsGroup": { + "type": "integer" + }, + "runAsUser": { + "type": "integer" + }, + "seccompProfile": { + "type": "object", + "properties": { + "type": { + "type": "string" + } + } + } + } + }, + "crds": { + "type": "object", + "properties": { + "create": { + "type": "boolean" + } + } + }, + "fullnameOverride": { + "type": "string" + }, + "image": { + "type": "object", + "properties": { + "pullPolicy": { + "type": "string" + }, + "repository": { + "type": "string" + }, + "tag": { + "type": "string" + } + } + }, + "imagePullSecrets": { + "type": "array" + }, + "monitoring": { + "type": "object", + "properties": { + "grafanaDashboard": { + "type": "object", + "properties": { + "annotations": { + "type": "object" + }, + "configMapName": { + "type": "string" + }, + "create": { + "type": "boolean" + }, + "labels": { + "type": "object" + }, + "namespace": { + "type": "string" + }, + "sidecarLabel": { + "type": "string" + }, + "sidecarLabelValue": { + "type": "string" + } + } + }, + "podMonitorAdditionalLabels": { + "type": "object" + }, + "podMonitorEnabled": { + "type": "boolean" + } + } + }, + "monitoringQueriesConfigMap": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "queries": { + "type": "string" + } + } + }, + "nameOverride": { + "type": "string" + }, + "nodeSelector": { + "type": "object" + }, + "podAnnotations": { + "type": "object" + }, + "podLabels": { + "type": "object" + }, + "podSecurityContext": { + "type": "object", + "properties": { + "runAsNonRoot": { + "type": "boolean" + }, + "seccompProfile": { + "type": "object", + "properties": { + "type": { + "type": "string" + } + } + } + } + }, + "priorityClassName": { + "type": "string" + }, + "rbac": { + "type": "object", + "properties": { + "aggregateClusterRoles": { + "type": "boolean" + }, + "create": { + "type": "boolean" + } + } + }, + "replicaCount": { + "type": "integer" + }, + "resources": { + "type": "object" + }, + "service": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "integer" + }, + "type": { + "type": "string" + } + } + }, + "serviceAccount": { + "type": "object", + "properties": { + "create": { + "type": "boolean" + }, + "name": { + "type": "string" + } + } + }, + "tolerations": { + "type": "array" + }, + "webhook": { + "type": "object", + "properties": { + "livenessProbe": { + "type": "object", + "properties": { + "initialDelaySeconds": { + "type": "integer" + } + } + }, + "mutating": { + "type": "object", + "properties": { + "create": { + "type": "boolean" + }, + "failurePolicy": { + "type": "string" + } + } + }, + "port": { + "type": "integer" + }, + "readinessProbe": { + "type": "object", + "properties": { + "initialDelaySeconds": { + "type": "integer" + } + } + }, + "validating": { + "type": "object", + "properties": { + "create": { + "type": "boolean" + }, + "failurePolicy": { + "type": "string" + } + } + } + } + } + } +} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/values.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/values.yaml new file mode 100644 index 000000000..f240cb359 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/cloudnative-pg/values.yaml @@ -0,0 +1,555 @@ +# +# Copyright The CloudNativePG Contributors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Default values for CloudNativePG. +# This is a YAML-formatted file. +# Please declare variables to be passed to your templates. + +replicaCount: 1 + +image: + repository: ghcr.io/cloudnative-pg/cloudnative-pg + pullPolicy: IfNotPresent + # -- Overrides the image tag whose default is the chart appVersion. + tag: "" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +crds: + # -- Specifies whether the CRDs should be created when installing the chart. + create: true + +# -- The webhook configuration. +webhook: + port: 9443 + mutating: + create: true + failurePolicy: Fail + validating: + create: true + failurePolicy: Fail + livenessProbe: + initialDelaySeconds: 3 + readinessProbe: + initialDelaySeconds: 3 + +# -- Operator configuration. +config: + # -- Specifies whether the secret should be created. + create: true + # -- The name of the configmap/secret to use. + name: cnpg-controller-manager-config + # -- Specifies whether it should be stored in a secret, instead of a configmap. + secret: false + # -- The content of the configmap/secret, see + # https://cloudnative-pg.io/documentation/current/operator_conf/#available-options + # for all the available options. + data: {} + # INHERITED_ANNOTATIONS: categories + # INHERITED_LABELS: environment, workload, app + # WATCH_NAMESPACE: namespace-a,namespace-b + +# -- Additinal arguments to be added to the operator's args list. +additionalArgs: [] + +# -- Array containing extra environment variables which can be templated. +# For example: +# - name: RELEASE_NAME +# value: "{{ .Release.Name }}" +# - name: MY_VAR +# value: "mySpecialKey" +additionalEnv: [] + +serviceAccount: + # -- Specifies whether the service account should be created. + create: true + # -- The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template. + name: "" + +rbac: + # -- Specifies whether ClusterRole and ClusterRoleBinding should be created. + create: true + # -- Aggregate ClusterRoles to Kubernetes default user-facing roles. + # Ref: https://kubernetes.io/docs/reference/access-authn-authz/rbac/#user-facing-roles + aggregateClusterRoles: false + +# -- Annotations to be added to all other resources. +commonAnnotations: {} +# -- Annotations to be added to the pod. +podAnnotations: {} +# -- Labels to be added to the pod. +podLabels: {} + +# -- Container Security Context. +containerSecurityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + runAsUser: 10001 + runAsGroup: 10001 + seccompProfile: + type: RuntimeDefault + capabilities: + drop: + - "ALL" + +# -- Security Context for the whole pod. +podSecurityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + # fsGroup: 2000 + +# -- Priority indicates the importance of a Pod relative to other Pods. +priorityClassName: "" + +service: + type: ClusterIP + # -- DO NOT CHANGE THE SERVICE NAME as it is currently used to generate the certificate + # and can not be configured + name: cnpg-webhook-service + port: 443 + +resources: {} + # If you want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # + # limits: + # cpu: 100m + # memory: 200Mi + # requests: + # cpu: 100m + # memory: 100Mi + +# -- Nodeselector for the operator to be installed. +nodeSelector: {} + +# -- Tolerations for the operator to be installed. +tolerations: [] + +# -- Affinity for the operator to be installed. +affinity: {} + +monitoring: + + # -- Specifies whether the monitoring should be enabled. Requires Prometheus Operator CRDs. + podMonitorEnabled: false + # -- Additional labels for the podMonitor + podMonitorAdditionalLabels: {} + + grafanaDashboard: + create: false + # -- Allows overriding the namespace where the ConfigMap will be created, defaulting to the same one as the Release. + namespace: "" + # -- The name of the ConfigMap containing the dashboard. + configMapName: "cnpg-grafana-dashboard" + # -- Label that ConfigMaps should have to be loaded as dashboards. DEPRECATED: Use labels instead. + sidecarLabel: "grafana_dashboard" + # -- Label value that ConfigMaps should have to be loaded as dashboards. DEPRECATED: Use labels instead. + sidecarLabelValue: "1" + # -- Labels that ConfigMaps should have to get configured in Grafana. + labels: {} + # -- Annotations that ConfigMaps can have to get configured in Grafana. + annotations: {} + +# Default monitoring queries +monitoringQueriesConfigMap: + # -- The name of the default monitoring configmap. + name: cnpg-default-monitoring + # -- A string representation of a YAML defining monitoring queries. + queries: | + backends: + query: | + SELECT sa.datname + , sa.usename + , sa.application_name + , states.state + , COALESCE(sa.count, 0) AS total + , COALESCE(sa.max_tx_secs, 0) AS max_tx_duration_seconds + FROM ( VALUES ('active') + , ('idle') + , ('idle in transaction') + , ('idle in transaction (aborted)') + , ('fastpath function call') + , ('disabled') + ) AS states(state) + LEFT JOIN ( + SELECT datname + , state + , usename + , COALESCE(application_name, '') AS application_name + , COUNT(*) + , COALESCE(EXTRACT (EPOCH FROM (max(now() - xact_start))), 0) AS max_tx_secs + FROM pg_catalog.pg_stat_activity + GROUP BY datname, state, usename, application_name + ) sa ON states.state = sa.state + WHERE sa.usename IS NOT NULL + metrics: + - datname: + usage: "LABEL" + description: "Name of the database" + - usename: + usage: "LABEL" + description: "Name of the user" + - application_name: + usage: "LABEL" + description: "Name of the application" + - state: + usage: "LABEL" + description: "State of the backend" + - total: + usage: "GAUGE" + description: "Number of backends" + - max_tx_duration_seconds: + usage: "GAUGE" + description: "Maximum duration of a transaction in seconds" + + backends_waiting: + query: | + SELECT count(*) AS total + FROM pg_catalog.pg_locks blocked_locks + JOIN pg_catalog.pg_locks blocking_locks + ON blocking_locks.locktype = blocked_locks.locktype + AND blocking_locks.database IS NOT DISTINCT FROM blocked_locks.database + AND blocking_locks.relation IS NOT DISTINCT FROM blocked_locks.relation + AND blocking_locks.page IS NOT DISTINCT FROM blocked_locks.page + AND blocking_locks.tuple IS NOT DISTINCT FROM blocked_locks.tuple + AND blocking_locks.virtualxid IS NOT DISTINCT FROM blocked_locks.virtualxid + AND blocking_locks.transactionid IS NOT DISTINCT FROM blocked_locks.transactionid + AND blocking_locks.classid IS NOT DISTINCT FROM blocked_locks.classid + AND blocking_locks.objid IS NOT DISTINCT FROM blocked_locks.objid + AND blocking_locks.objsubid IS NOT DISTINCT FROM blocked_locks.objsubid + AND blocking_locks.pid != blocked_locks.pid + JOIN pg_catalog.pg_stat_activity blocking_activity ON blocking_activity.pid = blocking_locks.pid + WHERE NOT blocked_locks.granted + metrics: + - total: + usage: "GAUGE" + description: "Total number of backends that are currently waiting on other queries" + + pg_database: + query: | + SELECT datname + , pg_catalog.pg_database_size(datname) AS size_bytes + , pg_catalog.age(datfrozenxid) AS xid_age + , pg_catalog.mxid_age(datminmxid) AS mxid_age + FROM pg_catalog.pg_database + metrics: + - datname: + usage: "LABEL" + description: "Name of the database" + - size_bytes: + usage: "GAUGE" + description: "Disk space used by the database" + - xid_age: + usage: "GAUGE" + description: "Number of transactions from the frozen XID to the current one" + - mxid_age: + usage: "GAUGE" + description: "Number of multiple transactions (Multixact) from the frozen XID to the current one" + + pg_postmaster: + query: | + SELECT EXTRACT(EPOCH FROM pg_postmaster_start_time) AS start_time + FROM pg_catalog.pg_postmaster_start_time() + metrics: + - start_time: + usage: "GAUGE" + description: "Time at which postgres started (based on epoch)" + + pg_replication: + query: "SELECT CASE WHEN ( + NOT pg_catalog.pg_is_in_recovery() + OR pg_catalog.pg_last_wal_receive_lsn() = pg_catalog.pg_last_wal_replay_lsn()) + THEN 0 + ELSE GREATEST (0, + EXTRACT(EPOCH FROM (now() - pg_catalog.pg_last_xact_replay_timestamp()))) + END AS lag, + pg_catalog.pg_is_in_recovery() AS in_recovery, + EXISTS (TABLE pg_stat_wal_receiver) AS is_wal_receiver_up, + (SELECT count(*) FROM pg_catalog.pg_stat_replication) AS streaming_replicas" + metrics: + - lag: + usage: "GAUGE" + description: "Replication lag behind primary in seconds" + - in_recovery: + usage: "GAUGE" + description: "Whether the instance is in recovery" + - is_wal_receiver_up: + usage: "GAUGE" + description: "Whether the instance wal_receiver is up" + - streaming_replicas: + usage: "GAUGE" + description: "Number of streaming replicas connected to the instance" + + pg_replication_slots: + query: | + SELECT slot_name, + slot_type, + database, + active, + (CASE pg_catalog.pg_is_in_recovery() + WHEN TRUE THEN pg_catalog.pg_wal_lsn_diff(pg_catalog.pg_last_wal_receive_lsn(), restart_lsn) + ELSE pg_catalog.pg_wal_lsn_diff(pg_catalog.pg_current_wal_lsn(), restart_lsn) + END) as pg_wal_lsn_diff + FROM pg_catalog.pg_replication_slots + WHERE NOT temporary + metrics: + - slot_name: + usage: "LABEL" + description: "Name of the replication slot" + - slot_type: + usage: "LABEL" + description: "Type of the replication slot" + - database: + usage: "LABEL" + description: "Name of the database" + - active: + usage: "GAUGE" + description: "Flag indicating whether the slot is active" + - pg_wal_lsn_diff: + usage: "GAUGE" + description: "Replication lag in bytes" + + pg_stat_archiver: + query: | + SELECT archived_count + , failed_count + , COALESCE(EXTRACT(EPOCH FROM (now() - last_archived_time)), -1) AS seconds_since_last_archival + , COALESCE(EXTRACT(EPOCH FROM (now() - last_failed_time)), -1) AS seconds_since_last_failure + , COALESCE(EXTRACT(EPOCH FROM last_archived_time), -1) AS last_archived_time + , COALESCE(EXTRACT(EPOCH FROM last_failed_time), -1) AS last_failed_time + , COALESCE(CAST(CAST('x'||pg_catalog.right(pg_catalog.split_part(last_archived_wal, '.', 1), 16) AS pg_catalog.bit(64)) AS pg_catalog.int8), -1) AS last_archived_wal_start_lsn + , COALESCE(CAST(CAST('x'||pg_catalog.right(pg_catalog.split_part(last_failed_wal, '.', 1), 16) AS pg_catalog.bit(64)) AS pg_catalog.int8), -1) AS last_failed_wal_start_lsn + , EXTRACT(EPOCH FROM stats_reset) AS stats_reset_time + FROM pg_catalog.pg_stat_archiver + metrics: + - archived_count: + usage: "COUNTER" + description: "Number of WAL files that have been successfully archived" + - failed_count: + usage: "COUNTER" + description: "Number of failed attempts for archiving WAL files" + - seconds_since_last_archival: + usage: "GAUGE" + description: "Seconds since the last successful archival operation" + - seconds_since_last_failure: + usage: "GAUGE" + description: "Seconds since the last failed archival operation" + - last_archived_time: + usage: "GAUGE" + description: "Epoch of the last time WAL archiving succeeded" + - last_failed_time: + usage: "GAUGE" + description: "Epoch of the last time WAL archiving failed" + - last_archived_wal_start_lsn: + usage: "GAUGE" + description: "Archived WAL start LSN" + - last_failed_wal_start_lsn: + usage: "GAUGE" + description: "Last failed WAL LSN" + - stats_reset_time: + usage: "GAUGE" + description: "Time at which these statistics were last reset" + + pg_stat_bgwriter: + runonserver: "<17.0.0" + query: | + SELECT checkpoints_timed + , checkpoints_req + , checkpoint_write_time + , checkpoint_sync_time + , buffers_checkpoint + , buffers_clean + , maxwritten_clean + , buffers_backend + , buffers_backend_fsync + , buffers_alloc + FROM pg_catalog.pg_stat_bgwriter + metrics: + - checkpoints_timed: + usage: "COUNTER" + description: "Number of scheduled checkpoints that have been performed" + - checkpoints_req: + usage: "COUNTER" + description: "Number of requested checkpoints that have been performed" + - checkpoint_write_time: + usage: "COUNTER" + description: "Total amount of time that has been spent in the portion of checkpoint processing where files are written to disk, in milliseconds" + - checkpoint_sync_time: + usage: "COUNTER" + description: "Total amount of time that has been spent in the portion of checkpoint processing where files are synchronized to disk, in milliseconds" + - buffers_checkpoint: + usage: "COUNTER" + description: "Number of buffers written during checkpoints" + - buffers_clean: + usage: "COUNTER" + description: "Number of buffers written by the background writer" + - maxwritten_clean: + usage: "COUNTER" + description: "Number of times the background writer stopped a cleaning scan because it had written too many buffers" + - buffers_backend: + usage: "COUNTER" + description: "Number of buffers written directly by a backend" + - buffers_backend_fsync: + usage: "COUNTER" + description: "Number of times a backend had to execute its own fsync call (normally the background writer handles those even when the backend does its own write)" + - buffers_alloc: + usage: "COUNTER" + description: "Number of buffers allocated" + + pg_stat_database: + query: | + SELECT datname + , xact_commit + , xact_rollback + , blks_read + , blks_hit + , tup_returned + , tup_fetched + , tup_inserted + , tup_updated + , tup_deleted + , conflicts + , temp_files + , temp_bytes + , deadlocks + , blk_read_time + , blk_write_time + FROM pg_catalog.pg_stat_database + metrics: + - datname: + usage: "LABEL" + description: "Name of this database" + - xact_commit: + usage: "COUNTER" + description: "Number of transactions in this database that have been committed" + - xact_rollback: + usage: "COUNTER" + description: "Number of transactions in this database that have been rolled back" + - blks_read: + usage: "COUNTER" + description: "Number of disk blocks read in this database" + - blks_hit: + usage: "COUNTER" + description: "Number of times disk blocks were found already in the buffer cache, so that a read was not necessary (this only includes hits in the PostgreSQL buffer cache, not the operating system's file system cache)" + - tup_returned: + usage: "COUNTER" + description: "Number of rows returned by queries in this database" + - tup_fetched: + usage: "COUNTER" + description: "Number of rows fetched by queries in this database" + - tup_inserted: + usage: "COUNTER" + description: "Number of rows inserted by queries in this database" + - tup_updated: + usage: "COUNTER" + description: "Number of rows updated by queries in this database" + - tup_deleted: + usage: "COUNTER" + description: "Number of rows deleted by queries in this database" + - conflicts: + usage: "COUNTER" + description: "Number of queries canceled due to conflicts with recovery in this database" + - temp_files: + usage: "COUNTER" + description: "Number of temporary files created by queries in this database" + - temp_bytes: + usage: "COUNTER" + description: "Total amount of data written to temporary files by queries in this database" + - deadlocks: + usage: "COUNTER" + description: "Number of deadlocks detected in this database" + - blk_read_time: + usage: "COUNTER" + description: "Time spent reading data file blocks by backends in this database, in milliseconds" + - blk_write_time: + usage: "COUNTER" + description: "Time spent writing data file blocks by backends in this database, in milliseconds" + + pg_stat_replication: + primary: true + query: | + SELECT usename + , COALESCE(application_name, '') AS application_name + , COALESCE(client_addr::text, '') AS client_addr + , COALESCE(client_port::text, '') AS client_port + , EXTRACT(EPOCH FROM backend_start) AS backend_start + , COALESCE(pg_catalog.age(backend_xmin), 0) AS backend_xmin_age + , pg_catalog.pg_wal_lsn_diff(pg_catalog.pg_current_wal_lsn(), sent_lsn) AS sent_diff_bytes + , pg_catalog.pg_wal_lsn_diff(pg_catalog.pg_current_wal_lsn(), write_lsn) AS write_diff_bytes + , pg_catalog.pg_wal_lsn_diff(pg_catalog.pg_current_wal_lsn(), flush_lsn) AS flush_diff_bytes + , COALESCE(pg_catalog.pg_wal_lsn_diff(pg_catalog.pg_current_wal_lsn(), replay_lsn),0) AS replay_diff_bytes + , COALESCE((EXTRACT(EPOCH FROM write_lag)),0)::float AS write_lag_seconds + , COALESCE((EXTRACT(EPOCH FROM flush_lag)),0)::float AS flush_lag_seconds + , COALESCE((EXTRACT(EPOCH FROM replay_lag)),0)::float AS replay_lag_seconds + FROM pg_catalog.pg_stat_replication + metrics: + - usename: + usage: "LABEL" + description: "Name of the replication user" + - application_name: + usage: "LABEL" + description: "Name of the application" + - client_addr: + usage: "LABEL" + description: "Client IP address" + - client_port: + usage: "LABEL" + description: "Client TCP port" + - backend_start: + usage: "COUNTER" + description: "Time when this process was started" + - backend_xmin_age: + usage: "COUNTER" + description: "The age of this standby's xmin horizon" + - sent_diff_bytes: + usage: "GAUGE" + description: "Difference in bytes from the last write-ahead log location sent on this connection" + - write_diff_bytes: + usage: "GAUGE" + description: "Difference in bytes from the last write-ahead log location written to disk by this standby server" + - flush_diff_bytes: + usage: "GAUGE" + description: "Difference in bytes from the last write-ahead log location flushed to disk by this standby server" + - replay_diff_bytes: + usage: "GAUGE" + description: "Difference in bytes from the last write-ahead log location replayed into the database on this standby server" + - write_lag_seconds: + usage: "GAUGE" + description: "Time elapsed between flushing recent WAL locally and receiving notification that this standby server has written it" + - flush_lag_seconds: + usage: "GAUGE" + description: "Time elapsed between flushing recent WAL locally and receiving notification that this standby server has written and flushed it" + - replay_lag_seconds: + usage: "GAUGE" + description: "Time elapsed between flushing recent WAL locally and receiving notification that this standby server has written, flushed and applied it" + + pg_settings: + query: | + SELECT name, + CASE setting WHEN 'on' THEN '1' WHEN 'off' THEN '0' ELSE setting END AS setting + FROM pg_catalog.pg_settings + WHERE vartype IN ('integer', 'real', 'bool') + ORDER BY 1 + metrics: + - name: + usage: "LABEL" + description: "Name of the setting" + - setting: + usage: "GAUGE" + description: "Setting value" diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/.helmignore b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/.helmignore new file mode 100644 index 000000000..207983f36 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/.helmignore @@ -0,0 +1,25 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj +# img folder +img/ +# Changelog +CHANGELOG.md diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/Chart.lock b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/Chart.lock new file mode 100644 index 000000000..6caefbae0 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: common + repository: oci://registry-1.docker.io/bitnamicharts + version: 2.20.5 +digest: sha256:5b98791747a148b9d4956b81bb8635f49a0ae831869d700d52e514b8fd1a2445 +generated: "2024-07-16T12:17:30.845825+02:00" diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/Chart.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/Chart.yaml new file mode 100644 index 000000000..07d7645f2 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/Chart.yaml @@ -0,0 +1,38 @@ +annotations: + category: Infrastructure + images: | + - name: rabbitmq + image: docker.io/bitnami/rabbitmq:3.13.6-debian-12-r0 + - name: rabbitmq-cluster-operator + image: docker.io/bitnami/rabbitmq-cluster-operator:2.9.0-debian-12-r6 + - name: rmq-default-credential-updater + image: docker.io/bitnami/rmq-default-credential-updater:1.0.4-debian-12-r24 + - name: rmq-messaging-topology-operator + image: docker.io/bitnami/rmq-messaging-topology-operator:1.14.2-debian-12-r3 + licenses: Apache-2.0 +apiVersion: v2 +appVersion: 2.9.0 +dependencies: +- name: common + repository: oci://registry-1.docker.io/bitnamicharts + tags: + - bitnami-common + version: 2.x.x +description: The RabbitMQ Cluster Kubernetes Operator automates provisioning, management, + and operations of RabbitMQ clusters running on Kubernetes. +home: https://bitnami.com +icon: https://bitnami.com/assets/stacks/rabbitmq-cluster-operator/img/rabbitmq-cluster-operator-stack-220x234.png +keywords: +- rabbitmq +- operator +- infrastructure +- message queue +- AMQP +kubeVersion: '>= 1.19.0-0' +maintainers: +- name: Broadcom, Inc. All Rights Reserved. + url: https://github.com/bitnami/charts +name: rabbitmq-cluster-operator +sources: +- https://github.com/bitnami/charts/tree/main/bitnami/rabbitmq-cluster-operator +version: 4.3.16 diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/README.md b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/README.md new file mode 100644 index 000000000..38b231326 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/README.md @@ -0,0 +1,634 @@ + + +# Bitnami package for RabbitMQ Cluster Operator + +The RabbitMQ Cluster Kubernetes Operator automates provisioning, management, and operations of RabbitMQ clusters running on Kubernetes. + +[Overview of RabbitMQ Cluster Operator](https://github.com/rabbitmq/cluster-operator) + +Trademarks: This software listing is packaged by Bitnami. The respective trademarks mentioned in the offering are owned by the respective companies, and use of them does not imply any affiliation or endorsement. + +## TL;DR + +```console +helm install my-release oci://registry-1.docker.io/bitnamicharts/rabbitmq-cluster-operator +``` + +Looking to use RabbitMQ Cluster Operator in production? Try [VMware Tanzu Application Catalog](https://bitnami.com/enterprise), the commercial edition of the Bitnami catalog. + +## Introduction + +Bitnami charts for Helm are carefully engineered, actively maintained and are the quickest and easiest way to deploy containers on a Kubernetes cluster that are ready to handle production workloads. + +This chart bootstraps a [RabbitMQ Cluster Operator](https://www.rabbitmq.com/kubernetes/operator/operator-overview.html) Deployment in a [Kubernetes](https://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + +Bitnami charts can be used with [Kubeapps](https://kubeapps.dev/) for deployment and management of Helm Charts in clusters. + +## Prerequisites + +- Kubernetes 1.23+ +- Helm 3.8.0+ +- PV provisioner support in the underlying infrastructure + +## Installing the Chart + +To install the chart with the release name `my-release`: + +```console +helm install my-release oci://REGISTRY_NAME/REPOSITORY_NAME/rabbitmq-cluster-operator +``` + +> Note: You need to substitute the placeholders `REGISTRY_NAME` and `REPOSITORY_NAME` with a reference to your Helm chart registry and repository. For example, in the case of Bitnami, you need to use `REGISTRY_NAME=registry-1.docker.io` and `REPOSITORY_NAME=bitnamicharts`. + +The command deploy the RabbitMQ Cluster Kubernetes Operator on the Kubernetes cluster in the default configuration. The [Parameters](#parameters) section lists the parameters that can be configured during installation. + +> **Tip**: List all releases using `helm list` + +## Differences between the Bitnami RabbitMQ chart and the Bitnami RabbitMQ Operator chart + +In the Bitnami catalog we offer both the *bitnami/rabbitmq* and *bitnami/rabbitmq-operator* charts. Each solution covers different needs and use cases. + +The *bitnami/rabbitmq* chart deploys a single RabbitMQ installation using a Kubernetes StatefulSet object (together with Services, PVCs, ConfigMaps, etc.). The figure below shows the deployed objects in the cluster after executing *helm install*: + +```text + +--------------+ +-----+ + | | | | + Service | RabbitMQ +<------------+ PVC | +<-------------------+ | | | + | StatefulSet | +-----+ + | | + +-----------+--+ + ^ +------------+ + | | | + +----------------+ Configmaps | + | Secrets | + +------------+ + +``` + +Its lifecycle is managed using Helm and, at the RabbitMQ container level, the following operations are automated: persistence management, configuration based on environment variables and plugin initialization. The StatefulSet do not require any ServiceAccounts with special RBAC privileges so this solution would fit better in more restricted Kubernetes installations. + +The *bitnami/rabbitmq-operator* chart deploys a RabbitMQ Operator installation using a Kubernetes Deployment. The figure below shows the RabbitMQ operator deployment after executing *helm install*: + +```text ++--------------------+ +| | +---------------+ +| RabbitMQ Operator | | | +| | | RBAC | +| Deployment | | Privileges | ++-------+------------+ +-------+-------+ + ^ | + | +-----------------+ | + +---+ Service Account +<----+ + +-----------------+ +``` + +The operator will extend the Kubernetes API with the following object: *RabbitmqCluster*. From that moment, the user will be able to deploy objects of these kinds and the previously deployed Operator will take care of deploying all the required StatefulSets, ConfigMaps and Services for running a RabbitMQ instance. Its lifecycle is managed using *kubectl* on the RabbitmqCluster objects. The following figure shows the deployed objects after deploying a *RabbitmqCluster* object using *kubectl*: + +```text + +--------------------+ + | | +---------------+ + | RabbitMQ Operator | | | + | | | RBAC | + | Deployment | | Privileges | + +-------+------------+ +-------+-------+ + | ^ | + | | +-----------------+ | + | +---+ Service Account +<----+ + | +-----------------+ + | + | + | + | + | ------------------------------------------------------------------------- + | | | + | | +--------------+ +-----+ | + | | | | | | | + |--->| Service | RabbitMQ +<------------+ PVC | | + | <-------------------+ | | | | + | | StatefulSet | +-----+ | + | | | | + | +-----------+--+ | + | ^ +------------+ | + | | | | | + | +----------------+ Configmaps | | + | | Secrets | | + | +------------+ | + | | + | | + ------------------------------------------------------------------------- + +``` + +This solution allows to easily deploy multiple RabbitMQ instances compared to the *bitnami/rabbitmq* chart. As the operator automatically deploys RabbitMQ installations, the RabbitMQ Operator pods will require a ServiceAccount with privileges to create and destroy multiple Kubernetes objects. This may be problematic for Kubernetes clusters with strict role-based access policies. + +## Configuration and installation details + +### Resource requests and limits + +Bitnami charts allow setting resource requests and limits for all containers inside the chart deployment. These are inside the `resources` value (check parameter table). Setting requests is essential for production workloads and these should be adapted to your specific use case. + +To make this process easier, the chart contains the `resourcesPreset` values, which automatically sets the `resources` section according to different presets. Check these presets in [the bitnami/common chart](https://github.com/bitnami/charts/blob/main/bitnami/common/templates/_resources.tpl#L15). However, in production workloads using `resourcePreset` is discouraged as it may not fully adapt to your specific needs. Find more information on container resource management in the [official Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/). + +### [Rolling VS Immutable tags](https://docs.vmware.com/en/VMware-Tanzu-Application-Catalog/services/tutorials/GUID-understand-rolling-tags-containers-index.html) + +It is strongly recommended to use immutable tags in a production environment. This ensures your deployment does not change automatically if the same tag is updated with a different image. + +Bitnami will release a new chart updating its containers if a new version of the main container, significant changes, or critical vulnerabilities exist. + +### Additional environment variables + +In case you want to add extra environment variables (useful for advanced operations like custom init scripts), you can use the `extraEnvVars` property. + +```yaml +rabbitmq-cluster-operator: + extraEnvVars: + - name: LOG_LEVEL + value: error +``` + +Alternatively, you can use a ConfigMap or a Secret with the environment variables. To do so, use the `extraEnvVarsCM` or the `extraEnvVarsSecret` values. + +### Sidecars + +If additional containers are needed in the same pod as rabbitmq-cluster-operator (such as additional metrics or logging exporters), they can be defined using the `sidecars` parameter. + +```yaml +sidecars: +- name: your-image-name + image: your-image + imagePullPolicy: Always + ports: + - name: portname + containerPort: 1234 +``` + +If these sidecars export extra ports, extra port definitions can be added using the `service.extraPorts` parameter (where available), as shown in the example below: + +```yaml +service: + extraPorts: + - name: extraPort + port: 11311 + targetPort: 11311 +``` + +> NOTE: This Helm chart already includes sidecar containers for the Prometheus exporters (where applicable). These can be activated by adding the `--enable-metrics=true` parameter at deployment time. The `sidecars` parameter should therefore only be used for any extra sidecar containers. + +If additional init containers are needed in the same pod, they can be defined using the `initContainers` parameter. Here is an example: + +```yaml +initContainers: + - name: your-image-name + image: your-image + imagePullPolicy: Always + ports: + - name: portname + containerPort: 1234 +``` + +Learn more about [sidecar containers](https://kubernetes.io/docs/concepts/workloads/pods/) and [init containers](https://kubernetes.io/docs/concepts/workloads/pods/init-containers/). + +### Pod affinity + +This chart allows you to set your custom affinity using the `affinity` parameter. Find more information about Pod affinity in the [kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity). + +As an alternative, use one of the preset configurations for pod affinity, pod anti-affinity, and node affinity available at the [bitnami/common](https://github.com/bitnami/charts/tree/main/bitnami/common#affinities) chart. To do so, set the `podAffinityPreset`, `podAntiAffinityPreset`, or `nodeAffinityPreset` parameters. + +### Deploying extra resources + +There are cases where you may want to deploy extra objects, such your custom *RabbitmqCluster* objects. For covering this case, the chart allows adding the full specification of other objects using the `extraDeploy` parameter. + +For instance, to deploy your custom *RabbitmqCluster* definition, you can install the RabbitMQ Cluster Operator using the values below: + +```yaml +extraDeploy: + - apiVersion: rabbitmq.com/v1beta1 + kind: RabbitmqCluster + metadata: + name: rabbitmq-custom-configuration + spec: + replicas: 1 + rabbitmq: + additionalConfig: | + log.console.level = debug +``` + +## Parameters + +### Global parameters + +| Name | Description | Value | +| ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | +| `global.imageRegistry` | Global Docker image registry | `""` | +| `global.imagePullSecrets` | Global Docker registry secret names as an array | `[]` | +| `global.defaultStorageClass` | Global default StorageClass for Persistent Volume(s) | `""` | +| `global.storageClass` | DEPRECATED: use global.defaultStorageClass instead | `""` | +| `global.compatibility.openshift.adaptSecurityContext` | 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) | `auto` | + +### Common parameters + +| Name | Description | Value | +| ------------------------ | ---------------------------------------------------- | --------------- | +| `kubeVersion` | Override Kubernetes version | `""` | +| `nameOverride` | String to partially override common.names.fullname | `""` | +| `fullnameOverride` | String to fully override common.names.fullname | `""` | +| `commonLabels` | Labels to add to all deployed objects | `{}` | +| `commonAnnotations` | Annotations to add to all deployed objects | `{}` | +| `clusterDomain` | Kubernetes cluster domain name | `cluster.local` | +| `extraDeploy` | Array of extra objects to deploy with the release | `[]` | +| `diagnosticMode.enabled` | Enable diagnostic mode (all probes will be disabled) | `false` | + +### RabbitMQ Cluster Operator Parameters + +| Name | Description | Value | +| ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ | +| `rabbitmqImage.registry` | RabbitMQ Image registry | `REGISTRY_NAME` | +| `rabbitmqImage.repository` | RabbitMQ Image repository | `REPOSITORY_NAME/rabbitmq` | +| `rabbitmqImage.digest` | RabbitMQ image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag | `""` | +| `rabbitmqImage.pullSecrets` | RabbitMQ Image pull secrets | `[]` | +| `credentialUpdaterImage.registry` | RabbitMQ Default User Credential Updater image registry | `REGISTRY_NAME` | +| `credentialUpdaterImage.repository` | RabbitMQ Default User Credential Updater image repository | `REPOSITORY_NAME/rmq-default-credential-updater` | +| `credentialUpdaterImage.digest` | RabbitMQ Default User Credential Updater image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag | `""` | +| `credentialUpdaterImage.pullSecrets` | RabbitMQ Default User Credential Updater image pull secrets | `[]` | +| `clusterOperator.image.registry` | RabbitMQ Cluster Operator image registry | `REGISTRY_NAME` | +| `clusterOperator.image.repository` | RabbitMQ Cluster Operator image repository | `REPOSITORY_NAME/rabbitmq-cluster-operator` | +| `clusterOperator.image.digest` | RabbitMQ Cluster Operator image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag | `""` | +| `clusterOperator.image.pullPolicy` | RabbitMQ Cluster Operator image pull policy | `IfNotPresent` | +| `clusterOperator.image.pullSecrets` | RabbitMQ Cluster Operator image pull secrets | `[]` | +| `clusterOperator.revisionHistoryLimit` | sets number of replicaset to keep in k8s | `10` | +| `clusterOperator.watchAllNamespaces` | Watch for resources in all namespaces | `true` | +| `clusterOperator.watchNamespaces` | Watch for resources in the given namespaces (ignored if watchAllNamespaces=true) | `[]` | +| `clusterOperator.replicaCount` | Number of RabbitMQ Cluster Operator replicas to deploy | `1` | +| `clusterOperator.schedulerName` | Alternative scheduler | `""` | +| `clusterOperator.topologySpreadConstraints` | Topology Spread Constraints for pod assignment | `[]` | +| `clusterOperator.terminationGracePeriodSeconds` | In seconds, time the given to the %%MAIN_CONTAINER_NAME%% pod needs to terminate gracefully | `""` | +| `clusterOperator.livenessProbe.enabled` | Enable livenessProbe on RabbitMQ Cluster Operator nodes | `true` | +| `clusterOperator.livenessProbe.initialDelaySeconds` | Initial delay seconds for livenessProbe | `5` | +| `clusterOperator.livenessProbe.periodSeconds` | Period seconds for livenessProbe | `30` | +| `clusterOperator.livenessProbe.timeoutSeconds` | Timeout seconds for livenessProbe | `5` | +| `clusterOperator.livenessProbe.failureThreshold` | Failure threshold for livenessProbe | `5` | +| `clusterOperator.livenessProbe.successThreshold` | Success threshold for livenessProbe | `1` | +| `clusterOperator.readinessProbe.enabled` | Enable readinessProbe on RabbitMQ Cluster Operator nodes | `true` | +| `clusterOperator.readinessProbe.initialDelaySeconds` | Initial delay seconds for readinessProbe | `5` | +| `clusterOperator.readinessProbe.periodSeconds` | Period seconds for readinessProbe | `30` | +| `clusterOperator.readinessProbe.timeoutSeconds` | Timeout seconds for readinessProbe | `5` | +| `clusterOperator.readinessProbe.failureThreshold` | Failure threshold for readinessProbe | `5` | +| `clusterOperator.readinessProbe.successThreshold` | Success threshold for readinessProbe | `1` | +| `clusterOperator.startupProbe.enabled` | Enable startupProbe on RabbitMQ Cluster Operator nodes | `false` | +| `clusterOperator.startupProbe.initialDelaySeconds` | Initial delay seconds for startupProbe | `5` | +| `clusterOperator.startupProbe.periodSeconds` | Period seconds for startupProbe | `30` | +| `clusterOperator.startupProbe.timeoutSeconds` | Timeout seconds for startupProbe | `5` | +| `clusterOperator.startupProbe.failureThreshold` | Failure threshold for startupProbe | `5` | +| `clusterOperator.startupProbe.successThreshold` | Success threshold for startupProbe | `1` | +| `clusterOperator.customLivenessProbe` | Custom livenessProbe that overrides the default one | `{}` | +| `clusterOperator.customReadinessProbe` | Custom readinessProbe that overrides the default one | `{}` | +| `clusterOperator.customStartupProbe` | Custom startupProbe that overrides the default one | `{}` | +| `clusterOperator.resourcesPreset` | Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if clusterOperator.resources is set (clusterOperator.resources is recommended for production). | `nano` | +| `clusterOperator.resources` | Set container requests and limits for different resources like CPU or memory (essential for production workloads) | `{}` | +| `clusterOperator.podSecurityContext.enabled` | Enabled RabbitMQ Cluster Operator pods' Security Context | `true` | +| `clusterOperator.podSecurityContext.fsGroupChangePolicy` | Set filesystem group change policy | `Always` | +| `clusterOperator.podSecurityContext.sysctls` | Set kernel settings using the sysctl interface | `[]` | +| `clusterOperator.podSecurityContext.supplementalGroups` | Set filesystem extra groups | `[]` | +| `clusterOperator.podSecurityContext.fsGroup` | Set RabbitMQ Cluster Operator pod's Security Context fsGroup | `1001` | +| `clusterOperator.containerSecurityContext.enabled` | Enabled containers' Security Context | `true` | +| `clusterOperator.containerSecurityContext.seLinuxOptions` | Set SELinux options in container | `nil` | +| `clusterOperator.containerSecurityContext.runAsUser` | Set containers' Security Context runAsUser | `1001` | +| `clusterOperator.containerSecurityContext.runAsGroup` | Set containers' Security Context runAsGroup | `1001` | +| `clusterOperator.containerSecurityContext.runAsNonRoot` | Set container's Security Context runAsNonRoot | `true` | +| `clusterOperator.containerSecurityContext.privileged` | Set container's Security Context privileged | `false` | +| `clusterOperator.containerSecurityContext.readOnlyRootFilesystem` | Set container's Security Context readOnlyRootFilesystem | `true` | +| `clusterOperator.containerSecurityContext.allowPrivilegeEscalation` | Set container's Security Context allowPrivilegeEscalation | `false` | +| `clusterOperator.containerSecurityContext.capabilities.drop` | List of capabilities to be dropped | `["ALL"]` | +| `clusterOperator.containerSecurityContext.seccompProfile.type` | Set container's Security Context seccomp profile | `RuntimeDefault` | +| `clusterOperator.command` | Override default container command (useful when using custom images) | `[]` | +| `clusterOperator.args` | Override default container args (useful when using custom images) | `[]` | +| `clusterOperator.automountServiceAccountToken` | Mount Service Account token in pod | `true` | +| `clusterOperator.hostAliases` | RabbitMQ Cluster Operator pods host aliases | `[]` | +| `clusterOperator.podLabels` | Extra labels for RabbitMQ Cluster Operator pods | `{}` | +| `clusterOperator.podAnnotations` | Annotations for RabbitMQ Cluster Operator pods | `{}` | +| `clusterOperator.podAffinityPreset` | Pod affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` | `""` | +| `clusterOperator.podAntiAffinityPreset` | Pod anti-affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` | `soft` | +| `clusterOperator.nodeAffinityPreset.type` | Node affinity preset type. Ignored if `affinity` is set. Allowed values: `soft` or `hard` | `""` | +| `clusterOperator.nodeAffinityPreset.key` | Node label key to match. Ignored if `affinity` is set | `""` | +| `clusterOperator.nodeAffinityPreset.values` | Node label values to match. Ignored if `affinity` is set | `[]` | +| `clusterOperator.affinity` | Affinity for RabbitMQ Cluster Operator pods assignment | `{}` | +| `clusterOperator.nodeSelector` | Node labels for RabbitMQ Cluster Operator pods assignment | `{}` | +| `clusterOperator.tolerations` | Tolerations for RabbitMQ Cluster Operator pods assignment | `[]` | +| `clusterOperator.updateStrategy.type` | RabbitMQ Cluster Operator statefulset strategy type | `RollingUpdate` | +| `clusterOperator.priorityClassName` | RabbitMQ Cluster Operator pods' priorityClassName | `""` | +| `clusterOperator.lifecycleHooks` | for the RabbitMQ Cluster Operator container(s) to automate configuration before or after startup | `{}` | +| `clusterOperator.containerPorts.metrics` | RabbitMQ Cluster Operator container port (used for metrics) | `9782` | +| `clusterOperator.extraEnvVars` | Array with extra environment variables to add to RabbitMQ Cluster Operator nodes | `[]` | +| `clusterOperator.extraEnvVarsCM` | Name of existing ConfigMap containing extra env vars for RabbitMQ Cluster Operator nodes | `""` | +| `clusterOperator.extraEnvVarsSecret` | Name of existing Secret containing extra env vars for RabbitMQ Cluster Operator nodes | `""` | +| `clusterOperator.extraVolumes` | Optionally specify extra list of additional volumes for the RabbitMQ Cluster Operator pod(s) | `[]` | +| `clusterOperator.extraVolumeMounts` | Optionally specify extra list of additional volumeMounts for the RabbitMQ Cluster Operator container(s) | `[]` | +| `clusterOperator.sidecars` | Add additional sidecar containers to the RabbitMQ Cluster Operator pod(s) | `[]` | +| `clusterOperator.initContainers` | Add additional init containers to the RabbitMQ Cluster Operator pod(s) | `[]` | +| `clusterOperator.networkPolicy.enabled` | Specifies whether a NetworkPolicy should be created | `true` | +| `clusterOperator.networkPolicy.kubeAPIServerPorts` | List of possible endpoints to kube-apiserver (limit to your cluster settings to increase security) | `[]` | +| `clusterOperator.networkPolicy.allowExternal` | Don't require injector label for connections | `true` | +| `clusterOperator.networkPolicy.allowExternalEgress` | Allow the pod to access any range of port and all destinations. | `true` | +| `clusterOperator.networkPolicy.extraIngress` | Add extra ingress rules to the NetworkPolicy | `[]` | +| `clusterOperator.networkPolicy.extraEgress` | Add extra ingress rules to the NetworkPolicy | `[]` | +| `clusterOperator.networkPolicy.ingressNSMatchLabels` | Labels to match to allow traffic from other namespaces | `{}` | +| `clusterOperator.networkPolicy.ingressNSPodMatchLabels` | Pod labels to match to allow traffic from other namespaces | `{}` | +| `clusterOperator.rbac.create` | Specifies whether RBAC resources should be created | `true` | +| `clusterOperator.rbac.clusterRole.customRules` | Define custom access rules for the ClusterRole | `[]` | +| `clusterOperator.rbac.clusterRole.extraRules` | Define extra access rules for the ClusterRole. This has no effect if customerRules is a non-empty array. | `[]` | +| `clusterOperator.serviceAccount.create` | Specifies whether a ServiceAccount should be created | `true` | +| `clusterOperator.serviceAccount.name` | The name of the ServiceAccount to use. | `""` | +| `clusterOperator.serviceAccount.annotations` | Add annotations | `{}` | +| `clusterOperator.serviceAccount.automountServiceAccountToken` | Automount API credentials for a service account. | `false` | + +### RabbitMQ Cluster Operator Metrics parameters + +| Name | Description | Value | +| ---------------------------------------------------------- | ---------------------------------------------------------------------------------- | ------------------------ | +| `clusterOperator.metrics.service.enabled` | Create a service for accessing the metrics endpoint | `false` | +| `clusterOperator.metrics.service.type` | RabbitMQ Cluster Operator metrics service type | `ClusterIP` | +| `clusterOperator.metrics.service.ports.http` | RabbitMQ Cluster Operator metrics service HTTP port | `80` | +| `clusterOperator.metrics.service.nodePorts.http` | Node port for HTTP | `""` | +| `clusterOperator.metrics.service.clusterIP` | RabbitMQ Cluster Operator metrics service Cluster IP | `""` | +| `clusterOperator.metrics.service.extraPorts` | Extra ports to expose (normally used with the `sidecar` value) | `[]` | +| `clusterOperator.metrics.service.loadBalancerIP` | RabbitMQ Cluster Operator metrics service Load Balancer IP | `""` | +| `clusterOperator.metrics.service.loadBalancerSourceRanges` | RabbitMQ Cluster Operator metrics service Load Balancer sources | `[]` | +| `clusterOperator.metrics.service.externalTrafficPolicy` | RabbitMQ Cluster Operator metrics service external traffic policy | `Cluster` | +| `clusterOperator.metrics.service.annotations` | Additional custom annotations for RabbitMQ Cluster Operator metrics service | `{}` | +| `clusterOperator.metrics.service.sessionAffinity` | Session Affinity for Kubernetes service, can be "None" or "ClientIP" | `None` | +| `clusterOperator.metrics.service.sessionAffinityConfig` | Additional settings for the sessionAffinity | `{}` | +| `clusterOperator.metrics.serviceMonitor.enabled` | Specify if a servicemonitor will be deployed for prometheus-operator | `false` | +| `clusterOperator.metrics.serviceMonitor.namespace` | Namespace which Prometheus is running in | `""` | +| `clusterOperator.metrics.serviceMonitor.jobLabel` | Specify the jobLabel to use for the prometheus-operator | `app.kubernetes.io/name` | +| `clusterOperator.metrics.serviceMonitor.honorLabels` | Honor metrics labels | `false` | +| `clusterOperator.metrics.serviceMonitor.selector` | Prometheus instance selector labels | `{}` | +| `clusterOperator.metrics.serviceMonitor.scrapeTimeout` | Timeout after which the scrape is ended | `""` | +| `clusterOperator.metrics.serviceMonitor.interval` | Scrape interval. If not set, the Prometheus default scrape interval is used | `""` | +| `clusterOperator.metrics.serviceMonitor.metricRelabelings` | Specify additional relabeling of metrics | `[]` | +| `clusterOperator.metrics.serviceMonitor.relabelings` | Specify general relabeling | `[]` | +| `clusterOperator.metrics.serviceMonitor.labels` | Extra labels for the ServiceMonitor | `{}` | +| `clusterOperator.metrics.serviceMonitor.path` | Define the path used by ServiceMonitor to scrap metrics | `""` | +| `clusterOperator.metrics.serviceMonitor.params` | Define the HTTP URL parameters used by ServiceMonitor | `{}` | +| `clusterOperator.metrics.podMonitor.enabled` | Create PodMonitor Resource for scraping metrics using PrometheusOperator | `false` | +| `clusterOperator.metrics.podMonitor.jobLabel` | Specify the jobLabel to use for the prometheus-operator | `app.kubernetes.io/name` | +| `clusterOperator.metrics.podMonitor.namespace` | Namespace which Prometheus is running in | `""` | +| `clusterOperator.metrics.podMonitor.honorLabels` | Honor metrics labels | `false` | +| `clusterOperator.metrics.podMonitor.selector` | Prometheus instance selector labels | `{}` | +| `clusterOperator.metrics.podMonitor.interval` | Specify the interval at which metrics should be scraped | `30s` | +| `clusterOperator.metrics.podMonitor.scrapeTimeout` | Specify the timeout after which the scrape is ended | `30s` | +| `clusterOperator.metrics.podMonitor.additionalLabels` | Additional labels that can be used so PodMonitors will be discovered by Prometheus | `{}` | +| `clusterOperator.metrics.podMonitor.path` | Define HTTP path to scrape for metrics. | `""` | +| `clusterOperator.metrics.podMonitor.relabelings` | Specify general relabeling | `[]` | +| `clusterOperator.metrics.podMonitor.metricRelabelings` | Specify additional relabeling of metrics | `[]` | +| `clusterOperator.metrics.podMonitor.params` | Define the HTTP URL parameters used by PodMonitor | `{}` | + +### RabbitMQ Messaging Topology Operator Parameters + +| Name | Description | Value | +| ----------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------- | +| `msgTopologyOperator.enabled` | Deploy RabbitMQ Messaging Topology Operator as part of the installation | `true` | +| `msgTopologyOperator.image.registry` | RabbitMQ Messaging Topology Operator image registry | `REGISTRY_NAME` | +| `msgTopologyOperator.image.repository` | RabbitMQ Messaging Topology Operator image repository | `REPOSITORY_NAME/rmq-messaging-topology-operator` | +| `msgTopologyOperator.image.digest` | RabbitMQ Messaging Topology Operator image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag | `""` | +| `msgTopologyOperator.image.pullPolicy` | RabbitMQ Messaging Topology Operator image pull policy | `IfNotPresent` | +| `msgTopologyOperator.image.pullSecrets` | RabbitMQ Messaging Topology Operator image pull secrets | `[]` | +| `msgTopologyOperator.revisionHistoryLimit` | sets number of replicaset to keep in k8s | `10` | +| `msgTopologyOperator.watchAllNamespaces` | Watch for resources in all namespaces | `true` | +| `msgTopologyOperator.watchNamespaces` | Watch for resources in the given namespaces ## @param clusterOperator.watchNamespaces [array] Watch for resources in the given namespaces (ignored if watchAllNamespaces=true) | `[]` | +| `msgTopologyOperator.replicaCount` | Number of RabbitMQ Messaging Topology Operator replicas to deploy | `1` | +| `msgTopologyOperator.topologySpreadConstraints` | Topology Spread Constraints for pod assignment | `[]` | +| `msgTopologyOperator.schedulerName` | Alternative scheduler | `""` | +| `msgTopologyOperator.terminationGracePeriodSeconds` | In seconds, time the given to the %%MAIN_CONTAINER_NAME%% pod needs to terminate gracefully | `""` | +| `msgTopologyOperator.hostNetwork` | Boolean | `false` | +| `msgTopologyOperator.dnsPolicy` | Alternative DNS policy | `ClusterFirst` | +| `msgTopologyOperator.livenessProbe.enabled` | Enable livenessProbe on RabbitMQ Messaging Topology Operator nodes | `true` | +| `msgTopologyOperator.livenessProbe.initialDelaySeconds` | Initial delay seconds for livenessProbe | `5` | +| `msgTopologyOperator.livenessProbe.periodSeconds` | Period seconds for livenessProbe | `30` | +| `msgTopologyOperator.livenessProbe.timeoutSeconds` | Timeout seconds for livenessProbe | `5` | +| `msgTopologyOperator.livenessProbe.failureThreshold` | Failure threshold for livenessProbe | `5` | +| `msgTopologyOperator.livenessProbe.successThreshold` | Success threshold for livenessProbe | `1` | +| `msgTopologyOperator.readinessProbe.enabled` | Enable readinessProbe on RabbitMQ Messaging Topology Operator nodes | `true` | +| `msgTopologyOperator.readinessProbe.initialDelaySeconds` | Initial delay seconds for readinessProbe | `5` | +| `msgTopologyOperator.readinessProbe.periodSeconds` | Period seconds for readinessProbe | `30` | +| `msgTopologyOperator.readinessProbe.timeoutSeconds` | Timeout seconds for readinessProbe | `5` | +| `msgTopologyOperator.readinessProbe.failureThreshold` | Failure threshold for readinessProbe | `5` | +| `msgTopologyOperator.readinessProbe.successThreshold` | Success threshold for readinessProbe | `1` | +| `msgTopologyOperator.startupProbe.enabled` | Enable startupProbe on RabbitMQ Messaging Topology Operator nodes | `false` | +| `msgTopologyOperator.startupProbe.initialDelaySeconds` | Initial delay seconds for startupProbe | `5` | +| `msgTopologyOperator.startupProbe.periodSeconds` | Period seconds for startupProbe | `30` | +| `msgTopologyOperator.startupProbe.timeoutSeconds` | Timeout seconds for startupProbe | `5` | +| `msgTopologyOperator.startupProbe.failureThreshold` | Failure threshold for startupProbe | `5` | +| `msgTopologyOperator.startupProbe.successThreshold` | Success threshold for startupProbe | `1` | +| `msgTopologyOperator.customLivenessProbe` | Custom livenessProbe that overrides the default one | `{}` | +| `msgTopologyOperator.customReadinessProbe` | Custom readinessProbe that overrides the default one | `{}` | +| `msgTopologyOperator.customStartupProbe` | Custom startupProbe that overrides the default one | `{}` | +| `msgTopologyOperator.existingWebhookCertSecret` | name of a secret containing the certificates (use it to avoid certManager creating one) | `""` | +| `msgTopologyOperator.existingWebhookCertCABundle` | PEM-encoded CA Bundle of the existing secret provided in existingWebhookCertSecret (only if useCertManager=false) | `""` | +| `msgTopologyOperator.resourcesPreset` | Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if msgTopologyOperator.resources is set (msgTopologyOperator.resources is recommended for production). | `nano` | +| `msgTopologyOperator.resources` | Set container requests and limits for different resources like CPU or memory (essential for production workloads) | `{}` | +| `msgTopologyOperator.podSecurityContext.enabled` | Enabled RabbitMQ Messaging Topology Operator pods' Security Context | `true` | +| `msgTopologyOperator.podSecurityContext.fsGroupChangePolicy` | Set filesystem group change policy | `Always` | +| `msgTopologyOperator.podSecurityContext.sysctls` | Set kernel settings using the sysctl interface | `[]` | +| `msgTopologyOperator.podSecurityContext.supplementalGroups` | Set filesystem extra groups | `[]` | +| `msgTopologyOperator.podSecurityContext.fsGroup` | Set RabbitMQ Messaging Topology Operator pod's Security Context fsGroup | `1001` | +| `msgTopologyOperator.containerSecurityContext.enabled` | Enabled containers' Security Context | `true` | +| `msgTopologyOperator.containerSecurityContext.seLinuxOptions` | Set SELinux options in container | `nil` | +| `msgTopologyOperator.containerSecurityContext.runAsUser` | Set containers' Security Context runAsUser | `1001` | +| `msgTopologyOperator.containerSecurityContext.runAsGroup` | Set containers' Security Context runAsGroup | `1001` | +| `msgTopologyOperator.containerSecurityContext.runAsNonRoot` | Set container's Security Context runAsNonRoot | `true` | +| `msgTopologyOperator.containerSecurityContext.privileged` | Set container's Security Context privileged | `false` | +| `msgTopologyOperator.containerSecurityContext.readOnlyRootFilesystem` | Set container's Security Context readOnlyRootFilesystem | `true` | +| `msgTopologyOperator.containerSecurityContext.allowPrivilegeEscalation` | Set container's Security Context allowPrivilegeEscalation | `false` | +| `msgTopologyOperator.containerSecurityContext.capabilities.drop` | List of capabilities to be dropped | `["ALL"]` | +| `msgTopologyOperator.containerSecurityContext.seccompProfile.type` | Set container's Security Context seccomp profile | `RuntimeDefault` | +| `msgTopologyOperator.fullnameOverride` | String to fully override rmqco.msgTopologyOperator.fullname template | `""` | +| `msgTopologyOperator.command` | Override default container command (useful when using custom images) | `[]` | +| `msgTopologyOperator.args` | Override default container args (useful when using custom images) | `[]` | +| `msgTopologyOperator.automountServiceAccountToken` | Mount Service Account token in pod | `true` | +| `msgTopologyOperator.hostAliases` | RabbitMQ Messaging Topology Operator pods host aliases | `[]` | +| `msgTopologyOperator.podLabels` | Extra labels for RabbitMQ Messaging Topology Operator pods | `{}` | +| `msgTopologyOperator.podAnnotations` | Annotations for RabbitMQ Messaging Topology Operator pods | `{}` | +| `msgTopologyOperator.podAffinityPreset` | Pod affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` | `""` | +| `msgTopologyOperator.podAntiAffinityPreset` | Pod anti-affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` | `soft` | +| `msgTopologyOperator.nodeAffinityPreset.type` | Node affinity preset type. Ignored if `affinity` is set. Allowed values: `soft` or `hard` | `""` | +| `msgTopologyOperator.nodeAffinityPreset.key` | Node label key to match. Ignored if `affinity` is set | `""` | +| `msgTopologyOperator.nodeAffinityPreset.values` | Node label values to match. Ignored if `affinity` is set | `[]` | +| `msgTopologyOperator.affinity` | Affinity for RabbitMQ Messaging Topology Operator pods assignment | `{}` | +| `msgTopologyOperator.nodeSelector` | Node labels for RabbitMQ Messaging Topology Operator pods assignment | `{}` | +| `msgTopologyOperator.tolerations` | Tolerations for RabbitMQ Messaging Topology Operator pods assignment | `[]` | +| `msgTopologyOperator.updateStrategy.type` | RabbitMQ Messaging Topology Operator statefulset strategy type | `RollingUpdate` | +| `msgTopologyOperator.priorityClassName` | RabbitMQ Messaging Topology Operator pods' priorityClassName | `""` | +| `msgTopologyOperator.lifecycleHooks` | for the RabbitMQ Messaging Topology Operator container(s) to automate configuration before or after startup | `{}` | +| `msgTopologyOperator.containerPorts.metrics` | RabbitMQ Messaging Topology Operator container port (used for metrics) | `8080` | +| `msgTopologyOperator.extraEnvVars` | Array with extra environment variables to add to RabbitMQ Messaging Topology Operator nodes | `[]` | +| `msgTopologyOperator.extraEnvVarsCM` | Name of existing ConfigMap containing extra env vars for RabbitMQ Messaging Topology Operator nodes | `""` | +| `msgTopologyOperator.extraEnvVarsSecret` | Name of existing Secret containing extra env vars for RabbitMQ Messaging Topology Operator nodes | `""` | +| `msgTopologyOperator.extraVolumes` | Optionally specify extra list of additional volumes for the RabbitMQ Messaging Topology Operator pod(s) | `[]` | +| `msgTopologyOperator.extraVolumeMounts` | Optionally specify extra list of additional volumeMounts for the RabbitMQ Messaging Topology Operator container(s) | `[]` | +| `msgTopologyOperator.sidecars` | Add additional sidecar containers to the RabbitMQ Messaging Topology Operator pod(s) | `[]` | +| `msgTopologyOperator.initContainers` | Add additional init containers to the RabbitMQ Messaging Topology Operator pod(s) | `[]` | +| `msgTopologyOperator.service.type` | RabbitMQ Messaging Topology Operator webhook service type | `ClusterIP` | +| `msgTopologyOperator.service.ports.webhook` | RabbitMQ Messaging Topology Operator webhook service HTTP port | `443` | +| `msgTopologyOperator.service.nodePorts.http` | Node port for HTTP | `""` | +| `msgTopologyOperator.service.clusterIP` | RabbitMQ Messaging Topology Operator webhook service Cluster IP | `""` | +| `msgTopologyOperator.service.loadBalancerIP` | RabbitMQ Messaging Topology Operator webhook service Load Balancer IP | `""` | +| `msgTopologyOperator.service.extraPorts` | Extra ports to expose (normally used with the `sidecar` value) | `[]` | +| `msgTopologyOperator.service.loadBalancerSourceRanges` | RabbitMQ Messaging Topology Operator webhook service Load Balancer sources | `[]` | +| `msgTopologyOperator.service.externalTrafficPolicy` | RabbitMQ Messaging Topology Operator webhook service external traffic policy | `Cluster` | +| `msgTopologyOperator.service.annotations` | Additional custom annotations for RabbitMQ Messaging Topology Operator webhook service | `{}` | +| `msgTopologyOperator.service.sessionAffinity` | Session Affinity for Kubernetes service, can be "None" or "ClientIP" | `None` | +| `msgTopologyOperator.service.sessionAffinityConfig` | Additional settings for the sessionAffinity | `{}` | +| `msgTopologyOperator.networkPolicy.enabled` | Specifies whether a NetworkPolicy should be created | `true` | +| `msgTopologyOperator.networkPolicy.kubeAPIServerPorts` | List of possible endpoints to kube-apiserver (limit to your cluster settings to increase security) | `[]` | +| `msgTopologyOperator.networkPolicy.allowExternal` | Don't require injector label for connections | `true` | +| `msgTopologyOperator.networkPolicy.allowExternalEgress` | Allow the pod to access any range of port and all destinations. | `true` | +| `msgTopologyOperator.networkPolicy.extraIngress` | Add extra ingress rules to the NetworkPolicy | `[]` | +| `msgTopologyOperator.networkPolicy.extraEgress` | Add extra ingress rules to the NetworkPolicy | `[]` | +| `msgTopologyOperator.networkPolicy.ingressNSMatchLabels` | Labels to match to allow traffic from other namespaces | `{}` | +| `msgTopologyOperator.networkPolicy.ingressNSPodMatchLabels` | Pod labels to match to allow traffic from other namespaces | `{}` | +| `msgTopologyOperator.rbac.create` | Specifies whether RBAC resources should be created | `true` | +| `msgTopologyOperator.rbac.clusterRole.customRules` | Define custom access rules for the ClusterRole | `[]` | +| `msgTopologyOperator.rbac.clusterRole.extraRules` | Define extra access rules for the ClusterRole. This has no effect if customerRules is a non-empty array. | `[]` | +| `msgTopologyOperator.serviceAccount.create` | Specifies whether a ServiceAccount should be created | `true` | +| `msgTopologyOperator.serviceAccount.name` | The name of the ServiceAccount to use. | `""` | +| `msgTopologyOperator.serviceAccount.annotations` | Add annotations | `{}` | +| `msgTopologyOperator.serviceAccount.automountServiceAccountToken` | Automount API credentials for a service account. | `false` | + +### RabbitMQ Messaging Topology Operator parameters + +| Name | Description | Value | +| -------------------------------------------------------------- | ---------------------------------------------------------------------------------- | ------------------------ | +| `msgTopologyOperator.metrics.service.enabled` | Create a service for accessing the metrics endpoint | `false` | +| `msgTopologyOperator.metrics.service.type` | RabbitMQ Cluster Operator metrics service type | `ClusterIP` | +| `msgTopologyOperator.metrics.service.ports.http` | RabbitMQ Cluster Operator metrics service HTTP port | `80` | +| `msgTopologyOperator.metrics.service.nodePorts.http` | Node port for HTTP | `""` | +| `msgTopologyOperator.metrics.service.clusterIP` | RabbitMQ Cluster Operator metrics service Cluster IP | `""` | +| `msgTopologyOperator.metrics.service.extraPorts` | Extra ports to expose (normally used with the `sidecar` value) | `[]` | +| `msgTopologyOperator.metrics.service.loadBalancerIP` | RabbitMQ Cluster Operator metrics service Load Balancer IP | `""` | +| `msgTopologyOperator.metrics.service.loadBalancerSourceRanges` | RabbitMQ Cluster Operator metrics service Load Balancer sources | `[]` | +| `msgTopologyOperator.metrics.service.externalTrafficPolicy` | RabbitMQ Cluster Operator metrics service external traffic policy | `Cluster` | +| `msgTopologyOperator.metrics.service.annotations` | Additional custom annotations for RabbitMQ Cluster Operator metrics service | `{}` | +| `msgTopologyOperator.metrics.service.sessionAffinity` | Session Affinity for Kubernetes service, can be "None" or "ClientIP" | `None` | +| `msgTopologyOperator.metrics.service.sessionAffinityConfig` | Additional settings for the sessionAffinity | `{}` | +| `msgTopologyOperator.metrics.serviceMonitor.enabled` | Specify if a servicemonitor will be deployed for prometheus-operator | `false` | +| `msgTopologyOperator.metrics.serviceMonitor.namespace` | Namespace which Prometheus is running in | `""` | +| `msgTopologyOperator.metrics.serviceMonitor.jobLabel` | Specify the jobLabel to use for the prometheus-operator | `app.kubernetes.io/name` | +| `msgTopologyOperator.metrics.serviceMonitor.selector` | Prometheus instance selector labels | `{}` | +| `msgTopologyOperator.metrics.serviceMonitor.honorLabels` | Honor metrics labels | `false` | +| `msgTopologyOperator.metrics.serviceMonitor.scrapeTimeout` | Timeout after which the scrape is ended | `""` | +| `msgTopologyOperator.metrics.serviceMonitor.interval` | Scrape interval. If not set, the Prometheus default scrape interval is used | `""` | +| `msgTopologyOperator.metrics.serviceMonitor.metricRelabelings` | Specify additional relabeling of metrics | `[]` | +| `msgTopologyOperator.metrics.serviceMonitor.relabelings` | Specify general relabeling | `[]` | +| `msgTopologyOperator.metrics.serviceMonitor.labels` | Extra labels for the ServiceMonitor | `{}` | +| `msgTopologyOperator.metrics.podMonitor.enabled` | Create PodMonitor Resource for scraping metrics using PrometheusOperator | `false` | +| `msgTopologyOperator.metrics.podMonitor.jobLabel` | Specify the jobLabel to use for the prometheus-operator | `app.kubernetes.io/name` | +| `msgTopologyOperator.metrics.podMonitor.namespace` | Namespace which Prometheus is running in | `""` | +| `msgTopologyOperator.metrics.podMonitor.honorLabels` | Honor metrics labels | `false` | +| `msgTopologyOperator.metrics.podMonitor.selector` | Prometheus instance selector labels | `{}` | +| `msgTopologyOperator.metrics.podMonitor.interval` | Specify the interval at which metrics should be scraped | `30s` | +| `msgTopologyOperator.metrics.podMonitor.scrapeTimeout` | Specify the timeout after which the scrape is ended | `30s` | +| `msgTopologyOperator.metrics.podMonitor.additionalLabels` | Additional labels that can be used so PodMonitors will be discovered by Prometheus | `{}` | +| `msgTopologyOperator.metrics.podMonitor.relabelings` | Specify general relabeling | `[]` | +| `msgTopologyOperator.metrics.podMonitor.metricRelabelings` | Specify additional relabeling of metrics | `[]` | + +### cert-manager parameters + +| Name | Description | Value | +| ---------------- | ----------------------------------------------------------------- | ------- | +| `useCertManager` | Deploy cert-manager objects (Issuer and Certificate) for webhooks | `false` | + +The above parameters map to the env variables defined in [bitnami/rabbitmq-cluster-operator](https://github.com/bitnami/containers/tree/main/bitnami/rabbitmq-cluster-operator). For more information please refer to the [bitnami/rabbitmq-cluster-operator](https://github.com/bitnami/containers/tree/main/bitnami/rabbitmq-cluster-operator) image documentation. + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, + +```console +helm install my-release \ + --set livenessProbe.enabled=false \ + oci://REGISTRY_NAME/REPOSITORY_NAME/rabbitmq-cluster-operator +``` + +> Note: You need to substitute the placeholders `REGISTRY_NAME` and `REPOSITORY_NAME` with a reference to your Helm chart registry and repository. For example, in the case of Bitnami, you need to use `REGISTRY_NAME=registry-1.docker.io` and `REPOSITORY_NAME=bitnamicharts`. + +The above command disables the Operator liveness probes. + +Alternatively, a YAML file that specifies the values for the above parameters can be provided while installing the chart. For example, + +```console +helm install my-release -f values.yaml oci://REGISTRY_NAME/REPOSITORY_NAME/rabbitmq-cluster-operator +``` + +> Note: You need to substitute the placeholders `REGISTRY_NAME` and `REPOSITORY_NAME` with a reference to your Helm chart registry and repository. For example, in the case of Bitnami, you need to use `REGISTRY_NAME=registry-1.docker.io` and `REPOSITORY_NAME=bitnamicharts`. +> **Tip**: You can use the default [values.yaml](https://github.com/bitnami/charts/tree/main/bitnami/rabbitmq-cluster-operator/values.yaml) + +## Troubleshooting + +Find more information about how to deal with common errors related to Bitnami's Helm charts in [this troubleshooting guide](https://docs.bitnami.com/general/how-to/troubleshoot-helm-chart-issues). + +## Upgrading + +### Upgrading CRDs + +By design, the `helm upgrade` command will not upgrade the `CustomResourceDefinition` objects, as stated in their [official documentation](https://helm.sh/docs/chart_best_practices/custom_resource_definitions/#some-caveats-and-explanations). This is done to avoid the potential risks of upgrading CRD objects, such as data loss. + +In order to upgrade the CRD objects, perform the following steps: + +- Perform a backup of your running RabbitMQ instances following the [official documentation](https://www.rabbitmq.com/backup.html). + +- Execute the following commands (replace the VERSION placeholder): + +```console +helm fetch bitnami/rabbitmq-cluster-operator --version VERSION +tar xf rabbitmq-cluster-operator-VERSION.tar.gz +kubectl apply -f rabbitmq-cluster-operator/crds +``` + +### To 4.0.0 + +This major bump changes the following security defaults: + +- `resourcesPreset` is changed from `none` to the minimum size working in our test suites (NOTE: `resourcesPreset` is not meant for production usage, but `resources` adapted to your use case). +- `global.compatibility.openshift.adaptSecurityContext` is changed from `disabled` to `auto`. + +This could potentially break any customization or init scripts used in your deployment. If this is the case, change the default values to the previous ones. + +### To 2.0.0 + +This new version adds the following components: + +- RabbitMQ Messaging Topology Operator: all the settings are inside the `msgTopologyOperator` section. +- RabbitMQ Default User Credential Updater sidecar: this enables Hashicorp Vault integration for all `RabbitMQCluster` instances. +- `cert-manager` subchart: this is necessary for the RabbitMQ Messaging Topology Webhooks to work. + +As a breaking change, all `rabbitmq-cluster-operator` deployment values were moved to the `clusterOperator` section. + +No issues are expected during upgrades. + +### To 1.0.0 + +The CRD was updated according to the latest changes in the upstream project. Thanks to the improvements in the latest changes, the CRD is not templated anymore and can be placed under the `crds` directory following [Helm best practices for CRDS](https://helm.sh/docs/chart_best_practices/custom_resource_definitions/). + +You need to manually delete the old CRD before upgrading the release. + +```console +kubectl delete crd rabbitmqclusters.rabbitmq.com +helm upgrade my-release oci://REGISTRY_NAME/REPOSITORY_NAME/rabbitmq-cluster-operator +``` + +> Note: You need to substitute the placeholders `REGISTRY_NAME` and `REPOSITORY_NAME` with a reference to your Helm chart registry and repository. For example, in the case of Bitnami, you need to use `REGISTRY_NAME=registry-1.docker.io` and `REPOSITORY_NAME=bitnamicharts`. + +## License + +Copyright © 2024 Broadcom. The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. \ No newline at end of file diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/.helmignore b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/.helmignore new file mode 100644 index 000000000..d0e10845d --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/.helmignore @@ -0,0 +1,26 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ +# img folder +img/ +# Changelog +CHANGELOG.md diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/Chart.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/Chart.yaml new file mode 100644 index 000000000..dabd80681 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/Chart.yaml @@ -0,0 +1,23 @@ +annotations: + category: Infrastructure + licenses: Apache-2.0 +apiVersion: v2 +appVersion: 2.20.5 +description: A Library Helm Chart for grouping common logic between bitnami charts. + This chart is not deployable by itself. +home: https://bitnami.com +icon: https://bitnami.com/downloads/logos/bitnami-mark.png +keywords: +- common +- helper +- template +- function +- bitnami +maintainers: +- name: Broadcom, Inc. All Rights Reserved. + url: https://github.com/bitnami/charts +name: common +sources: +- https://github.com/bitnami/charts/tree/main/bitnami/common +type: library +version: 2.20.5 diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/README.md b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/README.md new file mode 100644 index 000000000..fee26c991 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/README.md @@ -0,0 +1,235 @@ +# Bitnami Common Library Chart + +A [Helm Library Chart](https://helm.sh/docs/topics/library_charts/#helm) for grouping common logic between Bitnami charts. + +## TL;DR + +```yaml +dependencies: + - name: common + version: 2.x.x + repository: oci://registry-1.docker.io/bitnamicharts +``` + +```console +helm dependency update +``` + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "common.names.fullname" . }} +data: + myvalue: "Hello World" +``` + +Looking to use our applications in production? Try [VMware Tanzu Application Catalog](https://bitnami.com/enterprise), the commercial edition of the Bitnami catalog. + +## Introduction + +This chart provides a common template helpers which can be used to develop new charts using [Helm](https://helm.sh) package manager. + +Bitnami charts can be used with [Kubeapps](https://kubeapps.dev/) for deployment and management of Helm Charts in clusters. + +## Prerequisites + +- Kubernetes 1.23+ +- Helm 3.8.0+ + +## Parameters + +## Special input schemas + +### ImageRoot + +```yaml +registry: + type: string + description: Docker registry where the image is located + example: docker.io + +repository: + type: string + description: Repository and image name + example: bitnami/nginx + +tag: + type: string + description: image tag + example: 1.16.1-debian-10-r63 + +pullPolicy: + type: string + description: Specify a imagePullPolicy. Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' + +pullSecrets: + type: array + items: + type: string + description: Optionally specify an array of imagePullSecrets (evaluated as templates). + +debug: + type: boolean + description: Set to true if you would like to see extra information on logs + example: false + +## An instance would be: +# registry: docker.io +# repository: bitnami/nginx +# tag: 1.16.1-debian-10-r63 +# pullPolicy: IfNotPresent +# debug: false +``` + +### Persistence + +```yaml +enabled: + type: boolean + description: Whether enable persistence. + example: true + +storageClass: + type: string + description: Ghost data Persistent Volume Storage Class, If set to "-", storageClassName: "" which disables dynamic provisioning. + example: "-" + +accessMode: + type: string + description: Access mode for the Persistent Volume Storage. + example: ReadWriteOnce + +size: + type: string + description: Size the Persistent Volume Storage. + example: 8Gi + +path: + type: string + description: Path to be persisted. + example: /bitnami + +## An instance would be: +# enabled: true +# storageClass: "-" +# accessMode: ReadWriteOnce +# size: 8Gi +# path: /bitnami +``` + +### ExistingSecret + +```yaml +name: + type: string + description: Name of the existing secret. + example: mySecret +keyMapping: + description: Mapping between the expected key name and the name of the key in the existing secret. + type: object + +## An instance would be: +# name: mySecret +# keyMapping: +# password: myPasswordKey +``` + +#### Example of use + +When we store sensitive data for a deployment in a secret, some times we want to give to users the possibility of using theirs existing secrets. + +```yaml +# templates/secret.yaml +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "common.names.fullname" . }} + labels: + app: {{ include "common.names.fullname" . }} +type: Opaque +data: + password: {{ .Values.password | b64enc | quote }} + +# templates/dpl.yaml +--- +... + env: + - name: PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "common.secrets.name" (dict "existingSecret" .Values.existingSecret "context" $) }} + key: {{ include "common.secrets.key" (dict "existingSecret" .Values.existingSecret "key" "password") }} +... + +# values.yaml +--- +name: mySecret +keyMapping: + password: myPasswordKey +``` + +### ValidateValue + +#### NOTES.txt + +```console +{{- $validateValueConf00 := (dict "valueKey" "path.to.value00" "secret" "secretName" "field" "password-00") -}} +{{- $validateValueConf01 := (dict "valueKey" "path.to.value01" "secret" "secretName" "field" "password-01") -}} + +{{ include "common.validations.values.multiple.empty" (dict "required" (list $validateValueConf00 $validateValueConf01) "context" $) }} +``` + +If we force those values to be empty we will see some alerts + +```console +helm install test mychart --set path.to.value00="",path.to.value01="" + 'path.to.value00' must not be empty, please add '--set path.to.value00=$PASSWORD_00' to the command. To get the current value: + + export PASSWORD_00=$(kubectl get secret --namespace default secretName -o jsonpath="{.data.password-00}" | base64 -d) + + 'path.to.value01' must not be empty, please add '--set path.to.value01=$PASSWORD_01' to the command. To get the current value: + + export PASSWORD_01=$(kubectl get secret --namespace default secretName -o jsonpath="{.data.password-01}" | base64 -d) +``` + +## Upgrading + +### To 1.0.0 + +[On November 13, 2020, Helm v2 support was formally finished](https://github.com/helm/charts#status-of-the-project), this major version is the result of the required changes applied to the Helm Chart to be able to incorporate the different features added in Helm v3 and to be consistent with the Helm project itself regarding the Helm v2 EOL. + +#### What changes were introduced in this major version? + +- Previous versions of this Helm Chart use `apiVersion: v1` (installable by both Helm 2 and 3), this Helm Chart was updated to `apiVersion: v2` (installable by Helm 3 only). [Here](https://helm.sh/docs/topics/charts/#the-apiversion-field) you can find more information about the `apiVersion` field. +- Use `type: library`. [Here](https://v3.helm.sh/docs/faq/#library-chart-support) you can find more information. +- The different fields present in the *Chart.yaml* file has been ordered alphabetically in a homogeneous way for all the Bitnami Helm Charts + +#### Considerations when upgrading to this version + +- If you want to upgrade to this version from a previous one installed with Helm v3, you shouldn't face any issues +- If you want to upgrade to this version using Helm v2, this scenario is not supported as this version doesn't support Helm v2 anymore +- If you installed the previous version with Helm v2 and wants to upgrade to this version with Helm v3, please refer to the [official Helm documentation](https://helm.sh/docs/topics/v2_v3_migration/#migration-use-cases) about migrating from Helm v2 to v3 + +#### Useful links + +- +- +- + +## License + +Copyright © 2024 Broadcom. The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_affinities.tpl b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_affinities.tpl new file mode 100644 index 000000000..c2d290792 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_affinities.tpl @@ -0,0 +1,139 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} + +{{/* +Return a soft nodeAffinity definition +{{ include "common.affinities.nodes.soft" (dict "key" "FOO" "values" (list "BAR" "BAZ")) -}} +*/}} +{{- define "common.affinities.nodes.soft" -}} +preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: {{ .key }} + operator: In + values: + {{- range .values }} + - {{ . | quote }} + {{- end }} + weight: 1 +{{- end -}} + +{{/* +Return a hard nodeAffinity definition +{{ include "common.affinities.nodes.hard" (dict "key" "FOO" "values" (list "BAR" "BAZ")) -}} +*/}} +{{- define "common.affinities.nodes.hard" -}} +requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: {{ .key }} + operator: In + values: + {{- range .values }} + - {{ . | quote }} + {{- end }} +{{- end -}} + +{{/* +Return a nodeAffinity definition +{{ include "common.affinities.nodes" (dict "type" "soft" "key" "FOO" "values" (list "BAR" "BAZ")) -}} +*/}} +{{- define "common.affinities.nodes" -}} + {{- if eq .type "soft" }} + {{- include "common.affinities.nodes.soft" . -}} + {{- else if eq .type "hard" }} + {{- include "common.affinities.nodes.hard" . -}} + {{- end -}} +{{- end -}} + +{{/* +Return a topologyKey definition +{{ include "common.affinities.topologyKey" (dict "topologyKey" "BAR") -}} +*/}} +{{- define "common.affinities.topologyKey" -}} +{{ .topologyKey | default "kubernetes.io/hostname" -}} +{{- end -}} + +{{/* +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" $) -}} +*/}} +{{- define "common.affinities.pods.soft" -}} +{{- $component := default "" .component -}} +{{- $customLabels := default (dict) .customLabels -}} +{{- $extraMatchLabels := default (dict) .extraMatchLabels -}} +{{- $extraPodAffinityTerms := default (list) .extraPodAffinityTerms -}} +preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: {{- (include "common.labels.matchLabels" ( dict "customLabels" $customLabels "context" .context )) | nindent 10 }} + {{- if not (empty $component) }} + {{ printf "app.kubernetes.io/component: %s" $component }} + {{- end }} + {{- range $key, $value := $extraMatchLabels }} + {{ $key }}: {{ $value | quote }} + {{- end }} + topologyKey: {{ include "common.affinities.topologyKey" (dict "topologyKey" .topologyKey) }} + weight: 1 + {{- range $extraPodAffinityTerms }} + - podAffinityTerm: + labelSelector: + matchLabels: {{- (include "common.labels.matchLabels" ( dict "customLabels" $customLabels "context" $.context )) | nindent 10 }} + {{- if not (empty $component) }} + {{ printf "app.kubernetes.io/component: %s" $component }} + {{- end }} + {{- range $key, $value := .extraMatchLabels }} + {{ $key }}: {{ $value | quote }} + {{- end }} + topologyKey: {{ include "common.affinities.topologyKey" (dict "topologyKey" .topologyKey) }} + weight: {{ .weight | default 1 -}} + {{- end -}} +{{- end -}} + +{{/* +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" $) -}} +*/}} +{{- define "common.affinities.pods.hard" -}} +{{- $component := default "" .component -}} +{{- $customLabels := default (dict) .customLabels -}} +{{- $extraMatchLabels := default (dict) .extraMatchLabels -}} +{{- $extraPodAffinityTerms := default (list) .extraPodAffinityTerms -}} +requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: {{- (include "common.labels.matchLabels" ( dict "customLabels" $customLabels "context" .context )) | nindent 8 }} + {{- if not (empty $component) }} + {{ printf "app.kubernetes.io/component: %s" $component }} + {{- end }} + {{- range $key, $value := $extraMatchLabels }} + {{ $key }}: {{ $value | quote }} + {{- end }} + topologyKey: {{ include "common.affinities.topologyKey" (dict "topologyKey" .topologyKey) }} + {{- range $extraPodAffinityTerms }} + - labelSelector: + matchLabels: {{- (include "common.labels.matchLabels" ( dict "customLabels" $customLabels "context" $.context )) | nindent 8 }} + {{- if not (empty $component) }} + {{ printf "app.kubernetes.io/component: %s" $component }} + {{- end }} + {{- range $key, $value := .extraMatchLabels }} + {{ $key }}: {{ $value | quote }} + {{- end }} + topologyKey: {{ include "common.affinities.topologyKey" (dict "topologyKey" .topologyKey) }} + {{- end -}} +{{- end -}} + +{{/* +Return a podAffinity/podAntiAffinity definition +{{ include "common.affinities.pods" (dict "type" "soft" "key" "FOO" "values" (list "BAR" "BAZ")) -}} +*/}} +{{- define "common.affinities.pods" -}} + {{- if eq .type "soft" }} + {{- include "common.affinities.pods.soft" . -}} + {{- else if eq .type "hard" }} + {{- include "common.affinities.pods.hard" . -}} + {{- end -}} +{{- end -}} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_capabilities.tpl b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_capabilities.tpl new file mode 100644 index 000000000..2fe81d32d --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_capabilities.tpl @@ -0,0 +1,229 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} + +{{/* +Return the target Kubernetes version +*/}} +{{- define "common.capabilities.kubeVersion" -}} +{{- default (default .Capabilities.KubeVersion.Version .Values.kubeVersion) ((.Values.global).kubeVersion) -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for poddisruptionbudget. +*/}} +{{- define "common.capabilities.policy.apiVersion" -}} +{{- $kubeVersion := include "common.capabilities.kubeVersion" . -}} +{{- if and (not (empty $kubeVersion)) (semverCompare "<1.21-0" $kubeVersion) -}} +{{- print "policy/v1beta1" -}} +{{- else -}} +{{- print "policy/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for networkpolicy. +*/}} +{{- define "common.capabilities.networkPolicy.apiVersion" -}} +{{- $kubeVersion := include "common.capabilities.kubeVersion" . -}} +{{- if and (not (empty $kubeVersion)) (semverCompare "<1.7-0" $kubeVersion) -}} +{{- print "extensions/v1beta1" -}} +{{- else -}} +{{- print "networking.k8s.io/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for cronjob. +*/}} +{{- define "common.capabilities.cronjob.apiVersion" -}} +{{- $kubeVersion := include "common.capabilities.kubeVersion" . -}} +{{- if and (not (empty $kubeVersion)) (semverCompare "<1.21-0" $kubeVersion) -}} +{{- print "batch/v1beta1" -}} +{{- else -}} +{{- print "batch/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for daemonset. +*/}} +{{- define "common.capabilities.daemonset.apiVersion" -}} +{{- $kubeVersion := include "common.capabilities.kubeVersion" . -}} +{{- if and (not (empty $kubeVersion)) (semverCompare "<1.14-0" $kubeVersion) -}} +{{- print "extensions/v1beta1" -}} +{{- else -}} +{{- print "apps/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for deployment. +*/}} +{{- define "common.capabilities.deployment.apiVersion" -}} +{{- $kubeVersion := include "common.capabilities.kubeVersion" . -}} +{{- if and (not (empty $kubeVersion)) (semverCompare "<1.14-0" $kubeVersion) -}} +{{- print "extensions/v1beta1" -}} +{{- else -}} +{{- print "apps/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for statefulset. +*/}} +{{- define "common.capabilities.statefulset.apiVersion" -}} +{{- $kubeVersion := include "common.capabilities.kubeVersion" . -}} +{{- if and (not (empty $kubeVersion)) (semverCompare "<1.14-0" $kubeVersion) -}} +{{- print "apps/v1beta1" -}} +{{- else -}} +{{- print "apps/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for ingress. +*/}} +{{- define "common.capabilities.ingress.apiVersion" -}} +{{- $kubeVersion := include "common.capabilities.kubeVersion" . -}} +{{- if (.Values.ingress).apiVersion -}} +{{- .Values.ingress.apiVersion -}} +{{- else if and (not (empty $kubeVersion)) (semverCompare "<1.14-0" $kubeVersion) -}} +{{- print "extensions/v1beta1" -}} +{{- else if and (not (empty $kubeVersion)) (semverCompare "<1.19-0" $kubeVersion) -}} +{{- print "networking.k8s.io/v1beta1" -}} +{{- else -}} +{{- print "networking.k8s.io/v1" -}} +{{- end }} +{{- end -}} + +{{/* +Return the appropriate apiVersion for RBAC resources. +*/}} +{{- define "common.capabilities.rbac.apiVersion" -}} +{{- $kubeVersion := include "common.capabilities.kubeVersion" . -}} +{{- if and (not (empty $kubeVersion)) (semverCompare "<1.17-0" $kubeVersion) -}} +{{- print "rbac.authorization.k8s.io/v1beta1" -}} +{{- else -}} +{{- print "rbac.authorization.k8s.io/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for CRDs. +*/}} +{{- define "common.capabilities.crd.apiVersion" -}} +{{- $kubeVersion := include "common.capabilities.kubeVersion" . -}} +{{- if and (not (empty $kubeVersion)) (semverCompare "<1.19-0" $kubeVersion) -}} +{{- print "apiextensions.k8s.io/v1beta1" -}} +{{- else -}} +{{- print "apiextensions.k8s.io/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for APIService. +*/}} +{{- define "common.capabilities.apiService.apiVersion" -}} +{{- $kubeVersion := include "common.capabilities.kubeVersion" . -}} +{{- if and (not (empty $kubeVersion)) (semverCompare "<1.10-0" $kubeVersion) -}} +{{- print "apiregistration.k8s.io/v1beta1" -}} +{{- else -}} +{{- print "apiregistration.k8s.io/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for Horizontal Pod Autoscaler. +*/}} +{{- define "common.capabilities.hpa.apiVersion" -}} +{{- $kubeVersion := include "common.capabilities.kubeVersion" .context -}} +{{- if and (not (empty $kubeVersion)) (semverCompare "<1.23-0" $kubeVersion) -}} +{{- if .beta2 -}} +{{- print "autoscaling/v2beta2" -}} +{{- else -}} +{{- print "autoscaling/v2beta1" -}} +{{- end -}} +{{- else -}} +{{- print "autoscaling/v2" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for Vertical Pod Autoscaler. +*/}} +{{- define "common.capabilities.vpa.apiVersion" -}} +{{- $kubeVersion := include "common.capabilities.kubeVersion" .context -}} +{{- if and (not (empty $kubeVersion)) (semverCompare "<1.23-0" $kubeVersion) -}} +{{- if .beta2 -}} +{{- print "autoscaling/v2beta2" -}} +{{- else -}} +{{- print "autoscaling/v2beta1" -}} +{{- end -}} +{{- else -}} +{{- print "autoscaling/v2" -}} +{{- end -}} +{{- end -}} + +{{/* +Returns true if PodSecurityPolicy is supported +*/}} +{{- define "common.capabilities.psp.supported" -}} +{{- $kubeVersion := include "common.capabilities.kubeVersion" . -}} +{{- if or (empty $kubeVersion) (semverCompare "<1.25-0" $kubeVersion) -}} + {{- true -}} +{{- end -}} +{{- end -}} + +{{/* +Returns true if AdmissionConfiguration is supported +*/}} +{{- define "common.capabilities.admissionConfiguration.supported" -}} +{{- $kubeVersion := include "common.capabilities.kubeVersion" . -}} +{{- if or (empty $kubeVersion) (not (semverCompare "<1.23-0" $kubeVersion)) -}} + {{- true -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for AdmissionConfiguration. +*/}} +{{- define "common.capabilities.admissionConfiguration.apiVersion" -}} +{{- $kubeVersion := include "common.capabilities.kubeVersion" . -}} +{{- if and (not (empty $kubeVersion)) (semverCompare "<1.23-0" $kubeVersion) -}} +{{- print "apiserver.config.k8s.io/v1alpha1" -}} +{{- else if and (not (empty $kubeVersion)) (semverCompare "<1.25-0" $kubeVersion) -}} +{{- print "apiserver.config.k8s.io/v1beta1" -}} +{{- else -}} +{{- print "apiserver.config.k8s.io/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for PodSecurityConfiguration. +*/}} +{{- define "common.capabilities.podSecurityConfiguration.apiVersion" -}} +{{- $kubeVersion := include "common.capabilities.kubeVersion" . -}} +{{- if and (not (empty $kubeVersion)) (semverCompare "<1.23-0" $kubeVersion) -}} +{{- print "pod-security.admission.config.k8s.io/v1alpha1" -}} +{{- else if and (not (empty $kubeVersion)) (semverCompare "<1.25-0" $kubeVersion) -}} +{{- print "pod-security.admission.config.k8s.io/v1beta1" -}} +{{- else -}} +{{- print "pod-security.admission.config.k8s.io/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Returns true if the used Helm version is 3.3+. +A way to check the used Helm version was not introduced until version 3.3.0 with .Capabilities.HelmVersion, which contains an additional "{}}" structure. +This check is introduced as a regexMatch instead of {{ if .Capabilities.HelmVersion }} because checking for the key HelmVersion in <3.3 results in a "interface not found" error. +**To be removed when the catalog's minimun Helm version is 3.3** +*/}} +{{- define "common.capabilities.supportsHelmVersion" -}} +{{- if regexMatch "{(v[0-9])*[^}]*}}$" (.Capabilities | toString ) }} + {{- true -}} +{{- end -}} +{{- end -}} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_compatibility.tpl b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_compatibility.tpl new file mode 100644 index 000000000..eb4061d7d --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_compatibility.tpl @@ -0,0 +1,42 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} + +{{/* +Return true if the detected platform is Openshift +Usage: +{{- include "common.compatibility.isOpenshift" . -}} +*/}} +{{- define "common.compatibility.isOpenshift" -}} +{{- if .Capabilities.APIVersions.Has "security.openshift.io/v1" -}} +{{- true -}} +{{- end -}} +{{- end -}} + +{{/* +Render a compatible securityContext depending on the platform. By default it is maintained as it is. In other platforms like Openshift we remove default user/group values that do not work out of the box with the restricted-v1 SCC +Usage: +{{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.containerSecurityContext "context" $) -}} +*/}} +{{- define "common.compatibility.renderSecurityContext" -}} +{{- $adaptedContext := .secContext -}} + +{{- if (((.context.Values.global).compatibility).openshift) -}} + {{- if or (eq .context.Values.global.compatibility.openshift.adaptSecurityContext "force") (and (eq .context.Values.global.compatibility.openshift.adaptSecurityContext "auto") (include "common.compatibility.isOpenshift" .context)) -}} + {{/* Remove incompatible user/group values that do not work in Openshift out of the box */}} + {{- $adaptedContext = omit $adaptedContext "fsGroup" "runAsUser" "runAsGroup" -}} + {{- if not .secContext.seLinuxOptions -}} + {{/* If it is an empty object, we remove it from the resulting context because it causes validation issues */}} + {{- $adaptedContext = omit $adaptedContext "seLinuxOptions" -}} + {{- end -}} + {{- end -}} +{{- end -}} +{{/* Remove fields that are disregarded when running the container in privileged mode */}} +{{- if $adaptedContext.privileged -}} + {{- $adaptedContext = omit $adaptedContext "capabilities" "seLinuxOptions" -}} +{{- end -}} +{{- omit $adaptedContext "enabled" | toYaml -}} +{{- end -}} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_errors.tpl b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_errors.tpl new file mode 100644 index 000000000..e96536519 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_errors.tpl @@ -0,0 +1,28 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Through error when upgrading using empty passwords values that must not be empty. + +Usage: +{{- $validationError00 := include "common.validations.values.single.empty" (dict "valueKey" "path.to.password00" "secret" "secretName" "field" "password-00") -}} +{{- $validationError01 := include "common.validations.values.single.empty" (dict "valueKey" "path.to.password01" "secret" "secretName" "field" "password-01") -}} +{{ include "common.errors.upgrade.passwords.empty" (dict "validationErrors" (list $validationError00 $validationError01) "context" $) }} + +Required password params: + - validationErrors - String - Required. List of validation strings to be return, if it is empty it won't throw error. + - context - Context - Required. Parent context. +*/}} +{{- define "common.errors.upgrade.passwords.empty" -}} + {{- $validationErrors := join "" .validationErrors -}} + {{- if and $validationErrors .context.Release.IsUpgrade -}} + {{- $errorString := "\nPASSWORDS ERROR: You must provide your current passwords when upgrading the release." -}} + {{- $errorString = print $errorString "\n Note that even after reinstallation, old credentials may be needed as they may be kept in persistent volume claims." -}} + {{- $errorString = print $errorString "\n Further information can be obtained at https://docs.bitnami.com/general/how-to/troubleshoot-helm-chart-issues/#credential-errors-while-upgrading-chart-releases" -}} + {{- $errorString = print $errorString "\n%s" -}} + {{- printf $errorString $validationErrors | fail -}} + {{- end -}} +{{- end -}} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_images.tpl b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_images.tpl new file mode 100644 index 000000000..6821b1ce2 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_images.tpl @@ -0,0 +1,109 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +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 ) }} +*/}} +{{- define "common.images.image" -}} +{{- $registryName := default .imageRoot.registry ((.global).imageRegistry) -}} +{{- $repositoryName := .imageRoot.repository -}} +{{- $separator := ":" -}} +{{- $termination := .imageRoot.tag | toString -}} + +{{- if .imageRoot.digest }} + {{- $separator = "@" -}} + {{- $termination = .imageRoot.digest | toString -}} +{{- end -}} +{{- if $registryName }} + {{- printf "%s/%s%s%s" $registryName $repositoryName $separator $termination -}} +{{- else -}} + {{- printf "%s%s%s" $repositoryName $separator $termination -}} +{{- end -}} +{{- end -}} + +{{/* +Return the proper Docker Image Registry Secret Names (deprecated: use common.images.renderPullSecrets instead) +{{ include "common.images.pullSecrets" ( dict "images" (list .Values.path.to.the.image1, .Values.path.to.the.image2) "global" .Values.global) }} +*/}} +{{- define "common.images.pullSecrets" -}} + {{- $pullSecrets := list }} + + {{- range ((.global).imagePullSecrets) -}} + {{- if kindIs "map" . -}} + {{- $pullSecrets = append $pullSecrets .name -}} + {{- else -}} + {{- $pullSecrets = append $pullSecrets . -}} + {{- end }} + {{- end -}} + + {{- range .images -}} + {{- range .pullSecrets -}} + {{- if kindIs "map" . -}} + {{- $pullSecrets = append $pullSecrets .name -}} + {{- else -}} + {{- $pullSecrets = append $pullSecrets . -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- if (not (empty $pullSecrets)) -}} +imagePullSecrets: + {{- range $pullSecrets | uniq }} + - name: {{ . }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Return the proper Docker Image Registry Secret Names evaluating values as templates +{{ include "common.images.renderPullSecrets" ( dict "images" (list .Values.path.to.the.image1, .Values.path.to.the.image2) "context" $) }} +*/}} +{{- define "common.images.renderPullSecrets" -}} + {{- $pullSecrets := list }} + {{- $context := .context }} + + {{- range (($context.Values.global).imagePullSecrets) -}} + {{- if kindIs "map" . -}} + {{- $pullSecrets = append $pullSecrets (include "common.tplvalues.render" (dict "value" .name "context" $context)) -}} + {{- else -}} + {{- $pullSecrets = append $pullSecrets (include "common.tplvalues.render" (dict "value" . "context" $context)) -}} + {{- end -}} + {{- end -}} + + {{- range .images -}} + {{- range .pullSecrets -}} + {{- if kindIs "map" . -}} + {{- $pullSecrets = append $pullSecrets (include "common.tplvalues.render" (dict "value" .name "context" $context)) -}} + {{- else -}} + {{- $pullSecrets = append $pullSecrets (include "common.tplvalues.render" (dict "value" . "context" $context)) -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- if (not (empty $pullSecrets)) -}} +imagePullSecrets: + {{- range $pullSecrets | uniq }} + - name: {{ . }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Return the proper image version (ingores image revision/prerelease info & fallbacks to chart appVersion) +{{ include "common.images.version" ( dict "imageRoot" .Values.path.to.the.image "chart" .Chart ) }} +*/}} +{{- define "common.images.version" -}} +{{- $imageTag := .imageRoot.tag | toString -}} +{{/* regexp from https://github.com/Masterminds/semver/blob/23f51de38a0866c5ef0bfc42b3f735c73107b700/version.go#L41-L44 */}} +{{- if regexMatch `^([0-9]+)(\.[0-9]+)?(\.[0-9]+)?(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?$` $imageTag -}} + {{- $version := semver $imageTag -}} + {{- printf "%d.%d.%d" $version.Major $version.Minor $version.Patch -}} +{{- else -}} + {{- print .chart.AppVersion -}} +{{- end -}} +{{- end -}} + diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_ingress.tpl b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_ingress.tpl new file mode 100644 index 000000000..7d2b87985 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_ingress.tpl @@ -0,0 +1,73 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} + +{{/* +Generate backend entry that is compatible with all Kubernetes API versions. + +Usage: +{{ include "common.ingress.backend" (dict "serviceName" "backendName" "servicePort" "backendPort" "context" $) }} + +Params: + - serviceName - String. Name of an existing service backend + - servicePort - String/Int. Port name (or number) of the service. It will be translated to different yaml depending if it is a string or an integer. + - context - Dict - Required. The context for the template evaluation. +*/}} +{{- define "common.ingress.backend" -}} +{{- $apiVersion := (include "common.capabilities.ingress.apiVersion" .context) -}} +{{- if or (eq $apiVersion "extensions/v1beta1") (eq $apiVersion "networking.k8s.io/v1beta1") -}} +serviceName: {{ .serviceName }} +servicePort: {{ .servicePort }} +{{- else -}} +service: + name: {{ .serviceName }} + port: + {{- if typeIs "string" .servicePort }} + name: {{ .servicePort }} + {{- else if or (typeIs "int" .servicePort) (typeIs "float64" .servicePort) }} + number: {{ .servicePort | int }} + {{- end }} +{{- end -}} +{{- end -}} + +{{/* +Print "true" if the API pathType field is supported +Usage: +{{ include "common.ingress.supportsPathType" . }} +*/}} +{{- define "common.ingress.supportsPathType" -}} +{{- if (semverCompare "<1.18-0" (include "common.capabilities.kubeVersion" .)) -}} +{{- print "false" -}} +{{- else -}} +{{- print "true" -}} +{{- end -}} +{{- end -}} + +{{/* +Returns true if the ingressClassname field is supported +Usage: +{{ include "common.ingress.supportsIngressClassname" . }} +*/}} +{{- define "common.ingress.supportsIngressClassname" -}} +{{- if semverCompare "<1.18-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "false" -}} +{{- else -}} +{{- print "true" -}} +{{- end -}} +{{- end -}} + +{{/* +Return true if cert-manager required annotations for TLS signed +certificates are set in the Ingress annotations +Ref: https://cert-manager.io/docs/usage/ingress/#supported-annotations +Usage: +{{ include "common.ingress.certManagerRequest" ( dict "annotations" .Values.path.to.the.ingress.annotations ) }} +*/}} +{{- define "common.ingress.certManagerRequest" -}} +{{ if or (hasKey .annotations "cert-manager.io/cluster-issuer") (hasKey .annotations "cert-manager.io/issuer") (hasKey .annotations "kubernetes.io/tls-acme") }} + {{- true -}} +{{- end -}} +{{- end -}} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_labels.tpl b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_labels.tpl new file mode 100644 index 000000000..0a0cc5488 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_labels.tpl @@ -0,0 +1,46 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} + +{{/* +Kubernetes standard labels +{{ include "common.labels.standard" (dict "customLabels" .Values.commonLabels "context" $) -}} +*/}} +{{- define "common.labels.standard" -}} +{{- if and (hasKey . "customLabels") (hasKey . "context") -}} +{{- $default := dict "app.kubernetes.io/name" (include "common.names.name" .context) "helm.sh/chart" (include "common.names.chart" .context) "app.kubernetes.io/instance" .context.Release.Name "app.kubernetes.io/managed-by" .context.Release.Service -}} +{{- with .context.Chart.AppVersion -}} +{{- $_ := set $default "app.kubernetes.io/version" . -}} +{{- end -}} +{{ template "common.tplvalues.merge" (dict "values" (list .customLabels $default) "context" .context) }} +{{- else -}} +app.kubernetes.io/name: {{ include "common.names.name" . }} +helm.sh/chart: {{ include "common.names.chart" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- with .Chart.AppVersion }} +app.kubernetes.io/version: {{ . | quote }} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Labels used on immutable fields such as deploy.spec.selector.matchLabels or svc.spec.selector +{{ include "common.labels.matchLabels" (dict "customLabels" .Values.podLabels "context" $) -}} + +We don't want to loop over custom labels appending them to the selector +since it's very likely that it will break deployments, services, etc. +However, it's important to overwrite the standard labels if the user +overwrote them on metadata.labels fields. +*/}} +{{- define "common.labels.matchLabels" -}} +{{- if and (hasKey . "customLabels") (hasKey . "context") -}} +{{ merge (pick (include "common.tplvalues.render" (dict "value" .customLabels "context" .context) | fromYaml) "app.kubernetes.io/name" "app.kubernetes.io/instance") (dict "app.kubernetes.io/name" (include "common.names.name" .context) "app.kubernetes.io/instance" .context.Release.Name ) | toYaml }} +{{- else -}} +app.kubernetes.io/name: {{ include "common.names.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end -}} +{{- end -}} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_names.tpl b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_names.tpl new file mode 100644 index 000000000..ba8395685 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_names.tpl @@ -0,0 +1,71 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "common.names.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "common.names.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "common.names.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create a default fully qualified dependency name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +Usage: +{{ include "common.names.dependency.fullname" (dict "chartName" "dependency-chart-name" "chartValues" .Values.dependency-chart "context" $) }} +*/}} +{{- define "common.names.dependency.fullname" -}} +{{- if .chartValues.fullnameOverride -}} +{{- .chartValues.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .chartName .chartValues.nameOverride -}} +{{- if contains $name .context.Release.Name -}} +{{- .context.Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .context.Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Allow the release namespace to be overridden for multi-namespace deployments in combined charts. +*/}} +{{- define "common.names.namespace" -}} +{{- default .Release.Namespace .Values.namespaceOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a fully qualified app name adding the installation's namespace. +*/}} +{{- define "common.names.fullname.namespace" -}} +{{- printf "%s-%s" (include "common.names.fullname" .) (include "common.names.namespace" .) | trunc 63 | trimSuffix "-" -}} +{{- end -}} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_resources.tpl b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_resources.tpl new file mode 100644 index 000000000..d8a43e1c2 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_resources.tpl @@ -0,0 +1,50 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} + +{{/* +Return a resource request/limit object based on a given preset. +These presets are for basic testing and not meant to be used in production +{{ include "common.resources.preset" (dict "type" "nano") -}} +*/}} +{{- define "common.resources.preset" -}} +{{/* The limits are the requests increased by 50% (except ephemeral-storage and xlarge/2xlarge sizes)*/}} +{{- $presets := dict + "nano" (dict + "requests" (dict "cpu" "100m" "memory" "128Mi" "ephemeral-storage" "50Mi") + "limits" (dict "cpu" "150m" "memory" "192Mi" "ephemeral-storage" "2Gi") + ) + "micro" (dict + "requests" (dict "cpu" "250m" "memory" "256Mi" "ephemeral-storage" "50Mi") + "limits" (dict "cpu" "375m" "memory" "384Mi" "ephemeral-storage" "2Gi") + ) + "small" (dict + "requests" (dict "cpu" "500m" "memory" "512Mi" "ephemeral-storage" "50Mi") + "limits" (dict "cpu" "750m" "memory" "768Mi" "ephemeral-storage" "2Gi") + ) + "medium" (dict + "requests" (dict "cpu" "500m" "memory" "1024Mi" "ephemeral-storage" "50Mi") + "limits" (dict "cpu" "750m" "memory" "1536Mi" "ephemeral-storage" "2Gi") + ) + "large" (dict + "requests" (dict "cpu" "1.0" "memory" "2048Mi" "ephemeral-storage" "50Mi") + "limits" (dict "cpu" "1.5" "memory" "3072Mi" "ephemeral-storage" "2Gi") + ) + "xlarge" (dict + "requests" (dict "cpu" "1.0" "memory" "3072Mi" "ephemeral-storage" "50Mi") + "limits" (dict "cpu" "3.0" "memory" "6144Mi" "ephemeral-storage" "2Gi") + ) + "2xlarge" (dict + "requests" (dict "cpu" "1.0" "memory" "3072Mi" "ephemeral-storage" "50Mi") + "limits" (dict "cpu" "6.0" "memory" "12288Mi" "ephemeral-storage" "2Gi") + ) + }} +{{- if hasKey $presets .type -}} +{{- index $presets .type | toYaml -}} +{{- else -}} +{{- printf "ERROR: Preset key '%s' invalid. Allowed values are %s" .type (join "," (keys $presets)) | fail -}} +{{- end -}} +{{- end -}} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_secrets.tpl b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_secrets.tpl new file mode 100644 index 000000000..e87575a88 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_secrets.tpl @@ -0,0 +1,182 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Generate secret name. + +Usage: +{{ include "common.secrets.name" (dict "existingSecret" .Values.path.to.the.existingSecret "defaultNameSuffix" "mySuffix" "context" $) }} + +Params: + - existingSecret - ExistingSecret/String - Optional. The path to the existing secrets in the values.yaml given by the user + to be used instead of the default one. Allows for it to be of type String (just the secret name) for backwards compatibility. + +info: https://github.com/bitnami/charts/tree/main/bitnami/common#existingsecret + - defaultNameSuffix - String - Optional. It is used only if we have several secrets in the same deployment. + - context - Dict - Required. The context for the template evaluation. +*/}} +{{- define "common.secrets.name" -}} +{{- $name := (include "common.names.fullname" .context) -}} + +{{- if .defaultNameSuffix -}} +{{- $name = printf "%s-%s" $name .defaultNameSuffix | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- with .existingSecret -}} +{{- if not (typeIs "string" .) -}} +{{- with .name -}} +{{- $name = . -}} +{{- end -}} +{{- else -}} +{{- $name = . -}} +{{- end -}} +{{- end -}} + +{{- printf "%s" $name -}} +{{- end -}} + +{{/* +Generate secret key. + +Usage: +{{ include "common.secrets.key" (dict "existingSecret" .Values.path.to.the.existingSecret "key" "keyName") }} + +Params: + - existingSecret - ExistingSecret/String - Optional. The path to the existing secrets in the values.yaml given by the user + to be used instead of the default one. Allows for it to be of type String (just the secret name) for backwards compatibility. + +info: https://github.com/bitnami/charts/tree/main/bitnami/common#existingsecret + - key - String - Required. Name of the key in the secret. +*/}} +{{- define "common.secrets.key" -}} +{{- $key := .key -}} + +{{- if .existingSecret -}} + {{- if not (typeIs "string" .existingSecret) -}} + {{- if .existingSecret.keyMapping -}} + {{- $key = index .existingSecret.keyMapping $.key -}} + {{- end -}} + {{- end }} +{{- end -}} + +{{- printf "%s" $key -}} +{{- end -}} + +{{/* +Generate secret password or retrieve one if already created. + +Usage: +{{ include "common.secrets.passwords.manage" (dict "secret" "secret-name" "key" "keyName" "providedValues" (list "path.to.password1" "path.to.password2") "length" 10 "strong" false "chartName" "chartName" "context" $) }} + +Params: + - secret - String - Required - Name of the 'Secret' resource where the password is stored. + - key - String - Required - Name of the key in the secret. + - providedValues - List - Required - The path to the validating value in the values.yaml, e.g: "mysql.password". Will pick first parameter with a defined value. + - length - int - Optional - Length of the generated random password. + - strong - Boolean - Optional - Whether to add symbols to the generated random password. + - chartName - String - Optional - Name of the chart used when said chart is deployed as a subchart. + - context - Context - Required - Parent context. + - failOnNew - Boolean - Optional - Default to true. If set to false, skip errors adding new keys to existing secrets. + - skipB64enc - Boolean - Optional - Default to false. If set to true, no the secret will not be base64 encrypted. + - skipQuote - Boolean - Optional - Default to false. If set to true, no quotes will be added around the secret. +The order in which this function returns a secret password: + 1. Already existing 'Secret' resource + (If a 'Secret' resource is found under the name provided to the 'secret' parameter to this function and that 'Secret' resource contains a key with the name passed as the 'key' parameter to this function then the value of this existing secret password will be returned) + 2. Password provided via the values.yaml + (If one of the keys passed to the 'providedValues' parameter to this function is a valid path to a key in the values.yaml and has a value, the value of the first key with a value will be returned) + 3. Randomly generated secret password + (A new random secret password with the length specified in the 'length' parameter will be generated and returned) + +*/}} +{{- define "common.secrets.passwords.manage" -}} + +{{- $password := "" }} +{{- $subchart := "" }} +{{- $chartName := default "" .chartName }} +{{- $passwordLength := default 10 .length }} +{{- $providedPasswordKey := include "common.utils.getKeyFromList" (dict "keys" .providedValues "context" $.context) }} +{{- $providedPasswordValue := include "common.utils.getValueFromKey" (dict "key" $providedPasswordKey "context" $.context) }} +{{- $secretData := (lookup "v1" "Secret" (include "common.names.namespace" .context) .secret).data }} +{{- if $secretData }} + {{- if hasKey $secretData .key }} + {{- $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 }} + {{- $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 }} +{{- end -}} +{{- if not .skipB64enc }} +{{- $password = $password | b64enc }} +{{- end -}} +{{- if .skipQuote -}} +{{- printf "%s" $password -}} +{{- else -}} +{{- printf "%s" $password | quote -}} +{{- end -}} +{{- end -}} + +{{/* +Reuses the value from an existing secret, otherwise sets its value to a default value. + +Usage: +{{ include "common.secrets.lookup" (dict "secret" "secret-name" "key" "keyName" "defaultValue" .Values.myValue "context" $) }} + +Params: + - secret - String - Required - Name of the 'Secret' resource where the password is stored. + - key - String - Required - Name of the key in the secret. + - defaultValue - String - Required - The path to the validating value in the values.yaml, e.g: "mysql.password". Will pick first parameter with a defined value. + - context - Context - Required - Parent context. + +*/}} +{{- define "common.secrets.lookup" -}} +{{- $value := "" -}} +{{- $secretData := (lookup "v1" "Secret" (include "common.names.namespace" .context) .secret).data -}} +{{- if and $secretData (hasKey $secretData .key) -}} + {{- $value = index $secretData .key -}} +{{- else if .defaultValue -}} + {{- $value = .defaultValue | toString | b64enc -}} +{{- end -}} +{{- if $value -}} +{{- printf "%s" $value -}} +{{- end -}} +{{- end -}} + +{{/* +Returns whether a previous generated secret already exists + +Usage: +{{ include "common.secrets.exists" (dict "secret" "secret-name" "context" $) }} + +Params: + - secret - String - Required - Name of the 'Secret' resource where the password is stored. + - context - Context - Required - Parent context. +*/}} +{{- define "common.secrets.exists" -}} +{{- $secret := (lookup "v1" "Secret" (include "common.names.namespace" .context) .secret) }} +{{- if $secret }} + {{- true -}} +{{- end -}} +{{- end -}} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_storage.tpl b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_storage.tpl new file mode 100644 index 000000000..aa75856c0 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_storage.tpl @@ -0,0 +1,21 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} + +{{/* +Return the proper Storage Class +{{ include "common.storage.class" ( dict "persistence" .Values.path.to.the.persistence "global" $) }} +*/}} +{{- define "common.storage.class" -}} +{{- $storageClass := (.global).storageClass | default .persistence.storageClass | default (.global).defaultStorageClass | default "" -}} +{{- if $storageClass -}} + {{- if (eq "-" $storageClass) -}} + {{- printf "storageClassName: \"\"" -}} + {{- else -}} + {{- printf "storageClassName: %s" $storageClass -}} + {{- end -}} +{{- end -}} +{{- end -}} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_tplvalues.tpl b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_tplvalues.tpl new file mode 100644 index 000000000..c84d72c80 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_tplvalues.tpl @@ -0,0 +1,38 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Renders a value that contains template perhaps with scope if the scope is present. +Usage: +{{ include "common.tplvalues.render" ( dict "value" .Values.path.to.the.Value "context" $ ) }} +{{ include "common.tplvalues.render" ( dict "value" .Values.path.to.the.Value "context" $ "scope" $app ) }} +*/}} +{{- define "common.tplvalues.render" -}} +{{- $value := typeIs "string" .value | ternary .value (.value | toYaml) }} +{{- if contains "{{" (toJson .value) }} + {{- if .scope }} + {{- tpl (cat "{{- with $.RelativeScope -}}" $value "{{- end }}") (merge (dict "RelativeScope" .scope) .context) }} + {{- else }} + {{- tpl $value .context }} + {{- end }} +{{- else }} + {{- $value }} +{{- end }} +{{- end -}} + +{{/* +Merge a list of values that contains template after rendering them. +Merge precedence is consistent with http://masterminds.github.io/sprig/dicts.html#merge-mustmerge +Usage: +{{ include "common.tplvalues.merge" ( dict "values" (list .Values.path.to.the.Value1 .Values.path.to.the.Value2) "context" $ ) }} +*/}} +{{- define "common.tplvalues.merge" -}} +{{- $dst := dict -}} +{{- range .values -}} +{{- $dst = include "common.tplvalues.render" (dict "value" . "context" $.context "scope" $.scope) | fromYaml | merge $dst -}} +{{- end -}} +{{ $dst | toYaml }} +{{- end -}} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_utils.tpl b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_utils.tpl new file mode 100644 index 000000000..d53c74aa2 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_utils.tpl @@ -0,0 +1,77 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Print instructions to get a secret value. +Usage: +{{ include "common.utils.secret.getvalue" (dict "secret" "secret-name" "field" "secret-value-field" "context" $) }} +*/}} +{{- define "common.utils.secret.getvalue" -}} +{{- $varname := include "common.utils.fieldToEnvVar" . -}} +export {{ $varname }}=$(kubectl get secret --namespace {{ include "common.names.namespace" .context | quote }} {{ .secret }} -o jsonpath="{.data.{{ .field }}}" | base64 -d) +{{- end -}} + +{{/* +Build env var name given a field +Usage: +{{ include "common.utils.fieldToEnvVar" dict "field" "my-password" }} +*/}} +{{- define "common.utils.fieldToEnvVar" -}} + {{- $fieldNameSplit := splitList "-" .field -}} + {{- $upperCaseFieldNameSplit := list -}} + + {{- range $fieldNameSplit -}} + {{- $upperCaseFieldNameSplit = append $upperCaseFieldNameSplit ( upper . ) -}} + {{- end -}} + + {{ join "_" $upperCaseFieldNameSplit }} +{{- end -}} + +{{/* +Gets a value from .Values given +Usage: +{{ include "common.utils.getValueFromKey" (dict "key" "path.to.key" "context" $) }} +*/}} +{{- define "common.utils.getValueFromKey" -}} +{{- $splitKey := splitList "." .key -}} +{{- $value := "" -}} +{{- $latestObj := $.context.Values -}} +{{- range $splitKey -}} + {{- if not $latestObj -}} + {{- printf "please review the entire path of '%s' exists in values" $.key | fail -}} + {{- end -}} + {{- $value = ( index $latestObj . ) -}} + {{- $latestObj = $value -}} +{{- end -}} +{{- printf "%v" (default "" $value) -}} +{{- end -}} + +{{/* +Returns first .Values key with a defined value or first of the list if all non-defined +Usage: +{{ include "common.utils.getKeyFromList" (dict "keys" (list "path.to.key1" "path.to.key2") "context" $) }} +*/}} +{{- define "common.utils.getKeyFromList" -}} +{{- $key := first .keys -}} +{{- $reverseKeys := reverse .keys }} +{{- range $reverseKeys }} + {{- $value := include "common.utils.getValueFromKey" (dict "key" . "context" $.context ) }} + {{- if $value -}} + {{- $key = . }} + {{- end -}} +{{- end -}} +{{- printf "%s" $key -}} +{{- end -}} + +{{/* +Checksum a template at "path" containing a *single* resource (ConfigMap,Secret) for use in pod annotations, excluding the metadata (see #18376). +Usage: +{{ include "common.utils.checksumTemplate" (dict "path" "/configmap.yaml" "context" $) }} +*/}} +{{- define "common.utils.checksumTemplate" -}} +{{- $obj := include (print .context.Template.BasePath .path) .context | fromYaml -}} +{{ omit $obj "apiVersion" "kind" "metadata" | toYaml | sha256sum }} +{{- end -}} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_warnings.tpl b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_warnings.tpl new file mode 100644 index 000000000..e4dbecde2 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/_warnings.tpl @@ -0,0 +1,109 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Warning about using rolling tag. +Usage: +{{ include "common.warnings.rollingTag" .Values.path.to.the.imageRoot }} +*/}} +{{- define "common.warnings.rollingTag" -}} + +{{- if and (contains "bitnami/" .repository) (not (.tag | toString | regexFind "-r\\d+$|sha256:")) }} +WARNING: Rolling tag detected ({{ .repository }}:{{ .tag }}), please note that it is strongly recommended to avoid using rolling tags in a production environment. ++info https://docs.vmware.com/en/VMware-Tanzu-Application-Catalog/services/tutorials/GUID-understand-rolling-tags-containers-index.html +{{- end }} +{{- end -}} + +{{/* +Warning about replaced images from the original. +Usage: +{{ include "common.warnings.modifiedImages" (dict "images" (list .Values.path.to.the.imageRoot) "context" $) }} +*/}} +{{- define "common.warnings.modifiedImages" -}} +{{- $affectedImages := list -}} +{{- $printMessage := false -}} +{{- $originalImages := .context.Chart.Annotations.images -}} +{{- range .images -}} + {{- $fullImageName := printf (printf "%s/%s:%s" .registry .repository .tag) -}} + {{- if not (contains $fullImageName $originalImages) }} + {{- $affectedImages = append $affectedImages (printf "%s/%s:%s" .registry .repository .tag) -}} + {{- $printMessage = true -}} + {{- end -}} +{{- end -}} +{{- if $printMessage }} + +⚠ SECURITY WARNING: Original containers have been substituted. This Helm chart was designed, tested, and validated on multiple platforms using a specific set of Bitnami and Tanzu Application Catalog containers. Substituting other containers is likely to cause degraded security and performance, broken chart features, and missing environment variables. + +Substituted images detected: +{{- range $affectedImages }} + - {{ . }} +{{- end }} +{{- end -}} +{{- end -}} + +{{/* +Warning about not setting the resource object in all deployments. +Usage: +{{ include "common.warnings.resources" (dict "sections" (list "path1" "path2") context $) }} +Example: +{{- include "common.warnings.resources" (dict "sections" (list "csiProvider.provider" "server" "volumePermissions" "") "context" $) }} +The list in the example assumes that the following values exist: + - csiProvider.provider.resources + - server.resources + - volumePermissions.resources + - resources +*/}} +{{- define "common.warnings.resources" -}} +{{- $values := .context.Values -}} +{{- $printMessage := false -}} +{{ $affectedSections := list -}} +{{- range .sections -}} + {{- if eq . "" -}} + {{/* Case where the resources section is at the root (one main deployment in the chart) */}} + {{- if not (index $values "resources") -}} + {{- $affectedSections = append $affectedSections "resources" -}} + {{- $printMessage = true -}} + {{- end -}} + {{- else -}} + {{/* Case where the are multiple resources sections (more than one main deployment in the chart) */}} + {{- $keys := split "." . -}} + {{/* We iterate through the different levels until arriving to the resource section. Example: a.b.c.resources */}} + {{- $section := $values -}} + {{- range $keys -}} + {{- $section = index $section . -}} + {{- end -}} + {{- if not (index $section "resources") -}} + {{/* If the section has enabled=false or replicaCount=0, do not include it */}} + {{- if and (hasKey $section "enabled") -}} + {{- if index $section "enabled" -}} + {{/* enabled=true */}} + {{- $affectedSections = append $affectedSections (printf "%s.resources" .) -}} + {{- $printMessage = true -}} + {{- end -}} + {{- else if and (hasKey $section "replicaCount") -}} + {{/* We need a casting to int because number 0 is not treated as an int by default */}} + {{- if (gt (index $section "replicaCount" | int) 0) -}} + {{/* replicaCount > 0 */}} + {{- $affectedSections = append $affectedSections (printf "%s.resources" .) -}} + {{- $printMessage = true -}} + {{- end -}} + {{- else -}} + {{/* Default case, add it to the affected sections */}} + {{- $affectedSections = append $affectedSections (printf "%s.resources" .) -}} + {{- $printMessage = true -}} + {{- end -}} + {{- end -}} + {{- end -}} +{{- end -}} +{{- if $printMessage }} + +WARNING: There are "resources" sections in the chart not set. Using "resourcesPreset" is not recommended for production. For production installations, please set the following values according to your workload needs: +{{- range $affectedSections }} + - {{ . }} +{{- end }} ++info https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ +{{- end -}} +{{- end -}} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/validations/_cassandra.tpl b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/validations/_cassandra.tpl new file mode 100644 index 000000000..3f41ff8fc --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/validations/_cassandra.tpl @@ -0,0 +1,77 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +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. + +Usage: +{{ include "common.cassandra.values.existingSecret" (dict "context" $) }} +Params: + - subchart - Boolean - Optional. Whether Cassandra is used as subchart or not. Default: false +*/}} +{{- define "common.cassandra.values.existingSecret" -}} + {{- if .subchart -}} + {{- .context.Values.cassandra.dbUser.existingSecret | quote -}} + {{- else -}} + {{- .context.Values.dbUser.existingSecret | quote -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled cassandra. + +Usage: +{{ include "common.cassandra.values.enabled" (dict "context" $) }} +*/}} +{{- define "common.cassandra.values.enabled" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.cassandra.enabled -}} + {{- else -}} + {{- printf "%v" (not .context.Values.enabled) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for the key dbUser + +Usage: +{{ include "common.cassandra.values.key.dbUser" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether Cassandra is used as subchart or not. Default: false +*/}} +{{- define "common.cassandra.values.key.dbUser" -}} + {{- if .subchart -}} + cassandra.dbUser + {{- else -}} + dbUser + {{- end -}} +{{- end -}} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/validations/_mariadb.tpl b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/validations/_mariadb.tpl new file mode 100644 index 000000000..6ea8c0f45 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/validations/_mariadb.tpl @@ -0,0 +1,108 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Validate MariaDB required passwords are not empty. + +Usage: +{{ include "common.validations.values.mariadb.passwords" (dict "secret" "secretName" "subchart" false "context" $) }} +Params: + - secret - String - Required. Name of the secret where MariaDB values are stored, e.g: "mysql-passwords-secret" + - subchart - Boolean - Optional. Whether MariaDB is used as subchart or not. Default: false +*/}} +{{- define "common.validations.values.mariadb.passwords" -}} + {{- $existingSecret := include "common.mariadb.values.auth.existingSecret" . -}} + {{- $enabled := include "common.mariadb.values.enabled" . -}} + {{- $architecture := include "common.mariadb.values.architecture" . -}} + {{- $authPrefix := include "common.mariadb.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" "mariadb-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" "mariadb-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredPassword -}} + {{- end -}} + + {{- if (eq $architecture "replication") -}} + {{- $requiredReplicationPassword := dict "valueKey" $valueKeyReplicationPassword "secret" .secret "field" "mariadb-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. + +Usage: +{{ include "common.mariadb.values.auth.existingSecret" (dict "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MariaDB is used as subchart or not. Default: false +*/}} +{{- define "common.mariadb.values.auth.existingSecret" -}} + {{- if .subchart -}} + {{- .context.Values.mariadb.auth.existingSecret | quote -}} + {{- else -}} + {{- .context.Values.auth.existingSecret | quote -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled mariadb. + +Usage: +{{ include "common.mariadb.values.enabled" (dict "context" $) }} +*/}} +{{- define "common.mariadb.values.enabled" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.mariadb.enabled -}} + {{- else -}} + {{- printf "%v" (not .context.Values.enabled) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for architecture + +Usage: +{{ include "common.mariadb.values.architecture" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MariaDB is used as subchart or not. Default: false +*/}} +{{- define "common.mariadb.values.architecture" -}} + {{- if .subchart -}} + {{- .context.Values.mariadb.architecture -}} + {{- else -}} + {{- .context.Values.architecture -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for the key auth + +Usage: +{{ include "common.mariadb.values.key.auth" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MariaDB is used as subchart or not. Default: false +*/}} +{{- define "common.mariadb.values.key.auth" -}} + {{- if .subchart -}} + mariadb.auth + {{- else -}} + auth + {{- end -}} +{{- end -}} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/validations/_mongodb.tpl b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/validations/_mongodb.tpl new file mode 100644 index 000000000..d4cd38cbb --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/validations/_mongodb.tpl @@ -0,0 +1,113 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +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. + +Usage: +{{ include "common.mongodb.values.auth.existingSecret" (dict "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MongoDb is used as subchart or not. Default: false +*/}} +{{- define "common.mongodb.values.auth.existingSecret" -}} + {{- if .subchart -}} + {{- .context.Values.mongodb.auth.existingSecret | quote -}} + {{- else -}} + {{- .context.Values.auth.existingSecret | quote -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled mongodb. + +Usage: +{{ include "common.mongodb.values.enabled" (dict "context" $) }} +*/}} +{{- define "common.mongodb.values.enabled" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.mongodb.enabled -}} + {{- else -}} + {{- printf "%v" (not .context.Values.enabled) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for the key auth + +Usage: +{{ include "common.mongodb.values.key.auth" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MongoDB® is used as subchart or not. Default: false +*/}} +{{- define "common.mongodb.values.key.auth" -}} + {{- if .subchart -}} + mongodb.auth + {{- else -}} + auth + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for architecture + +Usage: +{{ include "common.mongodb.values.architecture" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MongoDB® is used as subchart or not. Default: false +*/}} +{{- define "common.mongodb.values.architecture" -}} + {{- if .subchart -}} + {{- .context.Values.mongodb.architecture -}} + {{- else -}} + {{- .context.Values.architecture -}} + {{- end -}} +{{- end -}} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/validations/_mysql.tpl b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/validations/_mysql.tpl new file mode 100644 index 000000000..924812a93 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/validations/_mysql.tpl @@ -0,0 +1,108 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +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. + +Usage: +{{ include "common.mysql.values.auth.existingSecret" (dict "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MySQL is used as subchart or not. Default: false +*/}} +{{- define "common.mysql.values.auth.existingSecret" -}} + {{- if .subchart -}} + {{- .context.Values.mysql.auth.existingSecret | quote -}} + {{- else -}} + {{- .context.Values.auth.existingSecret | quote -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled mysql. + +Usage: +{{ include "common.mysql.values.enabled" (dict "context" $) }} +*/}} +{{- define "common.mysql.values.enabled" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.mysql.enabled -}} + {{- else -}} + {{- printf "%v" (not .context.Values.enabled) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for architecture + +Usage: +{{ include "common.mysql.values.architecture" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MySQL is used as subchart or not. Default: false +*/}} +{{- define "common.mysql.values.architecture" -}} + {{- if .subchart -}} + {{- .context.Values.mysql.architecture -}} + {{- else -}} + {{- .context.Values.architecture -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for the key auth + +Usage: +{{ include "common.mysql.values.key.auth" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MySQL is used as subchart or not. Default: false +*/}} +{{- define "common.mysql.values.key.auth" -}} + {{- if .subchart -}} + mysql.auth + {{- else -}} + auth + {{- end -}} +{{- end -}} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/validations/_postgresql.tpl b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/validations/_postgresql.tpl new file mode 100644 index 000000000..0fa0b1467 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/validations/_postgresql.tpl @@ -0,0 +1,134 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +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. + +Usage: +{{ include "common.postgresql.values.use.global" (dict "key" "key-of-global" "context" $) }} +Params: + - key - String - Required. Field to be evaluated within global, e.g: "existingSecret" +*/}} +{{- define "common.postgresql.values.use.global" -}} + {{- if .context.Values.global -}} + {{- if .context.Values.global.postgresql -}} + {{- index .context.Values.global.postgresql .key | quote -}} + {{- end -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for existingSecret. + +Usage: +{{ include "common.postgresql.values.existingSecret" (dict "context" $) }} +*/}} +{{- define "common.postgresql.values.existingSecret" -}} + {{- $globalValue := include "common.postgresql.values.use.global" (dict "key" "existingSecret" "context" .context) -}} + + {{- if .subchart -}} + {{- default (.context.Values.postgresql.existingSecret | quote) $globalValue -}} + {{- else -}} + {{- default (.context.Values.existingSecret | quote) $globalValue -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled postgresql. + +Usage: +{{ include "common.postgresql.values.enabled" (dict "context" $) }} +*/}} +{{- define "common.postgresql.values.enabled" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.postgresql.enabled -}} + {{- else -}} + {{- printf "%v" (not .context.Values.enabled) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for the key postgressPassword. + +Usage: +{{ include "common.postgresql.values.key.postgressPassword" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether postgresql is used as subchart or not. Default: false +*/}} +{{- define "common.postgresql.values.key.postgressPassword" -}} + {{- $globalValue := include "common.postgresql.values.use.global" (dict "key" "postgresqlUsername" "context" .context) -}} + + {{- if not $globalValue -}} + {{- if .subchart -}} + postgresql.postgresqlPassword + {{- else -}} + postgresqlPassword + {{- end -}} + {{- else -}} + global.postgresql.postgresqlPassword + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled.replication. + +Usage: +{{ include "common.postgresql.values.enabled.replication" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether postgresql is used as subchart or not. Default: false +*/}} +{{- define "common.postgresql.values.enabled.replication" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.postgresql.replication.enabled -}} + {{- else -}} + {{- printf "%v" .context.Values.replication.enabled -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for the key replication.password. + +Usage: +{{ include "common.postgresql.values.key.replicationPassword" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether postgresql is used as subchart or not. Default: false +*/}} +{{- define "common.postgresql.values.key.replicationPassword" -}} + {{- if .subchart -}} + postgresql.replication.password + {{- else -}} + replication.password + {{- end -}} +{{- end -}} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/validations/_redis.tpl b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/validations/_redis.tpl new file mode 100644 index 000000000..f4778256d --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/validations/_redis.tpl @@ -0,0 +1,81 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +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. + +Usage: +{{ include "common.redis.values.enabled" (dict "context" $) }} +*/}} +{{- define "common.redis.values.enabled" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.redis.enabled -}} + {{- else -}} + {{- printf "%v" (not .context.Values.enabled) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right prefix path for the values + +Usage: +{{ include "common.redis.values.key.prefix" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether redis is used as subchart or not. Default: false +*/}} +{{- define "common.redis.values.keys.prefix" -}} + {{- if .subchart -}}redis.{{- else -}}{{- end -}} +{{- end -}} + +{{/* +Checks whether the redis chart's includes the standarizations (version >= 14) + +Usage: +{{ include "common.redis.values.standarized.version" (dict "context" $) }} +*/}} +{{- define "common.redis.values.standarized.version" -}} + + {{- $standarizedAuth := printf "%s%s" (include "common.redis.values.keys.prefix" .) "auth" -}} + {{- $standarizedAuthValues := include "common.utils.getValueFromKey" (dict "key" $standarizedAuth "context" .context) }} + + {{- if $standarizedAuthValues -}} + {{- true -}} + {{- end -}} +{{- end -}} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/validations/_validations.tpl b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/validations/_validations.tpl new file mode 100644 index 000000000..7cdee6170 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/templates/validations/_validations.tpl @@ -0,0 +1,51 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Validate values must not be empty. + +Usage: +{{- $validateValueConf00 := (dict "valueKey" "path.to.value" "secret" "secretName" "field" "password-00") -}} +{{- $validateValueConf01 := (dict "valueKey" "path.to.value" "secret" "secretName" "field" "password-01") -}} +{{ include "common.validations.values.empty" (dict "required" (list $validateValueConf00 $validateValueConf01) "context" $) }} + +Validate value params: + - valueKey - String - Required. The path to the validating value in the values.yaml, e.g: "mysql.password" + - secret - String - Optional. Name of the secret where the validating value is generated/stored, e.g: "mysql-passwords-secret" + - field - String - Optional. Name of the field in the secret data, e.g: "mysql-password" +*/}} +{{- define "common.validations.values.multiple.empty" -}} + {{- range .required -}} + {{- include "common.validations.values.single.empty" (dict "valueKey" .valueKey "secret" .secret "field" .field "context" $.context) -}} + {{- end -}} +{{- end -}} + +{{/* +Validate a value must not be empty. + +Usage: +{{ include "common.validations.value.empty" (dict "valueKey" "mariadb.password" "secret" "secretName" "field" "my-password" "subchart" "subchart" "context" $) }} + +Validate value params: + - valueKey - String - Required. The path to the validating value in the values.yaml, e.g: "mysql.password" + - secret - String - Optional. Name of the secret where the validating value is generated/stored, e.g: "mysql-passwords-secret" + - field - String - Optional. Name of the field in the secret data, e.g: "mysql-password" + - subchart - String - Optional - Name of the subchart that the validated password is part of. +*/}} +{{- define "common.validations.values.single.empty" -}} + {{- $value := include "common.utils.getValueFromKey" (dict "key" .valueKey "context" .context) }} + {{- $subchart := ternary "" (printf "%s." .subchart) (empty .subchart) }} + + {{- if not $value -}} + {{- $varname := "my-value" -}} + {{- $getCurrentValue := "" -}} + {{- if and .secret .field -}} + {{- $varname = include "common.utils.fieldToEnvVar" . -}} + {{- $getCurrentValue = printf " To get the current value:\n\n %s\n" (include "common.utils.secret.getvalue" .) -}} + {{- end -}} + {{- printf "\n '%s' must not be empty, please add '--set %s%s=$%s' to the command.%s" .valueKey $subchart .valueKey $varname $getCurrentValue -}} + {{- end -}} +{{- end -}} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/values.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/values.yaml new file mode 100644 index 000000000..de2cac57d --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/charts/common/values.yaml @@ -0,0 +1,8 @@ +# Copyright Broadcom, Inc. All Rights Reserved. +# SPDX-License-Identifier: APACHE-2.0 + +## bitnami/common +## It is required by CI/CD tools and processes. +## @skip exampleValue +## +exampleValue: common-chart diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_bindings.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_bindings.yaml new file mode 100644 index 000000000..909cb1746 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_bindings.yaml @@ -0,0 +1,148 @@ +# Source: https://raw.githubusercontent.com/rabbitmq/messaging-topology-operator/v{version}/config/crd/bases/rabbitmq.com_bindings.yaml +# Version: 1.14.2 +# VersionOf: rmq-messaging-topology-operator +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: bindings.rabbitmq.com +spec: + group: rabbitmq.com + names: + categories: + - rabbitmq + kind: Binding + listKind: BindingList + plural: bindings + singular: binding + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + description: Binding is the Schema for the bindings API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: BindingSpec defines the desired state of Binding + properties: + arguments: + description: Cannot be updated + type: object + x-kubernetes-preserve-unknown-fields: true + destination: + description: Cannot be updated + type: string + destinationType: + description: Cannot be updated + enum: + - exchange + - queue + type: string + rabbitmqClusterReference: + description: |- + Reference to the RabbitmqCluster that the binding will be created in. + Required property. + properties: + connectionSecret: + description: |- + Secret contains the http management uri for the RabbitMQ cluster. + The Secret must contain the key `uri`, `username` and `password` or operator will error. + Have to set either name or connectionSecret, but not both. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + type: object + x-kubernetes-map-type: atomic + name: + description: |- + The name of the RabbitMQ cluster to reference. + Have to set either name or connectionSecret, but not both. + type: string + namespace: + description: |- + The namespace of the RabbitMQ cluster to reference. + Defaults to the namespace of the requested resource if omitted. + type: string + type: object + routingKey: + description: Cannot be updated + type: string + source: + description: Cannot be updated + type: string + vhost: + default: / + description: Default to vhost '/'; cannot be updated + type: string + required: + - rabbitmqClusterReference + type: object + status: + description: BindingStatus defines the observed state of Binding + properties: + conditions: + items: + properties: + lastTransitionTime: + description: The last time this Condition status changed. + format: date-time + type: string + message: + description: Full text reason for current status of the condition. + type: string + reason: + description: One word, camel-case reason for current status + of the condition. + type: string + status: + description: True, False, or Unknown + type: string + type: + description: Type indicates the scope of the custom resource + status addressed by the condition. + type: string + required: + - status + - type + type: object + type: array + observedGeneration: + description: |- + observedGeneration is the most recent successful generation observed for this Binding. It corresponds to the + Binding's generation, which is updated on mutation by the API Server. + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_exchanges.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_exchanges.yaml new file mode 100644 index 000000000..0ad6a61bc --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_exchanges.yaml @@ -0,0 +1,146 @@ +# Source: https://raw.githubusercontent.com/rabbitmq/messaging-topology-operator/v{version}/config/crd/bases/rabbitmq.com_exchanges.yaml +# Version: 1.14.2 +# VersionOf: rmq-messaging-topology-operator +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: exchanges.rabbitmq.com +spec: + group: rabbitmq.com + names: + categories: + - rabbitmq + kind: Exchange + listKind: ExchangeList + plural: exchanges + singular: exchange + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + description: Exchange is the Schema for the exchanges API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ExchangeSpec defines the desired state of Exchange + properties: + arguments: + type: object + x-kubernetes-preserve-unknown-fields: true + autoDelete: + description: Cannot be updated + type: boolean + durable: + description: Cannot be updated + type: boolean + name: + description: Required property; cannot be updated + type: string + rabbitmqClusterReference: + description: |- + Reference to the RabbitmqCluster that the exchange will be created in. + Required property. + properties: + connectionSecret: + description: |- + Secret contains the http management uri for the RabbitMQ cluster. + The Secret must contain the key `uri`, `username` and `password` or operator will error. + Have to set either name or connectionSecret, but not both. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + type: object + x-kubernetes-map-type: atomic + name: + description: |- + The name of the RabbitMQ cluster to reference. + Have to set either name or connectionSecret, but not both. + type: string + namespace: + description: |- + The namespace of the RabbitMQ cluster to reference. + Defaults to the namespace of the requested resource if omitted. + type: string + type: object + type: + default: direct + description: Cannot be updated + type: string + vhost: + default: / + description: Default to vhost '/'; cannot be updated + type: string + required: + - name + - rabbitmqClusterReference + type: object + status: + description: ExchangeStatus defines the observed state of Exchange + properties: + conditions: + items: + properties: + lastTransitionTime: + description: The last time this Condition status changed. + format: date-time + type: string + message: + description: Full text reason for current status of the condition. + type: string + reason: + description: One word, camel-case reason for current status + of the condition. + type: string + status: + description: True, False, or Unknown + type: string + type: + description: Type indicates the scope of the custom resource + status addressed by the condition. + type: string + required: + - status + - type + type: object + type: array + observedGeneration: + description: |- + observedGeneration is the most recent successful generation observed for this Exchange. It corresponds to the + Exchange's generation, which is updated on mutation by the API Server. + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_federations.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_federations.yaml new file mode 100644 index 000000000..f61501d3c --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_federations.yaml @@ -0,0 +1,178 @@ +# Source: https://raw.githubusercontent.com/rabbitmq/messaging-topology-operator/v{version}/config/crd/bases/rabbitmq.com_federations.yaml +# Version: 1.14.2 +# VersionOf: rmq-messaging-topology-operator +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: federations.rabbitmq.com +spec: + group: rabbitmq.com + names: + categories: + - rabbitmq + kind: Federation + listKind: FederationList + plural: federations + singular: federation + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + description: Federation is the Schema for the federations API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: |- + FederationSpec defines the desired state of Federation + For how to configure federation upstreams, see: https://www.rabbitmq.com/federation-reference.html. + properties: + ackMode: + enum: + - on-confirm + - on-publish + - no-ack + type: string + exchange: + type: string + expires: + type: integer + maxHops: + type: integer + messageTTL: + type: integer + name: + description: Required property; cannot be updated + type: string + prefetch-count: + type: integer + queue: + type: string + rabbitmqClusterReference: + description: |- + Reference to the RabbitmqCluster that this federation upstream will be created in. + Required property. + properties: + connectionSecret: + description: |- + Secret contains the http management uri for the RabbitMQ cluster. + The Secret must contain the key `uri`, `username` and `password` or operator will error. + Have to set either name or connectionSecret, but not both. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + type: object + x-kubernetes-map-type: atomic + name: + description: |- + The name of the RabbitMQ cluster to reference. + Have to set either name or connectionSecret, but not both. + type: string + namespace: + description: |- + The namespace of the RabbitMQ cluster to reference. + Defaults to the namespace of the requested resource if omitted. + type: string + type: object + reconnectDelay: + type: integer + trustUserId: + type: boolean + uriSecret: + description: |- + Secret contains the AMQP URI(s) for the upstream. + The Secret must contain the key `uri` or operator will error. + `uri` should be one or multiple uris separated by ','. + Required property. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + type: object + x-kubernetes-map-type: atomic + vhost: + default: / + description: Default to vhost '/'; cannot be updated + type: string + required: + - name + - rabbitmqClusterReference + - uriSecret + type: object + status: + description: FederationStatus defines the observed state of Federation + properties: + conditions: + items: + properties: + lastTransitionTime: + description: The last time this Condition status changed. + format: date-time + type: string + message: + description: Full text reason for current status of the condition. + type: string + reason: + description: One word, camel-case reason for current status + of the condition. + type: string + status: + description: True, False, or Unknown + type: string + type: + description: Type indicates the scope of the custom resource + status addressed by the condition. + type: string + required: + - status + - type + type: object + type: array + observedGeneration: + description: |- + observedGeneration is the most recent successful generation observed for this Federation. It corresponds to the + Federation's generation, which is updated on mutation by the API Server. + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_operatorpolicies.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_operatorpolicies.yaml new file mode 100644 index 000000000..7ceb69b2c --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_operatorpolicies.yaml @@ -0,0 +1,163 @@ +# Source: https://raw.githubusercontent.com/rabbitmq/messaging-topology-operator/v{version}/config/crd/bases/rabbitmq.com_operatorpolicies.yaml +# Version: 1.14.2 +# VersionOf: rmq-messaging-topology-operator +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: operatorpolicies.rabbitmq.com +spec: + group: rabbitmq.com + names: + categories: + - rabbitmq + kind: OperatorPolicy + listKind: OperatorPolicyList + plural: operatorpolicies + singular: operatorpolicy + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + description: OperatorPolicy is the Schema for the operator policies API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: |- + OperatorPolicySpec defines the desired state of OperatorPolicy + https://www.rabbitmq.com/parameters.html#operator-policies + properties: + applyTo: + default: queues + description: |- + What this operator policy applies to: 'queues', 'classic_queues', 'quorum_queues', 'streams'. + Default to 'queues'. + enum: + - queues + - classic_queues + - quorum_queues + - streams + type: string + definition: + description: OperatorPolicy definition. Required property. + type: object + x-kubernetes-preserve-unknown-fields: true + name: + description: Required property; cannot be updated + type: string + pattern: + description: |- + Regular expression pattern used to match queues, e.g. "^my-queue$". + Required property. + type: string + priority: + default: 0 + description: |- + Default to '0'. + In the event that more than one operator policy can match a given queue, the operator policy with the greatest priority applies. + type: integer + rabbitmqClusterReference: + description: |- + Reference to the RabbitmqCluster that the operator policy will be created in. + Required property. + properties: + connectionSecret: + description: |- + Secret contains the http management uri for the RabbitMQ cluster. + The Secret must contain the key `uri`, `username` and `password` or operator will error. + Have to set either name or connectionSecret, but not both. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + type: object + x-kubernetes-map-type: atomic + name: + description: |- + The name of the RabbitMQ cluster to reference. + Have to set either name or connectionSecret, but not both. + type: string + namespace: + description: |- + The namespace of the RabbitMQ cluster to reference. + Defaults to the namespace of the requested resource if omitted. + type: string + type: object + vhost: + default: / + description: Default to vhost '/'; cannot be updated + type: string + required: + - definition + - name + - pattern + - rabbitmqClusterReference + type: object + status: + description: OperatorPolicyStatus defines the observed state of OperatorPolicy + properties: + conditions: + items: + properties: + lastTransitionTime: + description: The last time this Condition status changed. + format: date-time + type: string + message: + description: Full text reason for current status of the condition. + type: string + reason: + description: One word, camel-case reason for current status + of the condition. + type: string + status: + description: True, False, or Unknown + type: string + type: + description: Type indicates the scope of the custom resource + status addressed by the condition. + type: string + required: + - status + - type + type: object + type: array + observedGeneration: + description: |- + observedGeneration is the most recent successful generation observed for this OperatorPolicy. It corresponds to the + OperatorPolicy's generation, which is updated on mutation by the API Server. + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_permissions.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_permissions.yaml new file mode 100644 index 000000000..282c52a89 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_permissions.yaml @@ -0,0 +1,165 @@ +# Source: https://raw.githubusercontent.com/rabbitmq/messaging-topology-operator/v{version}/config/crd/bases/rabbitmq.com_permissions.yaml +# Version: 1.14.2 +# VersionOf: rmq-messaging-topology-operator +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: permissions.rabbitmq.com +spec: + group: rabbitmq.com + names: + categories: + - rabbitmq + kind: Permission + listKind: PermissionList + plural: permissions + singular: permission + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + description: Permission is the Schema for the permissions API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: PermissionSpec defines the desired state of Permission + properties: + permissions: + description: |- + Permissions to grant to the user in the specific vhost; required property. + See RabbitMQ doc for more information: https://www.rabbitmq.com/access-control.html#user-management + properties: + configure: + type: string + read: + type: string + write: + type: string + type: object + rabbitmqClusterReference: + description: |- + Reference to the RabbitmqCluster that both the provided user and vhost are. + Required property. + properties: + connectionSecret: + description: |- + Secret contains the http management uri for the RabbitMQ cluster. + The Secret must contain the key `uri`, `username` and `password` or operator will error. + Have to set either name or connectionSecret, but not both. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + type: object + x-kubernetes-map-type: atomic + name: + description: |- + The name of the RabbitMQ cluster to reference. + Have to set either name or connectionSecret, but not both. + type: string + namespace: + description: |- + The namespace of the RabbitMQ cluster to reference. + Defaults to the namespace of the requested resource if omitted. + type: string + type: object + user: + description: Name of an existing user; must provide user or userReference, + else create/update will fail; cannot be updated + type: string + userReference: + description: Reference to an existing user.rabbitmq.com object; must + provide user or userReference, else create/update will fail; cannot + be updated + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + type: object + x-kubernetes-map-type: atomic + vhost: + description: Name of an existing vhost; required property; cannot + be updated + type: string + required: + - permissions + - rabbitmqClusterReference + - vhost + type: object + status: + description: PermissionStatus defines the observed state of Permission + properties: + conditions: + items: + properties: + lastTransitionTime: + description: The last time this Condition status changed. + format: date-time + type: string + message: + description: Full text reason for current status of the condition. + type: string + reason: + description: One word, camel-case reason for current status + of the condition. + type: string + status: + description: True, False, or Unknown + type: string + type: + description: Type indicates the scope of the custom resource + status addressed by the condition. + type: string + required: + - status + - type + type: object + type: array + observedGeneration: + description: |- + observedGeneration is the most recent successful generation observed for this Permission. It corresponds to the + Permission's generation, which is updated on mutation by the API Server. + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_policies.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_policies.yaml new file mode 100644 index 000000000..c6f081731 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_policies.yaml @@ -0,0 +1,165 @@ +# Source: https://raw.githubusercontent.com/rabbitmq/messaging-topology-operator/v{version}/config/crd/bases/rabbitmq.com_policies.yaml +# Version: 1.14.2 +# VersionOf: rmq-messaging-topology-operator +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: policies.rabbitmq.com +spec: + group: rabbitmq.com + names: + categories: + - rabbitmq + kind: Policy + listKind: PolicyList + plural: policies + singular: policy + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + description: Policy is the Schema for the policies API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: |- + PolicySpec defines the desired state of Policy + https://www.rabbitmq.com/parameters.html#policies + properties: + applyTo: + default: all + description: |- + What this policy applies to: 'queues', 'classic_queues', 'quorum_queues', 'streams', 'exchanges', or 'all'. + Default to 'all'. + enum: + - queues + - classic_queues + - quorum_queues + - streams + - exchanges + - all + type: string + definition: + description: Policy definition. Required property. + type: object + x-kubernetes-preserve-unknown-fields: true + name: + description: Required property; cannot be updated + type: string + pattern: + description: |- + Regular expression pattern used to match queues and exchanges, e.g. "^amq.". + Required property. + type: string + priority: + default: 0 + description: |- + Default to '0'. + In the event that more than one policy can match a given exchange or queue, the policy with the greatest priority applies. + type: integer + rabbitmqClusterReference: + description: |- + Reference to the RabbitmqCluster that the policy will be created in. + Required property. + properties: + connectionSecret: + description: |- + Secret contains the http management uri for the RabbitMQ cluster. + The Secret must contain the key `uri`, `username` and `password` or operator will error. + Have to set either name or connectionSecret, but not both. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + type: object + x-kubernetes-map-type: atomic + name: + description: |- + The name of the RabbitMQ cluster to reference. + Have to set either name or connectionSecret, but not both. + type: string + namespace: + description: |- + The namespace of the RabbitMQ cluster to reference. + Defaults to the namespace of the requested resource if omitted. + type: string + type: object + vhost: + default: / + description: Default to vhost '/'; cannot be updated + type: string + required: + - definition + - name + - pattern + - rabbitmqClusterReference + type: object + status: + description: PolicyStatus defines the observed state of Policy + properties: + conditions: + items: + properties: + lastTransitionTime: + description: The last time this Condition status changed. + format: date-time + type: string + message: + description: Full text reason for current status of the condition. + type: string + reason: + description: One word, camel-case reason for current status + of the condition. + type: string + status: + description: True, False, or Unknown + type: string + type: + description: Type indicates the scope of the custom resource + status addressed by the condition. + type: string + required: + - status + - type + type: object + type: array + observedGeneration: + description: |- + observedGeneration is the most recent successful generation observed for this Policy. It corresponds to the + Policy's generation, which is updated on mutation by the API Server. + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_queues.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_queues.yaml new file mode 100644 index 000000000..c77b149b2 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_queues.yaml @@ -0,0 +1,155 @@ +# Source: https://raw.githubusercontent.com/rabbitmq/messaging-topology-operator/v{version}/config/crd/bases/rabbitmq.com_queues.yaml +# Version: 1.14.2 +# VersionOf: rmq-messaging-topology-operator +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: queues.rabbitmq.com +spec: + group: rabbitmq.com + names: + categories: + - rabbitmq + kind: Queue + listKind: QueueList + plural: queues + singular: queue + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + description: Queue is the Schema for the queues API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: QueueSpec defines the desired state of Queue + properties: + arguments: + description: |- + Queue arguments in the format of KEY: VALUE. e.g. x-delivery-limit: 10000. + Configuring queues through arguments is not recommended because they cannot be updated once set; we recommend configuring queues through policies instead. + type: object + x-kubernetes-preserve-unknown-fields: true + autoDelete: + description: when set to true, queues that have had at least one consumer + before are deleted after the last consumer unsubscribes. + type: boolean + deleteIfEmpty: + description: when set to true, queues are deleted only if empty. + type: boolean + deleteIfUnused: + description: when set to true, queues are delete only if they have + no consumer. + type: boolean + durable: + description: When set to false queues does not survive server restart. + type: boolean + name: + description: Name of the queue; required property. + type: string + rabbitmqClusterReference: + description: |- + Reference to the RabbitmqCluster that the queue will be created in. + Required property. + properties: + connectionSecret: + description: |- + Secret contains the http management uri for the RabbitMQ cluster. + The Secret must contain the key `uri`, `username` and `password` or operator will error. + Have to set either name or connectionSecret, but not both. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + type: object + x-kubernetes-map-type: atomic + name: + description: |- + The name of the RabbitMQ cluster to reference. + Have to set either name or connectionSecret, but not both. + type: string + namespace: + description: |- + The namespace of the RabbitMQ cluster to reference. + Defaults to the namespace of the requested resource if omitted. + type: string + type: object + type: + type: string + vhost: + default: / + description: Default to vhost '/' + type: string + required: + - name + - rabbitmqClusterReference + type: object + status: + description: QueueStatus defines the observed state of Queue + properties: + conditions: + items: + properties: + lastTransitionTime: + description: The last time this Condition status changed. + format: date-time + type: string + message: + description: Full text reason for current status of the condition. + type: string + reason: + description: One word, camel-case reason for current status + of the condition. + type: string + status: + description: True, False, or Unknown + type: string + type: + description: Type indicates the scope of the custom resource + status addressed by the condition. + type: string + required: + - status + - type + type: object + type: array + observedGeneration: + description: |- + observedGeneration is the most recent successful generation observed for this Queue. It corresponds to the + Queue's generation, which is updated on mutation by the API Server. + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_schemareplications.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_schemareplications.yaml new file mode 100644 index 000000000..e659288a1 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_schemareplications.yaml @@ -0,0 +1,166 @@ +# Source: https://raw.githubusercontent.com/rabbitmq/messaging-topology-operator/v{version}/config/crd/bases/rabbitmq.com_schemareplications.yaml +# Version: 1.14.2 +# VersionOf: rmq-messaging-topology-operator +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: schemareplications.rabbitmq.com +spec: + group: rabbitmq.com + names: + kind: SchemaReplication + listKind: SchemaReplicationList + plural: schemareplications + singular: schemareplication + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + description: |- + SchemaReplication is the Schema for the schemareplications API + This feature requires Tanzu RabbitMQ with schema replication plugin. + For more information, see: https://tanzu.vmware.com/rabbitmq and https://www.rabbitmq.com/definitions-standby.html. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: SchemaReplicationSpec defines the desired state of SchemaReplication + properties: + endpoints: + description: |- + endpoints should be one or multiple endpoints separated by ','. + Must provide either spec.endpoints or endpoints in spec.upstreamSecret. + When endpoints are provided in both spec.endpoints and spec.upstreamSecret, spec.endpoints takes + precedence. + type: string + rabbitmqClusterReference: + description: Reference to the RabbitmqCluster that schema replication + would be set for. Must be an existing cluster. + properties: + connectionSecret: + description: |- + Secret contains the http management uri for the RabbitMQ cluster. + The Secret must contain the key `uri`, `username` and `password` or operator will error. + Have to set either name or connectionSecret, but not both. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + type: object + x-kubernetes-map-type: atomic + name: + description: |- + The name of the RabbitMQ cluster to reference. + Have to set either name or connectionSecret, but not both. + type: string + namespace: + description: |- + The namespace of the RabbitMQ cluster to reference. + Defaults to the namespace of the requested resource if omitted. + type: string + type: object + secretBackend: + description: Set to fetch user credentials from K8s external secret + stores to be used for schema replication. + properties: + vault: + properties: + secretPath: + description: |- + Path in Vault to access a KV (Key-Value) secret with the fields username and password to be used for replication. + For example "secret/data/rabbitmq/config". + Optional; if not provided, username and password will come from upstreamSecret instead. + Have to set either secretBackend.vault.secretPath or upstreamSecret, but not both. + type: string + type: object + type: object + upstreamSecret: + description: |- + Defines a Secret which contains credentials to be used for schema replication. + The Secret must contain the keys `username` and `password` in its Data field, or operator will error. + Have to set either secretBackend.vault.secretPath or spec.upstreamSecret, but not both. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + type: object + x-kubernetes-map-type: atomic + required: + - rabbitmqClusterReference + type: object + status: + description: SchemaReplicationStatus defines the observed state of SchemaReplication + properties: + conditions: + items: + properties: + lastTransitionTime: + description: The last time this Condition status changed. + format: date-time + type: string + message: + description: Full text reason for current status of the condition. + type: string + reason: + description: One word, camel-case reason for current status + of the condition. + type: string + status: + description: True, False, or Unknown + type: string + type: + description: Type indicates the scope of the custom resource + status addressed by the condition. + type: string + required: + - status + - type + type: object + type: array + observedGeneration: + description: |- + observedGeneration is the most recent successful generation observed for this Queue. It corresponds to the + Queue's generation, which is updated on mutation by the API Server. + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_shovels.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_shovels.yaml new file mode 100644 index 000000000..8a3383065 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_shovels.yaml @@ -0,0 +1,232 @@ +# Source: https://raw.githubusercontent.com/rabbitmq/messaging-topology-operator/v{version}/config/crd/bases/rabbitmq.com_shovels.yaml +# Version: 1.14.2 +# VersionOf: rmq-messaging-topology-operator +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: shovels.rabbitmq.com +spec: + group: rabbitmq.com + names: + categories: + - rabbitmq + kind: Shovel + listKind: ShovelList + plural: shovels + singular: shovel + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + description: Shovel is the Schema for the shovels API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: |- + ShovelSpec defines the desired state of Shovel + For how to configure Shovel, see: https://www.rabbitmq.com/shovel.html. + properties: + ackMode: + enum: + - on-confirm + - on-publish + - no-ack + type: string + addForwardHeaders: + type: boolean + deleteAfter: + type: string + destAddForwardHeaders: + type: boolean + destAddTimestampHeader: + type: boolean + destAddress: + description: amqp10 configuration; required if destProtocol is amqp10 + type: string + destApplicationProperties: + description: amqp10 configuration + type: object + x-kubernetes-preserve-unknown-fields: true + destExchange: + description: amqp091 configuration + type: string + destExchangeKey: + description: amqp091 configuration + type: string + destMessageAnnotations: + description: amqp10 configuration + type: object + x-kubernetes-preserve-unknown-fields: true + destProperties: + description: amqp10 configuration + type: object + x-kubernetes-preserve-unknown-fields: true + destProtocol: + enum: + - amqp091 + - amqp10 + type: string + destPublishProperties: + description: amqp091 configuration + type: object + x-kubernetes-preserve-unknown-fields: true + destQueue: + description: amqp091 configuration + type: string + name: + description: Required property; cannot be updated + type: string + prefetchCount: + type: integer + rabbitmqClusterReference: + description: |- + Reference to the RabbitmqCluster that this Shovel will be created in. + Required property. + properties: + connectionSecret: + description: |- + Secret contains the http management uri for the RabbitMQ cluster. + The Secret must contain the key `uri`, `username` and `password` or operator will error. + Have to set either name or connectionSecret, but not both. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + type: object + x-kubernetes-map-type: atomic + name: + description: |- + The name of the RabbitMQ cluster to reference. + Have to set either name or connectionSecret, but not both. + type: string + namespace: + description: |- + The namespace of the RabbitMQ cluster to reference. + Defaults to the namespace of the requested resource if omitted. + type: string + type: object + reconnectDelay: + type: integer + srcAddress: + description: amqp10 configuration; required if srcProtocol is amqp10 + type: string + srcConsumerArgs: + description: amqp091 configuration + type: object + x-kubernetes-preserve-unknown-fields: true + srcDeleteAfter: + type: string + srcExchange: + description: amqp091 configuration + type: string + srcExchangeKey: + description: amqp091 configuration + type: string + srcPrefetchCount: + type: integer + srcProtocol: + enum: + - amqp091 + - amqp10 + type: string + srcQueue: + description: amqp091 configuration + type: string + uriSecret: + description: |- + Secret contains the AMQP URI(s) to configure Shovel destination and source. + The Secret must contain the key `destUri` and `srcUri` or operator will error. + Both fields should be one or multiple uris separated by ','. + Required property. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + type: object + x-kubernetes-map-type: atomic + vhost: + default: / + description: Default to vhost '/'; cannot be updated + type: string + required: + - name + - rabbitmqClusterReference + - uriSecret + type: object + status: + description: ShovelStatus defines the observed state of Shovel + properties: + conditions: + items: + properties: + lastTransitionTime: + description: The last time this Condition status changed. + format: date-time + type: string + message: + description: Full text reason for current status of the condition. + type: string + reason: + description: One word, camel-case reason for current status + of the condition. + type: string + status: + description: True, False, or Unknown + type: string + type: + description: Type indicates the scope of the custom resource + status addressed by the condition. + type: string + required: + - status + - type + type: object + type: array + observedGeneration: + description: |- + observedGeneration is the most recent successful generation observed for this Shovel. It corresponds to the + Shovel's generation, which is updated on mutation by the API Server. + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_superstreams.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_superstreams.yaml new file mode 100644 index 000000000..c5266b6a5 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_superstreams.yaml @@ -0,0 +1,152 @@ +# Source: https://raw.githubusercontent.com/rabbitmq/messaging-topology-operator/v{version}/config/crd/bases/rabbitmq.com_superstreams.yaml +# Version: 1.14.2 +# VersionOf: rmq-messaging-topology-operator +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: superstreams.rabbitmq.com +spec: + group: rabbitmq.com + names: + categories: + - rabbitmq + kind: SuperStream + listKind: SuperStreamList + plural: superstreams + singular: superstream + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: SuperStream is the Schema for the queues API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: SuperStreamSpec defines the desired state of SuperStream + properties: + name: + description: Name of the queue; required property. + type: string + partitions: + default: 3 + description: |- + Number of partitions to create within this super stream. + Defaults to '3'. + type: integer + rabbitmqClusterReference: + description: |- + Reference to the RabbitmqCluster that the SuperStream will be created in. + Required property. + properties: + connectionSecret: + description: |- + Secret contains the http management uri for the RabbitMQ cluster. + The Secret must contain the key `uri`, `username` and `password` or operator will error. + Have to set either name or connectionSecret, but not both. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + type: object + x-kubernetes-map-type: atomic + name: + description: |- + The name of the RabbitMQ cluster to reference. + Have to set either name or connectionSecret, but not both. + type: string + namespace: + description: |- + The namespace of the RabbitMQ cluster to reference. + Defaults to the namespace of the requested resource if omitted. + type: string + type: object + routingKeys: + description: |- + Routing keys to use for each of the partitions in the SuperStream + If unset, the routing keys for the partitions will be set to the index of the partitions + items: + type: string + type: array + vhost: + default: / + description: Default to vhost '/'; cannot be updated + type: string + required: + - name + - rabbitmqClusterReference + type: object + status: + description: SuperStreamStatus defines the observed state of SuperStream + properties: + conditions: + items: + properties: + lastTransitionTime: + description: The last time this Condition status changed. + format: date-time + type: string + message: + description: Full text reason for current status of the condition. + type: string + reason: + description: One word, camel-case reason for current status + of the condition. + type: string + status: + description: True, False, or Unknown + type: string + type: + description: Type indicates the scope of the custom resource + status addressed by the condition. + type: string + required: + - status + - type + type: object + type: array + observedGeneration: + description: |- + observedGeneration is the most recent successful generation observed for this SuperStream. It corresponds to the + SuperStream's generation, which is updated on mutation by the API Server. + format: int64 + type: integer + partitions: + description: Partitions are a list of the stream queue names which + form the partitions of this SuperStream. + items: + type: string + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_topicpermissions.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_topicpermissions.yaml new file mode 100644 index 000000000..f8366f5ba --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_topicpermissions.yaml @@ -0,0 +1,164 @@ +# Source: https://raw.githubusercontent.com/rabbitmq/messaging-topology-operator/v{version}/config/crd/bases/rabbitmq.com_topicpermissions.yaml +# Version: 1.14.2 +# VersionOf: rmq-messaging-topology-operator +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: topicpermissions.rabbitmq.com +spec: + group: rabbitmq.com + names: + kind: TopicPermission + listKind: TopicPermissionList + plural: topicpermissions + singular: topicpermission + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + description: TopicPermission is the Schema for the topicpermissions API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: TopicPermissionSpec defines the desired state of TopicPermission + properties: + permissions: + description: Permissions to grant to the user to a topic exchange; + required property. + properties: + exchange: + description: Name of a topic exchange; required property; cannot + be updated. + type: string + read: + type: string + write: + type: string + type: object + rabbitmqClusterReference: + description: |- + Reference to the RabbitmqCluster that both the provided user and vhost are. + Required property. + properties: + connectionSecret: + description: |- + Secret contains the http management uri for the RabbitMQ cluster. + The Secret must contain the key `uri`, `username` and `password` or operator will error. + Have to set either name or connectionSecret, but not both. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + type: object + x-kubernetes-map-type: atomic + name: + description: |- + The name of the RabbitMQ cluster to reference. + Have to set either name or connectionSecret, but not both. + type: string + namespace: + description: |- + The namespace of the RabbitMQ cluster to reference. + Defaults to the namespace of the requested resource if omitted. + type: string + type: object + user: + description: Name of an existing user; must provide user or userReference, + else create/update will fail; cannot be updated. + type: string + userReference: + description: Reference to an existing user.rabbitmq.com object; must + provide user or userReference, else create/update will fail; cannot + be updated. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + type: object + x-kubernetes-map-type: atomic + vhost: + description: Name of an existing vhost; required property; cannot + be updated. + type: string + required: + - permissions + - rabbitmqClusterReference + - vhost + type: object + status: + description: TopicPermissionStatus defines the observed state of TopicPermission + properties: + conditions: + items: + properties: + lastTransitionTime: + description: The last time this Condition status changed. + format: date-time + type: string + message: + description: Full text reason for current status of the condition. + type: string + reason: + description: One word, camel-case reason for current status + of the condition. + type: string + status: + description: True, False, or Unknown + type: string + type: + description: Type indicates the scope of the custom resource + status addressed by the condition. + type: string + required: + - status + - type + type: object + type: array + observedGeneration: + description: |- + observedGeneration is the most recent successful generation observed for this TopicPermission. It corresponds to the + TopicPermission's generation, which is updated on mutation by the API Server. + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_users.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_users.yaml new file mode 100644 index 000000000..b366a2369 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_users.yaml @@ -0,0 +1,187 @@ +# Source: https://raw.githubusercontent.com/rabbitmq/messaging-topology-operator/v{version}/config/crd/bases/rabbitmq.com_users.yaml +# Version: 1.14.2 +# VersionOf: rmq-messaging-topology-operator +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: users.rabbitmq.com +spec: + group: rabbitmq.com + names: + categories: + - rabbitmq + kind: User + listKind: UserList + plural: users + singular: user + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + description: User is the Schema for the users API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Spec configures the desired state of the User object. + properties: + importCredentialsSecret: + description: |- + Defines a Secret used to pre-define the username and password set for this User. User objects created + with this field set will not have randomly-generated credentials, and will instead import + the username/password values from this Secret. + The Secret must contain the keys `username` and `password` in its Data field, or the import will fail. + Note that this import only occurs at creation time, and is ignored once a password has been set + on a User. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + type: object + x-kubernetes-map-type: atomic + rabbitmqClusterReference: + description: |- + Reference to the RabbitmqCluster that the user will be created for. This cluster must + exist for the User object to be created. + properties: + connectionSecret: + description: |- + Secret contains the http management uri for the RabbitMQ cluster. + The Secret must contain the key `uri`, `username` and `password` or operator will error. + Have to set either name or connectionSecret, but not both. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + type: object + x-kubernetes-map-type: atomic + name: + description: |- + The name of the RabbitMQ cluster to reference. + Have to set either name or connectionSecret, but not both. + type: string + namespace: + description: |- + The namespace of the RabbitMQ cluster to reference. + Defaults to the namespace of the requested resource if omitted. + type: string + type: object + tags: + description: |- + List of permissions tags to associate with the user. This determines the level of + access to the RabbitMQ management UI granted to the user. Omitting this field will + lead to a user than can still connect to the cluster through messaging protocols, + but cannot perform any management actions. + For more information, see https://www.rabbitmq.com/management.html#permissions. + items: + description: |- + UserTag defines the level of access to the management UI allocated to the user. + For more information, see https://www.rabbitmq.com/management.html#permissions. + enum: + - management + - policymaker + - monitoring + - administrator + type: string + type: array + required: + - rabbitmqClusterReference + type: object + status: + description: Status exposes the observed state of the User object. + properties: + conditions: + items: + properties: + lastTransitionTime: + description: The last time this Condition status changed. + format: date-time + type: string + message: + description: Full text reason for current status of the condition. + type: string + reason: + description: One word, camel-case reason for current status + of the condition. + type: string + status: + description: True, False, or Unknown + type: string + type: + description: Type indicates the scope of the custom resource + status addressed by the condition. + type: string + required: + - status + - type + type: object + type: array + credentials: + description: Provides a reference to a Secret object containing the + user credentials. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + type: object + x-kubernetes-map-type: atomic + observedGeneration: + description: |- + observedGeneration is the most recent successful generation observed for this User. It corresponds to the + User's generation, which is updated on mutation by the API Server. + format: int64 + type: integer + username: + description: Provide rabbitmq Username + type: string + required: + - username + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_vhosts.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_vhosts.yaml new file mode 100644 index 000000000..d3f9c1719 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/messaging-topology-operator/rabbitmq.com_vhosts.yaml @@ -0,0 +1,144 @@ +# Source: https://raw.githubusercontent.com/rabbitmq/messaging-topology-operator/v{version}/config/crd/bases/rabbitmq.com_vhosts.yaml +# Version: 1.14.2 +# VersionOf: rmq-messaging-topology-operator +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: vhosts.rabbitmq.com +spec: + group: rabbitmq.com + names: + categories: + - rabbitmq + kind: Vhost + listKind: VhostList + plural: vhosts + singular: vhost + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + description: Vhost is the Schema for the vhosts API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: VhostSpec defines the desired state of Vhost + properties: + defaultQueueType: + description: |- + Default queue type for this vhost; can be set to quorum, classic or stream. + Supported in RabbitMQ 3.11.12 or above. + enum: + - quorum + - classic + - stream + type: string + name: + description: Name of the vhost; see https://www.rabbitmq.com/vhosts.html. + type: string + rabbitmqClusterReference: + description: |- + Reference to the RabbitmqCluster that the vhost will be created in. + Required property. + properties: + connectionSecret: + description: |- + Secret contains the http management uri for the RabbitMQ cluster. + The Secret must contain the key `uri`, `username` and `password` or operator will error. + Have to set either name or connectionSecret, but not both. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + type: object + x-kubernetes-map-type: atomic + name: + description: |- + The name of the RabbitMQ cluster to reference. + Have to set either name or connectionSecret, but not both. + type: string + namespace: + description: |- + The namespace of the RabbitMQ cluster to reference. + Defaults to the namespace of the requested resource if omitted. + type: string + type: object + tags: + items: + type: string + type: array + tracing: + type: boolean + required: + - name + - rabbitmqClusterReference + type: object + status: + description: VhostStatus defines the observed state of Vhost + properties: + conditions: + items: + properties: + lastTransitionTime: + description: The last time this Condition status changed. + format: date-time + type: string + message: + description: Full text reason for current status of the condition. + type: string + reason: + description: One word, camel-case reason for current status + of the condition. + type: string + status: + description: True, False, or Unknown + type: string + type: + description: Type indicates the scope of the custom resource + status addressed by the condition. + type: string + required: + - status + - type + type: object + type: array + observedGeneration: + description: |- + observedGeneration is the most recent successful generation observed for this Vhost. It corresponds to the + Vhost's generation, which is updated on mutation by the API Server. + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/rabbitmq-cluster/rabbitmq.com_rabbitmqclusters.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/rabbitmq-cluster/rabbitmq.com_rabbitmqclusters.yaml new file mode 100644 index 000000000..4970fce33 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/crds/rabbitmq-cluster/rabbitmq.com_rabbitmqclusters.yaml @@ -0,0 +1,5006 @@ +# Source: https://raw.githubusercontent.com/rabbitmq/cluster-operator/v{version}/config/crd/bases/rabbitmq.com_rabbitmqclusters.yaml +# Version: 2.9.0 +# RabbitMQ Cluster Operator +# +# Copyright 2020 VMware, Inc. All Rights Reserved. +# +# This product is licensed to you under the Mozilla Public license, Version 2.0 (the "License"). You may not use this product except in compliance with the Mozilla Public License. +# +# This product may include a number of subcomponents with separate copyright notices and license terms. Your use of these subcomponents is subject to the terms and conditions of the subcomponent's license, as noted in the LICENSE file. + +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + name: rabbitmqclusters.rabbitmq.com +spec: + group: rabbitmq.com + names: + categories: + - all + - rabbitmq + kind: RabbitmqCluster + listKind: RabbitmqClusterList + plural: rabbitmqclusters + shortNames: + - rmq + singular: rabbitmqcluster + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.conditions[?(@.type == 'AllReplicasReady')].status + name: AllReplicasReady + type: string + - jsonPath: .status.conditions[?(@.type == 'ReconcileSuccess')].status + name: ReconcileSuccess + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: |- + RabbitmqCluster is the Schema for the RabbitmqCluster API. Each instance of this object + corresponds to a single RabbitMQ cluster. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Spec is the desired state of the RabbitmqCluster Custom Resource. + properties: + affinity: + description: Affinity scheduling rules to be applied on created Pods. + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. + items: + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching the corresponding nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. The terms are ORed. + items: + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. co-locate this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules (e.g. avoid putting this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + delayStartSeconds: + default: 30 + description: |- + DelayStartSeconds is the time the init container (`setup-container`) will sleep before terminating. + This effectively delays the time between starting the Pod and starting the `rabbitmq` container. + RabbitMQ relies on up-to-date DNS entries early during peer discovery. + The purpose of this artificial delay is to ensure that DNS entries are up-to-date when booting RabbitMQ. + For more information, see https://github.com/kubernetes/kubernetes/issues/92559 + If your Kubernetes DNS backend is configured with a low DNS cache value or publishes not ready addresses + promptly, you can decrase this value or set it to 0. + format: int32 + minimum: 0 + type: integer + image: + description: |- + Image is the name of the RabbitMQ docker image to use for RabbitMQ nodes in the RabbitmqCluster. + Must be provided together with ImagePullSecrets in order to use an image in a private registry. + type: string + imagePullSecrets: + description: List of Secret resource containing access credentials to the registry for the RabbitMQ image. Required if the docker registry is private. + items: + description: |- + LocalObjectReference contains enough information to let you locate the + referenced object inside the same namespace. + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + type: object + x-kubernetes-map-type: atomic + type: array + override: + properties: + service: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + allocateLoadBalancerNodePorts: + type: boolean + clusterIP: + type: string + clusterIPs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + externalIPs: + items: + type: string + type: array + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + internalTrafficPolicy: + type: string + ipFamilies: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ipFamilyPolicy: + type: string + loadBalancerClass: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + default: TCP + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + - protocol + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + type: + type: string + type: object + type: object + statefulSet: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + minReadySeconds: + format: int32 + type: integer + persistentVolumeClaimRetentionPolicy: + properties: + whenDeleted: + type: string + whenScaled: + type: string + type: object + podManagementPolicy: + type: string + replicas: + format: int32 + type: integer + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + serviceName: + type: string + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + activeDeadlineSeconds: + format: int64 + type: integer + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + automountServiceAccountToken: + type: boolean + containers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + searches: + items: + type: string + type: array + type: object + dnsPolicy: + type: string + enableServiceLinks: + type: boolean + ephemeralContainers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + targetContainerName: + type: string + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + hostAliases: + items: + properties: + hostnames: + items: + type: string + type: array + ip: + type: string + type: object + type: array + hostIPC: + type: boolean + hostNetwork: + type: boolean + hostPID: + type: boolean + hostUsers: + type: boolean + hostname: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + type: array + initContainers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + nodeName: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + os: + properties: + name: + type: string + required: + - name + type: object + overhead: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + preemptionPolicy: + type: string + priority: + format: int32 + type: integer + priorityClassName: + type: string + readinessGates: + items: + properties: + conditionType: + type: string + required: + - conditionType + type: object + type: array + resourceClaims: + items: + properties: + name: + type: string + source: + properties: + resourceClaimName: + type: string + resourceClaimTemplateName: + type: string + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + restartPolicy: + type: string + runtimeClassName: + type: string + schedulerName: + type: string + schedulingGates: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + securityContext: + properties: + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + serviceAccountName: + type: string + setHostnameAsFQDN: + type: boolean + shareProcessNamespace: + type: boolean + subdomain: + type: string + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + format: int32 + type: integer + minDomains: + format: int32 + type: integer + nodeAffinityPolicy: + type: string + nodeTaintsPolicy: + type: string + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + x-kubernetes-list-map-keys: + - topologyKey + - whenUnsatisfiable + x-kubernetes-list-type: map + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + wwids: + items: + type: string + type: array + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + clusterTrustBundle: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + name: + type: string + optional: + type: boolean + path: + type: string + signerName: + type: string + required: + - path + type: object + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - containers + type: object + type: object + updateStrategy: + properties: + rollingUpdate: + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + partition: + format: int32 + type: integer + type: object + type: + type: string + type: object + volumeClaimTemplates: + items: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + type: object + type: array + type: object + type: object + type: object + persistence: + default: + storage: 10Gi + description: The desired persistent storage configuration for each Pod in the cluster. + properties: + storage: + anyOf: + - type: integer + - type: string + default: 10Gi + description: |- + The requested size of the persistent volume attached to each Pod in the RabbitmqCluster. + The format of this field matches that defined by kubernetes/apimachinery. + See https://pkg.go.dev/k8s.io/apimachinery/pkg/api/resource#Quantity for more info on the format of this field. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + storageClassName: + description: The name of the StorageClass to claim a PersistentVolume from. + type: string + type: object + rabbitmq: + description: Configuration options for RabbitMQ Pods created in the cluster. + properties: + additionalConfig: + description: |- + Modify to add to the rabbitmq.conf file in addition to default configurations set by the operator. + Modifying this property on an existing RabbitmqCluster will trigger a StatefulSet rolling restart and will cause rabbitmq downtime. + For more information on this config, see https://www.rabbitmq.com/configure.html#config-file + maxLength: 2000 + type: string + additionalPlugins: + description: 'List of plugins to enable in addition to essential plugins: rabbitmq_management, rabbitmq_prometheus, and rabbitmq_peer_discovery_k8s.' + items: + description: A Plugin to enable on the RabbitmqCluster. + maxLength: 100 + pattern: ^\w+$ + type: string + maxItems: 100 + type: array + advancedConfig: + description: |- + Specify any rabbitmq advanced.config configurations to apply to the cluster. + For more information on advanced config, see https://www.rabbitmq.com/configure.html#advanced-config-file + maxLength: 100000 + type: string + envConfig: + description: |- + Modify to add to the rabbitmq-env.conf file. Modifying this property on an existing RabbitmqCluster will trigger a StatefulSet rolling restart and will cause rabbitmq downtime. + For more information on env config, see https://www.rabbitmq.com/man/rabbitmq-env.conf.5.html + maxLength: 100000 + type: string + erlangInetConfig: + description: |- + Erlang Inet configuration to apply to the Erlang VM running rabbit. + See also: https://www.erlang.org/doc/apps/erts/inet_cfg.html + maxLength: 2000 + type: string + type: object + replicas: + default: 1 + description: |- + Replicas is the number of nodes in the RabbitMQ cluster. Each node is deployed as a Replica in a StatefulSet. Only 1, 3, 5 replicas clusters are tested. + This value should be an odd number to ensure the resultant cluster can establish exactly one quorum of nodes + in the event of a fragmenting network partition. + format: int32 + minimum: 0 + type: integer + resources: + default: + limits: + cpu: 2000m + memory: 2Gi + requests: + cpu: 1000m + memory: 2Gi + description: The desired compute resource requirements of Pods in the cluster. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + secretBackend: + description: |- + Secret backend configuration for the RabbitmqCluster. + Enables to fetch default user credentials and certificates from K8s external secret stores. + properties: + externalSecret: + description: |- + LocalObjectReference contains enough information to let you locate the + referenced object inside the same namespace. + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + type: object + x-kubernetes-map-type: atomic + vault: + description: |- + VaultSpec will add Vault annotations (see https://www.vaultproject.io/docs/platform/k8s/injector/annotations) + to RabbitMQ Pods. It requires a Vault Agent Sidecar Injector (https://www.vaultproject.io/docs/platform/k8s/injector) + to be installed in the K8s cluster. The injector is a K8s Mutation Webhook Controller that alters RabbitMQ Pod specifications + (based on the added Vault annotations) to include Vault Agent containers that render Vault secrets to the volume. + properties: + annotations: + additionalProperties: + type: string + description: |- + Vault annotations that override the Vault annotations set by the cluster-operator. + For a list of valid Vault annotations, see https://www.vaultproject.io/docs/platform/k8s/injector/annotations + type: object + defaultUserPath: + description: |- + Path in Vault to access a KV (Key-Value) secret with the fields username and password for the default user. + For example "secret/data/rabbitmq/config". + type: string + defaultUserUpdaterImage: + description: |- + Sidecar container that updates the default user's password in RabbitMQ when it changes in Vault. + Additionally, it updates /var/lib/rabbitmq/.rabbitmqadmin.conf (used by rabbitmqadmin CLI). + Set to empty string to disable the sidecar container. + type: string + role: + description: |- + Role in Vault. + If vault.defaultUserPath is set, this role must have capability to read the pre-created default user credential in Vault. + If vault.tls is set, this role must have capability to create and update certificates in the Vault PKI engine for the domains + "" and ".svc". + type: string + tls: + properties: + altNames: + description: |- + Specifies the requested Subject Alternative Names (SANs), in a comma-delimited list. + These will be appended to the SANs added by the cluster-operator. + The cluster-operator will add SANs: + "-server-.-nodes." for each pod, + e.g. "myrabbit-server-0.myrabbit-nodes.default". + type: string + commonName: + description: |- + Specifies the requested certificate Common Name (CN). + Defaults to ..svc if not provided. + type: string + ipSans: + description: Specifies the requested IP Subject Alternative Names, in a comma-delimited list. + type: string + pkiIssuerPath: + description: |- + Path in Vault PKI engine. + For example "pki/issue/hashicorp-com". + required + type: string + pkiRootPath: + description: Specifies an optional path to retrieve the root CA from vault. Useful if certificates are issued by an intermediate CA + type: string + type: object + type: object + type: object + service: + default: + type: ClusterIP + description: The desired state of the Kubernetes Service to create for the cluster. + properties: + annotations: + additionalProperties: + type: string + description: Annotations to add to the Service. + type: object + ipFamilyPolicy: + description: |- + IPFamilyPolicy represents the dual-stack-ness requested or required by a Service + See also: https://pkg.go.dev/k8s.io/api/core/v1#IPFamilyPolicy + enum: + - SingleStack + - PreferDualStack + - RequireDualStack + type: string + type: + default: ClusterIP + description: |- + Type of Service to create for the cluster. Must be one of: ClusterIP, LoadBalancer, NodePort. + For more info see https://pkg.go.dev/k8s.io/api/core/v1#ServiceType + enum: + - ClusterIP + - LoadBalancer + - NodePort + type: string + type: object + skipPostDeploySteps: + description: |- + If unset, or set to false, the cluster will run `rabbitmq-queues rebalance all` whenever the cluster is updated. + Set to true to prevent the operator rebalancing queue leaders after a cluster update. + Has no effect if the cluster only consists of one node. + For more information, see https://www.rabbitmq.com/rabbitmq-queues.8.html#rebalance + type: boolean + terminationGracePeriodSeconds: + default: 604800 + description: |- + TerminationGracePeriodSeconds is the timeout that each rabbitmqcluster pod will have to terminate gracefully. + It defaults to 604800 seconds ( a week long) to ensure that the container preStop lifecycle hook can finish running. + For more information, see: https://github.com/rabbitmq/cluster-operator/blob/main/docs/design/20200520-graceful-pod-termination.md + format: int64 + minimum: 0 + type: integer + tls: + description: TLS-related configuration for the RabbitMQ cluster. + properties: + caSecretName: + description: |- + Name of a Secret in the same Namespace as the RabbitmqCluster, containing the Certificate Authority's public certificate for TLS. + The Secret must store this as ca.crt. + This Secret can be created by running `kubectl create secret generic ca-secret --from-file=ca.crt=path/to/ca.cert` + Used for mTLS, and TLS for rabbitmq_web_stomp and rabbitmq_web_mqtt. + type: string + disableNonTLSListeners: + description: |- + When set to true, the RabbitmqCluster disables non-TLS listeners for RabbitMQ, management plugin and for any enabled plugins in the following list: stomp, mqtt, web_stomp, web_mqtt. + Only TLS-enabled clients will be able to connect. + type: boolean + secretName: + description: |- + Name of a Secret in the same Namespace as the RabbitmqCluster, containing the server's private key & public certificate for TLS. + The Secret must store these as tls.key and tls.crt, respectively. + This Secret can be created by running `kubectl create secret tls tls-secret --cert=path/to/tls.cert --key=path/to/tls.key` + type: string + type: object + tolerations: + description: Tolerations is the list of Toleration resources attached to each Pod in the RabbitmqCluster. + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + type: object + status: + description: Status presents the observed state of RabbitmqCluster + properties: + binding: + description: |- + Binding exposes a secret containing the binding information for this + RabbitmqCluster. It implements the service binding Provisioned Service + duck type. See: https://github.com/servicebinding/spec#provisioned-service + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + type: object + x-kubernetes-map-type: atomic + conditions: + description: Set of Conditions describing the current state of the RabbitmqCluster + items: + properties: + lastTransitionTime: + description: The last time this Condition type changed. + format: date-time + type: string + message: + description: Full text reason for current status of the condition. + type: string + reason: + description: One word, camel-case reason for current status of the condition. + type: string + status: + description: True, False, or Unknown + type: string + type: + description: Type indicates the scope of RabbitmqCluster status addressed by the condition. + type: string + required: + - status + - type + type: object + type: array + defaultUser: + description: Identifying information on internal resources + properties: + secretReference: + description: |- + Reference to the Kubernetes Secret containing the credentials of the default + user. + properties: + keys: + additionalProperties: + type: string + description: Key-value pairs in the Secret corresponding to `username`, `password`, `host`, and `port` + type: object + name: + description: Name of the Secret containing the default user credentials + type: string + namespace: + description: Namespace of the Secret containing the default user credentials + type: string + required: + - keys + - name + - namespace + type: object + serviceReference: + description: Reference to the Kubernetes Service serving the cluster. + properties: + name: + description: Name of the Service serving the cluster + type: string + namespace: + description: Namespace of the Service serving the cluster + type: string + required: + - name + - namespace + type: object + type: object + observedGeneration: + description: |- + observedGeneration is the most recent successful generation observed for this RabbitmqCluster. It corresponds to the + RabbitmqCluster's generation, which is updated on mutation by the API Server. + format: int64 + type: integer + required: + - conditions + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/NOTES.txt b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/NOTES.txt new file mode 100644 index 000000000..ff40a3319 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/NOTES.txt @@ -0,0 +1,52 @@ +CHART NAME: {{ .Chart.Name }} +CHART VERSION: {{ .Chart.Version }} +APP VERSION: {{ .Chart.AppVersion }} + +** Please be patient while the chart is being deployed ** + +Watch the RabbitMQ Cluster Operator and RabbitMQ Messaging Topology Operator Deployment status using the command: + + kubectl get deploy -w --namespace {{ include "common.names.namespace" . }} -l app.kubernetes.io/name={{ include "common.names.name" . }},app.kubernetes.io/instance={{ .Release.Name }} + +{{- if .Values.clusterOperator.rbac.create }} +{{- if .Values.clusterOperator.watchAllNamespaces }} +WARNING: RabbitMQ Cluster Operator can access all secrets in the cluster. This could pose a security risk if the application gets compromised. + +You can limit allowed namespaces by setting clusterOperator.watchAllNamespaces = false and configuring clusterOperator.watchNamespaces +{{- else }} + +RabbitMQ Cluster Operator can ONLY access resources in the following namespaces: +{{ $namespaces := .Values.clusterOperator.watchAllNamespaces | default (list (include "common.names.namespace" .)) }} +{{- range $namespace := $namespaces }} + - {{ $namespace }} +{{- end }} + +RabbitMQ Cluster Operator won't be able to access resources in other namespaces. You can configure this behavior by setting clusterOperator.watchNamespaces + +{{- end }} +{{- end }} + +{{- if .Values.msgTopologyOperator.rbac.create }} +{{- if .Values.msgTopologyOperator.watchAllNamespaces }} +WARNING: RabbitMQ Messaging Topology Operator can access all secrets in the cluster. This could pose a security risk if the application gets compromised. + +You can limit allowed namespaces by setting msgTopologyOperator.watchAllNamespaces = false and configuring msgTopologyOperator.watchNamespaces +{{- else }} + +RabbitMQ Messaging Topology Operator can ONLY access resources in the following namespaces: +{{ $namespaces := .Values.msgTopologyOperator.watchAllNamespaces | default (list (include "common.names.namespace" .)) }} +{{- range $namespace := $namespaces }} + - {{ $namespace }} +{{- end }} + +RabbitMQ Messaging Topology Operator won't be able to access resources in other namespaces. You can configure this behavior by setting msgTopologyOperator.watchNamespaces + +{{- end }} +{{- end }} + +{{ include "common.warnings.rollingTag" .Values.clusterOperator.image }} +{{ include "common.warnings.rollingTag" .Values.msgTopologyOperator.image }} +{{ include "common.warnings.rollingTag" .Values.credentialUpdaterImage }} +{{ include "common.warnings.rollingTag" .Values.rabbitmqImage }} +{{- include "common.warnings.resources" (dict "sections" (list "clusterOperator" "msgTopologyOperator") "context" $) }} +{{- include "common.warnings.modifiedImages" (dict "images" (list .Values.rabbitmqImage .Values.credentialUpdaterImage .Values.clusterOperator.image .Values.msgTopologyOperator.image) "context" $) }} \ No newline at end of file diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/_helpers.tpl b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/_helpers.tpl new file mode 100644 index 000000000..799b0baf6 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/_helpers.tpl @@ -0,0 +1,143 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* +Return the proper RabbitMQ Cluster Operator fullname +Note: We use the regular common function as the chart name already contains the +the rabbitmq-cluster-operator name. +*/}} +{{- define "rmqco.clusterOperator.fullname" -}} +{{- include "common.names.fullname" . -}} +{{- end -}} + +{{/* +Return the proper RabbitMQ Messaging Topology Operator fullname +NOTE: Not using the common function to avoid generating too long names +*/}} +{{- define "rmqco.msgTopologyOperator.fullname" -}} +{{- if .Values.msgTopologyOperator.fullnameOverride -}} + {{- printf "%s" .Values.msgTopologyOperator.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else if .Values.fullnameOverride -}} + {{- printf "%s-%s" .Values.fullnameOverride "messaging-topology-operator" | trunc 63 | trimSuffix "-" -}} +{{- else -}} + {{- printf "%s-%s" .Release.Name "rabbitmq-messaging-topology-operator" | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the proper RabbitMQ Messaging Topology Operator fullname adding the installation's namespace. +*/}} +{{- define "rmqco.msgTopologyOperator.fullname.namespace" -}} +{{- printf "%s-%s" (include "rmqco.msgTopologyOperator.fullname" .) (include "common.names.namespace" .) | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Return the proper RabbitMQ Messaging Topology Operator fullname +NOTE: Not using the common function to avoid generating too long names +*/}} +{{- define "rmqco.msgTopologyOperator.webhook.fullname" -}} +{{- if .Values.msgTopologyOperator.fullnameOverride -}} + {{- printf "%s-%s" .Values.msgTopologyOperator.fullnameOverride "webhook" | trunc 63 | trimSuffix "-" -}} +{{- else if .Values.fullnameOverride -}} + {{- printf "%s-%s" .Values.fullnameOverride "messaging-topology-operator-webhook" | trunc 63 | trimSuffix "-" -}} +{{- else -}} + {{- printf "%s-%s" .Release.Name "rabbitmq-messaging-topology-operator-webhook" | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the proper RabbitMQ Messaging Topology Operator fullname adding the installation's namespace. +*/}} +{{- define "rmqco.msgTopologyOperator.webhook.fullname.namespace" -}} +{{- printf "%s-%s" (include "rmqco.msgTopologyOperator.webhook.fullname" .) (include "common.names.namespace" .) | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Return the proper RabbitMQ Messaging Topology Operator fullname +*/}} +{{- define "rmqco.msgTopologyOperator.webhook.secretName" -}} +{{- if .Values.msgTopologyOperator.existingWebhookCertSecret -}} + {{- .Values.msgTopologyOperator.existingWebhookCertSecret -}} +{{- else }} + {{- include "rmqco.msgTopologyOperator.webhook.fullname" . -}} +{{- end -}} +{{- end -}} + +{{/* +Return the proper RabbitMQ Default User Credential updater image name +*/}} +{{- define "rmqco.defaultCredentialUpdater.image" -}} +{{ include "common.images.image" (dict "imageRoot" .Values.credentialUpdaterImage "global" .Values.global) }} +{{- end -}} + +{{/* +Return the proper RabbitMQ Cluster Operator image name +*/}} +{{- define "rmqco.clusterOperator.image" -}} +{{ include "common.images.image" (dict "imageRoot" .Values.clusterOperator.image "global" .Values.global) }} +{{- end -}} + +{{/* +Return the proper RabbitMQ Cluster Operator image name +*/}} +{{- define "rmqco.msgTopologyOperator.image" -}} +{{ include "common.images.image" (dict "imageRoot" .Values.msgTopologyOperator.image "global" .Values.global) }} +{{- end -}} + +{{/* +Return the proper RabbitMQ image name +*/}} +{{- define "rmqco.rabbitmq.image" -}} +{{- include "common.images.image" ( dict "imageRoot" .Values.rabbitmqImage "global" .Values.global ) -}} +{{- end -}} + +{{/* +Return the proper Docker Image Registry Secret Names +*/}} +{{- define "rmqco.imagePullSecrets" -}} +{{- include "common.images.pullSecrets" (dict "images" (list .Values.clusterOperator.image .Values.rabbitmqImage) "global" .Values.global) -}} +{{- end -}} + +{{/* +Return the proper Docker Image Registry Secret Names as a comma separated string +*/}} +{{- define "rmqco.imagePullSecrets.string" -}} +{{- $pullSecrets := list }} +{{- if .Values.global }} + {{- range .Values.global.imagePullSecrets -}} + {{- $pullSecrets = append $pullSecrets . -}} + {{- end -}} +{{- end -}} +{{- range (list .Values.clusterOperator.image .Values.rabbitmqImage) -}} + {{- range .pullSecrets -}} + {{- $pullSecrets = append $pullSecrets . -}} + {{- end -}} +{{- end -}} +{{- if (not (empty $pullSecrets)) }} + {{- printf "%s" (join "," $pullSecrets) -}} +{{- end }} +{{- end }} + +{{/* +Create the name of the service account to use (Cluster Operator) +*/}} +{{- define "rmqco.clusterOperator.serviceAccountName" -}} +{{- if .Values.clusterOperator.serviceAccount.create -}} + {{ default (printf "%s" (include "rmqco.clusterOperator.fullname" .)) .Values.clusterOperator.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.clusterOperator.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the service account to use (Messaging Topology Operator) +*/}} +{{- define "rmqco.msgTopologyOperator.serviceAccountName" -}} +{{- if .Values.msgTopologyOperator.serviceAccount.create -}} + {{ default (printf "%s" (include "rmqco.msgTopologyOperator.fullname" .)) .Values.msgTopologyOperator.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.msgTopologyOperator.serviceAccount.name }} +{{- end -}} +{{- end -}} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/aggregate-cluster-roles.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/aggregate-cluster-roles.yaml new file mode 100644 index 000000000..f8c630fbe --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/aggregate-cluster-roles.yaml @@ -0,0 +1,31 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.clusterOperator.rbac.create -}} +{{- $readonlyVerbs := list "get" "list" "watch" }} +{{- $allVerbs := list "create" "delete" "deletecollection" "get" "list" "patch" "update" "watch" }} +{{- $roles := dict "view" $readonlyVerbs "edit" $allVerbs "admin" $allVerbs }} +{{- range $role, $verbs := $roles -}} +--- +apiVersion: {{ include "common.capabilities.rbac.apiVersion" $ }} +kind: ClusterRole +metadata: + name: {{ template "common.names.fullname.namespace" $ }}-{{ $role }} + labels: {{- include "common.labels.standard" ( dict "customLabels" $.Values.commonLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: rabbitmq-operator + app.kubernetes.io/part-of: rabbitmq + rbac.authorization.k8s.io/aggregate-to-{{ $role }}: "true" + {{- if $.Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" $.Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +rules: + - apiGroups: + - rabbitmq.com + resources: + - rabbitmqclusters + - rabbitmqclusters/finalizers + verbs: {{ $verbs | toYaml | nindent 6 }} +{{ end }} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/clusterrole.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/clusterrole.yaml new file mode 100644 index 000000000..d4ed1d56d --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/clusterrole.yaml @@ -0,0 +1,168 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.clusterOperator.rbac.create }} +apiVersion: {{ include "common.capabilities.rbac.apiVersion" . }} +kind: ClusterRole +metadata: + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: rabbitmq-operator + app.kubernetes.io/part-of: rabbitmq + name: {{ template "common.names.fullname.namespace" . }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +rules: + {{- if .Values.clusterOperator.rbac.clusterRole.customRules }} + {{- range .Values.clusterOperator.rbac.clusterRole.customRules }} + - apiGroups: {{ .apiGroups | toYaml | nindent 6 }} + resources: {{ .resources | toYaml | nindent 6 }} + verbs: {{ .verbs | toYaml | nindent 6 }} + {{- end }} + {{- else }} + {{- if .Values.clusterOperator.rbac.clusterRole.extraRules }} + {{- range .Values.clusterOperator.rbac.clusterRole.extraRules }} + - apiGroups: {{ .apiGroups | toYaml | nindent 6 }} + resources: {{ .resources | toYaml | nindent 6 }} + verbs: {{ .verbs | toYaml | nindent 6 }} + {{- end }} + {{- end }} + - apiGroups: + - "" + resources: + - configmaps + verbs: + - create + - get + - list + - update + - watch + - apiGroups: + - "" + resources: + - endpoints + verbs: + - get + - list + - watch + - apiGroups: + - "" + resources: + - events + verbs: + - create + - get + - patch + - apiGroups: + - "" + resources: + - persistentvolumeclaims + verbs: + - create + - get + - list + - update + - watch + - apiGroups: + - "" + resources: + - pods + verbs: + - get + - list + - update + - watch + - apiGroups: + - "" + resources: + - pods/exec + verbs: + - create + - apiGroups: + - "" + resources: + - secrets + verbs: + - create + - get + - list + - update + - watch + - apiGroups: + - "" + resources: + - serviceaccounts + verbs: + - create + - get + - list + - update + - watch + - apiGroups: + - "" + resources: + - services + verbs: + - create + - get + - list + - update + - watch + - apiGroups: + - apps + resources: + - statefulsets + verbs: + - create + - delete + - get + - list + - update + - watch + - apiGroups: + - rabbitmq.com + resources: + - rabbitmqclusters + verbs: + - create + - get + - list + - update + - watch + - apiGroups: + - rabbitmq.com + resources: + - rabbitmqclusters/finalizers + verbs: + - update + - apiGroups: + - rabbitmq.com + resources: + - rabbitmqclusters/status + verbs: + - get + - update + - apiGroups: + - rbac.authorization.k8s.io + resources: + - rolebindings + verbs: + - create + - get + - list + - update + - watch + - apiGroups: + - rbac.authorization.k8s.io + resources: + - roles + verbs: + - create + - get + - list + - update + - watch + {{- end }} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/clusterrolebinding.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/clusterrolebinding.yaml new file mode 100644 index 000000000..f5fa30abe --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/clusterrolebinding.yaml @@ -0,0 +1,51 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.clusterOperator.rbac.create }} +{{- if .Values.clusterOperator.watchAllNamespaces }} +apiVersion: {{ include "common.capabilities.rbac.apiVersion" . }} +kind: ClusterRoleBinding +metadata: + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: rabbitmq-operator + app.kubernetes.io/part-of: rabbitmq + name: {{ template "common.names.fullname.namespace" . }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "common.names.fullname.namespace" . }} +subjects: + - kind: ServiceAccount + name: {{ template "rmqco.clusterOperator.serviceAccountName" . }} + namespace: {{ include "common.names.namespace" . | quote }} +{{- else }} +{{- $watchNamespaces := default (list (include "common.names.namespace" .)) .Values.clusterOperator.watchNamespaces }} +{{- range $namespace := $watchNamespaces }} +--- +kind: RoleBinding +apiVersion: {{ include "common.capabilities.rbac.apiVersion" $ }} +metadata: + name: {{ printf "%s-%s" (include "rmqco.clusterOperator.fullname" $) $namespace | trunc 63 | trimSuffix "-" }} + namespace: {{ $namespace | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" $.Values.commonLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: rabbitmq-operator + app.kubernetes.io/part-of: rabbitmq + {{- if $.Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" $.Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "common.names.fullname.namespace" $ }} +subjects: + - kind: ServiceAccount + name: {{ template "rmqco.clusterOperator.serviceAccountName" $ }} + namespace: {{ include "common.names.namespace" $ | quote }} +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/deployment.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/deployment.yaml new file mode 100644 index 000000000..7dc16370f --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/deployment.yaml @@ -0,0 +1,169 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +apiVersion: {{ include "common.capabilities.deployment.apiVersion" . }} +kind: Deployment +metadata: + name: {{ template "rmqco.clusterOperator.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: rabbitmq-operator + app.kubernetes.io/part-of: rabbitmq + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.clusterOperator.replicaCount }} + revisionHistoryLimit: {{ .Values.clusterOperator.revisionHistoryLimit }} + {{- if .Values.clusterOperator.updateStrategy }} + strategy: {{- toYaml .Values.clusterOperator.updateStrategy | nindent 4 }} + {{- end }} + {{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.clusterOperator.podLabels .Values.commonLabels ) "context" . ) }} + selector: + matchLabels: {{- include "common.labels.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 6 }} + app.kubernetes.io/component: rabbitmq-operator + template: + metadata: + {{- if .Values.clusterOperator.podAnnotations }} + annotations: {{- include "common.tplvalues.render" (dict "value" .Values.clusterOperator.podAnnotations "context" $) | nindent 8 }} + {{- end }} + labels: {{- include "common.labels.standard" ( dict "customLabels" $podLabels "context" $ ) | nindent 8 }} + app.kubernetes.io/component: rabbitmq-operator + app.kubernetes.io/part-of: rabbitmq + spec: + serviceAccountName: {{ template "rmqco.clusterOperator.serviceAccountName" . }} + {{- include "rmqco.imagePullSecrets" . | nindent 6 }} + {{- if .Values.clusterOperator.schedulerName }} + schedulerName: {{ .Values.clusterOperator.schedulerName | quote }} + {{- end }} + automountServiceAccountToken: {{ .Values.clusterOperator.automountServiceAccountToken }} + {{- if .Values.clusterOperator.hostAliases }} + hostAliases: {{- include "common.tplvalues.render" (dict "value" .Values.clusterOperator.hostAliases "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.clusterOperator.topologySpreadConstraints }} + topologySpreadConstraints: {{- include "common.tplvalues.render" (dict "value" .Values.clusterOperator.topologySpreadConstraints "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.clusterOperator.affinity }} + affinity: {{- include "common.tplvalues.render" ( dict "value" .Values.clusterOperator.affinity "context" $) | nindent 8 }} + {{- else }} + affinity: + podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.clusterOperator.podAffinityPreset "component" "rabbitmq-operator" "customLabels" $podLabels "context" $) | nindent 10 }} + podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.clusterOperator.podAntiAffinityPreset "component" "rabbitmq-operator" "customLabels" $podLabels "context" $) | nindent 10 }} + nodeAffinity: {{- include "common.affinities.nodes" (dict "type" .Values.clusterOperator.nodeAffinityPreset.type "key" .Values.clusterOperator.nodeAffinityPreset.key "values" .Values.clusterOperator.nodeAffinityPreset.values) | nindent 10 }} + {{- end }} + {{- if .Values.clusterOperator.nodeSelector }} + nodeSelector: {{- include "common.tplvalues.render" ( dict "value" .Values.clusterOperator.nodeSelector "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.clusterOperator.tolerations }} + tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.clusterOperator.tolerations "context" .) | nindent 8 }} + {{- end }} + {{- if .Values.clusterOperator.priorityClassName }} + priorityClassName: {{ .Values.clusterOperator.priorityClassName | quote }} + {{- end }} + {{- if .Values.clusterOperator.podSecurityContext.enabled }} + securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.clusterOperator.podSecurityContext "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.clusterOperator.terminationGracePeriodSeconds }} + terminationGracePeriodSeconds: {{ .Values.clusterOperator.terminationGracePeriodSeconds }} + {{- end }} + initContainers: + {{- if .Values.clusterOperator.initContainers }} + {{- include "common.tplvalues.render" (dict "value" .Values.clusterOperator.initContainers "context" $) | nindent 8 }} + {{- end }} + containers: + - name: rabbitmq-cluster-operator + image: {{ template "rmqco.clusterOperator.image" . }} + imagePullPolicy: {{ .Values.clusterOperator.image.pullPolicy }} + {{- if .Values.clusterOperator.containerSecurityContext.enabled }} + securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.clusterOperator.containerSecurityContext "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.clusterOperator.command }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.clusterOperator.command "context" $) | nindent 12 }} + {{- else }} + command: + - /manager + {{- end }} + {{- if .Values.clusterOperator.args }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.clusterOperator.args "context" $) | nindent 12 }} + {{- else }} + args: + - --metrics-bind-address=:{{ .Values.clusterOperator.containerPorts.metrics }} + {{- end }} + env: + - name: OPERATOR_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- if not .Values.clusterOperator.watchAllNamespaces }} + {{- $watchNamespaces := default (list (include "common.names.namespace" .)) .Values.clusterOperator.watchNamespaces }} + - name: OPERATOR_SCOPE_NAMESPACE + value: {{ join "," $watchNamespaces | quote }} + {{- end }} + - name: DEFAULT_RABBITMQ_IMAGE + value: {{ include "rmqco.rabbitmq.image" . }} + - name: DEFAULT_USER_UPDATER_IMAGE + value: {{ include "rmqco.defaultCredentialUpdater.image" . }} + {{- if (include "rmqco.imagePullSecrets.string" .) }} + - name: DEFAULT_IMAGE_PULL_SECRETS + value: {{ include "rmqco.imagePullSecrets.string" . | quote }} + {{- end }} + {{- if .Values.clusterOperator.extraEnvVars }} + {{- include "common.tplvalues.render" (dict "value" .Values.clusterOperator.extraEnvVars "context" $) | nindent 12 }} + {{- end }} + envFrom: + {{- if .Values.clusterOperator.extraEnvVarsCM }} + - configMapRef: + name: {{ include "common.tplvalues.render" (dict "value" .Values.clusterOperator.extraEnvVarsCM "context" $) }} + {{- end }} + {{- if .Values.clusterOperator.extraEnvVarsSecret }} + - secretRef: + name: {{ include "common.tplvalues.render" (dict "value" .Values.clusterOperator.extraEnvVarsSecret "context" $) }} + {{- end }} + {{- if .Values.clusterOperator.resources }} + resources: {{- toYaml .Values.clusterOperator.resources | nindent 12 }} + {{- else if ne .Values.clusterOperator.resourcesPreset "none" }} + resources: {{- include "common.resources.preset" (dict "type" .Values.clusterOperator.resourcesPreset) | nindent 12 }} + {{- end }} + {{- if not .Values.diagnosticMode.enabled }} + {{- if .Values.clusterOperator.customLivenessProbe }} + livenessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.clusterOperator.customLivenessProbe "context" $) | nindent 12 }} + {{- else if .Values.clusterOperator.livenessProbe.enabled }} + livenessProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.clusterOperator.livenessProbe "enabled") "context" $) | nindent 12 }} + tcpSocket: + port: http + {{- end }} + {{- if .Values.clusterOperator.customReadinessProbe }} + readinessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.clusterOperator.customReadinessProbe "context" $) | nindent 12 }} + {{- else if .Values.clusterOperator.readinessProbe.enabled }} + readinessProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.clusterOperator.readinessProbe "enabled") "context" $) | nindent 12 }} + httpGet: + path: /metrics + port: http + {{- end }} + {{- if .Values.clusterOperator.customStartupProbe }} + startupProbe: {{- include "common.tplvalues.render" (dict "value" .Values.clusterOperator.customStartupProbe "context" $) | nindent 12 }} + {{- else if .Values.clusterOperator.startupProbe.enabled }} + startupProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.clusterOperator.startupProbe "enabled") "context" $) | nindent 12 }} + httpGet: + path: /metrics + port: http + {{- end }} + {{- end }} + {{- if .Values.clusterOperator.lifecycleHooks }} + lifecycle: {{- include "common.tplvalues.render" (dict "value" .Values.clusterOperator.lifecycleHooks "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.clusterOperator.extraVolumeMounts }} + volumeMounts: {{- include "common.tplvalues.render" (dict "value" .Values.clusterOperator.extraVolumeMounts "context" $) | nindent 12 }} + {{- end }} + ports: + - name: http + containerPort: {{ .Values.clusterOperator.containerPorts.metrics }} + protocol: TCP + {{- if .Values.clusterOperator.sidecars }} + {{- include "common.tplvalues.render" ( dict "value" .Values.clusterOperator.sidecars "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.clusterOperator.extraVolumes }} + volumes: {{- include "common.tplvalues.render" (dict "value" .Values.clusterOperator.extraVolumes "context" $) | nindent 8 }} + {{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/metrics-service.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/metrics-service.yaml new file mode 100644 index 000000000..597b3896c --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/metrics-service.yaml @@ -0,0 +1,55 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.clusterOperator.metrics.service.enabled }} +apiVersion: v1 +kind: Service +metadata: + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: rabbitmq-operator + app.kubernetes.io/part-of: rabbitmq + name: {{ printf "%s-metrics" (include "rmqco.clusterOperator.fullname" .) | trunc 63 | trimSuffix "-" }} + namespace: {{ include "common.names.namespace" . | quote }} + {{- if or .Values.commonAnnotations .Values.clusterOperator.metrics.service.annotations }} + {{- $annotations := include "common.tplvalues.merge" ( dict "values" ( list .Values.clusterOperator.metrics.service.annotations .Values.commonAnnotations ) "context" . ) }} + annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $) | nindent 4 }} + {{- end }} +spec: + type: {{ .Values.clusterOperator.metrics.service.type }} + {{- if (or (eq .Values.clusterOperator.metrics.service.type "LoadBalancer") (eq .Values.clusterOperator.metrics.service.type "NodePort")) }} + externalTrafficPolicy: {{ .Values.clusterOperator.metrics.service.externalTrafficPolicy | quote }} + {{- end }} + {{- if .Values.clusterOperator.metrics.service.clusterIP }} + clusterIP: {{ .Values.clusterOperator.metrics.service.clusterIP }} + {{- end }} + {{- if eq .Values.clusterOperator.metrics.service.type "LoadBalancer" }} + loadBalancerSourceRanges: {{ .Values.clusterOperator.metrics.service.loadBalancerSourceRanges }} + {{- end }} + {{- if (and (eq .Values.clusterOperator.metrics.service.type "LoadBalancer") (not (empty .Values.clusterOperator.metrics.service.loadBalancerIP))) }} + loadBalancerIP: {{ .Values.clusterOperator.metrics.service.loadBalancerIP }} + {{- end }} + {{- if .Values.clusterOperator.metrics.service.sessionAffinity }} + sessionAffinity: {{ .Values.clusterOperator.metrics.service.sessionAffinity }} + {{- end }} + {{- if .Values.clusterOperator.metrics.service.sessionAffinityConfig }} + sessionAffinityConfig: {{- include "common.tplvalues.render" (dict "value" .Values.clusterOperator.metrics.service.sessionAffinityConfig "context" $) | nindent 4 }} + {{- end }} + ports: + - name: http + port: {{ .Values.clusterOperator.metrics.service.ports.http }} + targetPort: http + protocol: TCP + {{- if (and (or (eq .Values.clusterOperator.metrics.service.type "NodePort") (eq .Values.clusterOperator.metrics.service.type "LoadBalancer")) (not (empty .Values.clusterOperator.metrics.service.nodePorts.http))) }} + nodePort: {{ .Values.clusterOperator.metrics.service.nodePorts.http }} + {{- else if eq .Values.clusterOperator.metrics.service.type "ClusterIP" }} + nodePort: null + {{- end }} + {{- if .Values.clusterOperator.metrics.service.extraPorts }} + {{- include "common.tplvalues.render" (dict "value" .Values.clusterOperator.metrics.service.extraPorts "context" $) | nindent 4 }} + {{- end }} + {{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.clusterOperator.podLabels .Values.commonLabels ) "context" . ) }} + selector: {{- include "common.labels.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: rabbitmq-operator +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/networkpolicy.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/networkpolicy.yaml new file mode 100644 index 000000000..890194f17 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/networkpolicy.yaml @@ -0,0 +1,93 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.clusterOperator.networkPolicy.enabled }} +kind: NetworkPolicy +apiVersion: {{ include "common.capabilities.networkPolicy.apiVersion" . }} +metadata: + name: {{ template "common.names.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: rabbitmq-operator + app.kubernetes.io/part-of: rabbitmq + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + {{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.clusterOperator.podLabels .Values.commonLabels ) "context" . ) }} + podSelector: + matchLabels: {{- include "common.labels.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 6 }} + app.kubernetes.io/component: rabbitmq-operator + app.kubernetes.io/part-of: rabbitmq + policyTypes: + - Ingress + - Egress + {{- if .Values.clusterOperator.networkPolicy.allowExternalEgress }} + egress: + - {} + {{- else }} + egress: + - ports: + # Allow dns resolution + - port: 53 + protocol: UDP + - port: 53 + protocol: TCP + # Allow access to kube-apiserver + {{- range $port := .Values.clusterOperator.networkPolicy.kubeAPIServerPorts }} + - port: {{ $port }} + {{- end }} + # RabbitMQCluster instances have the label app.kubernetes.io/component: rabbitmq + - to: + - podSelector: + matchLabels: + app.kubernetes.io/component: rabbitmq + {{- if not .Values.clusterOperator.watchAllNamespaces }} + {{- $watchNamespaces := default (list (include "common.names.namespace" .)) .Values.clusterOperator.watchNamespaces }} + namespaceSelector: + matchExpressions: + - key: namespace + operator: In + values: + {{- range $namespace := $watchNamespaces }} + - {{ $namespace }} + {{- end }} + {{- end }} + {{- if .Values.clusterOperator.networkPolicy.extraEgress }} + {{- include "common.tplvalues.render" ( dict "value" .Values.clusterOperator.networkPolicy.extraEgress "context" $ ) | nindent 4 }} + {{- end }} + {{- end }} + ingress: + {{- if .Values.clusterOperator.metrics.enabled }} + - ports: + - port: {{ .Values.clusterOperator.containerPorts.metrics }} + {{- if not .Values.clusterOperator.networkPolicy.allowExternal }} + from: + - podSelector: + matchLabels: {{- include "common.labels.matchLabels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 14 }} + app.kubernetes.io/part-of: rabbitmq + - podSelector: + matchLabels: + {{ template "common.names.fullname" . }}-client: "true" + {{- if .Values.clusterOperator.networkPolicy.ingressNSMatchLabels }} + - namespaceSelector: + matchLabels: + {{- range $key, $value := .Values.clusterOperator.networkPolicy.ingressNSMatchLabels }} + {{ $key | quote }}: {{ $value | quote }} + {{- end }} + {{- if .Values.clusterOperator.networkPolicy.ingressNSPodMatchLabels }} + podSelector: + matchLabels: + {{- range $key, $value := .Values.clusterOperator.networkPolicy.ingressNSPodMatchLabels }} + {{ $key | quote }}: {{ $value | quote }} + {{- end }} + {{- end }} + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.clusterOperator.networkPolicy.extraIngress }} + {{- include "common.tplvalues.render" ( dict "value" .Values.clusterOperator.networkPolicy.extraIngress "context" $ ) | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/podmonitor.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/podmonitor.yaml new file mode 100644 index 000000000..f880bff48 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/podmonitor.yaml @@ -0,0 +1,73 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.clusterOperator.metrics.podMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: rabbitmq-operator + app.kubernetes.io/part-of: rabbitmq + {{- if .Values.clusterOperator.metrics.podMonitor.additionalLabels }} + {{- include "common.tplvalues.render" (dict "value" .Values.clusterOperator.metrics.podMonitor.additionalLabels "context" $) | nindent 4 }} + {{- end }} + name: {{ printf "%s-metrics" (include "rmqco.clusterOperator.fullname" .) }} + namespace: {{ default (include "common.names.namespace" .) .Values.msgTopologyOperator.metrics.podMonitor.namespace | quote }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} + {{- end }} +spec: + jobLabel: {{ .Values.clusterOperator.metrics.podMonitor.jobLabel }} + selector: + matchLabels: + {{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.clusterOperator.podLabels .Values.commonLabels ) "context" . ) }} + {{- include "common.labels.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 6 }} + {{- if .Values.clusterOperator.metrics.podMonitor.selector }} + {{- include "common.tplvalues.render" ( dict "value" .Values.clusterOperator.metrics.podMonitor.selector "context" $ ) | nindent 6 }} + {{- end }} + app.kubernetes.io/component: rabbitmq-operator + namespaceSelector: + matchNames: + - {{ include "common.names.namespace" . | quote }} + podMetricsEndpoints: + - port: http + {{- if .Values.clusterOperator.metrics.podMonitor.interval }} + interval: {{ .Values.clusterOperator.metrics.podMonitor.interval }} + {{- end }} + {{- if .Values.clusterOperator.metrics.podMonitor.honorLabels }} + honorLabels: {{ .Values.clusterOperator.metrics.podMonitor.honorLabels }} + {{- end }} + {{- if .Values.clusterOperator.metrics.podMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.clusterOperator.metrics.podMonitor.scrapeTimeout }} + {{- end }} + {{- if .Values.clusterOperator.metrics.podMonitor.relabelings }} + relabelings: {{ toYaml .Values.clusterOperator.metrics.podMonitor.relabelings | nindent 8 }} + {{- end }} + {{- if .Values.clusterOperator.metrics.podMonitor.metricRelabelings }} + metricRelabelings: {{ toYaml .Values.clusterOperator.metrics.podMonitor.metricRelabelings | nindent 8 }} + {{- end }} + - port: metrics + {{- if .Values.clusterOperator.metrics.podMonitor.path }} + path: {{ .Values.clusterOperator.metrics.podMonitor.path }} + {{- end }} + {{- if .Values.clusterOperator.metrics.podMonitor.params }} + params: {{ toYaml .Values.clusterOperator.metrics.podMonitor.params | nindent 8 }} + {{- end }} + {{- if .Values.clusterOperator.metrics.podMonitor.interval }} + interval: {{ .Values.clusterOperator.metrics.podMonitor.interval }} + {{- end }} + {{- if .Values.clusterOperator.metrics.podMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.clusterOperator.metrics.podMonitor.scrapeTimeout }} + {{- end }} + {{- if .Values.clusterOperator.metrics.podMonitor.honorLabels }} + honorLabels: {{ .Values.clusterOperator.metrics.podMonitor.honorLabels }} + {{- end }} + {{- if .Values.clusterOperator.metrics.podMonitor.relabelings }} + relabelings: {{- include "common.tplvalues.render" ( dict "value" .Values.clusterOperator.metrics.podMonitor.relabelings "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.clusterOperator.metrics.podMonitor.metricRelabelings }} + metricRelabelings: {{- include "common.tplvalues.render" ( dict "value" .Values.clusterOperator.metrics.podMonitor.metricRelabelings "context" $) | nindent 8 }} + {{- end }} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/role.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/role.yaml new file mode 100644 index 000000000..71c6dd55f --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/role.yaml @@ -0,0 +1,37 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.clusterOperator.rbac.create }} +apiVersion: {{ include "common.capabilities.rbac.apiVersion" . }} +kind: Role +metadata: + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: rabbitmq-operator + app.kubernetes.io/part-of: rabbitmq + name: {{ template "rmqco.clusterOperator.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +rules: + - apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - "" + resources: + - events + verbs: + - create +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/rolebinding.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/rolebinding.yaml new file mode 100644 index 000000000..b903ea8ea --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/rolebinding.yaml @@ -0,0 +1,26 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.clusterOperator.rbac.create }} +apiVersion: {{ include "common.capabilities.rbac.apiVersion" . }} +kind: RoleBinding +metadata: + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: rabbitmq-operator + app.kubernetes.io/part-of: rabbitmq + name: {{ template "rmqco.clusterOperator.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "rmqco.clusterOperator.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ template "rmqco.clusterOperator.serviceAccountName" . }} + namespace: {{ include "common.names.namespace" . | quote }} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/service-account.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/service-account.yaml new file mode 100644 index 000000000..848c67888 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/service-account.yaml @@ -0,0 +1,20 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.clusterOperator.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: rabbitmq-operator + app.kubernetes.io/part-of: rabbitmq + name: {{ template "rmqco.clusterOperator.serviceAccountName" . }} + namespace: {{ include "common.names.namespace" . | quote }} + {{- if or .Values.commonAnnotations .Values.clusterOperator.serviceAccount.annotations }} + {{- $annotations := include "common.tplvalues.merge" ( dict "values" ( list .Values.clusterOperator.serviceAccount.annotations .Values.commonAnnotations ) "context" . ) }} + annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $) | nindent 4 }} + {{- end }} +automountServiceAccountToken: {{ .Values.clusterOperator.serviceAccount.automountServiceAccountToken }} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/servicemonitor.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/servicemonitor.yaml new file mode 100644 index 000000000..11adb4523 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/cluster-operator/servicemonitor.yaml @@ -0,0 +1,56 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if and .Values.clusterOperator.metrics.serviceMonitor.enabled .Values.clusterOperator.metrics.service.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "rmqco.clusterOperator.fullname" . }} + {{- $labels := include "common.tplvalues.merge" ( dict "values" ( list .Values.clusterOperator.metrics.serviceMonitor.labels .Values.commonLabels ) "context" . ) }} + labels: {{- include "common.labels.standard" ( dict "customLabels" $labels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: rabbitmq-operator + app.kubernetes.io/part-of: rabbitmq + {{- if .Values.clusterOperator.metrics.serviceMonitor.additionalLabels }} + {{- include "common.tplvalues.render" (dict "value" .Values.clusterOperator.metrics.serviceMonitor.additionalLabels "context" $) | nindent 4 }} + {{- end }} + namespace: {{ default (include "common.names.namespace" .) .Values.clusterOperator.metrics.serviceMonitor.namespace | quote }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + jobLabel: {{ .Values.clusterOperator.metrics.serviceMonitor.jobLabel }} + selector: + matchLabels: {{- include "common.labels.matchLabels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 6 }} + app.kubernetes.io/component: rabbitmq-operator + {{- if .Values.clusterOperator.metrics.serviceMonitor.selector }} + {{- include "common.tplvalues.render" ( dict "value" .Values.clusterOperator.metrics.serviceMonitor.selector "context" $ ) | nindent 6 }} + {{- end }} + namespaceSelector: + matchNames: + - {{ include "common.names.namespace" . | quote }} + endpoints: + - port: http + {{- if .Values.clusterOperator.metrics.serviceMonitor.path }} + path: {{ .Values.clusterOperator.metrics.serviceMonitor.path }} + {{- end }} + {{- if .Values.clusterOperator.metrics.serviceMonitor.params }} + params: {{ toYaml .Values.clusterOperator.metrics.serviceMonitor.params | nindent 8 }} + {{- end }} + {{- if .Values.clusterOperator.metrics.serviceMonitor.interval }} + interval: {{ .Values.clusterOperator.metrics.serviceMonitor.interval }} + {{- end }} + {{- if .Values.clusterOperator.metrics.serviceMonitor.honorLabels }} + honorLabels: {{ .Values.clusterOperator.metrics.serviceMonitor.honorLabels }} + {{- end }} + {{- if .Values.clusterOperator.metrics.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.clusterOperator.metrics.serviceMonitor.scrapeTimeout }} + {{- end }} + {{- if .Values.clusterOperator.metrics.serviceMonitor.relabelings }} + relabelings: {{- include "common.tplvalues.render" ( dict "value" .Values.clusterOperator.metrics.serviceMonitor.relabelings "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.clusterOperator.metrics.serviceMonitor.metricRelabelings }} + metricRelabelings: {{- include "common.tplvalues.render" ( dict "value" .Values.clusterOperator.metrics.serviceMonitor.metricRelabelings "context" $) | nindent 8 }} + {{- end }} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/extra-list.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/extra-list.yaml new file mode 100644 index 000000000..329f5c653 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/extra-list.yaml @@ -0,0 +1,9 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- range .Values.extraDeploy }} +--- +{{ include "common.tplvalues.render" (dict "value" . "context" $) }} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/issuer.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/issuer.yaml new file mode 100644 index 000000000..c85ca339f --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/issuer.yaml @@ -0,0 +1,16 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.useCertManager }} +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/part-of: rabbitmq + name: {{ template "common.names.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} +spec: + selfSigned: {} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/aggregate-cluster-roles.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/aggregate-cluster-roles.yaml new file mode 100644 index 000000000..dd6510f99 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/aggregate-cluster-roles.yaml @@ -0,0 +1,44 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if and .Values.msgTopologyOperator.enabled .Values.msgTopologyOperator.rbac.create -}} +{{- $readonlyVerbs := list "get" "list" "watch" }} +{{- $allVerbs := list "create" "delete" "deletecollection" "get" "list" "patch" "update" "watch" }} +{{- $roles := dict "view" $readonlyVerbs "edit" $allVerbs "admin" $allVerbs }} +{{- $versionLabel := dict "app.kubernetes.io/version" ( include "common.images.version" ( dict "imageRoot" .Values.msgTopologyOperator.image "chart" .Chart ) ) }} +{{- $labels := include "common.tplvalues.merge" ( dict "values" ( list .Values.commonLabels $versionLabel ) "context" . ) }} +{{- range $role, $verbs := $roles -}} +--- +apiVersion: {{ include "common.capabilities.rbac.apiVersion" $ }} +kind: ClusterRole +metadata: + name: {{ template "rmqco.msgTopologyOperator.fullname.namespace" $ }}-{{ $role }} + labels: {{- include "common.labels.standard" ( dict "customLabels" $labels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: messaging-topology-operator + app.kubernetes.io/part-of: rabbitmq + rbac.authorization.k8s.io/aggregate-to-{{ $role }}: "true" + {{- if $.Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" $.Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +rules: + - apiGroups: + - rabbitmq.com + resources: + - bindings + - exchanges + - federations + - operatorpolicies + - permissions + - policies + - queues + - schemareplications + - shovels + - superstreams + - topicpermissions + - users + - vhosts + verbs: {{ $verbs | toYaml | nindent 6 }} +{{ end }} +{{- end -}} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/certificate.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/certificate.yaml new file mode 100644 index 000000000..76a05c3fa --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/certificate.yaml @@ -0,0 +1,29 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if and (.Values.msgTopologyOperator.enabled) (.Values.useCertManager) (not .Values.msgTopologyOperator.existingWebhookCertSecret) }} +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + {{- $versionLabel := dict "app.kubernetes.io/version" ( include "common.images.version" ( dict "imageRoot" .Values.msgTopologyOperator.image "chart" .Chart ) ) }} + {{- $labels := include "common.tplvalues.merge" ( dict "values" ( list .Values.commonLabels $versionLabel ) "context" . ) }} + labels: {{- include "common.labels.standard" ( dict "customLabels" $labels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: messaging-topology-operator + app.kubernetes.io/part-of: rabbitmq + name: {{ template "rmqco.msgTopologyOperator.webhook.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + commonName: {{ template "rmqco.msgTopologyOperator.webhook.fullname" . }} + dnsNames: + - {{ printf "%s.%s.svc" (include "rmqco.msgTopologyOperator.webhook.fullname" .) (include "common.names.namespace" .) }} + - {{ printf "%s.%s.svc.%s" (include "rmqco.msgTopologyOperator.webhook.fullname" .) (include "common.names.namespace" .) .Values.clusterDomain }} + issuerRef: + kind: Issuer + name: {{ template "common.names.fullname" . }} + secretName: {{ template "rmqco.msgTopologyOperator.webhook.fullname" . }} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/clusterrole.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/clusterrole.yaml new file mode 100644 index 000000000..51fc9cbd0 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/clusterrole.yaml @@ -0,0 +1,414 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if and .Values.msgTopologyOperator.enabled .Values.msgTopologyOperator.rbac.create }} +apiVersion: {{ include "common.capabilities.rbac.apiVersion" . }} +kind: ClusterRole +metadata: + {{- $versionLabel := dict "app.kubernetes.io/version" ( include "common.images.version" ( dict "imageRoot" .Values.msgTopologyOperator.image "chart" .Chart ) ) }} + {{- $labels := include "common.tplvalues.merge" ( dict "values" ( list .Values.commonLabels $versionLabel ) "context" . ) }} + labels: {{- include "common.labels.standard" ( dict "customLabels" $labels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: messaging-topology-operator + app.kubernetes.io/part-of: rabbitmq + name: {{ template "rmqco.msgTopologyOperator.fullname.namespace" . }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +rules: + {{- if .Values.msgTopologyOperator.rbac.clusterRole.customRules }} + {{- range .Values.msgTopologyOperator.rbac.clusterRole.customRules }} + - apiGroups: {{ .apiGroups | toYaml | nindent 6 }} + resources: {{ .resources | toYaml | nindent 6 }} + verbs: {{ .verbs | toYaml | nindent 6 }} + {{- end }} + {{- else }} + {{- if .Values.msgTopologyOperator.rbac.clusterRole.extraRules }} + {{- range .Values.msgTopologyOperator.rbac.clusterRole.extraRules }} + - apiGroups: {{ .apiGroups | toYaml | nindent 6 }} + resources: {{ .resources | toYaml | nindent 6 }} + verbs: {{ .verbs | toYaml | nindent 6 }} + {{- end }} + {{- end }} + - apiGroups: + - "" + resources: + - events + verbs: + - create + - get + - patch + - apiGroups: + - "" + resources: + - secrets + verbs: + - create + - get + - list + - patch + - update + - watch + - apiGroups: + - "" + resources: + - services + verbs: + - get + - list + - watch + - apiGroups: + - rabbitmq.com + resources: + - bindings + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - rabbitmq.com + resources: + - bindings/status + verbs: + - get + - patch + - update + - apiGroups: + - rabbitmq.com + resources: + - bindings/finalizers + verbs: + - update + - apiGroups: + - rabbitmq.com + resources: + - exchanges + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - rabbitmq.com + resources: + - exchanges/status + verbs: + - get + - patch + - update + - apiGroups: + - rabbitmq.com + resources: + - exchanges/finalizers + verbs: + - update + - apiGroups: + - rabbitmq.com + resources: + - federations + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - rabbitmq.com + resources: + - federations/status + verbs: + - get + - patch + - update + - apiGroups: + - rabbitmq.com + resources: + - federations/finalizers + verbs: + - update + - apiGroups: + - rabbitmq.com + resources: + - permissions + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - rabbitmq.com + resources: + - permissions/status + verbs: + - get + - patch + - update + - apiGroups: + - rabbitmq.com + resources: + - permissions/finalizers + verbs: + - update + - apiGroups: + - rabbitmq.com + resources: + - policies + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - rabbitmq.com + resources: + - policies/status + verbs: + - get + - patch + - update + - apiGroups: + - rabbitmq.com + resources: + - policies/finalizers + verbs: + - update + - apiGroups: + - rabbitmq.com + resources: + - queues + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - rabbitmq.com + resources: + - queues/status + verbs: + - get + - patch + - update + - apiGroups: + - rabbitmq.com + resources: + - queues/finalizers + verbs: + - update + - apiGroups: + - rabbitmq.com + resources: + - rabbitmqclusters + verbs: + - get + - list + - watch + - apiGroups: + - rabbitmq.com + resources: + - rabbitmqclusters/status + verbs: + - get + - apiGroups: + - rabbitmq.com + resources: + - schemareplications + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - rabbitmq.com + resources: + - schemareplications/status + verbs: + - get + - patch + - update + - apiGroups: + - rabbitmq.com + resources: + - schemareplications/finalizers + verbs: + - update + - apiGroups: + - rabbitmq.com + resources: + - shovels + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - rabbitmq.com + resources: + - shovels/status + verbs: + - get + - patch + - update + - apiGroups: + - rabbitmq.com + resources: + - shovels/finalizers + verbs: + - update + - apiGroups: + - rabbitmq.com + resources: + - superstreams + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - rabbitmq.com + resources: + - superstreams/status + verbs: + - get + - patch + - update + - apiGroups: + - rabbitmq.com + resources: + - superstreams/finalizers + verbs: + - update + - apiGroups: + - rabbitmq.com + resources: + - users + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - rabbitmq.com + resources: + - users/status + verbs: + - get + - patch + - update + - apiGroups: + - rabbitmq.com + resources: + - users/finalizers + verbs: + - update + - apiGroups: + - rabbitmq.com + resources: + - vhosts + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - rabbitmq.com + resources: + - vhosts/status + verbs: + - get + - patch + - update + - apiGroups: + - rabbitmq.com + resources: + - vhosts/finalizers + verbs: + - update + - apiGroups: + - rabbitmq.com + resources: + - topicpermissions + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - rabbitmq.com + resources: + - topicpermissions/status + verbs: + - get + - patch + - update + - apiGroups: + - rabbitmq.com + resources: + - topicpermissions/finalizers + verbs: + - update + - apiGroups: + - rabbitmq.com + resources: + - operatorpolicies + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - rabbitmq.com + resources: + - operatorpolicies/status + verbs: + - get + - patch + - update + - apiGroups: + - rabbitmq.com + resources: + - operatorpolicies/finalizers + verbs: + - update + {{- end }} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/clusterrolebinding.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/clusterrolebinding.yaml new file mode 100644 index 000000000..d97405540 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/clusterrolebinding.yaml @@ -0,0 +1,51 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if and .Values.msgTopologyOperator.enabled .Values.msgTopologyOperator.rbac.create }} +{{- if .Values.msgTopologyOperator.watchAllNamespaces }} +apiVersion: {{ include "common.capabilities.rbac.apiVersion" . }} +kind: ClusterRoleBinding +metadata: + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: messaging-topology-operator + app.kubernetes.io/part-of: rabbitmq + name: {{ template "rmqco.msgTopologyOperator.fullname.namespace" . }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "rmqco.msgTopologyOperator.fullname.namespace" . }} +subjects: + - kind: ServiceAccount + name: {{ template "rmqco.msgTopologyOperator.serviceAccountName" . }} + namespace: {{ include "common.names.namespace" . | quote }} +{{- else }} +{{- $watchNamespaces := default (list (include "common.names.namespace" .)) .Values.msgTopologyOperator.watchNamespaces }} +{{- range $namespace := $watchNamespaces }} +--- +kind: RoleBinding +apiVersion: {{ include "common.capabilities.rbac.apiVersion" $ }} +metadata: + name: {{ printf "%s-%s" (include "rmqco.msgTopologyOperator.fullname" $) $namespace | trunc 63 | trimSuffix "-" }} + namespace: {{ $namespace | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" $.Values.commonLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: messaging-topology-operator + app.kubernetes.io/part-of: rabbitmq + {{- if $.Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" $.Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "rmqco.msgTopologyOperator.fullname.namespace" $ }} +subjects: + - kind: ServiceAccount + name: {{ template "rmqco.msgTopologyOperator.serviceAccountName" $ }} + namespace: {{ include "common.names.namespace" $ | quote }} +{{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/deployment.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/deployment.yaml new file mode 100644 index 000000000..85b3d44e2 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/deployment.yaml @@ -0,0 +1,183 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.msgTopologyOperator.enabled }} +apiVersion: {{ include "common.capabilities.deployment.apiVersion" . }} +kind: Deployment +metadata: + name: {{ template "rmqco.msgTopologyOperator.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + {{- $versionLabel := dict "app.kubernetes.io/version" ( include "common.images.version" ( dict "imageRoot" .Values.msgTopologyOperator.image "chart" .Chart ) ) }} + {{- $labels := include "common.tplvalues.merge" ( dict "values" ( list .Values.commonLabels $versionLabel ) "context" . ) }} + labels: {{- include "common.labels.standard" ( dict "customLabels" $labels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: messaging-topology-operator + app.kubernetes.io/part-of: rabbitmq + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.msgTopologyOperator.replicaCount }} + revisionHistoryLimit: {{ .Values.msgTopologyOperator.revisionHistoryLimit }} + {{- if .Values.msgTopologyOperator.updateStrategy }} + strategy: {{- toYaml .Values.msgTopologyOperator.updateStrategy | nindent 4 }} + {{- end }} + {{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.msgTopologyOperator.podLabels .Values.commonLabels $versionLabel ) "context" . ) }} + selector: + matchLabels: {{- include "common.labels.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 6 }} + app.kubernetes.io/component: messaging-topology-operator + template: + metadata: + {{- if .Values.msgTopologyOperator.podAnnotations }} + annotations: {{- include "common.tplvalues.render" (dict "value" .Values.msgTopologyOperator.podAnnotations "context" $) | nindent 8 }} + {{- end }} + labels: {{- include "common.labels.standard" ( dict "customLabels" $podLabels "context" $ ) | nindent 8 }} + app.kubernetes.io/component: messaging-topology-operator + app.kubernetes.io/part-of: rabbitmq + spec: + serviceAccountName: {{ template "rmqco.msgTopologyOperator.serviceAccountName" . }} + {{- include "rmqco.imagePullSecrets" . | nindent 6 }} + automountServiceAccountToken: {{ .Values.msgTopologyOperator.automountServiceAccountToken }} + {{- if .Values.msgTopologyOperator.hostAliases }} + hostAliases: {{- include "common.tplvalues.render" (dict "value" .Values.msgTopologyOperator.hostAliases "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.msgTopologyOperator.topologySpreadConstraints }} + topologySpreadConstraints: {{- include "common.tplvalues.render" (dict "value" .Values.msgTopologyOperator.topologySpreadConstraints "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.msgTopologyOperator.schedulerName }} + schedulerName: {{ .Values.msgTopologyOperator.schedulerName | quote }} + {{- end }} + {{- if .Values.msgTopologyOperator.affinity }} + affinity: {{- include "common.tplvalues.render" ( dict "value" .Values.msgTopologyOperator.affinity "context" $) | nindent 8 }} + {{- else }} + affinity: + podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.msgTopologyOperator.podAffinityPreset "component" "messaging-topology-operator" "customLabels" $podLabels "context" $) | nindent 10 }} + podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.msgTopologyOperator.podAntiAffinityPreset "component" "messaging-topology-operator" "customLabels" $podLabels "context" $) | nindent 10 }} + nodeAffinity: {{- include "common.affinities.nodes" (dict "type" .Values.msgTopologyOperator.nodeAffinityPreset.type "key" .Values.msgTopologyOperator.nodeAffinityPreset.key "values" .Values.msgTopologyOperator.nodeAffinityPreset.values) | nindent 10 }} + {{- end }} + {{- if .Values.msgTopologyOperator.nodeSelector }} + nodeSelector: {{- include "common.tplvalues.render" ( dict "value" .Values.msgTopologyOperator.nodeSelector "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.msgTopologyOperator.tolerations }} + tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.msgTopologyOperator.tolerations "context" .) | nindent 8 }} + {{- end }} + {{- if .Values.msgTopologyOperator.priorityClassName }} + priorityClassName: {{ .Values.msgTopologyOperator.priorityClassName | quote }} + {{- end }} + {{- if .Values.msgTopologyOperator.podSecurityContext.enabled }} + securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.msgTopologyOperator.podSecurityContext "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.msgTopologyOperator.terminationGracePeriodSeconds }} + terminationGracePeriodSeconds: {{ .Values.msgTopologyOperator.terminationGracePeriodSeconds }} + {{- end }} + {{- if .Values.msgTopologyOperator.hostNetwork }} + hostNetwork: {{ .Values.msgTopologyOperator.hostNetwork }} + {{- end }} + {{- if .Values.msgTopologyOperator.dnsPolicy }} + dnsPolicy: {{ .Values.msgTopologyOperator.dnsPolicy }} + {{- end }} + initContainers: + {{- if .Values.msgTopologyOperator.initContainers }} + {{- include "common.tplvalues.render" (dict "value" .Values.msgTopologyOperator.initContainers "context" $) | nindent 8 }} + {{- end }} + containers: + - name: rabbitmq-cluster-operator + image: {{ template "rmqco.msgTopologyOperator.image" . }} + imagePullPolicy: {{ .Values.msgTopologyOperator.image.pullPolicy }} + {{- if .Values.msgTopologyOperator.containerSecurityContext.enabled }} + securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.msgTopologyOperator.containerSecurityContext "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.msgTopologyOperator.command }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.msgTopologyOperator.command "context" $) | nindent 12 }} + {{- else }} + command: + - /manager + {{- end }} + {{- if .Values.msgTopologyOperator.args }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.msgTopologyOperator.args "context" $) | nindent 12 }} + {{- else }} + args: + - --metrics-bind-address=:{{ .Values.msgTopologyOperator.containerPorts.metrics }} + {{- end }} + env: + - name: OPERATOR_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- if not .Values.msgTopologyOperator.watchAllNamespaces }} + {{- $watchNamespaces := default (list (include "common.names.namespace" .)) .Values.msgTopologyOperator.watchNamespaces }} + - name: OPERATOR_SCOPE_NAMESPACE + value: {{ join "," $watchNamespaces | quote }} + {{- end }} + {{- if .Values.msgTopologyOperator.extraEnvVars }} + {{- include "common.tplvalues.render" (dict "value" .Values.msgTopologyOperator.extraEnvVars "context" $) | nindent 12 }} + {{- end }} + envFrom: + {{- if .Values.msgTopologyOperator.extraEnvVarsCM }} + - configMapRef: + name: {{ include "common.tplvalues.render" (dict "value" .Values.msgTopologyOperator.extraEnvVarsCM "context" $) }} + {{- end }} + {{- if .Values.msgTopologyOperator.extraEnvVarsSecret }} + - secretRef: + name: {{ include "common.tplvalues.render" (dict "value" .Values.msgTopologyOperator.extraEnvVarsSecret "context" $) }} + {{- end }} + {{- if .Values.msgTopologyOperator.resources }} + resources: {{- toYaml .Values.msgTopologyOperator.resources | nindent 12 }} + {{- else if ne .Values.msgTopologyOperator.resourcesPreset "none" }} + resources: {{- include "common.resources.preset" (dict "type" .Values.msgTopologyOperator.resourcesPreset) | nindent 12 }} + {{- end }} + ports: + - name: https-webhook + containerPort: 9443 + protocol: TCP + - name: http-metrics + containerPort: {{ .Values.msgTopologyOperator.containerPorts.metrics }} + protocol: TCP + {{- if not .Values.diagnosticMode.enabled }} + {{- if .Values.msgTopologyOperator.customLivenessProbe }} + livenessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.msgTopologyOperator.customLivenessProbe "context" $) | nindent 12 }} + {{- else if .Values.msgTopologyOperator.livenessProbe.enabled }} + livenessProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.msgTopologyOperator.livenessProbe "enabled") "context" $) | nindent 12 }} + tcpSocket: + port: http-metrics + {{- end }} + {{- if .Values.msgTopologyOperator.customReadinessProbe }} + readinessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.msgTopologyOperator.customReadinessProbe "context" $) | nindent 12 }} + {{- else if .Values.msgTopologyOperator.readinessProbe.enabled }} + readinessProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.msgTopologyOperator.readinessProbe "enabled") "context" $) | nindent 12 }} + httpGet: + path: /metrics + port: http-metrics + {{- end }} + {{- if .Values.msgTopologyOperator.customStartupProbe }} + startupProbe: {{- include "common.tplvalues.render" (dict "value" .Values.msgTopologyOperator.customStartupProbe "context" $) | nindent 12 }} + {{- else if .Values.msgTopologyOperator.startupProbe.enabled }} + startupProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.msgTopologyOperator.startupProbe "enabled") "context" $) | nindent 12 }} + httpGet: + path: /metrics + port: http-metrics + {{- end }} + {{- end }} + {{- if .Values.msgTopologyOperator.lifecycleHooks }} + lifecycle: {{- include "common.tplvalues.render" (dict "value" .Values.msgTopologyOperator.lifecycleHooks "context" $) | nindent 12 }} + {{- end }} + volumeMounts: + - mountPath: /tmp/k8s-webhook-server/serving-certs + name: cert + readOnly: true + {{- if .Values.msgTopologyOperator.extraVolumeMounts }} + {{- include "common.tplvalues.render" (dict "value" .Values.msgTopologyOperator.extraVolumeMounts "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.msgTopologyOperator.sidecars }} + {{- include "common.tplvalues.render" ( dict "value" .Values.msgTopologyOperator.sidecars "context" $) | nindent 8 }} + {{- end }} + volumes: + - name: cert + secret: + defaultMode: 420 + secretName: {{ template "rmqco.msgTopologyOperator.webhook.secretName" . }} + {{- if .Values.msgTopologyOperator.extraVolumes }} + {{- include "common.tplvalues.render" (dict "value" .Values.msgTopologyOperator.extraVolumes "context" $) | nindent 8 }} + {{- end }} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/metrics-service.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/metrics-service.yaml new file mode 100644 index 000000000..f57e04f93 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/metrics-service.yaml @@ -0,0 +1,58 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if and .Values.msgTopologyOperator.enabled .Values.msgTopologyOperator.metrics.service.enabled }} +apiVersion: v1 +kind: Service +metadata: + {{- $versionLabel := dict "app.kubernetes.io/version" ( include "common.images.version" ( dict "imageRoot" .Values.msgTopologyOperator.image "chart" .Chart ) ) }} + {{- $labels := include "common.tplvalues.merge" ( dict "values" ( list .Values.commonLabels $versionLabel ) "context" . ) }} + labels: {{- include "common.labels.standard" ( dict "customLabels" $labels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: messaging-topology-operator + app.kubernetes.io/part-of: rabbitmq + type: metrics + name: {{ printf "%s-metrics" (include "rmqco.msgTopologyOperator.fullname" .) | trunc 63 | trimSuffix "-" }} + namespace: {{ include "common.names.namespace" . | quote }} + {{- if or .Values.commonAnnotations .Values.msgTopologyOperator.metrics.service.annotations }} + {{- $annotations := include "common.tplvalues.merge" ( dict "values" ( list .Values.msgTopologyOperator.metrics.service.annotations .Values.commonAnnotations ) "context" . ) }} + annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $) | nindent 4 }} + {{- end }} +spec: + type: {{ .Values.msgTopologyOperator.metrics.service.type }} + {{- if (or (eq .Values.msgTopologyOperator.metrics.service.type "LoadBalancer") (eq .Values.msgTopologyOperator.metrics.service.type "NodePort")) }} + externalTrafficPolicy: {{ .Values.msgTopologyOperator.metrics.service.externalTrafficPolicy | quote }} + {{- end }} + {{- if .Values.msgTopologyOperator.metrics.service.clusterIP }} + clusterIP: {{ .Values.msgTopologyOperator.metrics.service.clusterIP }} + {{- end }} + {{- if eq .Values.msgTopologyOperator.metrics.service.type "LoadBalancer" }} + loadBalancerSourceRanges: {{ .Values.msgTopologyOperator.metrics.service.loadBalancerSourceRanges }} + {{- end }} + {{- if (and (eq .Values.msgTopologyOperator.metrics.service.type "LoadBalancer") (not (empty .Values.msgTopologyOperator.metrics.service.loadBalancerIP))) }} + loadBalancerIP: {{ .Values.msgTopologyOperator.metrics.service.loadBalancerIP }} + {{- end }} + {{- if .Values.msgTopologyOperator.metrics.service.sessionAffinity }} + sessionAffinity: {{ .Values.msgTopologyOperator.metrics.service.sessionAffinity }} + {{- end }} + {{- if .Values.msgTopologyOperator.metrics.service.sessionAffinityConfig }} + sessionAffinityConfig: {{- include "common.tplvalues.render" (dict "value" .Values.msgTopologyOperator.metrics.service.sessionAffinityConfig "context" $) | nindent 4 }} + {{- end }} + ports: + - name: http + port: {{ .Values.msgTopologyOperator.metrics.service.ports.http }} + targetPort: http-metrics + protocol: TCP + {{- if (and (or (eq .Values.msgTopologyOperator.metrics.service.type "NodePort") (eq .Values.msgTopologyOperator.metrics.service.type "LoadBalancer")) (not (empty .Values.msgTopologyOperator.metrics.service.nodePorts.http))) }} + nodePort: {{ .Values.msgTopologyOperator.metrics.service.nodePorts.http }} + {{- else if eq .Values.msgTopologyOperator.metrics.service.type "ClusterIP" }} + nodePort: null + {{- end }} + {{- if .Values.msgTopologyOperator.metrics.service.extraPorts }} + {{- include "common.tplvalues.render" (dict "value" .Values.msgTopologyOperator.metrics.service.extraPorts "context" $) | nindent 4 }} + {{- end }} + {{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.msgTopologyOperator.podLabels .Values.commonLabels ) "context" . ) }} + selector: {{- include "common.labels.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: messaging-topology-operator +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/networkpolicy.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/networkpolicy.yaml new file mode 100644 index 000000000..b22855844 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/networkpolicy.yaml @@ -0,0 +1,98 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.msgTopologyOperator.networkPolicy.enabled }} +kind: NetworkPolicy +apiVersion: {{ include "common.capabilities.networkPolicy.apiVersion" . }} +metadata: + name: {{ template "rmqco.msgTopologyOperator.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: messaging-topology-operator + app.kubernetes.io/part-of: rabbitmq + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + {{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.msgTopologyOperator.podLabels .Values.commonLabels ) "context" . ) }} + podSelector: + matchLabels: {{- include "common.labels.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 6 }} + app.kubernetes.io/component: messaging-topology-operator + app.kubernetes.io/part-of: rabbitmq + policyTypes: + - Ingress + - Egress + {{- if .Values.msgTopologyOperator.networkPolicy.allowExternalEgress }} + egress: + - {} + {{- else }} + egress: + - ports: + # Allow dns resolution + - port: 53 + protocol: UDP + - port: 53 + protocol: TCP + # Allow rabbitmq api + - port: 15672 + protocol: TCP + # Allow access to kube-apiserver + {{- range $port := .Values.msgTopologyOperator.networkPolicy.kubeAPIServerPorts }} + - port: {{ $port }} + {{- end }} + # RabbitMQCluster instances have the label app.kubernetes.io/component: rabbitmq + - to: + - podSelector: + matchLabels: + app.kubernetes.io/component: rabbitmq + {{- if not .Values.msgTopologyOperator.watchAllNamespaces }} + {{- $watchNamespaces := default (list (include "common.names.namespace" .)) .Values.msgTopologyOperator.watchNamespaces }} + namespaceSelector: + matchExpressions: + - key: namespace + operator: In + values: + {{- range $namespace := $watchNamespaces }} + - {{ $namespace }} + {{- end }} + {{- end }} + {{- if .Values.msgTopologyOperator.networkPolicy.extraEgress }} + {{- include "common.tplvalues.render" ( dict "value" .Values.msgTopologyOperator.networkPolicy.extraEgress "context" $ ) | nindent 4 }} + {{- end }} + {{- end }} + ingress: + - ports: + {{/* Webhook port is hardcoded in the operator code */}} + - port: 9443 + {{- if .Values.msgTopologyOperator.metrics.enabled }} + - port: {{ .Values.msgTopologyOperator.containerPorts.metrics }} + {{- end }} + {{- if not .Values.msgTopologyOperator.networkPolicy.allowExternal }} + from: + - podSelector: + matchLabels: {{- include "common.labels.matchLabels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 14 }} + app.kubernetes.io/part-of: rabbitmq + - podSelector: + matchLabels: + {{ template "rmqco.msgTopologyOperator.fullname" . }}-client: "true" + {{- if .Values.msgTopologyOperator.networkPolicy.ingressNSMatchLabels }} + - namespaceSelector: + matchLabels: + {{- range $key, $value := .Values.msgTopologyOperator.networkPolicy.ingressNSMatchLabels }} + {{ $key | quote }}: {{ $value | quote }} + {{- end }} + {{- if .Values.msgTopologyOperator.networkPolicy.ingressNSPodMatchLabels }} + podSelector: + matchLabels: + {{- range $key, $value := .Values.msgTopologyOperator.networkPolicy.ingressNSPodMatchLabels }} + {{ $key | quote }}: {{ $value | quote }} + {{- end }} + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.msgTopologyOperator.networkPolicy.extraIngress }} + {{- include "common.tplvalues.render" ( dict "value" .Values.msgTopologyOperator.networkPolicy.extraIngress "context" $ ) | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/podmonitor.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/podmonitor.yaml new file mode 100644 index 000000000..47636d313 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/podmonitor.yaml @@ -0,0 +1,53 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if and .Values.msgTopologyOperator.enabled .Values.msgTopologyOperator.metrics.podMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + name: {{ template "rmqco.msgTopologyOperator.fullname" . }} + {{- $versionLabel := dict "app.kubernetes.io/version" ( include "common.images.version" ( dict "imageRoot" .Values.msgTopologyOperator.image "chart" .Chart ) ) }} + {{- $labels := include "common.tplvalues.merge" ( dict "values" ( list .Values.msgTopologyOperator.metrics.podMonitor.labels .Values.commonLabels $versionLabel ) "context" . ) }} + labels: {{- include "common.labels.standard" ( dict "customLabels" $labels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: messaging-topology-operator + app.kubernetes.io/part-of: rabbitmq + {{- if .Values.msgTopologyOperator.metrics.podMonitor.additionalLabels }} + {{- include "common.tplvalues.render" (dict "value" .Values.msgTopologyOperator.metrics.podMonitor.additionalLabels "context" $) | nindent 4 }} + {{- end }} + namespace: {{ default (include "common.names.namespace" .) .Values.msgTopologyOperator.metrics.podMonitor.namespace | quote }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + jobLabel: {{ .Values.msgTopologyOperator.metrics.podMonitor.jobLabel }} + selector: + matchLabels: + {{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.msgTopologyOperator.podLabels .Values.commonLabels ) "context" . ) }} + {{- include "common.labels.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 6 }} + {{- if .Values.msgTopologyOperator.metrics.podMonitor.selector }} + {{- include "common.tplvalues.render" ( dict "value" .Values.msgTopologyOperator.metrics.podMonitor.selector "context" $ ) | nindent 6 }} + {{- end }} + app.kubernetes.io/component: rabbitmq-operator + namespaceSelector: + matchNames: + - {{ include "common.names.namespace" . | quote }} + podMetricsEndpoints: + - port: http + {{- if .Values.msgTopologyOperator.metrics.podMonitor.interval }} + interval: {{ .Values.msgTopologyOperator.metrics.podMonitor.interval }} + {{- end }} + {{- if .Values.msgTopologyOperator.metrics.podMonitor.honorLabels }} + honorLabels: {{ .Values.msgTopologyOperator.metrics.podMonitor.honorLabels }} + {{- end }} + {{- if .Values.msgTopologyOperator.metrics.podMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.msgTopologyOperator.metrics.podMonitor.scrapeTimeout }} + {{- end }} + {{- if .Values.msgTopologyOperator.metrics.podMonitor.relabelings }} + relabelings: {{ toYaml .Values.msgTopologyOperator.metrics.podMonitor.relabelings | nindent 8 }} + {{- end }} + {{- if .Values.msgTopologyOperator.metrics.podMonitor.metricRelabelings }} + metricRelabelings: {{ toYaml .Values.msgTopologyOperator.metrics.podMonitor.metricRelabelings | nindent 8 }} + {{- end }} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/role.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/role.yaml new file mode 100644 index 000000000..aeffa65e3 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/role.yaml @@ -0,0 +1,51 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if and .Values.msgTopologyOperator.enabled .Values.msgTopologyOperator.rbac.create }} +apiVersion: {{ include "common.capabilities.rbac.apiVersion" . }} +kind: Role +metadata: + {{- $versionLabel := dict "app.kubernetes.io/version" ( include "common.images.version" ( dict "imageRoot" .Values.msgTopologyOperator.image "chart" .Chart ) ) }} + {{- $labels := include "common.tplvalues.merge" ( dict "values" ( list .Values.commonLabels $versionLabel ) "context" . ) }} + labels: {{- include "common.labels.standard" ( dict "customLabels" $labels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: messaging-topology-operator + app.kubernetes.io/part-of: rabbitmq + name: {{ template "rmqco.msgTopologyOperator.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +rules: + - apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - "" + resources: + - events + verbs: + - create + - apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/rolebinding.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/rolebinding.yaml new file mode 100644 index 000000000..3432b5f8d --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/rolebinding.yaml @@ -0,0 +1,28 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if and .Values.msgTopologyOperator.enabled .Values.msgTopologyOperator.rbac.create }} +apiVersion: {{ include "common.capabilities.rbac.apiVersion" . }} +kind: RoleBinding +metadata: + {{- $versionLabel := dict "app.kubernetes.io/version" ( include "common.images.version" ( dict "imageRoot" .Values.msgTopologyOperator.image "chart" .Chart ) ) }} + {{- $labels := include "common.tplvalues.merge" ( dict "values" ( list .Values.commonLabels $versionLabel ) "context" . ) }} + labels: {{- include "common.labels.standard" ( dict "customLabels" $labels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: messaging-topology-operator + app.kubernetes.io/part-of: rabbitmq + name: {{ template "rmqco.msgTopologyOperator.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "rmqco.msgTopologyOperator.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ template "rmqco.msgTopologyOperator.serviceAccountName" . }} + namespace: {{ include "common.names.namespace" . | quote }} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/service-account.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/service-account.yaml new file mode 100644 index 000000000..52c72ab61 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/service-account.yaml @@ -0,0 +1,22 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if and .Values.msgTopologyOperator.enabled .Values.msgTopologyOperator.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + {{- $versionLabel := dict "app.kubernetes.io/version" ( include "common.images.version" ( dict "imageRoot" .Values.msgTopologyOperator.image "chart" .Chart ) ) }} + {{- $labels := include "common.tplvalues.merge" ( dict "values" ( list .Values.commonLabels $versionLabel ) "context" . ) }} + labels: {{- include "common.labels.standard" ( dict "customLabels" $labels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: messaging-topology-operator + app.kubernetes.io/part-of: rabbitmq + name: {{ template "rmqco.msgTopologyOperator.serviceAccountName" . }} + namespace: {{ include "common.names.namespace" . | quote }} + {{- if or .Values.commonAnnotations .Values.msgTopologyOperator.serviceAccount.annotations }} + {{- $annotations := include "common.tplvalues.merge" ( dict "values" ( list .Values.msgTopologyOperator.serviceAccount.annotations .Values.commonAnnotations ) "context" . ) }} + annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $) | nindent 4 }} + {{- end }} +automountServiceAccountToken: {{ .Values.msgTopologyOperator.serviceAccount.automountServiceAccountToken }} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/servicemonitor.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/servicemonitor.yaml new file mode 100644 index 000000000..b2a1c843d --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/servicemonitor.yaml @@ -0,0 +1,53 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if and .Values.msgTopologyOperator.enabled .Values.msgTopologyOperator.metrics.serviceMonitor.enabled .Values.msgTopologyOperator.metrics.service.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "rmqco.msgTopologyOperator.fullname" . }} + {{- $versionLabel := dict "app.kubernetes.io/version" ( include "common.images.version" ( dict "imageRoot" .Values.msgTopologyOperator.image "chart" .Chart ) ) }} + {{- $labels := include "common.tplvalues.merge" ( dict "values" ( list .Values.msgTopologyOperator.metrics.serviceMonitor.labels .Values.commonLabels $versionLabel ) "context" . ) }} + labels: {{- include "common.labels.standard" ( dict "customLabels" $labels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: messaging-topology-operator + app.kubernetes.io/part-of: rabbitmq + {{- if .Values.msgTopologyOperator.metrics.serviceMonitor.additionalLabels }} + {{- include "common.tplvalues.render" (dict "value" .Values.msgTopologyOperator.metrics.serviceMonitor.additionalLabels "context" $) | nindent 4 }} + {{- end }} + namespace: {{ default (include "common.names.namespace" .) .Values.msgTopologyOperator.metrics.serviceMonitor.namespace | quote }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + jobLabel: {{ .Values.msgTopologyOperator.metrics.serviceMonitor.jobLabel }} + selector: + matchLabels: {{- include "common.labels.matchLabels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 6 }} + app.kubernetes.io/component: messaging-topology-operator + # We need an extra label for the ServiceMonitor to scrape it correctly + type: metrics + {{- if .Values.msgTopologyOperator.metrics.serviceMonitor.selector }} + {{- include "common.tplvalues.render" ( dict "value" .Values.msgTopologyOperator.metrics.serviceMonitor.selector "context" $ ) | nindent 6 }} + {{- end }} + namespaceSelector: + matchNames: + - {{ include "common.names.namespace" . | quote }} + endpoints: + - port: http + {{- if .Values.msgTopologyOperator.metrics.serviceMonitor.interval }} + interval: {{ .Values.msgTopologyOperator.metrics.serviceMonitor.interval }} + {{- end }} + {{- if .Values.msgTopologyOperator.metrics.serviceMonitor.honorLabels }} + honorLabels: {{ .Values.msgTopologyOperator.metrics.serviceMonitor.honorLabels }} + {{- end }} + {{- if .Values.msgTopologyOperator.metrics.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.msgTopologyOperator.metrics.serviceMonitor.scrapeTimeout }} + {{- end }} + {{- if .Values.msgTopologyOperator.metrics.serviceMonitor.metricRelabelings }} + metricRelabelings: {{ toYaml .Values.msgTopologyOperator.metrics.serviceMonitor.metricRelabelings | nindent 8 }} + {{- end }} + {{- if .Values.msgTopologyOperator.metrics.serviceMonitor.relabelings }} + relabelings: {{ toYaml .Values.msgTopologyOperator.metrics.serviceMonitor.relabelings | nindent 8 }} + {{- end }} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/validating-webhook-configuration.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/validating-webhook-configuration.yaml new file mode 100644 index 000000000..2714a60ae --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/validating-webhook-configuration.yaml @@ -0,0 +1,358 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.msgTopologyOperator.enabled }} +{{- $versionLabel := dict "app.kubernetes.io/version" ( include "common.images.version" ( dict "imageRoot" .Values.msgTopologyOperator.image "chart" .Chart ) ) }} +{{- $labels := include "common.tplvalues.merge" ( dict "values" ( list .Values.commonLabels $versionLabel ) "context" . ) }} +{{/* + If the user does not have cert-manager and is not providing a secret with the certificates, the chart needs to generate the secret + */}} +{{- $secretName := printf "%s" (include "rmqco.msgTopologyOperator.webhook.fullname" .) }} +{{- $ca := genCA "rmq-msg-topology-ca" 365 }} +{{- $cert := genSignedCert (include "rmqco.msgTopologyOperator.fullname" .) nil (list (printf "%s.%s.svc" (include "rmqco.msgTopologyOperator.webhook.fullname" .) (include "common.names.namespace" .)) (printf "%s.%s.svc.%s" (include "rmqco.msgTopologyOperator.webhook.fullname" .) (include "common.names.namespace" .) .Values.clusterDomain)) 365 $ca }} +{{- if and (not .Values.useCertManager) (not .Values.msgTopologyOperator.existingWebhookCertSecret) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ $secretName }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" $labels "context" $ ) | nindent 4 }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +type: kubernetes.io/tls +data: + tls.crt: {{ include "common.secrets.lookup" (dict "secret" $secretName "key" "tls.crt" "defaultValue" $cert.Cert "context" $) }} + tls.key: {{ include "common.secrets.lookup" (dict "secret" $secretName "key" "tls.key" "defaultValue" $cert.Key "context" $) }} + ca.crt: {{ include "common.secrets.lookup" (dict "secret" $secretName "key" "ca.crt" "defaultValue" $ca.Cert "context" $) }} +{{- end }} +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + labels: {{- include "common.labels.standard" ( dict "customLabels" $labels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: messaging-topology-operator + app.kubernetes.io/part-of: rabbitmq + annotations: + {{- if and (.Values.useCertManager) (not .Values.msgTopologyOperator.existingWebhookCertSecret)}} + cert-manager.io/inject-ca-from: {{ printf "%s/%s" (include "common.names.namespace" .) ( include "rmqco.msgTopologyOperator.webhook.secretName" . ) }} + {{- else if and (.Values.useCertManager) (.Values.msgTopologyOperator.existingWebhookCertSecret)}} + cert-manager.io/inject-ca-from-secret: {{ printf "%s/%s" (include "common.names.namespace" .) ( include "rmqco.msgTopologyOperator.webhook.secretName" . ) }} + {{- end }} + {{- if .Values.commonAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + name: {{ template "rmqco.msgTopologyOperator.webhook.fullname.namespace" . }} +webhooks: + - admissionReviewVersions: + - v1 + clientConfig: + {{- if not .Values.useCertManager }} + caBundle: {{ include "common.secrets.lookup" (dict "secret" $secretName "key" "ca.crt" "defaultValue" (default $ca.Cert .Values.msgTopologyOperator.existingWebhookCertCABundle) "context" $) }} + {{- end }} + service: + name: {{ template "rmqco.msgTopologyOperator.webhook.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + path: /validate-rabbitmq-com-v1beta1-binding + port: {{ .Values.msgTopologyOperator.service.ports.webhook }} + failurePolicy: Fail + name: vbinding.kb.io + rules: + - apiGroups: + - rabbitmq.com + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - bindings + sideEffects: None + - admissionReviewVersions: + - v1 + clientConfig: + {{- if not .Values.useCertManager }} + caBundle: {{ include "common.secrets.lookup" (dict "secret" $secretName "key" "ca.crt" "defaultValue" (default $ca.Cert .Values.msgTopologyOperator.existingWebhookCertCABundle) "context" $) }} + {{- end }} + service: + name: {{ template "rmqco.msgTopologyOperator.webhook.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + path: /validate-rabbitmq-com-v1beta1-exchange + port: {{ .Values.msgTopologyOperator.service.ports.webhook }} + failurePolicy: Fail + name: vexchange.kb.io + rules: + - apiGroups: + - rabbitmq.com + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - exchanges + sideEffects: None + - admissionReviewVersions: + - v1 + clientConfig: + {{- if not .Values.useCertManager }} + caBundle: {{ include "common.secrets.lookup" (dict "secret" $secretName "key" "ca.crt" "defaultValue" (default $ca.Cert .Values.msgTopologyOperator.existingWebhookCertCABundle) "context" $) }} + {{- end }} + service: + name: {{ template "rmqco.msgTopologyOperator.webhook.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + path: /validate-rabbitmq-com-v1beta1-federation + port: {{ .Values.msgTopologyOperator.service.ports.webhook }} + failurePolicy: Fail + name: vfederation.kb.io + rules: + - apiGroups: + - rabbitmq.com + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - federations + sideEffects: None + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: {{ template "rmqco.msgTopologyOperator.webhook.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + path: /validate-rabbitmq-com-v1beta1-operatorpolicy + port: {{ .Values.msgTopologyOperator.service.ports.webhook }} + failurePolicy: Fail + name: voperatorpolicy.kb.io + rules: + - apiGroups: + - rabbitmq.com + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - operatorpolicies + sideEffects: None + - admissionReviewVersions: + - v1 + clientConfig: + {{- if not .Values.useCertManager }} + caBundle: {{ include "common.secrets.lookup" (dict "secret" $secretName "key" "ca.crt" "defaultValue" (default $ca.Cert .Values.msgTopologyOperator.existingWebhookCertCABundle) "context" $) }} + {{- end }} + service: + name: {{ template "rmqco.msgTopologyOperator.webhook.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + path: /validate-rabbitmq-com-v1alpha1-superstream + port: {{ .Values.msgTopologyOperator.service.ports.webhook }} + failurePolicy: Fail + name: vsuperstream.kb.io + rules: + - apiGroups: + - rabbitmq.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - superstreams + sideEffects: None + - admissionReviewVersions: + - v1 + clientConfig: + {{- if not .Values.useCertManager }} + caBundle: {{ include "common.secrets.lookup" (dict "secret" $secretName "key" "ca.crt" "defaultValue" (default $ca.Cert .Values.msgTopologyOperator.existingWebhookCertCABundle) "context" $) }} + {{- end }} + service: + name: {{ template "rmqco.msgTopologyOperator.webhook.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + path: /validate-rabbitmq-com-v1beta1-permission + port: {{ .Values.msgTopologyOperator.service.ports.webhook }} + failurePolicy: Fail + name: vpermission.kb.io + rules: + - apiGroups: + - rabbitmq.com + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - permissions + sideEffects: None + - admissionReviewVersions: + - v1 + clientConfig: + {{- if not .Values.useCertManager }} + caBundle: {{ include "common.secrets.lookup" (dict "secret" $secretName "key" "ca.crt" "defaultValue" (default $ca.Cert .Values.msgTopologyOperator.existingWebhookCertCABundle) "context" $) }} + {{- end }} + service: + name: {{ template "rmqco.msgTopologyOperator.webhook.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + path: /validate-rabbitmq-com-v1beta1-topicpermission + port: {{ .Values.msgTopologyOperator.service.ports.webhook }} + failurePolicy: Fail + name: vtopicpermission.kb.io + rules: + - apiGroups: + - rabbitmq.com + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - topicpermissions + sideEffects: None + - admissionReviewVersions: + - v1 + clientConfig: + {{- if not .Values.useCertManager }} + caBundle: {{ include "common.secrets.lookup" (dict "secret" $secretName "key" "ca.crt" "defaultValue" (default $ca.Cert .Values.msgTopologyOperator.existingWebhookCertCABundle) "context" $) }} + {{- end }} + service: + name: {{ template "rmqco.msgTopologyOperator.webhook.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + path: /validate-rabbitmq-com-v1beta1-policy + port: {{ .Values.msgTopologyOperator.service.ports.webhook }} + failurePolicy: Fail + name: vpolicy.kb.io + rules: + - apiGroups: + - rabbitmq.com + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - policies + sideEffects: None + - admissionReviewVersions: + - v1 + clientConfig: + {{- if not .Values.useCertManager }} + caBundle: {{ include "common.secrets.lookup" (dict "secret" $secretName "key" "ca.crt" "defaultValue" (default $ca.Cert .Values.msgTopologyOperator.existingWebhookCertCABundle) "context" $) }} + {{- end }} + service: + name: {{ template "rmqco.msgTopologyOperator.webhook.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + path: /validate-rabbitmq-com-v1beta1-queue + port: {{ .Values.msgTopologyOperator.service.ports.webhook }} + failurePolicy: Fail + name: vqueue.kb.io + rules: + - apiGroups: + - rabbitmq.com + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - queues + sideEffects: None + - admissionReviewVersions: + - v1 + clientConfig: + {{- if not .Values.useCertManager }} + caBundle: {{ include "common.secrets.lookup" (dict "secret" $secretName "key" "ca.crt" "defaultValue" (default $ca.Cert .Values.msgTopologyOperator.existingWebhookCertCABundle) "context" $) }} + {{- end }} + service: + name: {{ template "rmqco.msgTopologyOperator.webhook.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + path: /validate-rabbitmq-com-v1beta1-schemareplication + port: {{ .Values.msgTopologyOperator.service.ports.webhook }} + failurePolicy: Fail + name: vschemareplication.kb.io + rules: + - apiGroups: + - rabbitmq.com + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - schemareplications + sideEffects: None + - admissionReviewVersions: + - v1 + clientConfig: + {{- if not .Values.useCertManager }} + caBundle: {{ include "common.secrets.lookup" (dict "secret" $secretName "key" "ca.crt" "defaultValue" (default $ca.Cert .Values.msgTopologyOperator.existingWebhookCertCABundle) "context" $) }} + {{- end }} + service: + name: {{ template "rmqco.msgTopologyOperator.webhook.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + path: /validate-rabbitmq-com-v1beta1-shovel + port: {{ .Values.msgTopologyOperator.service.ports.webhook }} + failurePolicy: Fail + name: vshovel.kb.io + rules: + - apiGroups: + - rabbitmq.com + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - shovels + sideEffects: None + - admissionReviewVersions: + - v1 + clientConfig: + {{- if not .Values.useCertManager }} + caBundle: {{ include "common.secrets.lookup" (dict "secret" $secretName "key" "ca.crt" "defaultValue" (default $ca.Cert .Values.msgTopologyOperator.existingWebhookCertCABundle) "context" $) }} + {{- end }} + service: + name: {{ template "rmqco.msgTopologyOperator.webhook.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + path: /validate-rabbitmq-com-v1beta1-user + port: {{ .Values.msgTopologyOperator.service.ports.webhook }} + failurePolicy: Fail + name: vuser.kb.io + rules: + - apiGroups: + - rabbitmq.com + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - users + sideEffects: None + - admissionReviewVersions: + - v1 + clientConfig: + {{- if not .Values.useCertManager }} + caBundle: {{ include "common.secrets.lookup" (dict "secret" $secretName "key" "ca.crt" "defaultValue" (default $ca.Cert .Values.msgTopologyOperator.existingWebhookCertCABundle) "context" $) }} + {{- end }} + service: + name: {{ template "rmqco.msgTopologyOperator.webhook.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + path: /validate-rabbitmq-com-v1beta1-vhost + port: {{ .Values.msgTopologyOperator.service.ports.webhook }} + failurePolicy: Fail + name: vvhost.kb.io + rules: + - apiGroups: + - rabbitmq.com + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - vhosts + sideEffects: None +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/webhook-service.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/webhook-service.yaml new file mode 100644 index 000000000..90acccfef --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/templates/messaging-topology-operator/webhook-service.yaml @@ -0,0 +1,57 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.msgTopologyOperator.enabled }} +apiVersion: v1 +kind: Service +metadata: + {{- $versionLabel := dict "app.kubernetes.io/version" ( include "common.images.version" ( dict "imageRoot" .Values.msgTopologyOperator.image "chart" .Chart ) ) }} + {{- $labels := include "common.tplvalues.merge" ( dict "values" ( list .Values.commonLabels $versionLabel ) "context" . ) }} + labels: {{- include "common.labels.standard" ( dict "customLabels" $labels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: messaging-topology-operator + app.kubernetes.io/part-of: rabbitmq + name: {{ template "rmqco.msgTopologyOperator.webhook.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + {{- if or .Values.commonAnnotations .Values.msgTopologyOperator.service.annotations }} + {{- $annotations := include "common.tplvalues.merge" ( dict "values" ( list .Values.msgTopologyOperator.service.annotations .Values.commonAnnotations ) "context" . ) }} + annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $) | nindent 4 }} + {{- end }} +spec: + type: {{ .Values.msgTopologyOperator.service.type }} + {{- if (or (eq .Values.msgTopologyOperator.service.type "LoadBalancer") (eq .Values.msgTopologyOperator.service.type "NodePort")) }} + externalTrafficPolicy: {{ .Values.msgTopologyOperator.service.externalTrafficPolicy | quote }} + {{- end }} + {{- if .Values.msgTopologyOperator.service.clusterIP }} + clusterIP: {{ .Values.msgTopologyOperator.service.clusterIP }} + {{- end }} + {{- if eq .Values.msgTopologyOperator.service.type "LoadBalancer" }} + loadBalancerSourceRanges: {{ .Values.msgTopologyOperator.service.loadBalancerSourceRanges }} + {{- end }} + {{- if (and (eq .Values.msgTopologyOperator.service.type "LoadBalancer") (not (empty .Values.msgTopologyOperator.service.loadBalancerIP))) }} + loadBalancerIP: {{ .Values.msgTopologyOperator.service.loadBalancerIP }} + {{- end }} + {{- if .Values.msgTopologyOperator.service.sessionAffinity }} + sessionAffinity: {{ .Values.msgTopologyOperator.service.sessionAffinity }} + {{- end }} + {{- if .Values.msgTopologyOperator.service.sessionAffinityConfig }} + sessionAffinityConfig: {{- include "common.tplvalues.render" (dict "value" .Values.msgTopologyOperator.service.sessionAffinityConfig "context" $) | nindent 4 }} + {{- end }} + ports: + - name: https + port: {{ .Values.msgTopologyOperator.service.ports.webhook }} + targetPort: https-webhook + protocol: TCP + {{- if (and (or (eq .Values.msgTopologyOperator.service.type "NodePort") (eq .Values.msgTopologyOperator.service.type "LoadBalancer")) (not (empty .Values.msgTopologyOperator.service.nodePorts.http))) }} + nodePort: {{ .Values.msgTopologyOperator.service.nodePorts.http }} + {{- else if eq .Values.msgTopologyOperator.service.type "ClusterIP" }} + nodePort: null + {{- end }} + {{- if .Values.msgTopologyOperator.service.extraPorts }} + {{- include "common.tplvalues.render" (dict "value" .Values.msgTopologyOperator.service.extraPorts "context" $) | nindent 4 }} + {{- end }} + {{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.msgTopologyOperator.podLabels .Values.commonLabels ) "context" . ) }} + selector: {{- include "common.labels.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: messaging-topology-operator +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/values.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/values.yaml new file mode 100644 index 000000000..613755959 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/rabbitmq-cluster-operator/values.yaml @@ -0,0 +1,1229 @@ +# Copyright Broadcom, Inc. All Rights Reserved. +# SPDX-License-Identifier: APACHE-2.0 + +## @section Global parameters +## Global Docker image parameters +## Please, note that this will override the image parameters, including dependencies, configured to use the global value +## Current available global Docker image parameters: imageRegistry, imagePullSecrets and storageClass +## + +## @param global.imageRegistry Global Docker image registry +## @param global.imagePullSecrets Global Docker registry secret names as an array +## @param global.defaultStorageClass Global default StorageClass for Persistent Volume(s) +## @param global.storageClass DEPRECATED: use global.defaultStorageClass instead +## +global: + imageRegistry: "" + ## E.g. + ## imagePullSecrets: + ## - myRegistryKeySecretName + ## + imagePullSecrets: [] + defaultStorageClass: "" + storageClass: "" + ## Compatibility adaptations for Kubernetes platforms + ## + compatibility: + ## Compatibility adaptations for Openshift + ## + openshift: + ## @param global.compatibility.openshift.adaptSecurityContext 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) + ## + adaptSecurityContext: auto +## @section Common parameters +## + +## @param kubeVersion Override Kubernetes version +## +kubeVersion: "" +## @param nameOverride String to partially override common.names.fullname +## +nameOverride: "" +## @param fullnameOverride String to fully override common.names.fullname +## +fullnameOverride: "" +## @param commonLabels Labels to add to all deployed objects +## +commonLabels: {} +## @param commonAnnotations Annotations to add to all deployed objects +## +commonAnnotations: {} +## @param clusterDomain Kubernetes cluster domain name +## +clusterDomain: cluster.local +## @param extraDeploy Array of extra objects to deploy with the release +## +extraDeploy: [] +## Enable diagnostic mode in the deployment(s)/statefulset(s) +## +diagnosticMode: + ## @param diagnosticMode.enabled Enable diagnostic mode (all probes will be disabled) + ## + enabled: false +## @section RabbitMQ Cluster Operator Parameters +## + +## Bitnami RabbitMQ Image +## ref: https://hub.docker.com/r/bitnami/rabbitmq/tags/ +## @param rabbitmqImage.registry [default: REGISTRY_NAME] RabbitMQ Image registry +## @param rabbitmqImage.repository [default: REPOSITORY_NAME/rabbitmq] RabbitMQ Image repository +## @skip rabbitmqImage.tag RabbitMQ Image tag (immutable tags are recommended) +## @param rabbitmqImage.digest RabbitMQ image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag +## @param rabbitmqImage.pullSecrets RabbitMQ Image pull secrets +## +rabbitmqImage: + registry: docker.io + repository: bitnami/rabbitmq + tag: 3.13.6-debian-12-r0 + digest: "" + ## Optionally specify an array of imagePullSecrets. + ## Secrets must be manually created in the namespace. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-rabbitmqImage-private-registry/ + ## e.g: + ## pullSecrets: + ## - myRegistryKeySecretName + ## + pullSecrets: [] +## Bitnami RabbitMQ Default User Credential Updater Image +## ref: https://hub.docker.com/r/bitnami/rmq-default-credential-updater/tags/ +## @param credentialUpdaterImage.registry [default: REGISTRY_NAME] RabbitMQ Default User Credential Updater image registry +## @param credentialUpdaterImage.repository [default: REPOSITORY_NAME/rmq-default-credential-updater] RabbitMQ Default User Credential Updater image repository +## @skip credentialUpdaterImage.tag RabbitMQ Default User Credential Updater image tag (immutable tags are recommended) +## @param credentialUpdaterImage.digest RabbitMQ Default User Credential Updater image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag +## @param credentialUpdaterImage.pullSecrets RabbitMQ Default User Credential Updater image pull secrets +## +credentialUpdaterImage: + registry: docker.io + repository: bitnami/rmq-default-credential-updater + tag: 1.0.4-debian-12-r24 + digest: "" + ## Optionally specify an array of imagePullSecrets. + ## Secrets must be manually created in the namespace. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-credentialUpdaterImage-private-registry/ + ## e.g: + ## pullSecrets: + ## - myRegistryKeySecretName + ## + pullSecrets: [] +clusterOperator: + ## Bitnami RabbitMQ Cluster Operator image + ## ref: https://hub.docker.com/r/bitnami/rabbitmq-cluster-operator/tags/ + ## @param clusterOperator.image.registry [default: REGISTRY_NAME] RabbitMQ Cluster Operator image registry + ## @param clusterOperator.image.repository [default: REPOSITORY_NAME/rabbitmq-cluster-operator] RabbitMQ Cluster Operator image repository + ## @skip clusterOperator.image.tag RabbitMQ Cluster Operator image tag (immutable tags are recommended) + ## @param clusterOperator.image.digest RabbitMQ Cluster Operator image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag + ## @param clusterOperator.image.pullPolicy RabbitMQ Cluster Operator image pull policy + ## @param clusterOperator.image.pullSecrets RabbitMQ Cluster Operator image pull secrets + ## + image: + registry: docker.io + repository: bitnami/rabbitmq-cluster-operator + tag: 2.9.0-debian-12-r6 + 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 + ## Optionally specify an array of imagePullSecrets. + ## Secrets must be manually created in the namespace. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## e.g: + ## pullSecrets: + ## - myRegistryKeySecretName + ## + pullSecrets: [] + ## @param clusterOperator.revisionHistoryLimit sets number of replicaset to keep in k8s + ## + revisionHistoryLimit: 10 + ## @param clusterOperator.watchAllNamespaces Watch for resources in all namespaces + ## + watchAllNamespaces: true + ## @param clusterOperator.watchNamespaces [array] Watch for resources in the given namespaces (ignored if watchAllNamespaces=true) + ## + watchNamespaces: [] + ## @param clusterOperator.replicaCount Number of RabbitMQ Cluster Operator replicas to deploy + ## + replicaCount: 1 + ## @param clusterOperator.schedulerName Alternative scheduler + ## + schedulerName: "" + ## @param clusterOperator.topologySpreadConstraints Topology Spread Constraints for pod assignment + ## https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ + ## The value is evaluated as a template + ## + topologySpreadConstraints: [] + ## @param clusterOperator.terminationGracePeriodSeconds In seconds, time the given to the %%MAIN_CONTAINER_NAME%% pod needs to terminate gracefully + ## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods + ## + terminationGracePeriodSeconds: "" + ## Configure extra options for RabbitMQ Cluster Operator containers' liveness and readiness probes + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes + ## @param clusterOperator.livenessProbe.enabled Enable livenessProbe on RabbitMQ Cluster Operator nodes + ## @param clusterOperator.livenessProbe.initialDelaySeconds Initial delay seconds for livenessProbe + ## @param clusterOperator.livenessProbe.periodSeconds Period seconds for livenessProbe + ## @param clusterOperator.livenessProbe.timeoutSeconds Timeout seconds for livenessProbe + ## @param clusterOperator.livenessProbe.failureThreshold Failure threshold for livenessProbe + ## @param clusterOperator.livenessProbe.successThreshold Success threshold for livenessProbe + ## + livenessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 30 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 5 + ## @param clusterOperator.readinessProbe.enabled Enable readinessProbe on RabbitMQ Cluster Operator nodes + ## @param clusterOperator.readinessProbe.initialDelaySeconds Initial delay seconds for readinessProbe + ## @param clusterOperator.readinessProbe.periodSeconds Period seconds for readinessProbe + ## @param clusterOperator.readinessProbe.timeoutSeconds Timeout seconds for readinessProbe + ## @param clusterOperator.readinessProbe.failureThreshold Failure threshold for readinessProbe + ## @param clusterOperator.readinessProbe.successThreshold Success threshold for readinessProbe + ## + readinessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 30 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 5 + ## @param clusterOperator.startupProbe.enabled Enable startupProbe on RabbitMQ Cluster Operator nodes + ## @param clusterOperator.startupProbe.initialDelaySeconds Initial delay seconds for startupProbe + ## @param clusterOperator.startupProbe.periodSeconds Period seconds for startupProbe + ## @param clusterOperator.startupProbe.timeoutSeconds Timeout seconds for startupProbe + ## @param clusterOperator.startupProbe.failureThreshold Failure threshold for startupProbe + ## @param clusterOperator.startupProbe.successThreshold Success threshold for startupProbe + ## + startupProbe: + enabled: false + initialDelaySeconds: 5 + periodSeconds: 30 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 5 + ## @param clusterOperator.customLivenessProbe Custom livenessProbe that overrides the default one + ## + customLivenessProbe: {} + ## @param clusterOperator.customReadinessProbe Custom readinessProbe that overrides the default one + ## + customReadinessProbe: {} + ## @param clusterOperator.customStartupProbe Custom startupProbe that overrides the default one + ## + customStartupProbe: {} + ## RabbitMQ Cluster Operator resource requests and limits + ## ref: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/ + ## @param clusterOperator.resourcesPreset Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if clusterOperator.resources is set (clusterOperator.resources is recommended for production). + ## More information: https://github.com/bitnami/charts/blob/main/bitnami/common/templates/_resources.tpl#L15 + ## + resourcesPreset: "nano" + ## @param clusterOperator.resources Set container requests and limits for different resources like CPU or memory (essential for production workloads) + ## Example: + ## resources: + ## requests: + ## cpu: 2 + ## memory: 512Mi + ## limits: + ## cpu: 3 + ## memory: 1024Mi + ## + resources: {} + ## Configure Pods Security Context + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod + ## @param clusterOperator.podSecurityContext.enabled Enabled RabbitMQ Cluster Operator pods' Security Context + ## @param clusterOperator.podSecurityContext.fsGroupChangePolicy Set filesystem group change policy + ## @param clusterOperator.podSecurityContext.sysctls Set kernel settings using the sysctl interface + ## @param clusterOperator.podSecurityContext.supplementalGroups Set filesystem extra groups + ## @param clusterOperator.podSecurityContext.fsGroup Set RabbitMQ Cluster Operator pod's Security Context fsGroup + ## + podSecurityContext: + enabled: true + fsGroupChangePolicy: Always + sysctls: [] + supplementalGroups: [] + fsGroup: 1001 + ## Configure Container Security Context + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod + ## @param clusterOperator.containerSecurityContext.enabled Enabled containers' Security Context + ## @param clusterOperator.containerSecurityContext.seLinuxOptions [object,nullable] Set SELinux options in container + ## @param clusterOperator.containerSecurityContext.runAsUser Set containers' Security Context runAsUser + ## @param clusterOperator.containerSecurityContext.runAsGroup Set containers' Security Context runAsGroup + ## @param clusterOperator.containerSecurityContext.runAsNonRoot Set container's Security Context runAsNonRoot + ## @param clusterOperator.containerSecurityContext.privileged Set container's Security Context privileged + ## @param clusterOperator.containerSecurityContext.readOnlyRootFilesystem Set container's Security Context readOnlyRootFilesystem + ## @param clusterOperator.containerSecurityContext.allowPrivilegeEscalation Set container's Security Context allowPrivilegeEscalation + ## @param clusterOperator.containerSecurityContext.capabilities.drop List of capabilities to be dropped + ## @param clusterOperator.containerSecurityContext.seccompProfile.type Set container's Security Context seccomp profile + ## + containerSecurityContext: + enabled: true + seLinuxOptions: null + runAsUser: 1001 + runAsGroup: 1001 + runAsNonRoot: true + privileged: false + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + capabilities: + drop: ["ALL"] + seccompProfile: + type: "RuntimeDefault" + ## @param clusterOperator.command Override default container command (useful when using custom images) + ## + command: [] + ## @param clusterOperator.args Override default container args (useful when using custom images) + ## + args: [] + ## @param clusterOperator.automountServiceAccountToken Mount Service Account token in pod + ## + automountServiceAccountToken: true + ## @param clusterOperator.hostAliases RabbitMQ Cluster Operator pods host aliases + ## https://kubernetes.io/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases/ + ## + hostAliases: [] + ## @param clusterOperator.podLabels Extra labels for RabbitMQ Cluster Operator pods + ## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ + ## + podLabels: {} + ## @param clusterOperator.podAnnotations Annotations for RabbitMQ Cluster Operator pods + ## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ + ## + podAnnotations: {} + ## @param clusterOperator.podAffinityPreset Pod affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` + ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity + ## + podAffinityPreset: "" + ## @param clusterOperator.podAntiAffinityPreset Pod anti-affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` + ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity + ## + podAntiAffinityPreset: soft + ## Node affinity preset + ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity + ## + nodeAffinityPreset: + ## @param clusterOperator.nodeAffinityPreset.type Node affinity preset type. Ignored if `affinity` is set. Allowed values: `soft` or `hard` + ## + type: "" + ## @param clusterOperator.nodeAffinityPreset.key Node label key to match. Ignored if `affinity` is set + ## + key: "" + ## @param clusterOperator.nodeAffinityPreset.values Node label values to match. Ignored if `affinity` is set + ## E.g. + ## values: + ## - e2e-az1 + ## - e2e-az2 + ## + values: [] + ## @param clusterOperator.affinity Affinity for RabbitMQ Cluster Operator pods assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + ## NOTE: `podAffinityPreset`, `podAntiAffinityPreset`, and `nodeAffinityPreset` will be ignored when it's set + ## + affinity: {} + ## @param clusterOperator.nodeSelector Node labels for RabbitMQ Cluster Operator pods assignment + ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/ + ## + nodeSelector: {} + ## @param clusterOperator.tolerations Tolerations for RabbitMQ Cluster Operator pods assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ + ## + tolerations: [] + ## @param clusterOperator.updateStrategy.type RabbitMQ Cluster Operator statefulset strategy type + ## ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#update-strategies + ## + updateStrategy: + ## StrategyType + ## Can be set to RollingUpdate or OnDelete + ## + type: RollingUpdate + ## @param clusterOperator.priorityClassName RabbitMQ Cluster Operator pods' priorityClassName + ## + priorityClassName: "" + ## @param clusterOperator.lifecycleHooks for the RabbitMQ Cluster Operator container(s) to automate configuration before or after startup + ## + lifecycleHooks: {} + ## @param clusterOperator.containerPorts.metrics RabbitMQ Cluster Operator container port (used for metrics) + ## + containerPorts: + metrics: 9782 + ## @param clusterOperator.extraEnvVars Array with extra environment variables to add to RabbitMQ Cluster Operator nodes + ## e.g: + ## extraEnvVars: + ## - name: FOO + ## value: "bar" + ## + extraEnvVars: [] + ## @param clusterOperator.extraEnvVarsCM Name of existing ConfigMap containing extra env vars for RabbitMQ Cluster Operator nodes + ## + extraEnvVarsCM: "" + ## @param clusterOperator.extraEnvVarsSecret Name of existing Secret containing extra env vars for RabbitMQ Cluster Operator nodes + ## + extraEnvVarsSecret: "" + ## @param clusterOperator.extraVolumes Optionally specify extra list of additional volumes for the RabbitMQ Cluster Operator pod(s) + ## + extraVolumes: [] + ## @param clusterOperator.extraVolumeMounts Optionally specify extra list of additional volumeMounts for the RabbitMQ Cluster Operator container(s) + ## + extraVolumeMounts: [] + ## @param clusterOperator.sidecars Add additional sidecar containers to the RabbitMQ Cluster Operator pod(s) + ## e.g: + ## sidecars: + ## - name: your-image-name + ## image: your-image + ## imagePullPolicy: Always + ## ports: + ## - name: portname + ## containerPort: 1234 + ## + sidecars: [] + ## @param clusterOperator.initContainers Add additional init containers to the RabbitMQ Cluster Operator pod(s) + ## ref: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ + ## e.g: + ## initContainers: + ## - name: your-image-name + ## image: your-image + ## imagePullPolicy: Always + ## command: ['sh', '-c', 'echo "hello world"'] + ## + initContainers: [] + ## Network Policies + ## Ref: https://kubernetes.io/docs/concepts/services-networking/network-policies/ + ## + networkPolicy: + ## @param clusterOperator.networkPolicy.enabled Specifies whether a NetworkPolicy should be created + ## + enabled: true + ## @param clusterOperator.networkPolicy.kubeAPIServerPorts [array] List of possible endpoints to kube-apiserver (limit to your cluster settings to increase security) + ## + kubeAPIServerPorts: [443, 6443, 8443] + ## @param clusterOperator.networkPolicy.allowExternal Don't require injector label for connections + ## The Policy model to apply. When set to false, only pods with the correct + ## injector label will have network access to the ports injector is listening + ## on. When true, injector will accept connections from any source + ## (with the correct destination port). + ## + allowExternal: true + ## @param clusterOperator.networkPolicy.allowExternalEgress Allow the pod to access any range of port and all destinations. + ## + allowExternalEgress: true + ## @param clusterOperator.networkPolicy.extraIngress [array] Add extra ingress rules to the NetworkPolicy + ## e.g: + ## extraIngress: + ## - ports: + ## - port: 1234 + ## from: + ## - podSelector: + ## - matchLabels: + ## - role: frontend + ## - podSelector: + ## - matchExpressions: + ## - key: role + ## operator: In + ## values: + ## - frontend + extraIngress: [] + ## @param clusterOperator.networkPolicy.extraEgress [array] Add extra ingress rules to the NetworkPolicy + ## e.g: + ## extraEgress: + ## - ports: + ## - port: 1234 + ## to: + ## - podSelector: + ## - matchLabels: + ## - role: frontend + ## - podSelector: + ## - matchExpressions: + ## - key: role + ## operator: In + ## values: + ## - frontend + ## + extraEgress: [] + ## @param clusterOperator.networkPolicy.ingressNSMatchLabels [object] Labels to match to allow traffic from other namespaces + ## @param clusterOperator.networkPolicy.ingressNSPodMatchLabels [object] Pod labels to match to allow traffic from other namespaces + ## + ingressNSMatchLabels: {} + ingressNSPodMatchLabels: {} + ## RBAC configuration + ## + rbac: + ## @param clusterOperator.rbac.create Specifies whether RBAC resources should be created + ## + create: true + ## ClusterRole parameters + ## + clusterRole: + ## @param clusterOperator.rbac.clusterRole.customRules Define custom access rules for the ClusterRole + ## ref: https://kubernetes.io/docs/reference/access-authn-authz/rbac/#role-and-clusterrole + ## e.g: + ## customRules: + ## - apiGroups: A list of API groups (e.g., [""], ["apps"]). + ## - resources: A list of resource names (e.g., ["configmaps", "pods"]). + ## - verbs: A list of allowed access verbs (e.g., ["create", "get", "list"]). + customRules: [] + ## @param clusterOperator.rbac.clusterRole.extraRules Define extra access rules for the ClusterRole. This has no effect if customerRules is a non-empty array. + ## ref: https://kubernetes.io/docs/reference/access-authn-authz/rbac/#role-and-clusterrole + ## e.g: + ## extraRules: + ## - apiGroups: A list of API groups (e.g., [""], ["apps"]). + ## - resources: A list of resource names (e.g., ["configmaps", "pods"]). + ## - verbs: A list of allowed access verbs (e.g., ["create", "get", "list"]). + extraRules: [] + ## ServiceAccount configuration + ## + serviceAccount: + ## @param clusterOperator.serviceAccount.create Specifies whether a ServiceAccount should be created + ## + create: true + ## @param clusterOperator.serviceAccount.name The name of the ServiceAccount to use. + ## If not set and create is true, a name is generated using the common.names.fullname template + ## + name: "" + ## @param clusterOperator.serviceAccount.annotations Add annotations + ## + annotations: {} + ## @param clusterOperator.serviceAccount.automountServiceAccountToken Automount API credentials for a service account. + ## + automountServiceAccountToken: false + ## @section RabbitMQ Cluster Operator Metrics parameters + ## + metrics: + ## Metrics service parameters + ## + service: + ## @param clusterOperator.metrics.service.enabled Create a service for accessing the metrics endpoint + ## + enabled: false + ## @param clusterOperator.metrics.service.type RabbitMQ Cluster Operator metrics service type + ## + type: ClusterIP + ## @param clusterOperator.metrics.service.ports.http RabbitMQ Cluster Operator metrics service HTTP port + ## + ports: + http: 80 + ## Node ports to expose + ## @param clusterOperator.metrics.service.nodePorts.http Node port for HTTP + ## NOTE: choose port between <30000-32767> + ## + nodePorts: + http: "" + ## @param clusterOperator.metrics.service.clusterIP RabbitMQ Cluster Operator metrics service Cluster IP + ## e.g.: + ## clusterIP: None + ## + clusterIP: "" + ## @param clusterOperator.metrics.service.extraPorts Extra ports to expose (normally used with the `sidecar` value) + ## + extraPorts: [] + ## @param clusterOperator.metrics.service.loadBalancerIP RabbitMQ Cluster Operator metrics service Load Balancer IP + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-loadbalancer + ## + loadBalancerIP: "" + ## @param clusterOperator.metrics.service.loadBalancerSourceRanges RabbitMQ Cluster Operator metrics service Load Balancer sources + ## ref: https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/#restrict-access-for-loadbalancer-service + ## e.g: + ## loadBalancerSourceRanges: + ## - 10.10.10.0/24 + ## + loadBalancerSourceRanges: [] + ## @param clusterOperator.metrics.service.externalTrafficPolicy RabbitMQ Cluster Operator metrics service external traffic policy + ## ref https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip + ## + externalTrafficPolicy: Cluster + ## @param clusterOperator.metrics.service.annotations [object] Additional custom annotations for RabbitMQ Cluster Operator metrics service + ## + annotations: + prometheus.io/scrape: "true" + prometheus.io/port: "{{ .Values.clusterOperator.metrics.service.ports.http }}" + ## @param clusterOperator.metrics.service.sessionAffinity Session Affinity for Kubernetes service, can be "None" or "ClientIP" + ## If "ClientIP", consecutive client requests will be directed to the same Pod + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + ## + sessionAffinity: None + ## @param clusterOperator.metrics.service.sessionAffinityConfig Additional settings for the sessionAffinity + ## sessionAffinityConfig: + ## clientIP: + ## timeoutSeconds: 300 + ## + sessionAffinityConfig: {} + serviceMonitor: + ## @param clusterOperator.metrics.serviceMonitor.enabled Specify if a servicemonitor will be deployed for prometheus-operator + ## + enabled: false + ## @param clusterOperator.metrics.serviceMonitor.namespace Namespace which Prometheus is running in + ## e.g: + ## namespace: monitoring + ## + namespace: "" + ## @param clusterOperator.metrics.serviceMonitor.jobLabel Specify the jobLabel to use for the prometheus-operator + ## + jobLabel: app.kubernetes.io/name + ## @param clusterOperator.metrics.serviceMonitor.honorLabels Honor metrics labels + ## ref: https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#endpoint + ## + honorLabels: false + ## @param clusterOperator.metrics.serviceMonitor.selector Prometheus instance selector labels + ## ref: https://github.com/bitnami/charts/tree/main/bitnami/prometheus-operator#prometheus-configuration + ## e.g: + ## selector: + ## prometheus: my-prometheus + ## + selector: {} + ## @param clusterOperator.metrics.serviceMonitor.scrapeTimeout Timeout after which the scrape is ended + ## ref: https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#endpoint + ## e.g: + ## scrapeTimeout: 10s + ## + scrapeTimeout: "" + ## @param clusterOperator.metrics.serviceMonitor.interval Scrape interval. If not set, the Prometheus default scrape interval is used + ## + interval: "" + ## DEPRECATED: Use clusterOperator.metrics.serviceMonitor.labels instead + ## This value will be removed in a future release + ## additionalLabels: {} + + ## @param clusterOperator.metrics.serviceMonitor.metricRelabelings Specify additional relabeling of metrics + ## + metricRelabelings: [] + ## @param clusterOperator.metrics.serviceMonitor.relabelings Specify general relabeling + ## + relabelings: [] + ## @param clusterOperator.metrics.serviceMonitor.labels Extra labels for the ServiceMonitor + ## + labels: {} + ## @param clusterOperator.metrics.serviceMonitor.path Define the path used by ServiceMonitor to scrap metrics + ## Could be /metrics for aggregated metrics or /metrics/per-object for more details + ## + path: "" + ## @param clusterOperator.metrics.serviceMonitor.params Define the HTTP URL parameters used by ServiceMonitor + ## + params: {} + podMonitor: + ## @param clusterOperator.metrics.podMonitor.enabled Create PodMonitor Resource for scraping metrics using PrometheusOperator + ## + enabled: false + ## @param clusterOperator.metrics.podMonitor.jobLabel Specify the jobLabel to use for the prometheus-operator + ## + jobLabel: app.kubernetes.io/name + ## @param clusterOperator.metrics.podMonitor.namespace Namespace which Prometheus is running in + ## + namespace: "" + ## @param clusterOperator.metrics.podMonitor.honorLabels Honor metrics labels + ## + honorLabels: false + ## @param clusterOperator.metrics.podMonitor.selector Prometheus instance selector labels + ## ref: https://github.com/bitnami/charts/tree/main/bitnami/prometheus-operator#prometheus-configuration + selector: {} + ## @param clusterOperator.metrics.podMonitor.interval Specify the interval at which metrics should be scraped + ## + interval: 30s + ## @param clusterOperator.metrics.podMonitor.scrapeTimeout Specify the timeout after which the scrape is ended + ## + scrapeTimeout: 30s + ## @param clusterOperator.metrics.podMonitor.additionalLabels [object] Additional labels that can be used so PodMonitors will be discovered by Prometheus + ## + additionalLabels: {} + ## @param clusterOperator.metrics.podMonitor.path Define HTTP path to scrape for metrics. + ## + path: "" + ## @param clusterOperator.metrics.podMonitor.relabelings Specify general relabeling + ## + relabelings: [] + ## @param clusterOperator.metrics.podMonitor.metricRelabelings Specify additional relabeling of metrics + ## + metricRelabelings: [] + ## @param clusterOperator.metrics.podMonitor.params Define the HTTP URL parameters used by PodMonitor + ## + params: {} +## @section RabbitMQ Messaging Topology Operator Parameters +## +msgTopologyOperator: + ## @param msgTopologyOperator.enabled Deploy RabbitMQ Messaging Topology Operator as part of the installation + ## + enabled: true + ## Bitnami RabbitMQ Messaging Topology Operator image + ## ref: https://hub.docker.com/r/bitnami/rmq-messaging-topology-operator/tags/ + ## @param msgTopologyOperator.image.registry [default: REGISTRY_NAME] RabbitMQ Messaging Topology Operator image registry + ## @param msgTopologyOperator.image.repository [default: REPOSITORY_NAME/rmq-messaging-topology-operator] RabbitMQ Messaging Topology Operator image repository + ## @skip msgTopologyOperator.image.tag RabbitMQ Messaging Topology Operator image tag (immutable tags are recommended) + ## @param msgTopologyOperator.image.digest RabbitMQ Messaging Topology Operator image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag + ## @param msgTopologyOperator.image.pullPolicy RabbitMQ Messaging Topology Operator image pull policy + ## @param msgTopologyOperator.image.pullSecrets RabbitMQ Messaging Topology Operator image pull secrets + ## + image: + registry: docker.io + repository: bitnami/rmq-messaging-topology-operator + tag: 1.14.2-debian-12-r3 + 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 + ## Optionally specify an array of imagePullSecrets. + ## Secrets must be manually created in the namespace. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## e.g: + ## pullSecrets: + ## - myRegistryKeySecretName + ## + pullSecrets: [] + ## @param msgTopologyOperator.revisionHistoryLimit sets number of replicaset to keep in k8s + ## + revisionHistoryLimit: 10 + ## @param msgTopologyOperator.watchAllNamespaces Watch for resources in all namespaces + ## + watchAllNamespaces: true + ## @param msgTopologyOperator.watchNamespaces [array] Watch for resources in the given namespaces ## @param clusterOperator.watchNamespaces [array] Watch for resources in the given namespaces (ignored if watchAllNamespaces=true) + ## + watchNamespaces: [] + ## @param msgTopologyOperator.replicaCount Number of RabbitMQ Messaging Topology Operator replicas to deploy + ## + replicaCount: 1 + ## @param msgTopologyOperator.topologySpreadConstraints Topology Spread Constraints for pod assignment + ## https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ + ## The value is evaluated as a template + ## + topologySpreadConstraints: [] + ## @param msgTopologyOperator.schedulerName Alternative scheduler + ## + schedulerName: "" + ## @param msgTopologyOperator.terminationGracePeriodSeconds In seconds, time the given to the %%MAIN_CONTAINER_NAME%% pod needs to terminate gracefully + ## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods + ## + terminationGracePeriodSeconds: "" + ## @param msgTopologyOperator.hostNetwork Boolean + ## + hostNetwork: "false" + ## @param msgTopologyOperator.dnsPolicy Alternative DNS policy + ## + dnsPolicy: "ClusterFirst" + ## Configure extra options for RabbitMQ Messaging Topology Operator containers' liveness and readiness probes + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes + ## @param msgTopologyOperator.livenessProbe.enabled Enable livenessProbe on RabbitMQ Messaging Topology Operator nodes + ## @param msgTopologyOperator.livenessProbe.initialDelaySeconds Initial delay seconds for livenessProbe + ## @param msgTopologyOperator.livenessProbe.periodSeconds Period seconds for livenessProbe + ## @param msgTopologyOperator.livenessProbe.timeoutSeconds Timeout seconds for livenessProbe + ## @param msgTopologyOperator.livenessProbe.failureThreshold Failure threshold for livenessProbe + ## @param msgTopologyOperator.livenessProbe.successThreshold Success threshold for livenessProbe + ## + livenessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 30 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 5 + ## @param msgTopologyOperator.readinessProbe.enabled Enable readinessProbe on RabbitMQ Messaging Topology Operator nodes + ## @param msgTopologyOperator.readinessProbe.initialDelaySeconds Initial delay seconds for readinessProbe + ## @param msgTopologyOperator.readinessProbe.periodSeconds Period seconds for readinessProbe + ## @param msgTopologyOperator.readinessProbe.timeoutSeconds Timeout seconds for readinessProbe + ## @param msgTopologyOperator.readinessProbe.failureThreshold Failure threshold for readinessProbe + ## @param msgTopologyOperator.readinessProbe.successThreshold Success threshold for readinessProbe + ## + readinessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 30 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 5 + ## @param msgTopologyOperator.startupProbe.enabled Enable startupProbe on RabbitMQ Messaging Topology Operator nodes + ## @param msgTopologyOperator.startupProbe.initialDelaySeconds Initial delay seconds for startupProbe + ## @param msgTopologyOperator.startupProbe.periodSeconds Period seconds for startupProbe + ## @param msgTopologyOperator.startupProbe.timeoutSeconds Timeout seconds for startupProbe + ## @param msgTopologyOperator.startupProbe.failureThreshold Failure threshold for startupProbe + ## @param msgTopologyOperator.startupProbe.successThreshold Success threshold for startupProbe + ## + startupProbe: + enabled: false + initialDelaySeconds: 5 + periodSeconds: 30 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 5 + ## @param msgTopologyOperator.customLivenessProbe Custom livenessProbe that overrides the default one + ## + customLivenessProbe: {} + ## @param msgTopologyOperator.customReadinessProbe Custom readinessProbe that overrides the default one + ## + customReadinessProbe: {} + ## @param msgTopologyOperator.customStartupProbe Custom startupProbe that overrides the default one + ## + customStartupProbe: {} + ## @param msgTopologyOperator.existingWebhookCertSecret name of a secret containing the certificates (use it to avoid certManager creating one) + ## + existingWebhookCertSecret: "" + ## @param msgTopologyOperator.existingWebhookCertCABundle PEM-encoded CA Bundle of the existing secret provided in existingWebhookCertSecret (only if useCertManager=false) + ## + existingWebhookCertCABundle: "" + ## RabbitMQ Messaging Topology Operator resource requests and limits + ## ref: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/ + ## @param msgTopologyOperator.resourcesPreset Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if msgTopologyOperator.resources is set (msgTopologyOperator.resources is recommended for production). + ## More information: https://github.com/bitnami/charts/blob/main/bitnami/common/templates/_resources.tpl#L15 + ## + resourcesPreset: "nano" + ## @param msgTopologyOperator.resources Set container requests and limits for different resources like CPU or memory (essential for production workloads) + ## Example: + ## resources: + ## requests: + ## cpu: 2 + ## memory: 512Mi + ## limits: + ## cpu: 3 + ## memory: 1024Mi + ## + resources: {} + ## Configure Pods Security Context + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod + ## @param msgTopologyOperator.podSecurityContext.enabled Enabled RabbitMQ Messaging Topology Operator pods' Security Context + ## @param msgTopologyOperator.podSecurityContext.fsGroupChangePolicy Set filesystem group change policy + ## @param msgTopologyOperator.podSecurityContext.sysctls Set kernel settings using the sysctl interface + ## @param msgTopologyOperator.podSecurityContext.supplementalGroups Set filesystem extra groups + ## @param msgTopologyOperator.podSecurityContext.fsGroup Set RabbitMQ Messaging Topology Operator pod's Security Context fsGroup + ## + podSecurityContext: + enabled: true + fsGroupChangePolicy: Always + sysctls: [] + supplementalGroups: [] + fsGroup: 1001 + ## Configure Container Security Context + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod + ## @param msgTopologyOperator.containerSecurityContext.enabled Enabled containers' Security Context + ## @param msgTopologyOperator.containerSecurityContext.seLinuxOptions [object,nullable] Set SELinux options in container + ## @param msgTopologyOperator.containerSecurityContext.runAsUser Set containers' Security Context runAsUser + ## @param msgTopologyOperator.containerSecurityContext.runAsGroup Set containers' Security Context runAsGroup + ## @param msgTopologyOperator.containerSecurityContext.runAsNonRoot Set container's Security Context runAsNonRoot + ## @param msgTopologyOperator.containerSecurityContext.privileged Set container's Security Context privileged + ## @param msgTopologyOperator.containerSecurityContext.readOnlyRootFilesystem Set container's Security Context readOnlyRootFilesystem + ## @param msgTopologyOperator.containerSecurityContext.allowPrivilegeEscalation Set container's Security Context allowPrivilegeEscalation + ## @param msgTopologyOperator.containerSecurityContext.capabilities.drop List of capabilities to be dropped + ## @param msgTopologyOperator.containerSecurityContext.seccompProfile.type Set container's Security Context seccomp profile + ## + containerSecurityContext: + enabled: true + seLinuxOptions: null + runAsUser: 1001 + runAsGroup: 1001 + runAsNonRoot: true + privileged: false + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + capabilities: + drop: ["ALL"] + seccompProfile: + type: "RuntimeDefault" + ## @param msgTopologyOperator.fullnameOverride String to fully override rmqco.msgTopologyOperator.fullname template + ## + fullnameOverride: "" + ## @param msgTopologyOperator.command Override default container command (useful when using custom images) + ## + command: [] + ## @param msgTopologyOperator.args Override default container args (useful when using custom images) + ## + args: [] + ## @param msgTopologyOperator.automountServiceAccountToken Mount Service Account token in pod + ## + automountServiceAccountToken: true + ## @param msgTopologyOperator.hostAliases RabbitMQ Messaging Topology Operator pods host aliases + ## https://kubernetes.io/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases/ + ## + hostAliases: [] + ## @param msgTopologyOperator.podLabels Extra labels for RabbitMQ Messaging Topology Operator pods + ## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ + ## + podLabels: {} + ## @param msgTopologyOperator.podAnnotations Annotations for RabbitMQ Messaging Topology Operator pods + ## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ + ## + podAnnotations: {} + ## @param msgTopologyOperator.podAffinityPreset Pod affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` + ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity + ## + podAffinityPreset: "" + ## @param msgTopologyOperator.podAntiAffinityPreset Pod anti-affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` + ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity + ## + podAntiAffinityPreset: soft + ## Node affinity preset + ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity + ## + nodeAffinityPreset: + ## @param msgTopologyOperator.nodeAffinityPreset.type Node affinity preset type. Ignored if `affinity` is set. Allowed values: `soft` or `hard` + ## + type: "" + ## @param msgTopologyOperator.nodeAffinityPreset.key Node label key to match. Ignored if `affinity` is set + ## + key: "" + ## @param msgTopologyOperator.nodeAffinityPreset.values Node label values to match. Ignored if `affinity` is set + ## E.g. + ## values: + ## - e2e-az1 + ## - e2e-az2 + ## + values: [] + ## @param msgTopologyOperator.affinity Affinity for RabbitMQ Messaging Topology Operator pods assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + ## NOTE: `podAffinityPreset`, `podAntiAffinityPreset`, and `nodeAffinityPreset` will be ignored when it's set + ## + affinity: {} + ## @param msgTopologyOperator.nodeSelector Node labels for RabbitMQ Messaging Topology Operator pods assignment + ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/ + ## + nodeSelector: {} + ## @param msgTopologyOperator.tolerations Tolerations for RabbitMQ Messaging Topology Operator pods assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ + ## + tolerations: [] + ## @param msgTopologyOperator.updateStrategy.type RabbitMQ Messaging Topology Operator statefulset strategy type + ## ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#update-strategies + ## + updateStrategy: + ## StrategyType + ## Can be set to RollingUpdate or OnDelete + ## + type: RollingUpdate + ## @param msgTopologyOperator.priorityClassName RabbitMQ Messaging Topology Operator pods' priorityClassName + ## + priorityClassName: "" + ## @param msgTopologyOperator.lifecycleHooks for the RabbitMQ Messaging Topology Operator container(s) to automate configuration before or after startup + ## + lifecycleHooks: {} + ## @param msgTopologyOperator.containerPorts.metrics RabbitMQ Messaging Topology Operator container port (used for metrics) + ## + containerPorts: + metrics: 8080 + ## @param msgTopologyOperator.extraEnvVars Array with extra environment variables to add to RabbitMQ Messaging Topology Operator nodes + ## e.g: + ## extraEnvVars: + ## - name: FOO + ## value: "bar" + ## + extraEnvVars: [] + ## @param msgTopologyOperator.extraEnvVarsCM Name of existing ConfigMap containing extra env vars for RabbitMQ Messaging Topology Operator nodes + ## + extraEnvVarsCM: "" + ## @param msgTopologyOperator.extraEnvVarsSecret Name of existing Secret containing extra env vars for RabbitMQ Messaging Topology Operator nodes + ## + extraEnvVarsSecret: "" + ## @param msgTopologyOperator.extraVolumes Optionally specify extra list of additional volumes for the RabbitMQ Messaging Topology Operator pod(s) + ## + extraVolumes: [] + ## @param msgTopologyOperator.extraVolumeMounts Optionally specify extra list of additional volumeMounts for the RabbitMQ Messaging Topology Operator container(s) + ## + extraVolumeMounts: [] + ## @param msgTopologyOperator.sidecars Add additional sidecar containers to the RabbitMQ Messaging Topology Operator pod(s) + ## e.g: + ## sidecars: + ## - name: your-image-name + ## image: your-image + ## imagePullPolicy: Always + ## ports: + ## - name: portname + ## containerPort: 1234 + ## + sidecars: [] + ## @param msgTopologyOperator.initContainers Add additional init containers to the RabbitMQ Messaging Topology Operator pod(s) + ## ref: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ + ## e.g: + ## initContainers: + ## - name: your-image-name + ## image: your-image + ## imagePullPolicy: Always + ## command: ['sh', '-c', 'echo "hello world"'] + ## + initContainers: [] + ## Webhook service parameters + ## + service: + ## @param msgTopologyOperator.service.type RabbitMQ Messaging Topology Operator webhook service type + ## + type: ClusterIP + ## @param msgTopologyOperator.service.ports.webhook RabbitMQ Messaging Topology Operator webhook service HTTP port + ## + ports: + webhook: 443 + ## Node ports to expose + ## @param msgTopologyOperator.service.nodePorts.http Node port for HTTP + ## NOTE: choose port between <30000-32767> + ## + nodePorts: + http: "" + ## @param msgTopologyOperator.service.clusterIP RabbitMQ Messaging Topology Operator webhook service Cluster IP + ## e.g.: + ## clusterIP: None + ## + clusterIP: "" + ## @param msgTopologyOperator.service.loadBalancerIP RabbitMQ Messaging Topology Operator webhook service Load Balancer IP + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-loadbalancer + ## + loadBalancerIP: "" + ## @param msgTopologyOperator.service.extraPorts Extra ports to expose (normally used with the `sidecar` value) + ## + extraPorts: [] + ## @param msgTopologyOperator.service.loadBalancerSourceRanges RabbitMQ Messaging Topology Operator webhook service Load Balancer sources + ## ref: https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/#restrict-access-for-loadbalancer-service + ## e.g: + ## loadBalancerSourceRanges: + ## - 10.10.10.0/24 + ## + loadBalancerSourceRanges: [] + ## @param msgTopologyOperator.service.externalTrafficPolicy RabbitMQ Messaging Topology Operator webhook service external traffic policy + ## ref https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip + ## + externalTrafficPolicy: Cluster + ## @param msgTopologyOperator.service.annotations Additional custom annotations for RabbitMQ Messaging Topology Operator webhook service + ## + annotations: {} + ## @param msgTopologyOperator.service.sessionAffinity Session Affinity for Kubernetes service, can be "None" or "ClientIP" + ## If "ClientIP", consecutive client requests will be directed to the same Pod + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + ## + sessionAffinity: None + ## @param msgTopologyOperator.service.sessionAffinityConfig Additional settings for the sessionAffinity + ## sessionAffinityConfig: + ## clientIP: + ## timeoutSeconds: 300 + ## + sessionAffinityConfig: {} + ## Network Policies + ## Ref: https://kubernetes.io/docs/concepts/services-networking/network-policies/ + ## + networkPolicy: + ## @param msgTopologyOperator.networkPolicy.enabled Specifies whether a NetworkPolicy should be created + ## + enabled: true + ## @param msgTopologyOperator.networkPolicy.kubeAPIServerPorts [array] List of possible endpoints to kube-apiserver (limit to your cluster settings to increase security) + ## + kubeAPIServerPorts: [443, 6443, 8443] + ## @param msgTopologyOperator.networkPolicy.allowExternal Don't require injector label for connections + ## The Policy model to apply. When set to false, only pods with the correct + ## injector label will have network access to the ports injector is listening + ## on. When true, injector will accept connections from any source + ## (with the correct destination port). + ## + allowExternal: true + ## @param msgTopologyOperator.networkPolicy.allowExternalEgress Allow the pod to access any range of port and all destinations. + ## + allowExternalEgress: true + ## @param msgTopologyOperator.networkPolicy.extraIngress [array] Add extra ingress rules to the NetworkPolicy + ## e.g: + ## extraIngress: + ## - ports: + ## - port: 1234 + ## from: + ## - podSelector: + ## - matchLabels: + ## - role: frontend + ## - podSelector: + ## - matchExpressions: + ## - key: role + ## operator: In + ## values: + ## - frontend + extraIngress: [] + ## @param msgTopologyOperator.networkPolicy.extraEgress [array] Add extra ingress rules to the NetworkPolicy + ## e.g: + ## extraEgress: + ## - ports: + ## - port: 1234 + ## to: + ## - podSelector: + ## - matchLabels: + ## - role: frontend + ## - podSelector: + ## - matchExpressions: + ## - key: role + ## operator: In + ## values: + ## - frontend + ## + extraEgress: [] + ## @param msgTopologyOperator.networkPolicy.ingressNSMatchLabels [object] Labels to match to allow traffic from other namespaces + ## @param msgTopologyOperator.networkPolicy.ingressNSPodMatchLabels [object] Pod labels to match to allow traffic from other namespaces + ## + ingressNSMatchLabels: {} + ingressNSPodMatchLabels: {} + ## RBAC configuration + ## + rbac: + ## @param msgTopologyOperator.rbac.create Specifies whether RBAC resources should be created + ## + create: true + ## ClusterRole parameters + ## + clusterRole: + ## @param msgTopologyOperator.rbac.clusterRole.customRules Define custom access rules for the ClusterRole + ## ref: https://kubernetes.io/docs/reference/access-authn-authz/rbac/#role-and-clusterrole + ## e.g: + ## customRules: + ## - apiGroups: A list of API groups (e.g., [""], ["apps"]). + ## - resources: A list of resource names (e.g., ["configmaps", "pods"]). + ## - verbs: A list of allowed access verbs (e.g., ["create", "get", "list"]). + customRules: [] + ## @param msgTopologyOperator.rbac.clusterRole.extraRules Define extra access rules for the ClusterRole. This has no effect if customerRules is a non-empty array. + ## ref: https://kubernetes.io/docs/reference/access-authn-authz/rbac/#role-and-clusterrole + ## e.g: + ## extraRules: + ## - apiGroups: A list of API groups (e.g., [""], ["apps"]). + ## - resources: A list of resource names (e.g., ["configmaps", "pods"]). + ## - verbs: A list of allowed access verbs (e.g., ["create", "get", "list"]). + extraRules: [] + ## ServiceAccount configuration + ## + serviceAccount: + ## @param msgTopologyOperator.serviceAccount.create Specifies whether a ServiceAccount should be created + ## + create: true + ## @param msgTopologyOperator.serviceAccount.name The name of the ServiceAccount to use. + ## If not set and create is true, a name is generated using the common.names.fullname template + ## + name: "" + ## @param msgTopologyOperator.serviceAccount.annotations Add annotations + ## + annotations: {} + ## @param msgTopologyOperator.serviceAccount.automountServiceAccountToken Automount API credentials for a service account. + ## + automountServiceAccountToken: false + ## @section RabbitMQ Messaging Topology Operator parameters + ## + metrics: + ## Metrics service parameters + ## + service: + ## @param msgTopologyOperator.metrics.service.enabled Create a service for accessing the metrics endpoint + ## + enabled: false + ## @param msgTopologyOperator.metrics.service.type RabbitMQ Cluster Operator metrics service type + ## + type: ClusterIP + ## @param msgTopologyOperator.metrics.service.ports.http RabbitMQ Cluster Operator metrics service HTTP port + ## + ports: + http: 80 + ## Node ports to expose + ## @param msgTopologyOperator.metrics.service.nodePorts.http Node port for HTTP + ## NOTE: choose port between <30000-32767> + ## + nodePorts: + http: "" + ## @param msgTopologyOperator.metrics.service.clusterIP RabbitMQ Cluster Operator metrics service Cluster IP + ## e.g.: + ## clusterIP: None + ## + clusterIP: "" + ## @param msgTopologyOperator.metrics.service.extraPorts Extra ports to expose (normally used with the `sidecar` value) + ## + extraPorts: [] + ## @param msgTopologyOperator.metrics.service.loadBalancerIP RabbitMQ Cluster Operator metrics service Load Balancer IP + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-loadbalancer + ## + loadBalancerIP: "" + ## @param msgTopologyOperator.metrics.service.loadBalancerSourceRanges RabbitMQ Cluster Operator metrics service Load Balancer sources + ## ref: https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/#restrict-access-for-loadbalancer-service + ## e.g: + ## loadBalancerSourceRanges: + ## - 10.10.10.0/24 + ## + loadBalancerSourceRanges: [] + ## @param msgTopologyOperator.metrics.service.externalTrafficPolicy RabbitMQ Cluster Operator metrics service external traffic policy + ## ref https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip + ## + externalTrafficPolicy: Cluster + ## @param msgTopologyOperator.metrics.service.annotations [object] Additional custom annotations for RabbitMQ Cluster Operator metrics service + ## + annotations: + prometheus.io/scrape: "true" + prometheus.io/port: "{{ .Values.msgTopologyOperator.metrics.service.ports.http }}" + ## @param msgTopologyOperator.metrics.service.sessionAffinity Session Affinity for Kubernetes service, can be "None" or "ClientIP" + ## If "ClientIP", consecutive client requests will be directed to the same Pod + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + ## + sessionAffinity: None + ## @param msgTopologyOperator.metrics.service.sessionAffinityConfig Additional settings for the sessionAffinity + ## sessionAffinityConfig: + ## clientIP: + ## timeoutSeconds: 300 + ## + sessionAffinityConfig: {} + serviceMonitor: + ## @param msgTopologyOperator.metrics.serviceMonitor.enabled Specify if a servicemonitor will be deployed for prometheus-operator + ## + enabled: false + ## @param msgTopologyOperator.metrics.serviceMonitor.namespace Namespace which Prometheus is running in + ## e.g: + ## namespace: monitoring + ## + namespace: "" + ## @param msgTopologyOperator.metrics.serviceMonitor.jobLabel Specify the jobLabel to use for the prometheus-operator + ## + jobLabel: app.kubernetes.io/name + ## DEPRECATED: Use msgTopologyOperator.metrics.serviceMonitor.labels instead. + ## This value will be removed in a future release + ## additionalLabels: {} + + ## @param msgTopologyOperator.metrics.serviceMonitor.selector Prometheus instance selector labels + ## ref: https://github.com/bitnami/charts/tree/main/bitnami/prometheus-operator#prometheus-configuration + ## e.g: + ## selector: + ## prometheus: my-prometheus + ## + selector: {} + ## @param msgTopologyOperator.metrics.serviceMonitor.honorLabels Honor metrics labels + ## ref: https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#endpoint + ## + honorLabels: false + ## @param msgTopologyOperator.metrics.serviceMonitor.scrapeTimeout Timeout after which the scrape is ended + ## ref: https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#endpoint + ## e.g: + ## scrapeTimeout: 10s + ## + scrapeTimeout: "" + ## @param msgTopologyOperator.metrics.serviceMonitor.interval Scrape interval. If not set, the Prometheus default scrape interval is used + ## + interval: "" + ## @param msgTopologyOperator.metrics.serviceMonitor.metricRelabelings Specify additional relabeling of metrics + ## + metricRelabelings: [] + ## @param msgTopologyOperator.metrics.serviceMonitor.relabelings Specify general relabeling + ## + relabelings: [] + ## @param msgTopologyOperator.metrics.serviceMonitor.labels Extra labels for the ServiceMonitor + ## + labels: {} + podMonitor: + ## @param msgTopologyOperator.metrics.podMonitor.enabled Create PodMonitor Resource for scraping metrics using PrometheusOperator + ## + enabled: false + ## @param msgTopologyOperator.metrics.podMonitor.jobLabel Specify the jobLabel to use for the prometheus-operator + ## + jobLabel: app.kubernetes.io/name + ## @param msgTopologyOperator.metrics.podMonitor.namespace Namespace which Prometheus is running in + ## + namespace: "" + ## @param msgTopologyOperator.metrics.podMonitor.honorLabels Honor metrics labels + ## + honorLabels: false + ## @param msgTopologyOperator.metrics.podMonitor.selector Prometheus instance selector labels + ## ref: https://github.com/bitnami/charts/tree/main/bitnami/prometheus-operator#prometheus-configuration + selector: {} + ## @param msgTopologyOperator.metrics.podMonitor.interval Specify the interval at which metrics should be scraped + ## + interval: 30s + ## @param msgTopologyOperator.metrics.podMonitor.scrapeTimeout Specify the timeout after which the scrape is ended + ## + scrapeTimeout: 30s + ## @param msgTopologyOperator.metrics.podMonitor.additionalLabels [object] Additional labels that can be used so PodMonitors will be discovered by Prometheus + ## + additionalLabels: {} + ## @param msgTopologyOperator.metrics.podMonitor.relabelings Specify general relabeling + ## + relabelings: [] + ## @param msgTopologyOperator.metrics.podMonitor.metricRelabelings Specify additional relabeling of metrics + ## + metricRelabelings: [] +## @section cert-manager parameters +## + +## @param useCertManager Deploy cert-manager objects (Issuer and Certificate) for webhooks +## +useCertManager: false diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/.gitignore b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/.gitignore new file mode 100644 index 000000000..aa1ec1ea0 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/.gitignore @@ -0,0 +1 @@ +*.tgz diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/Chart.lock b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/Chart.lock new file mode 100644 index 000000000..8da343e30 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: cert-manager + repository: https://charts.jetstack.io + version: v1.12.4 +digest: sha256:026d03c56e2f8369b0f7d79f9560d5a33b2c5ae8a7d751213e56e2a0176cb874 +generated: "2023-10-02T14:14:45.164829041+05:30" diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/Chart.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/Chart.yaml new file mode 100644 index 000000000..d81ed26ae --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/Chart.yaml @@ -0,0 +1,25 @@ +apiVersion: v2 +appVersion: 0.18.0 +dependencies: +- alias: certmanager + condition: certmanager.enabled + name: cert-manager + repository: https://charts.jetstack.io + version: v1.12.4 +description: Provides easy redis setup definitions for Kubernetes services, and deployment. +home: https://github.com/OT-CONTAINER-KIT/redis-operator +icon: https://github.com/OT-CONTAINER-KIT/redis-operator/raw/master/static/redis-operator-logo.svg +keywords: +- operator +- redis +- opstree +- kubernetes +- openshift +maintainers: +- name: iamabhishek-dubey +- name: sandy724 +- name: shubham-cmyk +name: redis-operator +sources: +- https://github.com/OT-CONTAINER-KIT/redis-operator +version: 0.18.0 diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/Chart.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/Chart.yaml new file mode 100644 index 000000000..1b479df0f --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/Chart.yaml @@ -0,0 +1,24 @@ +annotations: + artifacthub.io/prerelease: "false" + artifacthub.io/signKey: | + fingerprint: 1020CF3C033D4F35BAE1C19E1226061C665DF13E + url: https://cert-manager.io/public-keys/cert-manager-keyring-2021-09-20-1020CF3C033D4F35BAE1C19E1226061C665DF13E.gpg +apiVersion: v1 +appVersion: v1.12.4 +description: A Helm chart for cert-manager +home: https://github.com/cert-manager/cert-manager +icon: https://raw.githubusercontent.com/cert-manager/cert-manager/d53c0b9270f8cd90d908460d69502694e1838f5f/logo/logo-small.png +keywords: +- cert-manager +- kube-lego +- letsencrypt +- tls +kubeVersion: '>= 1.22.0-0' +maintainers: +- email: cert-manager-maintainers@googlegroups.com + name: cert-manager-maintainers + url: https://cert-manager.io +name: cert-manager +sources: +- https://github.com/cert-manager/cert-manager +version: v1.12.4 diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/README.md b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/README.md new file mode 100644 index 000000000..678da960a --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/README.md @@ -0,0 +1,271 @@ +# cert-manager + +cert-manager is a Kubernetes addon to automate the management and issuance of +TLS certificates from various issuing sources. + +It will ensure certificates are valid and up to date periodically, and attempt +to renew certificates at an appropriate time before expiry. + +## Prerequisites + +- Kubernetes 1.20+ + +## Installing the Chart + +Full installation instructions, including details on how to configure extra +functionality in cert-manager can be found in the [installation docs](https://cert-manager.io/docs/installation/kubernetes/). + +Before installing the chart, you must first install the cert-manager CustomResourceDefinition resources. +This is performed in a separate step to allow you to easily uninstall and reinstall cert-manager without deleting your installed custom resources. + +```bash +$ kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.12.4/cert-manager.crds.yaml +``` + +To install the chart with the release name `my-release`: + +```console +## Add the Jetstack Helm repository +$ helm repo add jetstack https://charts.jetstack.io + +## Install the cert-manager helm chart +$ helm install my-release --namespace cert-manager --version v1.12.4 jetstack/cert-manager +``` + +In order to begin issuing certificates, you will need to set up a ClusterIssuer +or Issuer resource (for example, by creating a 'letsencrypt-staging' issuer). + +More information on the different types of issuers and how to configure them +can be found in [our documentation](https://cert-manager.io/docs/configuration/). + +For information on how to configure cert-manager to automatically provision +Certificates for Ingress resources, take a look at the +[Securing Ingresses documentation](https://cert-manager.io/docs/usage/ingress/). + +> **Tip**: List all releases using `helm list` + +## Upgrading the Chart + +Special considerations may be required when upgrading the Helm chart, and these +are documented in our full [upgrading guide](https://cert-manager.io/docs/installation/upgrading/). + +**Please check here before performing upgrades!** + +## Uninstalling the Chart + +To uninstall/delete the `my-release` deployment: + +```console +$ helm delete my-release +``` + +The command removes all the Kubernetes components associated with the chart and deletes the release. + +If you want to completely uninstall cert-manager from your cluster, you will also need to +delete the previously installed CustomResourceDefinition resources: + +```console +$ kubectl delete -f https://github.com/cert-manager/cert-manager/releases/download/v1.12.4/cert-manager.crds.yaml +``` + +## Configuration + +The following table lists the configurable parameters of the cert-manager chart and their default values. + +| Parameter | Description | Default | +| --------- | ----------- | ------- | +| `global.imagePullSecrets` | Reference to one or more secrets to be used when pulling images | `[]` | +| `global.commonLabels` | Labels to apply to all resources | `{}` | +| `global.rbac.create` | If `true`, create and use RBAC resources (includes sub-charts) | `true` | +| `global.priorityClassName`| Priority class name for cert-manager and webhook pods | `""` | +| `global.podSecurityPolicy.enabled` | If `true`, create and use PodSecurityPolicy (includes sub-charts) | `false` | +| `global.podSecurityPolicy.useAppArmor` | If `true`, use Apparmor seccomp profile in PSP | `true` | +| `global.leaderElection.namespace` | Override the namespace used to store the ConfigMap for leader election | `kube-system` | +| `global.leaderElection.leaseDuration` | The duration that non-leader candidates will wait after observing a leadership renewal until attempting to acquire leadership of a led but unrenewed leader slot. This is effectively the maximum duration that a leader can be stopped before it is replaced by another candidate | | +| `global.leaderElection.renewDeadline` | The interval between attempts by the acting master to renew a leadership slot before it stops leading. This must be less than or equal to the lease duration | | +| `global.leaderElection.retryPeriod` | The duration the clients should wait between attempting acquisition and renewal of a leadership | | +| `installCRDs` | If true, CRD resources will be installed as part of the Helm chart. If enabled, when uninstalling CRD resources will be deleted causing all installed custom resources to be DELETED | `false` | +| `image.repository` | Image repository | `quay.io/jetstack/cert-manager-controller` | +| `image.tag` | Image tag | `v1.12.4` | +| `image.pullPolicy` | Image pull policy | `IfNotPresent` | +| `replicaCount` | Number of cert-manager replicas | `1` | +| `clusterResourceNamespace` | Override the namespace used to store DNS provider credentials etc. for ClusterIssuer resources | Same namespace as cert-manager pod | +| `featureGates` | Set of comma-separated key=value pairs that describe feature gates on the controller. Some feature gates may also have to be enabled on other components, and can be set supplying the `feature-gate` flag to `.extraArgs` | `` | +| `extraArgs` | Optional flags for cert-manager | `[]` | +| `extraEnv` | Optional environment variables for cert-manager | `[]` | +| `serviceAccount.create` | If `true`, create a new service account | `true` | +| `serviceAccount.name` | Service account to be used. If not set and `serviceAccount.create` is `true`, a name is generated using the fullname template | | +| `serviceAccount.annotations` | Annotations to add to the service account | | +| `serviceAccount.automountServiceAccountToken` | Automount API credentials for the Service Account | `true` | +| `volumes` | Optional volumes for cert-manager | `[]` | +| `volumeMounts` | Optional volume mounts for cert-manager | `[]` | +| `resources` | CPU/memory resource requests/limits | `{}` | +| `securityContext` | Security context for the controller pod assignment | refer to [Default Security Contexts](#default-security-contexts) | +| `containerSecurityContext` | Security context to be set on the controller component container | refer to [Default Security Contexts](#default-security-contexts) | +| `nodeSelector` | Node labels for pod assignment | `{}` | +| `affinity` | Node affinity for pod assignment | `{}` | +| `tolerations` | Node tolerations for pod assignment | `[]` | +| `topologySpreadConstraints` | Topology spread constraints for pod assignment | `[]` | +| `livenessProbe.enabled` | Enable or disable the liveness probe for the controller container in the controller Pod. See https://cert-manager.io/docs/installation/best-practice/ to learn about when you might want to enable this livenss probe. | `false` | +| `livenessProbe.initialDelaySeconds` | The liveness probe initial delay (in seconds) | `10` | +| `livenessProbe.periodSeconds` | The liveness probe period (in seconds) | `10` | +| `livenessProbe.timeoutSeconds` | The liveness probe timeout (in seconds) | `10` | +| `livenessProbe.periodSeconds` | The liveness probe period (in seconds) | `10` | +| `livenessProbe.successThreshold` | The liveness probe success threshold | `1` | +| `livenessProbe.failureThreshold` | The liveness probe failure threshold | `8` | +| `ingressShim.defaultIssuerName` | Optional default issuer to use for ingress resources | | +| `ingressShim.defaultIssuerKind` | Optional default issuer kind to use for ingress resources | | +| `ingressShim.defaultIssuerGroup` | Optional default issuer group to use for ingress resources | | +| `prometheus.enabled` | Enable Prometheus monitoring | `true` | +| `prometheus.servicemonitor.enabled` | Enable Prometheus Operator ServiceMonitor monitoring | `false` | +| `prometheus.servicemonitor.namespace` | Define namespace where to deploy the ServiceMonitor resource | (namespace where you are deploying) | +| `prometheus.servicemonitor.prometheusInstance` | Prometheus Instance definition | `default` | +| `prometheus.servicemonitor.targetPort` | Prometheus scrape port | `9402` | +| `prometheus.servicemonitor.path` | Prometheus scrape path | `/metrics` | +| `prometheus.servicemonitor.interval` | Prometheus scrape interval | `60s` | +| `prometheus.servicemonitor.labels` | Add custom labels to ServiceMonitor | | +| `prometheus.servicemonitor.scrapeTimeout` | Prometheus scrape timeout | `30s` | +| `prometheus.servicemonitor.honorLabels` | Enable label honoring for metrics scraped by Prometheus (see [Prometheus scrape config docs](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config) for details). By setting `honorLabels` to `true`, Prometheus will prefer label contents given by cert-manager on conflicts. Can be used to remove the "exported_namespace" label for example. | `false` | +| `podAnnotations` | Annotations to add to the cert-manager pod | `{}` | +| `deploymentAnnotations` | Annotations to add to the cert-manager deployment | `{}` | +| `podDisruptionBudget.enabled` | Adds a PodDisruptionBudget for the cert-manager deployment | `false` | +| `podDisruptionBudget.minAvailable` | Configures the minimum available pods for voluntary disruptions. Cannot used if `maxUnavailable` is set. | `1` | +| `podDisruptionBudget.maxUnavailable` | Configures the maximum unavailable pods for voluntary disruptions. Cannot used if `minAvailable` is set. | | +| `podDnsPolicy` | Optional cert-manager pod [DNS policy](https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pods-dns-policy) | | +| `podDnsConfig` | Optional cert-manager pod [DNS configurations](https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pods-dns-config) | | +| `podLabels` | Labels to add to the cert-manager pod | `{}` | +| `serviceLabels` | Labels to add to the cert-manager controller service | `{}` | +| `serviceAnnotations` | Annotations to add to the cert-manager service | `{}` | +| `http_proxy` | Value of the `HTTP_PROXY` environment variable in the cert-manager pod | | +| `https_proxy` | Value of the `HTTPS_PROXY` environment variable in the cert-manager pod | | +| `no_proxy` | Value of the `NO_PROXY` environment variable in the cert-manager pod | | +| `dns01RecursiveNameservers` | Comma separated string with host and port of the recursive nameservers cert-manager should query | `` | +| `dns01RecursiveNameserversOnly` | Forces cert-manager to only use the recursive nameservers for verification. | `false` | +| `enableCertificateOwnerRef` | When this flag is enabled, secrets will be automatically removed when the certificate resource is deleted | `false` | +| `webhook.replicaCount` | Number of cert-manager webhook replicas | `1` | +| `webhook.timeoutSeconds` | Seconds the API server should wait the webhook to respond before treating the call as a failure. | `10` | +| `webhook.podAnnotations` | Annotations to add to the webhook pods | `{}` | +| `webhook.podLabels` | Labels to add to the cert-manager webhook pod | `{}` | +| `webhook.serviceLabels` | Labels to add to the cert-manager webhook service | `{}` | +| `webhook.deploymentAnnotations` | Annotations to add to the webhook deployment | `{}` | +| `webhook.podDisruptionBudget.enabled` | Adds a PodDisruptionBudget for the cert-manager deployment | `false` | +| `webhook.podDisruptionBudget.minAvailable` | Configures the minimum available pods for voluntary disruptions. Cannot used if `maxUnavailable` is set. | `1` | +| `webhook.podDisruptionBudget.maxUnavailable` | Configures the maximum unavailable pods for voluntary disruptions. Cannot used if `minAvailable` is set. | | +| `webhook.mutatingWebhookConfigurationAnnotations` | Annotations to add to the mutating webhook configuration | `{}` | +| `webhook.validatingWebhookConfigurationAnnotations` | Annotations to add to the validating webhook configuration | `{}` | +| `webhook.serviceAnnotations` | Annotations to add to the webhook service | `{}` | +| `webhook.config` | WebhookConfiguration YAML used to configure flags for the webhook. Generates a ConfigMap containing contents of the field. See `values.yaml` for example. | `{}` | +| `webhook.extraArgs` | Optional flags for cert-manager webhook component | `[]` | +| `webhook.serviceAccount.create` | If `true`, create a new service account for the webhook component | `true` | +| `webhook.serviceAccount.name` | Service account for the webhook component to be used. If not set and `webhook.serviceAccount.create` is `true`, a name is generated using the fullname template | | +| `webhook.serviceAccount.annotations` | Annotations to add to the service account for the webhook component | | +| `webhook.serviceAccount.automountServiceAccountToken` | Automount API credentials for the webhook Service Account | | +| `webhook.resources` | CPU/memory resource requests/limits for the webhook pods | `{}` | +| `webhook.nodeSelector` | Node labels for webhook pod assignment | `{}` | +| `webhook.networkPolicy.enabled` | Enable default network policies for webhooks egress and ingress traffic | `false` | +| `webhook.networkPolicy.ingress` | Sets ingress policy block. See NetworkPolicy documentation. See `values.yaml` for example. | `{}` | +| `webhook.networkPolicy.egress` | Sets ingress policy block. See NetworkPolicy documentation. See `values.yaml` for example. | `{}` | +| `webhook.affinity` | Node affinity for webhook pod assignment | `{}` | +| `webhook.tolerations` | Node tolerations for webhook pod assignment | `[]` | +| `webhook.topologySpreadConstraints` | Topology spread constraints for webhook pod assignment | `[]` | +| `webhook.image.repository` | Webhook image repository | `quay.io/jetstack/cert-manager-webhook` | +| `webhook.image.tag` | Webhook image tag | `v1.12.4` | +| `webhook.image.pullPolicy` | Webhook image pull policy | `IfNotPresent` | +| `webhook.securePort` | The port that the webhook should listen on for requests. | `10250` | +| `webhook.securityContext` | Security context for webhook pod assignment | refer to [Default Security Contexts](#default-security-contexts) | +| `webhook.containerSecurityContext` | Security context to be set on the webhook component container | refer to [Default Security Contexts](#default-security-contexts) | +| `webhook.hostNetwork` | If `true`, run the Webhook on the host network. | `false` | +| `webhook.serviceType` | The type of the `Service`. | `ClusterIP` | +| `webhook.loadBalancerIP` | The specific load balancer IP to use (when `serviceType` is `LoadBalancer`). | | +| `webhook.url.host` | The host to use to reach the webhook, instead of using internal cluster DNS for the service. | | +| `webhook.livenessProbe.failureThreshold` | The liveness probe failure threshold | `3` | +| `webhook.livenessProbe.initialDelaySeconds` | The liveness probe initial delay (in seconds) | `60` | +| `webhook.livenessProbe.periodSeconds` | The liveness probe period (in seconds) | `10` | +| `webhook.livenessProbe.successThreshold` | The liveness probe success threshold | `1` | +| `webhook.livenessProbe.timeoutSeconds` | The liveness probe timeout (in seconds) | `1` | +| `webhook.readinessProbe.failureThreshold` | The readiness probe failure threshold | `3` | +| `webhook.readinessProbe.initialDelaySeconds` | The readiness probe initial delay (in seconds) | `5` | +| `webhook.readinessProbe.periodSeconds` | The readiness probe period (in seconds) | `5` | +| `webhook.readinessProbe.successThreshold` | The readiness probe success threshold | `1` | +| `webhook.readinessProbe.timeoutSeconds` | The readiness probe timeout (in seconds) | `1` | +| `cainjector.enabled` | Toggles whether the cainjector component should be installed (required for the webhook component to work) | `true` | +| `cainjector.replicaCount` | Number of cert-manager cainjector replicas | `1` | +| `cainjector.podAnnotations` | Annotations to add to the cainjector pods | `{}` | +| `cainjector.podLabels` | Labels to add to the cert-manager cainjector pod | `{}` | +| `cainjector.deploymentAnnotations` | Annotations to add to the cainjector deployment | `{}` | +| `cainjector.podDisruptionBudget.enabled` | Adds a PodDisruptionBudget for the cert-manager deployment | `false` | +| `cainjector.podDisruptionBudget.minAvailable` | Configures the minimum available pods for voluntary disruptions. Cannot used if `maxUnavailable` is set. | `1` | +| `cainjector.podDisruptionBudget.maxUnavailable` | Configures the maximum unavailable pods for voluntary disruptions. Cannot used if `minAvailable` is set. | | +| `cainjector.extraArgs` | Optional flags for cert-manager cainjector component | `[]` | +| `cainjector.serviceAccount.create` | If `true`, create a new service account for the cainjector component | `true` | +| `cainjector.serviceAccount.name` | Service account for the cainjector component to be used. If not set and `cainjector.serviceAccount.create` is `true`, a name is generated using the fullname template | | +| `cainjector.serviceAccount.annotations` | Annotations to add to the service account for the cainjector component | | +| `cainjector.serviceAccount.automountServiceAccountToken` | Automount API credentials for the cainjector Service Account | `true` | +| `cainjector.resources` | CPU/memory resource requests/limits for the cainjector pods | `{}` | +| `cainjector.nodeSelector` | Node labels for cainjector pod assignment | `{}` | +| `cainjector.affinity` | Node affinity for cainjector pod assignment | `{}` | +| `cainjector.tolerations` | Node tolerations for cainjector pod assignment | `[]` | +| `cainjector.topologySpreadConstraints` | Topology spread constraints for cainjector pod assignment | `[]` | +| `cainjector.image.repository` | cainjector image repository | `quay.io/jetstack/cert-manager-cainjector` | +| `cainjector.image.tag` | cainjector image tag | `v1.12.4` | +| `cainjector.image.pullPolicy` | cainjector image pull policy | `IfNotPresent` | +| `cainjector.securityContext` | Security context for cainjector pod assignment | refer to [Default Security Contexts](#default-security-contexts) | +| `cainjector.containerSecurityContext` | Security context to be set on cainjector component container | refer to [Default Security Contexts](#default-security-contexts) | +| `acmesolver.image.repository` | acmesolver image repository | `quay.io/jetstack/cert-manager-acmesolver` | +| `acmesolver.image.tag` | acmesolver image tag | `v1.12.4` | +| `acmesolver.image.pullPolicy` | acmesolver image pull policy | `IfNotPresent` | +| `startupapicheck.enabled` | Toggles whether the startupapicheck Job should be installed | `true` | +| `startupapicheck.securityContext` | Security context for startupapicheck pod assignment | refer to [Default Security Contexts](#default-security-contexts) | +| `startupapicheck.containerSecurityContext` | Security context to be set on startupapicheck component container | refer to [Default Security Contexts](#default-security-contexts) | +| `startupapicheck.timeout` | Timeout for 'kubectl check api' command | `1m` | +| `startupapicheck.backoffLimit` | Job backoffLimit | `4` | +| `startupapicheck.jobAnnotations` | Optional additional annotations to add to the startupapicheck Job | `{}` | +| `startupapicheck.podAnnotations` | Optional additional annotations to add to the startupapicheck Pods | `{}` | +| `startupapicheck.extraArgs` | Optional additional arguments for startupapicheck | `[]` | +| `startupapicheck.resources` | CPU/memory resource requests/limits for the startupapicheck pod | `{}` | +| `startupapicheck.nodeSelector` | Node labels for startupapicheck pod assignment | `{}` | +| `startupapicheck.affinity` | Node affinity for startupapicheck pod assignment | `{}` | +| `startupapicheck.tolerations` | Node tolerations for startupapicheck pod assignment | `[]` | +| `startupapicheck.podLabels` | Optional additional labels to add to the startupapicheck Pods | `{}` | +| `startupapicheck.image.repository` | startupapicheck image repository | `quay.io/jetstack/cert-manager-ctl` | +| `startupapicheck.image.tag` | startupapicheck image tag | `v1.12.4` | +| `startupapicheck.image.pullPolicy` | startupapicheck image pull policy | `IfNotPresent` | +| `startupapicheck.serviceAccount.create` | If `true`, create a new service account for the startupapicheck component | `true` | +| `startupapicheck.serviceAccount.name` | Service account for the startupapicheck component to be used. If not set and `startupapicheck.serviceAccount.create` is `true`, a name is generated using the fullname template | | +| `startupapicheck.serviceAccount.annotations` | Annotations to add to the service account for the startupapicheck component | | +| `startupapicheck.serviceAccount.automountServiceAccountToken` | Automount API credentials for the startupapicheck Service Account | `true` | +| `maxConcurrentChallenges` | The maximum number of challenges that can be scheduled as 'processing' at once | `60` | + +### Default Security Contexts + +The default pod-level and container-level security contexts, below, adhere to the [restricted](https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted) Pod Security Standards policies. + +Default pod-level securityContext: +```yaml +runAsNonRoot: true +seccompProfile: + type: RuntimeDefault +``` + +Default containerSecurityContext: +```yaml +allowPrivilegeEscalation: false +capabilities: + drop: + - ALL +``` + +### Assigning Values + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. + +Alternatively, a YAML file that specifies the values for the above parameters can be provided while installing the chart. For example, + +```console +$ helm install my-release -f values.yaml . +``` +> **Tip**: You can use the default [values.yaml](https://github.com/cert-manager/cert-manager/blob/master/deploy/charts/cert-manager/values.yaml) + +## Contributing + +This chart is maintained at [github.com/cert-manager/cert-manager](https://github.com/cert-manager/cert-manager/tree/master/deploy/charts/cert-manager). diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/NOTES.txt b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/NOTES.txt new file mode 100644 index 000000000..102535460 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/NOTES.txt @@ -0,0 +1,15 @@ +cert-manager {{ .Chart.AppVersion }} has been deployed successfully! + +In order to begin issuing certificates, you will need to set up a ClusterIssuer +or Issuer resource (for example, by creating a 'letsencrypt-staging' issuer). + +More information on the different types of issuers and how to configure them +can be found in our documentation: + +https://cert-manager.io/docs/configuration/ + +For information on how to configure cert-manager to automatically provision +Certificates for Ingress resources, take a look at the `ingress-shim` +documentation: + +https://cert-manager.io/docs/usage/ingress/ diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/_helpers.tpl b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/_helpers.tpl new file mode 100644 index 000000000..90db4af26 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/_helpers.tpl @@ -0,0 +1,174 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "cert-manager.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "cert-manager.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "cert-manager.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "cert-manager.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Webhook templates +*/}} + +{{/* +Expand the name of the chart. +Manually fix the 'app' and 'name' labels to 'webhook' to maintain +compatibility with the v0.9 deployment selector. +*/}} +{{- define "webhook.name" -}} +{{- printf "webhook" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "webhook.fullname" -}} +{{- $trimmedName := printf "%s" (include "cert-manager.fullname" .) | trunc 55 | trimSuffix "-" -}} +{{- printf "%s-webhook" $trimmedName | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- define "webhook.caRef" -}} +{{- template "cert-manager.namespace" }}/{{ template "webhook.fullname" . }}-ca +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "webhook.serviceAccountName" -}} +{{- if .Values.webhook.serviceAccount.create -}} + {{ default (include "webhook.fullname" .) .Values.webhook.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.webhook.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +cainjector templates +*/}} + +{{/* +Expand the name of the chart. +Manually fix the 'app' and 'name' labels to 'cainjector' to maintain +compatibility with the v0.9 deployment selector. +*/}} +{{- define "cainjector.name" -}} +{{- printf "cainjector" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "cainjector.fullname" -}} +{{- $trimmedName := printf "%s" (include "cert-manager.fullname" .) | trunc 52 | trimSuffix "-" -}} +{{- printf "%s-cainjector" $trimmedName | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "cainjector.serviceAccountName" -}} +{{- if .Values.cainjector.serviceAccount.create -}} + {{ default (include "cainjector.fullname" .) .Values.cainjector.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.cainjector.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +startupapicheck templates +*/}} + +{{/* +Expand the name of the chart. +Manually fix the 'app' and 'name' labels to 'startupapicheck' to maintain +compatibility with the v0.9 deployment selector. +*/}} +{{- define "startupapicheck.name" -}} +{{- printf "startupapicheck" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "startupapicheck.fullname" -}} +{{- $trimmedName := printf "%s" (include "cert-manager.fullname" .) | trunc 52 | trimSuffix "-" -}} +{{- printf "%s-startupapicheck" $trimmedName | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "startupapicheck.serviceAccountName" -}} +{{- if .Values.startupapicheck.serviceAccount.create -}} + {{ default (include "startupapicheck.fullname" .) .Values.startupapicheck.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.startupapicheck.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "chartName" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Labels that should be added on each resource +*/}} +{{- define "labels" -}} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- if eq (default "helm" .Values.creator) "helm" }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +helm.sh/chart: {{ include "chartName" . }} +{{- end -}} +{{- if .Values.global.commonLabels}} +{{ toYaml .Values.global.commonLabels }} +{{- end }} +{{- end -}} + +{{/* +Namespace for all resources to be installed into +If not defined in values file then the helm release namespace is used +By default this is not set so the helm release namespace will be used + +This gets around an problem within helm discussed here +https://github.com/helm/helm/issues/5358 +*/}} +{{- define "cert-manager.namespace" -}} + {{ .Values.namespace | default .Release.Namespace }} +{{- end -}} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/cainjector-deployment.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/cainjector-deployment.yaml new file mode 100644 index 000000000..122017374 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/cainjector-deployment.yaml @@ -0,0 +1,117 @@ +{{- if .Values.cainjector.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "cainjector.fullname" . }} + namespace: {{ include "cert-manager.namespace" . }} + labels: + app: {{ include "cainjector.name" . }} + app.kubernetes.io/name: {{ include "cainjector.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "cainjector" + {{- include "labels" . | nindent 4 }} + {{- with .Values.cainjector.deploymentAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.cainjector.replicaCount }} + selector: + matchLabels: + app.kubernetes.io/name: {{ include "cainjector.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "cainjector" + {{- with .Values.cainjector.strategy }} + strategy: + {{- toYaml . | nindent 4 }} + {{- end }} + template: + metadata: + labels: + app: {{ include "cainjector.name" . }} + app.kubernetes.io/name: {{ include "cainjector.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "cainjector" + {{- include "labels" . | nindent 8 }} + {{- with .Values.cainjector.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.cainjector.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + serviceAccountName: {{ template "cainjector.serviceAccountName" . }} + {{- if hasKey .Values.cainjector "automountServiceAccountToken" }} + automountServiceAccountToken: {{ .Values.cainjector.automountServiceAccountToken }} + {{- end }} + {{- with .Values.global.priorityClassName }} + priorityClassName: {{ . | quote }} + {{- end }} + {{- with .Values.cainjector.securityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: {{ .Chart.Name }}-cainjector + {{- with .Values.cainjector.image }} + image: "{{- if .registry -}}{{ .registry }}/{{- end -}}{{ .repository }}{{- if (.digest) -}} @{{ .digest }}{{- else -}}:{{ default $.Chart.AppVersion .tag }} {{- end -}}" + {{- end }} + imagePullPolicy: {{ .Values.cainjector.image.pullPolicy }} + args: + {{- if .Values.global.logLevel }} + - --v={{ .Values.global.logLevel }} + {{- end }} + {{- with .Values.global.leaderElection }} + - --leader-election-namespace={{ .namespace }} + {{- if .leaseDuration }} + - --leader-election-lease-duration={{ .leaseDuration }} + {{- end }} + {{- if .renewDeadline }} + - --leader-election-renew-deadline={{ .renewDeadline }} + {{- end }} + {{- if .retryPeriod }} + - --leader-election-retry-period={{ .retryPeriod }} + {{- end }} + {{- end }} + {{- with .Values.cainjector.extraArgs }} + {{- toYaml . | nindent 10 }} + {{- end }} + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- with .Values.cainjector.containerSecurityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.cainjector.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.cainjector.volumeMounts }} + volumeMounts: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.cainjector.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.cainjector.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.cainjector.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.cainjector.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.cainjector.volumes }} + volumes: + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/cainjector-poddisruptionbudget.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/cainjector-poddisruptionbudget.yaml new file mode 100644 index 000000000..f080b753a --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/cainjector-poddisruptionbudget.yaml @@ -0,0 +1,26 @@ +{{- if .Values.cainjector.podDisruptionBudget.enabled }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "cainjector.fullname" . }} + namespace: {{ include "cert-manager.namespace" . }} + labels: + app: {{ include "cainjector.name" . }} + app.kubernetes.io/name: {{ include "cainjector.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "cainjector" + {{- include "labels" . | nindent 4 }} +spec: + selector: + matchLabels: + app.kubernetes.io/name: {{ include "cainjector.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "cainjector" + + {{- with .Values.cainjector.podDisruptionBudget.minAvailable }} + minAvailable: {{ . }} + {{- end }} + {{- with .Values.cainjector.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ . }} + {{- end }} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/cainjector-psp-clusterrole.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/cainjector-psp-clusterrole.yaml new file mode 100644 index 000000000..b75b9eb6f --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/cainjector-psp-clusterrole.yaml @@ -0,0 +1,20 @@ +{{- if .Values.cainjector.enabled }} +{{- if .Values.global.podSecurityPolicy.enabled }} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "cainjector.fullname" . }}-psp + labels: + app: {{ include "cainjector.name" . }} + app.kubernetes.io/name: {{ include "cainjector.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "cainjector" + {{- include "labels" . | nindent 4 }} +rules: +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "cainjector.fullname" . }} +{{- end }} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/cainjector-psp-clusterrolebinding.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/cainjector-psp-clusterrolebinding.yaml new file mode 100644 index 000000000..e2bfa26bb --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/cainjector-psp-clusterrolebinding.yaml @@ -0,0 +1,22 @@ +{{- if .Values.cainjector.enabled }} +{{- if .Values.global.podSecurityPolicy.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "cainjector.fullname" . }}-psp + labels: + app: {{ include "cainjector.name" . }} + app.kubernetes.io/name: {{ include "cainjector.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "cainjector" + {{- include "labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "cainjector.fullname" . }}-psp +subjects: + - kind: ServiceAccount + name: {{ template "cainjector.serviceAccountName" . }} + namespace: {{ include "cert-manager.namespace" . }} +{{- end }} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/cainjector-psp.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/cainjector-psp.yaml new file mode 100644 index 000000000..24f01da5d --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/cainjector-psp.yaml @@ -0,0 +1,51 @@ +{{- if .Values.cainjector.enabled }} +{{- if .Values.global.podSecurityPolicy.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "cainjector.fullname" . }} + labels: + app: {{ include "cainjector.name" . }} + app.kubernetes.io/name: {{ include "cainjector.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "cainjector" + {{- include "labels" . | nindent 4 }} + annotations: + seccomp.security.alpha.kubernetes.io/allowedProfileNames: 'docker/default' + seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default' + {{- if .Values.global.podSecurityPolicy.useAppArmor }} + apparmor.security.beta.kubernetes.io/allowedProfileNames: 'runtime/default' + apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default' + {{- end }} +spec: + privileged: false + allowPrivilegeEscalation: false + allowedCapabilities: [] # default set of capabilities are implicitly allowed + volumes: + - 'configMap' + - 'emptyDir' + - 'projected' + - 'secret' + - 'downwardAPI' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'MustRunAs' + ranges: + - min: 1000 + max: 1000 + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'MustRunAs' + ranges: + - min: 1000 + max: 1000 + fsGroup: + rule: 'MustRunAs' + ranges: + - min: 1000 + max: 1000 +{{- end }} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/cainjector-rbac.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/cainjector-rbac.yaml new file mode 100644 index 000000000..2aa59eee9 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/cainjector-rbac.yaml @@ -0,0 +1,103 @@ +{{- if .Values.cainjector.enabled }} +{{- if .Values.global.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "cainjector.fullname" . }} + labels: + app: {{ include "cainjector.name" . }} + app.kubernetes.io/name: {{ include "cainjector.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "cainjector" + {{- include "labels" . | nindent 4 }} +rules: + - apiGroups: ["cert-manager.io"] + resources: ["certificates"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["events"] + verbs: ["get", "create", "update", "patch"] + - apiGroups: ["admissionregistration.k8s.io"] + resources: ["validatingwebhookconfigurations", "mutatingwebhookconfigurations"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: ["apiregistration.k8s.io"] + resources: ["apiservices"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions"] + verbs: ["get", "list", "watch", "update", "patch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "cainjector.fullname" . }} + labels: + app: {{ include "cainjector.name" . }} + app.kubernetes.io/name: {{ include "cainjector.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "cainjector" + {{- include "labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "cainjector.fullname" . }} +subjects: + - name: {{ template "cainjector.serviceAccountName" . }} + namespace: {{ include "cert-manager.namespace" . }} + kind: ServiceAccount + +--- +# leader election rules +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "cainjector.fullname" . }}:leaderelection + namespace: {{ .Values.global.leaderElection.namespace }} + labels: + app: {{ include "cainjector.name" . }} + app.kubernetes.io/name: {{ include "cainjector.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "cainjector" + {{- include "labels" . | nindent 4 }} +rules: + # Used for leader election by the controller + # cert-manager-cainjector-leader-election is used by the CertificateBased injector controller + # see cmd/cainjector/start.go#L113 + # cert-manager-cainjector-leader-election-core is used by the SecretBased injector controller + # see cmd/cainjector/start.go#L137 + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + resourceNames: ["cert-manager-cainjector-leader-election", "cert-manager-cainjector-leader-election-core"] + verbs: ["get", "update", "patch"] + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["create"] + +--- + +# grant cert-manager permission to manage the leaderelection configmap in the +# leader election namespace +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "cainjector.fullname" . }}:leaderelection + namespace: {{ .Values.global.leaderElection.namespace }} + labels: + app: {{ include "cainjector.name" . }} + app.kubernetes.io/name: {{ include "cainjector.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "cainjector" + {{- include "labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "cainjector.fullname" . }}:leaderelection +subjects: + - kind: ServiceAccount + name: {{ template "cainjector.serviceAccountName" . }} + namespace: {{ include "cert-manager.namespace" . }} +{{- end }} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/cainjector-serviceaccount.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/cainjector-serviceaccount.yaml new file mode 100644 index 000000000..fedc731f8 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/cainjector-serviceaccount.yaml @@ -0,0 +1,27 @@ +{{- if .Values.cainjector.enabled }} +{{- if .Values.cainjector.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +automountServiceAccountToken: {{ .Values.cainjector.serviceAccount.automountServiceAccountToken }} +metadata: + name: {{ template "cainjector.serviceAccountName" . }} + namespace: {{ include "cert-manager.namespace" . }} + {{- with .Values.cainjector.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + app: {{ include "cainjector.name" . }} + app.kubernetes.io/name: {{ include "cainjector.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "cainjector" + {{- include "labels" . | nindent 4 }} + {{- with .Values.cainjector.serviceAccount.labels }} + {{ toYaml . | nindent 4 }} + {{- end }} +{{- with .Values.global.imagePullSecrets }} +imagePullSecrets: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/crds.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/crds.yaml new file mode 100644 index 000000000..820698742 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/crds.yaml @@ -0,0 +1,4462 @@ +{{- if .Values.installCRDs }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: certificaterequests.cert-manager.io + labels: + app: '{{ template "cert-manager.name" . }}' + app.kubernetes.io/name: '{{ template "cert-manager.name" . }}' + app.kubernetes.io/instance: '{{ .Release.Name }}' + # Generated labels {{- include "labels" . | nindent 4 }} +spec: + group: cert-manager.io + names: + kind: CertificateRequest + listKind: CertificateRequestList + plural: certificaterequests + shortNames: + - cr + - crs + singular: certificaterequest + categories: + - cert-manager + scope: Namespaced + versions: + - name: v1 + subresources: + status: {} + additionalPrinterColumns: + - jsonPath: .status.conditions[?(@.type=="Approved")].status + name: Approved + type: string + - jsonPath: .status.conditions[?(@.type=="Denied")].status + name: Denied + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .spec.issuerRef.name + name: Issuer + type: string + - jsonPath: .spec.username + name: Requestor + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + priority: 1 + type: string + - jsonPath: .metadata.creationTimestamp + description: CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC. + name: Age + type: date + schema: + openAPIV3Schema: + description: "A CertificateRequest is used to request a signed certificate from one of the configured issuers. \n All fields within the CertificateRequest's `spec` are immutable after creation. A CertificateRequest will either succeed or fail, as denoted by its `status.state` field. \n A CertificateRequest is a one-shot resource, meaning it represents a single point in time request for a certificate and cannot be re-used." + type: object + required: + - spec + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Desired state of the CertificateRequest resource. + type: object + required: + - issuerRef + - request + properties: + duration: + description: The requested 'duration' (i.e. lifetime) of the Certificate. This option may be ignored/overridden by some issuer types. + type: string + extra: + description: Extra contains extra attributes of the user that created the CertificateRequest. Populated by the cert-manager webhook on creation and immutable. + type: object + additionalProperties: + type: array + items: + type: string + groups: + description: Groups contains group membership of the user that created the CertificateRequest. Populated by the cert-manager webhook on creation and immutable. + type: array + items: + type: string + x-kubernetes-list-type: atomic + isCA: + description: IsCA will request to mark the certificate as valid for certificate signing when submitting to the issuer. This will automatically add the `cert sign` usage to the list of `usages`. + type: boolean + issuerRef: + description: IssuerRef is a reference to the issuer for this CertificateRequest. If the `kind` field is not set, or set to `Issuer`, an Issuer resource with the given name in the same namespace as the CertificateRequest will be used. If the `kind` field is set to `ClusterIssuer`, a ClusterIssuer with the provided name will be used. The `name` field in this stanza is required at all times. The group field refers to the API group of the issuer which defaults to `cert-manager.io` if empty. + type: object + required: + - name + properties: + group: + description: Group of the resource being referred to. + type: string + kind: + description: Kind of the resource being referred to. + type: string + name: + description: Name of the resource being referred to. + type: string + request: + description: The PEM-encoded x509 certificate signing request to be submitted to the CA for signing. + type: string + format: byte + uid: + description: UID contains the uid of the user that created the CertificateRequest. Populated by the cert-manager webhook on creation and immutable. + type: string + usages: + description: Usages is the set of x509 usages that are requested for the certificate. If usages are set they SHOULD be encoded inside the CSR spec Defaults to `digital signature` and `key encipherment` if not specified. + type: array + items: + description: "KeyUsage specifies valid usage contexts for keys. See: https://tools.ietf.org/html/rfc5280#section-4.2.1.3 https://tools.ietf.org/html/rfc5280#section-4.2.1.12 \n Valid KeyUsage values are as follows: \"signing\", \"digital signature\", \"content commitment\", \"key encipherment\", \"key agreement\", \"data encipherment\", \"cert sign\", \"crl sign\", \"encipher only\", \"decipher only\", \"any\", \"server auth\", \"client auth\", \"code signing\", \"email protection\", \"s/mime\", \"ipsec end system\", \"ipsec tunnel\", \"ipsec user\", \"timestamping\", \"ocsp signing\", \"microsoft sgc\", \"netscape sgc\"" + type: string + enum: + - signing + - digital signature + - content commitment + - key encipherment + - key agreement + - data encipherment + - cert sign + - crl sign + - encipher only + - decipher only + - any + - server auth + - client auth + - code signing + - email protection + - s/mime + - ipsec end system + - ipsec tunnel + - ipsec user + - timestamping + - ocsp signing + - microsoft sgc + - netscape sgc + username: + description: Username contains the name of the user that created the CertificateRequest. Populated by the cert-manager webhook on creation and immutable. + type: string + status: + description: Status of the CertificateRequest. This is set and managed automatically. + type: object + properties: + ca: + description: The PEM encoded x509 certificate of the signer, also known as the CA (Certificate Authority). This is set on a best-effort basis by different issuers. If not set, the CA is assumed to be unknown/not available. + type: string + format: byte + certificate: + description: The PEM encoded x509 certificate resulting from the certificate signing request. If not set, the CertificateRequest has either not been completed or has failed. More information on failure can be found by checking the `conditions` field. + type: string + format: byte + conditions: + description: List of status conditions to indicate the status of a CertificateRequest. Known condition types are `Ready` and `InvalidRequest`. + type: array + items: + description: CertificateRequestCondition contains condition information for a CertificateRequest. + type: object + required: + - status + - type + properties: + lastTransitionTime: + description: LastTransitionTime is the timestamp corresponding to the last status change of this condition. + type: string + format: date-time + message: + description: Message is a human readable description of the details of the last transition, complementing reason. + type: string + reason: + description: Reason is a brief machine readable explanation for the condition's last transition. + type: string + status: + description: Status of the condition, one of (`True`, `False`, `Unknown`). + type: string + enum: + - "True" + - "False" + - Unknown + type: + description: Type of the condition, known values are (`Ready`, `InvalidRequest`, `Approved`, `Denied`). + type: string + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + failureTime: + description: FailureTime stores the time that this CertificateRequest failed. This is used to influence garbage collection and back-off. + type: string + format: date-time + served: true + storage: true +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: certificates.cert-manager.io + labels: + app: '{{ template "cert-manager.name" . }}' + app.kubernetes.io/name: '{{ template "cert-manager.name" . }}' + app.kubernetes.io/instance: '{{ .Release.Name }}' + # Generated labels {{- include "labels" . | nindent 4 }} +spec: + group: cert-manager.io + names: + kind: Certificate + listKind: CertificateList + plural: certificates + shortNames: + - cert + - certs + singular: certificate + categories: + - cert-manager + scope: Namespaced + versions: + - name: v1 + subresources: + status: {} + additionalPrinterColumns: + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .spec.secretName + name: Secret + type: string + - jsonPath: .spec.issuerRef.name + name: Issuer + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + priority: 1 + type: string + - jsonPath: .metadata.creationTimestamp + description: CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC. + name: Age + type: date + schema: + openAPIV3Schema: + description: "A Certificate resource should be created to ensure an up to date and signed x509 certificate is stored in the Kubernetes Secret resource named in `spec.secretName`. \n The stored certificate will be renewed before it expires (as configured by `spec.renewBefore`)." + type: object + required: + - spec + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Desired state of the Certificate resource. + type: object + required: + - issuerRef + - secretName + properties: + additionalOutputFormats: + description: AdditionalOutputFormats defines extra output formats of the private key and signed certificate chain to be written to this Certificate's target Secret. This is an Alpha Feature and is only enabled with the `--feature-gates=AdditionalCertificateOutputFormats=true` option on both the controller and webhook components. + type: array + items: + description: CertificateAdditionalOutputFormat defines an additional output format of a Certificate resource. These contain supplementary data formats of the signed certificate chain and paired private key. + type: object + required: + - type + properties: + type: + description: Type is the name of the format type that should be written to the Certificate's target Secret. + type: string + enum: + - DER + - CombinedPEM + commonName: + description: 'CommonName is a common name to be used on the Certificate. The CommonName should have a length of 64 characters or fewer to avoid generating invalid CSRs. This value is ignored by TLS clients when any subject alt name is set. This is x509 behaviour: https://tools.ietf.org/html/rfc6125#section-6.4.4' + type: string + dnsNames: + description: DNSNames is a list of DNS subjectAltNames to be set on the Certificate. + type: array + items: + type: string + duration: + description: The requested 'duration' (i.e. lifetime) of the Certificate. This option may be ignored/overridden by some issuer types. If unset this defaults to 90 days. Certificate will be renewed either 2/3 through its duration or `renewBefore` period before its expiry, whichever is later. Minimum accepted duration is 1 hour. Value must be in units accepted by Go time.ParseDuration https://golang.org/pkg/time/#ParseDuration + type: string + emailAddresses: + description: EmailAddresses is a list of email subjectAltNames to be set on the Certificate. + type: array + items: + type: string + encodeUsagesInRequest: + description: EncodeUsagesInRequest controls whether key usages should be present in the CertificateRequest + type: boolean + ipAddresses: + description: IPAddresses is a list of IP address subjectAltNames to be set on the Certificate. + type: array + items: + type: string + isCA: + description: IsCA will mark this Certificate as valid for certificate signing. This will automatically add the `cert sign` usage to the list of `usages`. + type: boolean + issuerRef: + description: IssuerRef is a reference to the issuer for this certificate. If the `kind` field is not set, or set to `Issuer`, an Issuer resource with the given name in the same namespace as the Certificate will be used. If the `kind` field is set to `ClusterIssuer`, a ClusterIssuer with the provided name will be used. The `name` field in this stanza is required at all times. + type: object + required: + - name + properties: + group: + description: Group of the resource being referred to. + type: string + kind: + description: Kind of the resource being referred to. + type: string + name: + description: Name of the resource being referred to. + type: string + keystores: + description: Keystores configures additional keystore output formats stored in the `secretName` Secret resource. + type: object + properties: + jks: + description: JKS configures options for storing a JKS keystore in the `spec.secretName` Secret resource. + type: object + required: + - create + - passwordSecretRef + properties: + create: + description: Create enables JKS keystore creation for the Certificate. If true, a file named `keystore.jks` will be created in the target Secret resource, encrypted using the password stored in `passwordSecretRef`. The keystore file will be updated immediately. If the issuer provided a CA certificate, a file named `truststore.jks` will also be created in the target Secret resource, encrypted using the password stored in `passwordSecretRef` containing the issuing Certificate Authority + type: boolean + passwordSecretRef: + description: PasswordSecretRef is a reference to a key in a Secret resource containing the password used to encrypt the JKS keystore. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + pkcs12: + description: PKCS12 configures options for storing a PKCS12 keystore in the `spec.secretName` Secret resource. + type: object + required: + - create + - passwordSecretRef + properties: + create: + description: Create enables PKCS12 keystore creation for the Certificate. If true, a file named `keystore.p12` will be created in the target Secret resource, encrypted using the password stored in `passwordSecretRef`. The keystore file will be updated immediately. If the issuer provided a CA certificate, a file named `truststore.p12` will also be created in the target Secret resource, encrypted using the password stored in `passwordSecretRef` containing the issuing Certificate Authority + type: boolean + passwordSecretRef: + description: PasswordSecretRef is a reference to a key in a Secret resource containing the password used to encrypt the PKCS12 keystore. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + literalSubject: + description: LiteralSubject is an LDAP formatted string that represents the [X.509 Subject field](https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6). Use this *instead* of the Subject field if you need to ensure the correct ordering of the RDN sequence, such as when issuing certs for LDAP authentication. See https://github.com/cert-manager/cert-manager/issues/3203, https://github.com/cert-manager/cert-manager/issues/4424. This field is alpha level and is only supported by cert-manager installations where LiteralCertificateSubject feature gate is enabled on both cert-manager controller and webhook. + type: string + privateKey: + description: Options to control private keys used for the Certificate. + type: object + properties: + algorithm: + description: Algorithm is the private key algorithm of the corresponding private key for this certificate. If provided, allowed values are either `RSA`,`Ed25519` or `ECDSA` If `algorithm` is specified and `size` is not provided, key size of 256 will be used for `ECDSA` key algorithm and key size of 2048 will be used for `RSA` key algorithm. key size is ignored when using the `Ed25519` key algorithm. + type: string + enum: + - RSA + - ECDSA + - Ed25519 + encoding: + description: The private key cryptography standards (PKCS) encoding for this certificate's private key to be encoded in. If provided, allowed values are `PKCS1` and `PKCS8` standing for PKCS#1 and PKCS#8, respectively. Defaults to `PKCS1` if not specified. + type: string + enum: + - PKCS1 + - PKCS8 + rotationPolicy: + description: RotationPolicy controls how private keys should be regenerated when a re-issuance is being processed. If set to Never, a private key will only be generated if one does not already exist in the target `spec.secretName`. If one does exists but it does not have the correct algorithm or size, a warning will be raised to await user intervention. If set to Always, a private key matching the specified requirements will be generated whenever a re-issuance occurs. Default is 'Never' for backward compatibility. + type: string + enum: + - Never + - Always + size: + description: Size is the key bit size of the corresponding private key for this certificate. If `algorithm` is set to `RSA`, valid values are `2048`, `4096` or `8192`, and will default to `2048` if not specified. If `algorithm` is set to `ECDSA`, valid values are `256`, `384` or `521`, and will default to `256` if not specified. If `algorithm` is set to `Ed25519`, Size is ignored. No other values are allowed. + type: integer + renewBefore: + description: How long before the currently issued certificate's expiry cert-manager should renew the certificate. The default is 2/3 of the issued certificate's duration. Minimum accepted value is 5 minutes. Value must be in units accepted by Go time.ParseDuration https://golang.org/pkg/time/#ParseDuration + type: string + revisionHistoryLimit: + description: revisionHistoryLimit is the maximum number of CertificateRequest revisions that are maintained in the Certificate's history. Each revision represents a single `CertificateRequest` created by this Certificate, either when it was created, renewed, or Spec was changed. Revisions will be removed by oldest first if the number of revisions exceeds this number. If set, revisionHistoryLimit must be a value of `1` or greater. If unset (`nil`), revisions will not be garbage collected. Default value is `nil`. + type: integer + format: int32 + secretName: + description: SecretName is the name of the secret resource that will be automatically created and managed by this Certificate resource. It will be populated with a private key and certificate, signed by the denoted issuer. + type: string + secretTemplate: + description: SecretTemplate defines annotations and labels to be copied to the Certificate's Secret. Labels and annotations on the Secret will be changed as they appear on the SecretTemplate when added or removed. SecretTemplate annotations are added in conjunction with, and cannot overwrite, the base set of annotations cert-manager sets on the Certificate's Secret. + type: object + properties: + annotations: + description: Annotations is a key value map to be copied to the target Kubernetes Secret. + type: object + additionalProperties: + type: string + labels: + description: Labels is a key value map to be copied to the target Kubernetes Secret. + type: object + additionalProperties: + type: string + subject: + description: Full X509 name specification (https://golang.org/pkg/crypto/x509/pkix/#Name). + type: object + properties: + countries: + description: Countries to be used on the Certificate. + type: array + items: + type: string + localities: + description: Cities to be used on the Certificate. + type: array + items: + type: string + organizationalUnits: + description: Organizational Units to be used on the Certificate. + type: array + items: + type: string + organizations: + description: Organizations to be used on the Certificate. + type: array + items: + type: string + postalCodes: + description: Postal codes to be used on the Certificate. + type: array + items: + type: string + provinces: + description: State/Provinces to be used on the Certificate. + type: array + items: + type: string + serialNumber: + description: Serial number to be used on the Certificate. + type: string + streetAddresses: + description: Street addresses to be used on the Certificate. + type: array + items: + type: string + uris: + description: URIs is a list of URI subjectAltNames to be set on the Certificate. + type: array + items: + type: string + usages: + description: Usages is the set of x509 usages that are requested for the certificate. Defaults to `digital signature` and `key encipherment` if not specified. + type: array + items: + description: "KeyUsage specifies valid usage contexts for keys. See: https://tools.ietf.org/html/rfc5280#section-4.2.1.3 https://tools.ietf.org/html/rfc5280#section-4.2.1.12 \n Valid KeyUsage values are as follows: \"signing\", \"digital signature\", \"content commitment\", \"key encipherment\", \"key agreement\", \"data encipherment\", \"cert sign\", \"crl sign\", \"encipher only\", \"decipher only\", \"any\", \"server auth\", \"client auth\", \"code signing\", \"email protection\", \"s/mime\", \"ipsec end system\", \"ipsec tunnel\", \"ipsec user\", \"timestamping\", \"ocsp signing\", \"microsoft sgc\", \"netscape sgc\"" + type: string + enum: + - signing + - digital signature + - content commitment + - key encipherment + - key agreement + - data encipherment + - cert sign + - crl sign + - encipher only + - decipher only + - any + - server auth + - client auth + - code signing + - email protection + - s/mime + - ipsec end system + - ipsec tunnel + - ipsec user + - timestamping + - ocsp signing + - microsoft sgc + - netscape sgc + status: + description: Status of the Certificate. This is set and managed automatically. + type: object + properties: + conditions: + description: List of status conditions to indicate the status of certificates. Known condition types are `Ready` and `Issuing`. + type: array + items: + description: CertificateCondition contains condition information for an Certificate. + type: object + required: + - status + - type + properties: + lastTransitionTime: + description: LastTransitionTime is the timestamp corresponding to the last status change of this condition. + type: string + format: date-time + message: + description: Message is a human readable description of the details of the last transition, complementing reason. + type: string + observedGeneration: + description: If set, this represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.condition[x].observedGeneration is 9, the condition is out of date with respect to the current state of the Certificate. + type: integer + format: int64 + reason: + description: Reason is a brief machine readable explanation for the condition's last transition. + type: string + status: + description: Status of the condition, one of (`True`, `False`, `Unknown`). + type: string + enum: + - "True" + - "False" + - Unknown + type: + description: Type of the condition, known values are (`Ready`, `Issuing`). + type: string + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + failedIssuanceAttempts: + description: The number of continuous failed issuance attempts up till now. This field gets removed (if set) on a successful issuance and gets set to 1 if unset and an issuance has failed. If an issuance has failed, the delay till the next issuance will be calculated using formula time.Hour * 2 ^ (failedIssuanceAttempts - 1). + type: integer + lastFailureTime: + description: LastFailureTime is set only if the lastest issuance for this Certificate failed and contains the time of the failure. If an issuance has failed, the delay till the next issuance will be calculated using formula time.Hour * 2 ^ (failedIssuanceAttempts - 1). If the latest issuance has succeeded this field will be unset. + type: string + format: date-time + nextPrivateKeySecretName: + description: The name of the Secret resource containing the private key to be used for the next certificate iteration. The keymanager controller will automatically set this field if the `Issuing` condition is set to `True`. It will automatically unset this field when the Issuing condition is not set or False. + type: string + notAfter: + description: The expiration time of the certificate stored in the secret named by this resource in `spec.secretName`. + type: string + format: date-time + notBefore: + description: The time after which the certificate stored in the secret named by this resource in spec.secretName is valid. + type: string + format: date-time + renewalTime: + description: RenewalTime is the time at which the certificate will be next renewed. If not set, no upcoming renewal is scheduled. + type: string + format: date-time + revision: + description: "The current 'revision' of the certificate as issued. \n When a CertificateRequest resource is created, it will have the `cert-manager.io/certificate-revision` set to one greater than the current value of this field. \n Upon issuance, this field will be set to the value of the annotation on the CertificateRequest resource used to issue the certificate. \n Persisting the value on the CertificateRequest resource allows the certificates controller to know whether a request is part of an old issuance or if it is part of the ongoing revision's issuance by checking if the revision value in the annotation is greater than this field." + type: integer + served: true + storage: true +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: challenges.acme.cert-manager.io + labels: + app: '{{ template "cert-manager.name" . }}' + app.kubernetes.io/name: '{{ template "cert-manager.name" . }}' + app.kubernetes.io/instance: '{{ .Release.Name }}' + # Generated labels {{- include "labels" . | nindent 4 }} +spec: + group: acme.cert-manager.io + names: + kind: Challenge + listKind: ChallengeList + plural: challenges + singular: challenge + categories: + - cert-manager + - cert-manager-acme + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.state + name: State + type: string + - jsonPath: .spec.dnsName + name: Domain + type: string + - jsonPath: .status.reason + name: Reason + priority: 1 + type: string + - description: CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC. + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: Challenge is a type to represent a Challenge request with an ACME server + type: object + required: + - metadata + - spec + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + type: object + required: + - authorizationURL + - dnsName + - issuerRef + - key + - solver + - token + - type + - url + properties: + authorizationURL: + description: The URL to the ACME Authorization resource that this challenge is a part of. + type: string + dnsName: + description: dnsName is the identifier that this challenge is for, e.g. example.com. If the requested DNSName is a 'wildcard', this field MUST be set to the non-wildcard domain, e.g. for `*.example.com`, it must be `example.com`. + type: string + issuerRef: + description: References a properly configured ACME-type Issuer which should be used to create this Challenge. If the Issuer does not exist, processing will be retried. If the Issuer is not an 'ACME' Issuer, an error will be returned and the Challenge will be marked as failed. + type: object + required: + - name + properties: + group: + description: Group of the resource being referred to. + type: string + kind: + description: Kind of the resource being referred to. + type: string + name: + description: Name of the resource being referred to. + type: string + key: + description: 'The ACME challenge key for this challenge For HTTP01 challenges, this is the value that must be responded with to complete the HTTP01 challenge in the format: `.`. For DNS01 challenges, this is the base64 encoded SHA256 sum of the `.` text that must be set as the TXT record content.' + type: string + solver: + description: Contains the domain solving configuration that should be used to solve this challenge resource. + type: object + properties: + dns01: + description: Configures cert-manager to attempt to complete authorizations by performing the DNS01 challenge flow. + type: object + properties: + acmeDNS: + description: Use the 'ACME DNS' (https://github.com/joohoi/acme-dns) API to manage DNS01 challenge records. + type: object + required: + - accountSecretRef + - host + properties: + accountSecretRef: + description: A reference to a specific 'key' within a Secret resource. In some instances, `key` is a required field. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + host: + type: string + akamai: + description: Use the Akamai DNS zone management API to manage DNS01 challenge records. + type: object + required: + - accessTokenSecretRef + - clientSecretSecretRef + - clientTokenSecretRef + - serviceConsumerDomain + properties: + accessTokenSecretRef: + description: A reference to a specific 'key' within a Secret resource. In some instances, `key` is a required field. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + clientSecretSecretRef: + description: A reference to a specific 'key' within a Secret resource. In some instances, `key` is a required field. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + clientTokenSecretRef: + description: A reference to a specific 'key' within a Secret resource. In some instances, `key` is a required field. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + serviceConsumerDomain: + type: string + azureDNS: + description: Use the Microsoft Azure DNS API to manage DNS01 challenge records. + type: object + required: + - resourceGroupName + - subscriptionID + properties: + clientID: + description: if both this and ClientSecret are left unset MSI will be used + type: string + clientSecretSecretRef: + description: if both this and ClientID are left unset MSI will be used + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + environment: + description: name of the Azure environment (default AzurePublicCloud) + type: string + enum: + - AzurePublicCloud + - AzureChinaCloud + - AzureGermanCloud + - AzureUSGovernmentCloud + hostedZoneName: + description: name of the DNS zone that should be used + type: string + managedIdentity: + description: managed identity configuration, can not be used at the same time as clientID, clientSecretSecretRef or tenantID + type: object + properties: + clientID: + description: client ID of the managed identity, can not be used at the same time as resourceID + type: string + resourceID: + description: resource ID of the managed identity, can not be used at the same time as clientID + type: string + resourceGroupName: + description: resource group the DNS zone is located in + type: string + subscriptionID: + description: ID of the Azure subscription + type: string + tenantID: + description: when specifying ClientID and ClientSecret then this field is also needed + type: string + cloudDNS: + description: Use the Google Cloud DNS API to manage DNS01 challenge records. + type: object + required: + - project + properties: + hostedZoneName: + description: HostedZoneName is an optional field that tells cert-manager in which Cloud DNS zone the challenge record has to be created. If left empty cert-manager will automatically choose a zone. + type: string + project: + type: string + serviceAccountSecretRef: + description: A reference to a specific 'key' within a Secret resource. In some instances, `key` is a required field. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + cloudflare: + description: Use the Cloudflare API to manage DNS01 challenge records. + type: object + properties: + apiKeySecretRef: + description: 'API key to use to authenticate with Cloudflare. Note: using an API token to authenticate is now the recommended method as it allows greater control of permissions.' + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + apiTokenSecretRef: + description: API token used to authenticate with Cloudflare. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + email: + description: Email of the account, only required when using API key based authentication. + type: string + cnameStrategy: + description: CNAMEStrategy configures how the DNS01 provider should handle CNAME records when found in DNS zones. + type: string + enum: + - None + - Follow + digitalocean: + description: Use the DigitalOcean DNS API to manage DNS01 challenge records. + type: object + required: + - tokenSecretRef + properties: + tokenSecretRef: + description: A reference to a specific 'key' within a Secret resource. In some instances, `key` is a required field. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + rfc2136: + description: Use RFC2136 ("Dynamic Updates in the Domain Name System") (https://datatracker.ietf.org/doc/rfc2136/) to manage DNS01 challenge records. + type: object + required: + - nameserver + properties: + nameserver: + description: The IP address or hostname of an authoritative DNS server supporting RFC2136 in the form host:port. If the host is an IPv6 address it must be enclosed in square brackets (e.g [2001:db8::1]) ; port is optional. This field is required. + type: string + tsigAlgorithm: + description: 'The TSIG Algorithm configured in the DNS supporting RFC2136. Used only when ``tsigSecretSecretRef`` and ``tsigKeyName`` are defined. Supported values are (case-insensitive): ``HMACMD5`` (default), ``HMACSHA1``, ``HMACSHA256`` or ``HMACSHA512``.' + type: string + tsigKeyName: + description: The TSIG Key name configured in the DNS. If ``tsigSecretSecretRef`` is defined, this field is required. + type: string + tsigSecretSecretRef: + description: The name of the secret containing the TSIG value. If ``tsigKeyName`` is defined, this field is required. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + route53: + description: Use the AWS Route53 API to manage DNS01 challenge records. + type: object + required: + - region + properties: + accessKeyID: + description: 'The AccessKeyID is used for authentication. Cannot be set when SecretAccessKeyID is set. If neither the Access Key nor Key ID are set, we fall-back to using env vars, shared credentials file or AWS Instance metadata, see: https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials' + type: string + accessKeyIDSecretRef: + description: 'The SecretAccessKey is used for authentication. If set, pull the AWS access key ID from a key within a Kubernetes Secret. Cannot be set when AccessKeyID is set. If neither the Access Key nor Key ID are set, we fall-back to using env vars, shared credentials file or AWS Instance metadata, see: https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials' + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + hostedZoneID: + description: If set, the provider will manage only this zone in Route53 and will not do an lookup using the route53:ListHostedZonesByName api call. + type: string + region: + description: Always set the region when using AccessKeyID and SecretAccessKey + type: string + role: + description: Role is a Role ARN which the Route53 provider will assume using either the explicit credentials AccessKeyID/SecretAccessKey or the inferred credentials from environment variables, shared credentials file or AWS Instance metadata + type: string + secretAccessKeySecretRef: + description: 'The SecretAccessKey is used for authentication. If neither the Access Key nor Key ID are set, we fall-back to using env vars, shared credentials file or AWS Instance metadata, see: https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials' + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + webhook: + description: Configure an external webhook based DNS01 challenge solver to manage DNS01 challenge records. + type: object + required: + - groupName + - solverName + properties: + config: + description: Additional configuration that should be passed to the webhook apiserver when challenges are processed. This can contain arbitrary JSON data. Secret values should not be specified in this stanza. If secret values are needed (e.g. credentials for a DNS service), you should use a SecretKeySelector to reference a Secret resource. For details on the schema of this field, consult the webhook provider implementation's documentation. + x-kubernetes-preserve-unknown-fields: true + groupName: + description: The API group name that should be used when POSTing ChallengePayload resources to the webhook apiserver. This should be the same as the GroupName specified in the webhook provider implementation. + type: string + solverName: + description: The name of the solver to use, as defined in the webhook provider implementation. This will typically be the name of the provider, e.g. 'cloudflare'. + type: string + http01: + description: Configures cert-manager to attempt to complete authorizations by performing the HTTP01 challenge flow. It is not possible to obtain certificates for wildcard domain names (e.g. `*.example.com`) using the HTTP01 challenge mechanism. + type: object + properties: + gatewayHTTPRoute: + description: The Gateway API is a sig-network community API that models service networking in Kubernetes (https://gateway-api.sigs.k8s.io/). The Gateway solver will create HTTPRoutes with the specified labels in the same namespace as the challenge. This solver is experimental, and fields / behaviour may change in the future. + type: object + properties: + labels: + description: Custom labels that will be applied to HTTPRoutes created by cert-manager while solving HTTP-01 challenges. + type: object + additionalProperties: + type: string + parentRefs: + description: 'When solving an HTTP-01 challenge, cert-manager creates an HTTPRoute. cert-manager needs to know which parentRefs should be used when creating the HTTPRoute. Usually, the parentRef references a Gateway. See: https://gateway-api.sigs.k8s.io/api-types/httproute/#attaching-to-gateways' + type: array + items: + description: "ParentReference identifies an API object (usually a Gateway) that can be considered a parent of this resource (usually a route). The only kind of parent resource with \"Core\" support is Gateway. This API may be extended in the future to support additional kinds of parent resources, such as HTTPRoute. \n The API object must be valid in the cluster; the Group and Kind must be registered in the cluster for this reference to be valid." + type: object + required: + - name + properties: + group: + description: "Group is the group of the referent. When unspecified, \"gateway.networking.k8s.io\" is inferred. To set the core API group (such as for a \"Service\" kind referent), Group must be explicitly set to \"\" (empty string). \n Support: Core" + type: string + default: gateway.networking.k8s.io + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + kind: + description: "Kind is kind of the referent. \n Support: Core (Gateway) \n Support: Implementation-specific (Other Resources)" + type: string + default: Gateway + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + name: + description: "Name is the name of the referent. \n Support: Core" + type: string + maxLength: 253 + minLength: 1 + namespace: + description: "Namespace is the namespace of the referent. When unspecified, this refers to the local namespace of the Route. \n Note that there are specific rules for ParentRefs which cross namespace boundaries. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example: Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable any other kind of cross-namespace reference. \n Support: Core" + type: string + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + port: + description: "Port is the network port this Route targets. It can be interpreted differently based on the type of parent resource. \n When the parent resource is a Gateway, this targets all listeners listening on the specified port that also support this kind of Route(and select this Route). It's not recommended to set `Port` unless the networking behaviors specified in a Route must apply to a specific port as opposed to a listener(s) whose port(s) may be changed. When both Port and SectionName are specified, the name and port of the selected listener must match both specified values. \n Implementations MAY choose to support other parent resources. Implementations supporting other types of parent resources MUST clearly document how/if Port is interpreted. \n For the purpose of status, an attachment is considered successful as long as the parent resource accepts it partially. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Extended \n " + type: integer + format: int32 + maximum: 65535 + minimum: 1 + sectionName: + description: "SectionName is the name of a section within the target resource. In the following resources, SectionName is interpreted as the following: \n * Gateway: Listener Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. \n Implementations MAY choose to support attaching Routes to other resources. If that is the case, they MUST clearly document how SectionName is interpreted. \n When unspecified (empty string), this will reference the entire resource. For the purpose of status, an attachment is considered successful if at least one section in the parent resource accepts it. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Core" + type: string + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + serviceType: + description: Optional service type for Kubernetes solver service. Supported values are NodePort or ClusterIP. If unset, defaults to NodePort. + type: string + ingress: + description: The ingress based HTTP01 challenge solver will solve challenges by creating or modifying Ingress resources in order to route requests for '/.well-known/acme-challenge/XYZ' to 'challenge solver' pods that are provisioned by cert-manager for each Challenge to be completed. + type: object + properties: + class: + description: This field configures the annotation `kubernetes.io/ingress.class` when creating Ingress resources to solve ACME challenges that use this challenge solver. Only one of `class`, `name` or `ingressClassName` may be specified. + type: string + ingressClassName: + description: This field configures the field `ingressClassName` on the created Ingress resources used to solve ACME challenges that use this challenge solver. This is the recommended way of configuring the ingress class. Only one of `class`, `name` or `ingressClassName` may be specified. + type: string + ingressTemplate: + description: Optional ingress template used to configure the ACME challenge solver ingress used for HTTP01 challenges. + type: object + properties: + metadata: + description: ObjectMeta overrides for the ingress used to solve HTTP01 challenges. Only the 'labels' and 'annotations' fields may be set. If labels or annotations overlap with in-built values, the values here will override the in-built values. + type: object + properties: + annotations: + description: Annotations that should be added to the created ACME HTTP01 solver ingress. + type: object + additionalProperties: + type: string + labels: + description: Labels that should be added to the created ACME HTTP01 solver ingress. + type: object + additionalProperties: + type: string + name: + description: The name of the ingress resource that should have ACME challenge solving routes inserted into it in order to solve HTTP01 challenges. This is typically used in conjunction with ingress controllers like ingress-gce, which maintains a 1:1 mapping between external IPs and ingress resources. Only one of `class`, `name` or `ingressClassName` may be specified. + type: string + podTemplate: + description: Optional pod template used to configure the ACME challenge solver pods used for HTTP01 challenges. + type: object + properties: + metadata: + description: ObjectMeta overrides for the pod used to solve HTTP01 challenges. Only the 'labels' and 'annotations' fields may be set. If labels or annotations overlap with in-built values, the values here will override the in-built values. + type: object + properties: + annotations: + description: Annotations that should be added to the create ACME HTTP01 solver pods. + type: object + additionalProperties: + type: string + labels: + description: Labels that should be added to the created ACME HTTP01 solver pods. + type: object + additionalProperties: + type: string + spec: + description: PodSpec defines overrides for the HTTP01 challenge solver pod. Check ACMEChallengeSolverHTTP01IngressPodSpec to find out currently supported fields. All other fields will be ignored. + type: object + properties: + affinity: + description: If specified, the pod's scheduling constraints + type: object + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for the pod. + type: object + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node matches the corresponding matchExpressions; the node(s) with the highest sum are the most preferred. + type: array + items: + description: An empty preferred scheduling term matches all objects with implicit weight 0 (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + type: object + required: + - preference + - weight + properties: + preference: + description: A node selector term, associated with the corresponding weight. + type: object + properties: + matchExpressions: + description: A list of node selector requirements by node's labels. + type: array + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchFields: + description: A list of node selector requirements by node's fields. + type: array + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + type: array + items: + type: string + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching the corresponding nodeSelectorTerm, in the range 1-100. + type: integer + format: int32 + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to an update), the system may or may not try to eventually evict the pod from its node. + type: object + required: + - nodeSelectorTerms + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. The terms are ORed. + type: array + items: + description: A null or empty node selector term matches no objects. The requirements of them are ANDed. The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + type: object + properties: + matchExpressions: + description: A list of node selector requirements by node's labels. + type: array + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchFields: + description: A list of node selector requirements by node's fields. + type: array + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + type: array + items: + type: string + x-kubernetes-map-type: atomic + x-kubernetes-map-type: atomic + podAffinity: + description: Describes pod affinity scheduling rules (e.g. co-locate this pod in the same node, zone, etc. as some other pod(s)). + type: object + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred. + type: array + items: + description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s) + type: object + required: + - podAffinityTerm + - weight + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated with the corresponding weight. + type: object + required: + - topologyKey + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + x-kubernetes-map-type: atomic + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace". + type: array + items: + type: string + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + weight: + description: weight associated with matching the corresponding podAffinityTerm, in the range 1-100. + type: integer + format: int32 + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied. + type: array + items: + description: Defines a set of pods (namely those matching the labelSelector relative to the given namespace(s)) that this pod should be co-located (affinity) or not co-located (anti-affinity) with, where co-located is defined as running on a node whose value of the label with key matches that of any node on which a pod of the set of pods is running + type: object + required: + - topologyKey + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + x-kubernetes-map-type: atomic + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace". + type: array + items: + type: string + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules (e.g. avoid putting this pod in the same node, zone, etc. as some other pod(s)). + type: object + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to nodes that satisfy the anti-affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling anti-affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred. + type: array + items: + description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s) + type: object + required: + - podAffinityTerm + - weight + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated with the corresponding weight. + type: object + required: + - topologyKey + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + x-kubernetes-map-type: atomic + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace". + type: array + items: + type: string + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + weight: + description: weight associated with matching the corresponding podAffinityTerm, in the range 1-100. + type: integer + format: int32 + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the anti-affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied. + type: array + items: + description: Defines a set of pods (namely those matching the labelSelector relative to the given namespace(s)) that this pod should be co-located (affinity) or not co-located (anti-affinity) with, where co-located is defined as running on a node whose value of the label with key matches that of any node on which a pod of the set of pods is running + type: object + required: + - topologyKey + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + x-kubernetes-map-type: atomic + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace". + type: array + items: + type: string + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + imagePullSecrets: + description: If specified, the pod's imagePullSecrets + type: array + items: + description: LocalObjectReference contains enough information to let you locate the referenced object inside the same namespace. + type: object + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + x-kubernetes-map-type: atomic + nodeSelector: + description: 'NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node''s labels for the pod to be scheduled on that node. More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' + type: object + additionalProperties: + type: string + priorityClassName: + description: If specified, the pod's priorityClassName. + type: string + serviceAccountName: + description: If specified, the pod's service account + type: string + tolerations: + description: If specified, the pod's tolerations. + type: array + items: + description: The pod this Toleration is attached to tolerates any taint that matches the triple using the matching operator . + type: object + properties: + effect: + description: Effect indicates the taint effect to match. Empty means match all taint effects. When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies to. Empty means match all taint keys. If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to the value. Valid operators are Exists and Equal. Defaults to Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of time the toleration (which must be of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, it is not set, which means tolerate the taint forever (do not evict). Zero and negative values will be treated as 0 (evict immediately) by the system. + type: integer + format: int64 + value: + description: Value is the taint value the toleration matches to. If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + serviceType: + description: Optional service type for Kubernetes solver service. Supported values are NodePort or ClusterIP. If unset, defaults to NodePort. + type: string + selector: + description: Selector selects a set of DNSNames on the Certificate resource that should be solved using this challenge solver. If not specified, the solver will be treated as the 'default' solver with the lowest priority, i.e. if any other solver has a more specific match, it will be used instead. + type: object + properties: + dnsNames: + description: List of DNSNames that this solver will be used to solve. If specified and a match is found, a dnsNames selector will take precedence over a dnsZones selector. If multiple solvers match with the same dnsNames value, the solver with the most matching labels in matchLabels will be selected. If neither has more matches, the solver defined earlier in the list will be selected. + type: array + items: + type: string + dnsZones: + description: List of DNSZones that this solver will be used to solve. The most specific DNS zone match specified here will take precedence over other DNS zone matches, so a solver specifying sys.example.com will be selected over one specifying example.com for the domain www.sys.example.com. If multiple solvers match with the same dnsZones value, the solver with the most matching labels in matchLabels will be selected. If neither has more matches, the solver defined earlier in the list will be selected. + type: array + items: + type: string + matchLabels: + description: A label selector that is used to refine the set of certificate's that this challenge solver will apply to. + type: object + additionalProperties: + type: string + token: + description: The ACME challenge token for this challenge. This is the raw value returned from the ACME server. + type: string + type: + description: The type of ACME challenge this resource represents. One of "HTTP-01" or "DNS-01". + type: string + enum: + - HTTP-01 + - DNS-01 + url: + description: The URL of the ACME Challenge resource for this challenge. This can be used to lookup details about the status of this challenge. + type: string + wildcard: + description: wildcard will be true if this challenge is for a wildcard identifier, for example '*.example.com'. + type: boolean + status: + type: object + properties: + presented: + description: presented will be set to true if the challenge values for this challenge are currently 'presented'. This *does not* imply the self check is passing. Only that the values have been 'submitted' for the appropriate challenge mechanism (i.e. the DNS01 TXT record has been presented, or the HTTP01 configuration has been configured). + type: boolean + processing: + description: Used to denote whether this challenge should be processed or not. This field will only be set to true by the 'scheduling' component. It will only be set to false by the 'challenges' controller, after the challenge has reached a final state or timed out. If this field is set to false, the challenge controller will not take any more action. + type: boolean + reason: + description: Contains human readable information on why the Challenge is in the current state. + type: string + state: + description: Contains the current 'state' of the challenge. If not set, the state of the challenge is unknown. + type: string + enum: + - valid + - ready + - pending + - processing + - invalid + - expired + - errored + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: clusterissuers.cert-manager.io + labels: + app: '{{ template "cert-manager.name" . }}' + app.kubernetes.io/name: '{{ template "cert-manager.name" . }}' + app.kubernetes.io/instance: "{{ .Release.Name }}" + # Generated labels {{- include "labels" . | nindent 4 }} +spec: + group: cert-manager.io + names: + kind: ClusterIssuer + listKind: ClusterIssuerList + plural: clusterissuers + singular: clusterissuer + categories: + - cert-manager + scope: Cluster + versions: + - name: v1 + subresources: + status: {} + additionalPrinterColumns: + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + priority: 1 + type: string + - jsonPath: .metadata.creationTimestamp + description: CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC. + name: Age + type: date + schema: + openAPIV3Schema: + description: A ClusterIssuer represents a certificate issuing authority which can be referenced as part of `issuerRef` fields. It is similar to an Issuer, however it is cluster-scoped and therefore can be referenced by resources that exist in *any* namespace, not just the same namespace as the referent. + type: object + required: + - spec + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Desired state of the ClusterIssuer resource. + type: object + properties: + acme: + description: ACME configures this issuer to communicate with a RFC8555 (ACME) server to obtain signed x509 certificates. + type: object + required: + - privateKeySecretRef + - server + properties: + caBundle: + description: Base64-encoded bundle of PEM CAs which can be used to validate the certificate chain presented by the ACME server. Mutually exclusive with SkipTLSVerify; prefer using CABundle to prevent various kinds of security vulnerabilities. If CABundle and SkipTLSVerify are unset, the system certificate bundle inside the container is used to validate the TLS connection. + type: string + format: byte + disableAccountKeyGeneration: + description: Enables or disables generating a new ACME account key. If true, the Issuer resource will *not* request a new account but will expect the account key to be supplied via an existing secret. If false, the cert-manager system will generate a new ACME account key for the Issuer. Defaults to false. + type: boolean + email: + description: Email is the email address to be associated with the ACME account. This field is optional, but it is strongly recommended to be set. It will be used to contact you in case of issues with your account or certificates, including expiry notification emails. This field may be updated after the account is initially registered. + type: string + enableDurationFeature: + description: Enables requesting a Not After date on certificates that matches the duration of the certificate. This is not supported by all ACME servers like Let's Encrypt. If set to true when the ACME server does not support it it will create an error on the Order. Defaults to false. + type: boolean + externalAccountBinding: + description: ExternalAccountBinding is a reference to a CA external account of the ACME server. If set, upon registration cert-manager will attempt to associate the given external account credentials with the registered ACME account. + type: object + required: + - keyID + - keySecretRef + properties: + keyAlgorithm: + description: 'Deprecated: keyAlgorithm field exists for historical compatibility reasons and should not be used. The algorithm is now hardcoded to HS256 in golang/x/crypto/acme.' + type: string + enum: + - HS256 + - HS384 + - HS512 + keyID: + description: keyID is the ID of the CA key that the External Account is bound to. + type: string + keySecretRef: + description: keySecretRef is a Secret Key Selector referencing a data item in a Kubernetes Secret which holds the symmetric MAC key of the External Account Binding. The `key` is the index string that is paired with the key data in the Secret and should not be confused with the key data itself, or indeed with the External Account Binding keyID above. The secret key stored in the Secret **must** be un-padded, base64 URL encoded data. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + preferredChain: + description: 'PreferredChain is the chain to use if the ACME server outputs multiple. PreferredChain is no guarantee that this one gets delivered by the ACME endpoint. For example, for Let''s Encrypt''s DST crosssign you would use: "DST Root CA X3" or "ISRG Root X1" for the newer Let''s Encrypt root CA. This value picks the first certificate bundle in the ACME alternative chains that has a certificate with this value as its issuer''s CN' + type: string + maxLength: 64 + privateKeySecretRef: + description: PrivateKey is the name of a Kubernetes Secret resource that will be used to store the automatically generated ACME account private key. Optionally, a `key` may be specified to select a specific entry within the named Secret resource. If `key` is not specified, a default of `tls.key` will be used. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + server: + description: 'Server is the URL used to access the ACME server''s ''directory'' endpoint. For example, for Let''s Encrypt''s staging endpoint, you would use: "https://acme-staging-v02.api.letsencrypt.org/directory". Only ACME v2 endpoints (i.e. RFC 8555) are supported.' + type: string + skipTLSVerify: + description: 'INSECURE: Enables or disables validation of the ACME server TLS certificate. If true, requests to the ACME server will not have the TLS certificate chain validated. Mutually exclusive with CABundle; prefer using CABundle to prevent various kinds of security vulnerabilities. Only enable this option in development environments. If CABundle and SkipTLSVerify are unset, the system certificate bundle inside the container is used to validate the TLS connection. Defaults to false.' + type: boolean + solvers: + description: 'Solvers is a list of challenge solvers that will be used to solve ACME challenges for the matching domains. Solver configurations must be provided in order to obtain certificates from an ACME server. For more information, see: https://cert-manager.io/docs/configuration/acme/' + type: array + items: + description: An ACMEChallengeSolver describes how to solve ACME challenges for the issuer it is part of. A selector may be provided to use different solving strategies for different DNS names. Only one of HTTP01 or DNS01 must be provided. + type: object + properties: + dns01: + description: Configures cert-manager to attempt to complete authorizations by performing the DNS01 challenge flow. + type: object + properties: + acmeDNS: + description: Use the 'ACME DNS' (https://github.com/joohoi/acme-dns) API to manage DNS01 challenge records. + type: object + required: + - accountSecretRef + - host + properties: + accountSecretRef: + description: A reference to a specific 'key' within a Secret resource. In some instances, `key` is a required field. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + host: + type: string + akamai: + description: Use the Akamai DNS zone management API to manage DNS01 challenge records. + type: object + required: + - accessTokenSecretRef + - clientSecretSecretRef + - clientTokenSecretRef + - serviceConsumerDomain + properties: + accessTokenSecretRef: + description: A reference to a specific 'key' within a Secret resource. In some instances, `key` is a required field. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + clientSecretSecretRef: + description: A reference to a specific 'key' within a Secret resource. In some instances, `key` is a required field. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + clientTokenSecretRef: + description: A reference to a specific 'key' within a Secret resource. In some instances, `key` is a required field. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + serviceConsumerDomain: + type: string + azureDNS: + description: Use the Microsoft Azure DNS API to manage DNS01 challenge records. + type: object + required: + - resourceGroupName + - subscriptionID + properties: + clientID: + description: if both this and ClientSecret are left unset MSI will be used + type: string + clientSecretSecretRef: + description: if both this and ClientID are left unset MSI will be used + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + environment: + description: name of the Azure environment (default AzurePublicCloud) + type: string + enum: + - AzurePublicCloud + - AzureChinaCloud + - AzureGermanCloud + - AzureUSGovernmentCloud + hostedZoneName: + description: name of the DNS zone that should be used + type: string + managedIdentity: + description: managed identity configuration, can not be used at the same time as clientID, clientSecretSecretRef or tenantID + type: object + properties: + clientID: + description: client ID of the managed identity, can not be used at the same time as resourceID + type: string + resourceID: + description: resource ID of the managed identity, can not be used at the same time as clientID + type: string + resourceGroupName: + description: resource group the DNS zone is located in + type: string + subscriptionID: + description: ID of the Azure subscription + type: string + tenantID: + description: when specifying ClientID and ClientSecret then this field is also needed + type: string + cloudDNS: + description: Use the Google Cloud DNS API to manage DNS01 challenge records. + type: object + required: + - project + properties: + hostedZoneName: + description: HostedZoneName is an optional field that tells cert-manager in which Cloud DNS zone the challenge record has to be created. If left empty cert-manager will automatically choose a zone. + type: string + project: + type: string + serviceAccountSecretRef: + description: A reference to a specific 'key' within a Secret resource. In some instances, `key` is a required field. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + cloudflare: + description: Use the Cloudflare API to manage DNS01 challenge records. + type: object + properties: + apiKeySecretRef: + description: 'API key to use to authenticate with Cloudflare. Note: using an API token to authenticate is now the recommended method as it allows greater control of permissions.' + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + apiTokenSecretRef: + description: API token used to authenticate with Cloudflare. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + email: + description: Email of the account, only required when using API key based authentication. + type: string + cnameStrategy: + description: CNAMEStrategy configures how the DNS01 provider should handle CNAME records when found in DNS zones. + type: string + enum: + - None + - Follow + digitalocean: + description: Use the DigitalOcean DNS API to manage DNS01 challenge records. + type: object + required: + - tokenSecretRef + properties: + tokenSecretRef: + description: A reference to a specific 'key' within a Secret resource. In some instances, `key` is a required field. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + rfc2136: + description: Use RFC2136 ("Dynamic Updates in the Domain Name System") (https://datatracker.ietf.org/doc/rfc2136/) to manage DNS01 challenge records. + type: object + required: + - nameserver + properties: + nameserver: + description: The IP address or hostname of an authoritative DNS server supporting RFC2136 in the form host:port. If the host is an IPv6 address it must be enclosed in square brackets (e.g [2001:db8::1]) ; port is optional. This field is required. + type: string + tsigAlgorithm: + description: 'The TSIG Algorithm configured in the DNS supporting RFC2136. Used only when ``tsigSecretSecretRef`` and ``tsigKeyName`` are defined. Supported values are (case-insensitive): ``HMACMD5`` (default), ``HMACSHA1``, ``HMACSHA256`` or ``HMACSHA512``.' + type: string + tsigKeyName: + description: The TSIG Key name configured in the DNS. If ``tsigSecretSecretRef`` is defined, this field is required. + type: string + tsigSecretSecretRef: + description: The name of the secret containing the TSIG value. If ``tsigKeyName`` is defined, this field is required. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + route53: + description: Use the AWS Route53 API to manage DNS01 challenge records. + type: object + required: + - region + properties: + accessKeyID: + description: 'The AccessKeyID is used for authentication. Cannot be set when SecretAccessKeyID is set. If neither the Access Key nor Key ID are set, we fall-back to using env vars, shared credentials file or AWS Instance metadata, see: https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials' + type: string + accessKeyIDSecretRef: + description: 'The SecretAccessKey is used for authentication. If set, pull the AWS access key ID from a key within a Kubernetes Secret. Cannot be set when AccessKeyID is set. If neither the Access Key nor Key ID are set, we fall-back to using env vars, shared credentials file or AWS Instance metadata, see: https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials' + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + hostedZoneID: + description: If set, the provider will manage only this zone in Route53 and will not do an lookup using the route53:ListHostedZonesByName api call. + type: string + region: + description: Always set the region when using AccessKeyID and SecretAccessKey + type: string + role: + description: Role is a Role ARN which the Route53 provider will assume using either the explicit credentials AccessKeyID/SecretAccessKey or the inferred credentials from environment variables, shared credentials file or AWS Instance metadata + type: string + secretAccessKeySecretRef: + description: 'The SecretAccessKey is used for authentication. If neither the Access Key nor Key ID are set, we fall-back to using env vars, shared credentials file or AWS Instance metadata, see: https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials' + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + webhook: + description: Configure an external webhook based DNS01 challenge solver to manage DNS01 challenge records. + type: object + required: + - groupName + - solverName + properties: + config: + description: Additional configuration that should be passed to the webhook apiserver when challenges are processed. This can contain arbitrary JSON data. Secret values should not be specified in this stanza. If secret values are needed (e.g. credentials for a DNS service), you should use a SecretKeySelector to reference a Secret resource. For details on the schema of this field, consult the webhook provider implementation's documentation. + x-kubernetes-preserve-unknown-fields: true + groupName: + description: The API group name that should be used when POSTing ChallengePayload resources to the webhook apiserver. This should be the same as the GroupName specified in the webhook provider implementation. + type: string + solverName: + description: The name of the solver to use, as defined in the webhook provider implementation. This will typically be the name of the provider, e.g. 'cloudflare'. + type: string + http01: + description: Configures cert-manager to attempt to complete authorizations by performing the HTTP01 challenge flow. It is not possible to obtain certificates for wildcard domain names (e.g. `*.example.com`) using the HTTP01 challenge mechanism. + type: object + properties: + gatewayHTTPRoute: + description: The Gateway API is a sig-network community API that models service networking in Kubernetes (https://gateway-api.sigs.k8s.io/). The Gateway solver will create HTTPRoutes with the specified labels in the same namespace as the challenge. This solver is experimental, and fields / behaviour may change in the future. + type: object + properties: + labels: + description: Custom labels that will be applied to HTTPRoutes created by cert-manager while solving HTTP-01 challenges. + type: object + additionalProperties: + type: string + parentRefs: + description: 'When solving an HTTP-01 challenge, cert-manager creates an HTTPRoute. cert-manager needs to know which parentRefs should be used when creating the HTTPRoute. Usually, the parentRef references a Gateway. See: https://gateway-api.sigs.k8s.io/api-types/httproute/#attaching-to-gateways' + type: array + items: + description: "ParentReference identifies an API object (usually a Gateway) that can be considered a parent of this resource (usually a route). The only kind of parent resource with \"Core\" support is Gateway. This API may be extended in the future to support additional kinds of parent resources, such as HTTPRoute. \n The API object must be valid in the cluster; the Group and Kind must be registered in the cluster for this reference to be valid." + type: object + required: + - name + properties: + group: + description: "Group is the group of the referent. When unspecified, \"gateway.networking.k8s.io\" is inferred. To set the core API group (such as for a \"Service\" kind referent), Group must be explicitly set to \"\" (empty string). \n Support: Core" + type: string + default: gateway.networking.k8s.io + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + kind: + description: "Kind is kind of the referent. \n Support: Core (Gateway) \n Support: Implementation-specific (Other Resources)" + type: string + default: Gateway + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + name: + description: "Name is the name of the referent. \n Support: Core" + type: string + maxLength: 253 + minLength: 1 + namespace: + description: "Namespace is the namespace of the referent. When unspecified, this refers to the local namespace of the Route. \n Note that there are specific rules for ParentRefs which cross namespace boundaries. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example: Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable any other kind of cross-namespace reference. \n Support: Core" + type: string + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + port: + description: "Port is the network port this Route targets. It can be interpreted differently based on the type of parent resource. \n When the parent resource is a Gateway, this targets all listeners listening on the specified port that also support this kind of Route(and select this Route). It's not recommended to set `Port` unless the networking behaviors specified in a Route must apply to a specific port as opposed to a listener(s) whose port(s) may be changed. When both Port and SectionName are specified, the name and port of the selected listener must match both specified values. \n Implementations MAY choose to support other parent resources. Implementations supporting other types of parent resources MUST clearly document how/if Port is interpreted. \n For the purpose of status, an attachment is considered successful as long as the parent resource accepts it partially. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Extended \n " + type: integer + format: int32 + maximum: 65535 + minimum: 1 + sectionName: + description: "SectionName is the name of a section within the target resource. In the following resources, SectionName is interpreted as the following: \n * Gateway: Listener Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. \n Implementations MAY choose to support attaching Routes to other resources. If that is the case, they MUST clearly document how SectionName is interpreted. \n When unspecified (empty string), this will reference the entire resource. For the purpose of status, an attachment is considered successful if at least one section in the parent resource accepts it. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Core" + type: string + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + serviceType: + description: Optional service type for Kubernetes solver service. Supported values are NodePort or ClusterIP. If unset, defaults to NodePort. + type: string + ingress: + description: The ingress based HTTP01 challenge solver will solve challenges by creating or modifying Ingress resources in order to route requests for '/.well-known/acme-challenge/XYZ' to 'challenge solver' pods that are provisioned by cert-manager for each Challenge to be completed. + type: object + properties: + class: + description: This field configures the annotation `kubernetes.io/ingress.class` when creating Ingress resources to solve ACME challenges that use this challenge solver. Only one of `class`, `name` or `ingressClassName` may be specified. + type: string + ingressClassName: + description: This field configures the field `ingressClassName` on the created Ingress resources used to solve ACME challenges that use this challenge solver. This is the recommended way of configuring the ingress class. Only one of `class`, `name` or `ingressClassName` may be specified. + type: string + ingressTemplate: + description: Optional ingress template used to configure the ACME challenge solver ingress used for HTTP01 challenges. + type: object + properties: + metadata: + description: ObjectMeta overrides for the ingress used to solve HTTP01 challenges. Only the 'labels' and 'annotations' fields may be set. If labels or annotations overlap with in-built values, the values here will override the in-built values. + type: object + properties: + annotations: + description: Annotations that should be added to the created ACME HTTP01 solver ingress. + type: object + additionalProperties: + type: string + labels: + description: Labels that should be added to the created ACME HTTP01 solver ingress. + type: object + additionalProperties: + type: string + name: + description: The name of the ingress resource that should have ACME challenge solving routes inserted into it in order to solve HTTP01 challenges. This is typically used in conjunction with ingress controllers like ingress-gce, which maintains a 1:1 mapping between external IPs and ingress resources. Only one of `class`, `name` or `ingressClassName` may be specified. + type: string + podTemplate: + description: Optional pod template used to configure the ACME challenge solver pods used for HTTP01 challenges. + type: object + properties: + metadata: + description: ObjectMeta overrides for the pod used to solve HTTP01 challenges. Only the 'labels' and 'annotations' fields may be set. If labels or annotations overlap with in-built values, the values here will override the in-built values. + type: object + properties: + annotations: + description: Annotations that should be added to the create ACME HTTP01 solver pods. + type: object + additionalProperties: + type: string + labels: + description: Labels that should be added to the created ACME HTTP01 solver pods. + type: object + additionalProperties: + type: string + spec: + description: PodSpec defines overrides for the HTTP01 challenge solver pod. Check ACMEChallengeSolverHTTP01IngressPodSpec to find out currently supported fields. All other fields will be ignored. + type: object + properties: + affinity: + description: If specified, the pod's scheduling constraints + type: object + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for the pod. + type: object + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node matches the corresponding matchExpressions; the node(s) with the highest sum are the most preferred. + type: array + items: + description: An empty preferred scheduling term matches all objects with implicit weight 0 (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + type: object + required: + - preference + - weight + properties: + preference: + description: A node selector term, associated with the corresponding weight. + type: object + properties: + matchExpressions: + description: A list of node selector requirements by node's labels. + type: array + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchFields: + description: A list of node selector requirements by node's fields. + type: array + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + type: array + items: + type: string + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching the corresponding nodeSelectorTerm, in the range 1-100. + type: integer + format: int32 + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to an update), the system may or may not try to eventually evict the pod from its node. + type: object + required: + - nodeSelectorTerms + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. The terms are ORed. + type: array + items: + description: A null or empty node selector term matches no objects. The requirements of them are ANDed. The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + type: object + properties: + matchExpressions: + description: A list of node selector requirements by node's labels. + type: array + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchFields: + description: A list of node selector requirements by node's fields. + type: array + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + type: array + items: + type: string + x-kubernetes-map-type: atomic + x-kubernetes-map-type: atomic + podAffinity: + description: Describes pod affinity scheduling rules (e.g. co-locate this pod in the same node, zone, etc. as some other pod(s)). + type: object + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred. + type: array + items: + description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s) + type: object + required: + - podAffinityTerm + - weight + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated with the corresponding weight. + type: object + required: + - topologyKey + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + x-kubernetes-map-type: atomic + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace". + type: array + items: + type: string + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + weight: + description: weight associated with matching the corresponding podAffinityTerm, in the range 1-100. + type: integer + format: int32 + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied. + type: array + items: + description: Defines a set of pods (namely those matching the labelSelector relative to the given namespace(s)) that this pod should be co-located (affinity) or not co-located (anti-affinity) with, where co-located is defined as running on a node whose value of the label with key matches that of any node on which a pod of the set of pods is running + type: object + required: + - topologyKey + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + x-kubernetes-map-type: atomic + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace". + type: array + items: + type: string + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules (e.g. avoid putting this pod in the same node, zone, etc. as some other pod(s)). + type: object + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to nodes that satisfy the anti-affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling anti-affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred. + type: array + items: + description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s) + type: object + required: + - podAffinityTerm + - weight + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated with the corresponding weight. + type: object + required: + - topologyKey + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + x-kubernetes-map-type: atomic + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace". + type: array + items: + type: string + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + weight: + description: weight associated with matching the corresponding podAffinityTerm, in the range 1-100. + type: integer + format: int32 + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the anti-affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied. + type: array + items: + description: Defines a set of pods (namely those matching the labelSelector relative to the given namespace(s)) that this pod should be co-located (affinity) or not co-located (anti-affinity) with, where co-located is defined as running on a node whose value of the label with key matches that of any node on which a pod of the set of pods is running + type: object + required: + - topologyKey + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + x-kubernetes-map-type: atomic + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace". + type: array + items: + type: string + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + imagePullSecrets: + description: If specified, the pod's imagePullSecrets + type: array + items: + description: LocalObjectReference contains enough information to let you locate the referenced object inside the same namespace. + type: object + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + x-kubernetes-map-type: atomic + nodeSelector: + description: 'NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node''s labels for the pod to be scheduled on that node. More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' + type: object + additionalProperties: + type: string + priorityClassName: + description: If specified, the pod's priorityClassName. + type: string + serviceAccountName: + description: If specified, the pod's service account + type: string + tolerations: + description: If specified, the pod's tolerations. + type: array + items: + description: The pod this Toleration is attached to tolerates any taint that matches the triple using the matching operator . + type: object + properties: + effect: + description: Effect indicates the taint effect to match. Empty means match all taint effects. When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies to. Empty means match all taint keys. If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to the value. Valid operators are Exists and Equal. Defaults to Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of time the toleration (which must be of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, it is not set, which means tolerate the taint forever (do not evict). Zero and negative values will be treated as 0 (evict immediately) by the system. + type: integer + format: int64 + value: + description: Value is the taint value the toleration matches to. If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + serviceType: + description: Optional service type for Kubernetes solver service. Supported values are NodePort or ClusterIP. If unset, defaults to NodePort. + type: string + selector: + description: Selector selects a set of DNSNames on the Certificate resource that should be solved using this challenge solver. If not specified, the solver will be treated as the 'default' solver with the lowest priority, i.e. if any other solver has a more specific match, it will be used instead. + type: object + properties: + dnsNames: + description: List of DNSNames that this solver will be used to solve. If specified and a match is found, a dnsNames selector will take precedence over a dnsZones selector. If multiple solvers match with the same dnsNames value, the solver with the most matching labels in matchLabels will be selected. If neither has more matches, the solver defined earlier in the list will be selected. + type: array + items: + type: string + dnsZones: + description: List of DNSZones that this solver will be used to solve. The most specific DNS zone match specified here will take precedence over other DNS zone matches, so a solver specifying sys.example.com will be selected over one specifying example.com for the domain www.sys.example.com. If multiple solvers match with the same dnsZones value, the solver with the most matching labels in matchLabels will be selected. If neither has more matches, the solver defined earlier in the list will be selected. + type: array + items: + type: string + matchLabels: + description: A label selector that is used to refine the set of certificate's that this challenge solver will apply to. + type: object + additionalProperties: + type: string + ca: + description: CA configures this issuer to sign certificates using a signing CA keypair stored in a Secret resource. This is used to build internal PKIs that are managed by cert-manager. + type: object + required: + - secretName + properties: + crlDistributionPoints: + description: The CRL distribution points is an X.509 v3 certificate extension which identifies the location of the CRL from which the revocation of this certificate can be checked. If not set, certificates will be issued without distribution points set. + type: array + items: + type: string + ocspServers: + description: The OCSP server list is an X.509 v3 extension that defines a list of URLs of OCSP responders. The OCSP responders can be queried for the revocation status of an issued certificate. If not set, the certificate will be issued with no OCSP servers set. For example, an OCSP server URL could be "http://ocsp.int-x3.letsencrypt.org". + type: array + items: + type: string + secretName: + description: SecretName is the name of the secret used to sign Certificates issued by this Issuer. + type: string + selfSigned: + description: SelfSigned configures this issuer to 'self sign' certificates using the private key used to create the CertificateRequest object. + type: object + properties: + crlDistributionPoints: + description: The CRL distribution points is an X.509 v3 certificate extension which identifies the location of the CRL from which the revocation of this certificate can be checked. If not set certificate will be issued without CDP. Values are strings. + type: array + items: + type: string + vault: + description: Vault configures this issuer to sign certificates using a HashiCorp Vault PKI backend. + type: object + required: + - auth + - path + - server + properties: + auth: + description: Auth configures how cert-manager authenticates with the Vault server. + type: object + properties: + appRole: + description: AppRole authenticates with Vault using the App Role auth mechanism, with the role and secret stored in a Kubernetes Secret resource. + type: object + required: + - path + - roleId + - secretRef + properties: + path: + description: 'Path where the App Role authentication backend is mounted in Vault, e.g: "approle"' + type: string + roleId: + description: RoleID configured in the App Role authentication backend when setting up the authentication backend in Vault. + type: string + secretRef: + description: Reference to a key in a Secret that contains the App Role secret used to authenticate with Vault. The `key` field must be specified and denotes which entry within the Secret resource is used as the app role secret. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + kubernetes: + description: Kubernetes authenticates with Vault by passing the ServiceAccount token stored in the named Secret resource to the Vault server. + type: object + required: + - role + properties: + mountPath: + description: The Vault mountPath here is the mount path to use when authenticating with Vault. For example, setting a value to `/v1/auth/foo`, will use the path `/v1/auth/foo/login` to authenticate with Vault. If unspecified, the default value "/v1/auth/kubernetes" will be used. + type: string + role: + description: A required field containing the Vault Role to assume. A Role binds a Kubernetes ServiceAccount with a set of Vault policies. + type: string + secretRef: + description: The required Secret field containing a Kubernetes ServiceAccount JWT used for authenticating with Vault. Use of 'ambient credentials' is not supported. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + serviceAccountRef: + description: A reference to a service account that will be used to request a bound token (also known as "projected token"). Compared to using "secretRef", using this field means that you don't rely on statically bound tokens. To use this field, you must configure an RBAC rule to let cert-manager request a token. + type: object + required: + - name + properties: + name: + description: Name of the ServiceAccount used to request a token. + type: string + tokenSecretRef: + description: TokenSecretRef authenticates with Vault by presenting a token. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + caBundle: + description: Base64-encoded bundle of PEM CAs which will be used to validate the certificate chain presented by Vault. Only used if using HTTPS to connect to Vault and ignored for HTTP connections. Mutually exclusive with CABundleSecretRef. If neither CABundle nor CABundleSecretRef are defined, the certificate bundle in the cert-manager controller container is used to validate the TLS connection. + type: string + format: byte + caBundleSecretRef: + description: Reference to a Secret containing a bundle of PEM-encoded CAs to use when verifying the certificate chain presented by Vault when using HTTPS. Mutually exclusive with CABundle. If neither CABundle nor CABundleSecretRef are defined, the certificate bundle in the cert-manager controller container is used to validate the TLS connection. If no key for the Secret is specified, cert-manager will default to 'ca.crt'. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Name of the vault namespace. Namespaces is a set of features within Vault Enterprise that allows Vault environments to support Secure Multi-tenancy. e.g: "ns1" More about namespaces can be found here https://www.vaultproject.io/docs/enterprise/namespaces' + type: string + path: + description: 'Path is the mount path of the Vault PKI backend''s `sign` endpoint, e.g: "my_pki_mount/sign/my-role-name".' + type: string + server: + description: 'Server is the connection address for the Vault server, e.g: "https://vault.example.com:8200".' + type: string + venafi: + description: Venafi configures this issuer to sign certificates using a Venafi TPP or Venafi Cloud policy zone. + type: object + required: + - zone + properties: + cloud: + description: Cloud specifies the Venafi cloud configuration settings. Only one of TPP or Cloud may be specified. + type: object + required: + - apiTokenSecretRef + properties: + apiTokenSecretRef: + description: APITokenSecretRef is a secret key selector for the Venafi Cloud API token. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + url: + description: URL is the base URL for Venafi Cloud. Defaults to "https://api.venafi.cloud/v1". + type: string + tpp: + description: TPP specifies Trust Protection Platform configuration settings. Only one of TPP or Cloud may be specified. + type: object + required: + - credentialsRef + - url + properties: + caBundle: + description: Base64-encoded bundle of PEM CAs which will be used to validate the certificate chain presented by the TPP server. Only used if using HTTPS; ignored for HTTP. If undefined, the certificate bundle in the cert-manager controller container is used to validate the chain. + type: string + format: byte + credentialsRef: + description: CredentialsRef is a reference to a Secret containing the username and password for the TPP server. The secret must contain two keys, 'username' and 'password'. + type: object + required: + - name + properties: + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + url: + description: 'URL is the base URL for the vedsdk endpoint of the Venafi TPP instance, for example: "https://tpp.example.com/vedsdk".' + type: string + zone: + description: Zone is the Venafi Policy Zone to use for this issuer. All requests made to the Venafi platform will be restricted by the named zone policy. This field is required. + type: string + status: + description: Status of the ClusterIssuer. This is set and managed automatically. + type: object + properties: + acme: + description: ACME specific status options. This field should only be set if the Issuer is configured to use an ACME server to issue certificates. + type: object + properties: + lastPrivateKeyHash: + description: LastPrivateKeyHash is a hash of the private key associated with the latest registered ACME account, in order to track changes made to registered account associated with the Issuer + type: string + lastRegisteredEmail: + description: LastRegisteredEmail is the email associated with the latest registered ACME account, in order to track changes made to registered account associated with the Issuer + type: string + uri: + description: URI is the unique account identifier, which can also be used to retrieve account details from the CA + type: string + conditions: + description: List of status conditions to indicate the status of a CertificateRequest. Known condition types are `Ready`. + type: array + items: + description: IssuerCondition contains condition information for an Issuer. + type: object + required: + - status + - type + properties: + lastTransitionTime: + description: LastTransitionTime is the timestamp corresponding to the last status change of this condition. + type: string + format: date-time + message: + description: Message is a human readable description of the details of the last transition, complementing reason. + type: string + observedGeneration: + description: If set, this represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.condition[x].observedGeneration is 9, the condition is out of date with respect to the current state of the Issuer. + type: integer + format: int64 + reason: + description: Reason is a brief machine readable explanation for the condition's last transition. + type: string + status: + description: Status of the condition, one of (`True`, `False`, `Unknown`). + type: string + enum: + - "True" + - "False" + - Unknown + type: + description: Type of the condition, known values are (`Ready`). + type: string + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + served: true + storage: true +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: issuers.cert-manager.io + labels: + app: '{{ template "cert-manager.name" . }}' + app.kubernetes.io/name: '{{ template "cert-manager.name" . }}' + app.kubernetes.io/instance: "{{ .Release.Name }}" + # Generated labels {{- include "labels" . | nindent 4 }} +spec: + group: cert-manager.io + names: + kind: Issuer + listKind: IssuerList + plural: issuers + singular: issuer + categories: + - cert-manager + scope: Namespaced + versions: + - name: v1 + subresources: + status: {} + additionalPrinterColumns: + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + priority: 1 + type: string + - jsonPath: .metadata.creationTimestamp + description: CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC. + name: Age + type: date + schema: + openAPIV3Schema: + description: An Issuer represents a certificate issuing authority which can be referenced as part of `issuerRef` fields. It is scoped to a single namespace and can therefore only be referenced by resources within the same namespace. + type: object + required: + - spec + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Desired state of the Issuer resource. + type: object + properties: + acme: + description: ACME configures this issuer to communicate with a RFC8555 (ACME) server to obtain signed x509 certificates. + type: object + required: + - privateKeySecretRef + - server + properties: + caBundle: + description: Base64-encoded bundle of PEM CAs which can be used to validate the certificate chain presented by the ACME server. Mutually exclusive with SkipTLSVerify; prefer using CABundle to prevent various kinds of security vulnerabilities. If CABundle and SkipTLSVerify are unset, the system certificate bundle inside the container is used to validate the TLS connection. + type: string + format: byte + disableAccountKeyGeneration: + description: Enables or disables generating a new ACME account key. If true, the Issuer resource will *not* request a new account but will expect the account key to be supplied via an existing secret. If false, the cert-manager system will generate a new ACME account key for the Issuer. Defaults to false. + type: boolean + email: + description: Email is the email address to be associated with the ACME account. This field is optional, but it is strongly recommended to be set. It will be used to contact you in case of issues with your account or certificates, including expiry notification emails. This field may be updated after the account is initially registered. + type: string + enableDurationFeature: + description: Enables requesting a Not After date on certificates that matches the duration of the certificate. This is not supported by all ACME servers like Let's Encrypt. If set to true when the ACME server does not support it it will create an error on the Order. Defaults to false. + type: boolean + externalAccountBinding: + description: ExternalAccountBinding is a reference to a CA external account of the ACME server. If set, upon registration cert-manager will attempt to associate the given external account credentials with the registered ACME account. + type: object + required: + - keyID + - keySecretRef + properties: + keyAlgorithm: + description: 'Deprecated: keyAlgorithm field exists for historical compatibility reasons and should not be used. The algorithm is now hardcoded to HS256 in golang/x/crypto/acme.' + type: string + enum: + - HS256 + - HS384 + - HS512 + keyID: + description: keyID is the ID of the CA key that the External Account is bound to. + type: string + keySecretRef: + description: keySecretRef is a Secret Key Selector referencing a data item in a Kubernetes Secret which holds the symmetric MAC key of the External Account Binding. The `key` is the index string that is paired with the key data in the Secret and should not be confused with the key data itself, or indeed with the External Account Binding keyID above. The secret key stored in the Secret **must** be un-padded, base64 URL encoded data. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + preferredChain: + description: 'PreferredChain is the chain to use if the ACME server outputs multiple. PreferredChain is no guarantee that this one gets delivered by the ACME endpoint. For example, for Let''s Encrypt''s DST crosssign you would use: "DST Root CA X3" or "ISRG Root X1" for the newer Let''s Encrypt root CA. This value picks the first certificate bundle in the ACME alternative chains that has a certificate with this value as its issuer''s CN' + type: string + maxLength: 64 + privateKeySecretRef: + description: PrivateKey is the name of a Kubernetes Secret resource that will be used to store the automatically generated ACME account private key. Optionally, a `key` may be specified to select a specific entry within the named Secret resource. If `key` is not specified, a default of `tls.key` will be used. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + server: + description: 'Server is the URL used to access the ACME server''s ''directory'' endpoint. For example, for Let''s Encrypt''s staging endpoint, you would use: "https://acme-staging-v02.api.letsencrypt.org/directory". Only ACME v2 endpoints (i.e. RFC 8555) are supported.' + type: string + skipTLSVerify: + description: 'INSECURE: Enables or disables validation of the ACME server TLS certificate. If true, requests to the ACME server will not have the TLS certificate chain validated. Mutually exclusive with CABundle; prefer using CABundle to prevent various kinds of security vulnerabilities. Only enable this option in development environments. If CABundle and SkipTLSVerify are unset, the system certificate bundle inside the container is used to validate the TLS connection. Defaults to false.' + type: boolean + solvers: + description: 'Solvers is a list of challenge solvers that will be used to solve ACME challenges for the matching domains. Solver configurations must be provided in order to obtain certificates from an ACME server. For more information, see: https://cert-manager.io/docs/configuration/acme/' + type: array + items: + description: An ACMEChallengeSolver describes how to solve ACME challenges for the issuer it is part of. A selector may be provided to use different solving strategies for different DNS names. Only one of HTTP01 or DNS01 must be provided. + type: object + properties: + dns01: + description: Configures cert-manager to attempt to complete authorizations by performing the DNS01 challenge flow. + type: object + properties: + acmeDNS: + description: Use the 'ACME DNS' (https://github.com/joohoi/acme-dns) API to manage DNS01 challenge records. + type: object + required: + - accountSecretRef + - host + properties: + accountSecretRef: + description: A reference to a specific 'key' within a Secret resource. In some instances, `key` is a required field. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + host: + type: string + akamai: + description: Use the Akamai DNS zone management API to manage DNS01 challenge records. + type: object + required: + - accessTokenSecretRef + - clientSecretSecretRef + - clientTokenSecretRef + - serviceConsumerDomain + properties: + accessTokenSecretRef: + description: A reference to a specific 'key' within a Secret resource. In some instances, `key` is a required field. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + clientSecretSecretRef: + description: A reference to a specific 'key' within a Secret resource. In some instances, `key` is a required field. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + clientTokenSecretRef: + description: A reference to a specific 'key' within a Secret resource. In some instances, `key` is a required field. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + serviceConsumerDomain: + type: string + azureDNS: + description: Use the Microsoft Azure DNS API to manage DNS01 challenge records. + type: object + required: + - resourceGroupName + - subscriptionID + properties: + clientID: + description: if both this and ClientSecret are left unset MSI will be used + type: string + clientSecretSecretRef: + description: if both this and ClientID are left unset MSI will be used + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + environment: + description: name of the Azure environment (default AzurePublicCloud) + type: string + enum: + - AzurePublicCloud + - AzureChinaCloud + - AzureGermanCloud + - AzureUSGovernmentCloud + hostedZoneName: + description: name of the DNS zone that should be used + type: string + managedIdentity: + description: managed identity configuration, can not be used at the same time as clientID, clientSecretSecretRef or tenantID + type: object + properties: + clientID: + description: client ID of the managed identity, can not be used at the same time as resourceID + type: string + resourceID: + description: resource ID of the managed identity, can not be used at the same time as clientID + type: string + resourceGroupName: + description: resource group the DNS zone is located in + type: string + subscriptionID: + description: ID of the Azure subscription + type: string + tenantID: + description: when specifying ClientID and ClientSecret then this field is also needed + type: string + cloudDNS: + description: Use the Google Cloud DNS API to manage DNS01 challenge records. + type: object + required: + - project + properties: + hostedZoneName: + description: HostedZoneName is an optional field that tells cert-manager in which Cloud DNS zone the challenge record has to be created. If left empty cert-manager will automatically choose a zone. + type: string + project: + type: string + serviceAccountSecretRef: + description: A reference to a specific 'key' within a Secret resource. In some instances, `key` is a required field. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + cloudflare: + description: Use the Cloudflare API to manage DNS01 challenge records. + type: object + properties: + apiKeySecretRef: + description: 'API key to use to authenticate with Cloudflare. Note: using an API token to authenticate is now the recommended method as it allows greater control of permissions.' + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + apiTokenSecretRef: + description: API token used to authenticate with Cloudflare. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + email: + description: Email of the account, only required when using API key based authentication. + type: string + cnameStrategy: + description: CNAMEStrategy configures how the DNS01 provider should handle CNAME records when found in DNS zones. + type: string + enum: + - None + - Follow + digitalocean: + description: Use the DigitalOcean DNS API to manage DNS01 challenge records. + type: object + required: + - tokenSecretRef + properties: + tokenSecretRef: + description: A reference to a specific 'key' within a Secret resource. In some instances, `key` is a required field. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + rfc2136: + description: Use RFC2136 ("Dynamic Updates in the Domain Name System") (https://datatracker.ietf.org/doc/rfc2136/) to manage DNS01 challenge records. + type: object + required: + - nameserver + properties: + nameserver: + description: The IP address or hostname of an authoritative DNS server supporting RFC2136 in the form host:port. If the host is an IPv6 address it must be enclosed in square brackets (e.g [2001:db8::1]) ; port is optional. This field is required. + type: string + tsigAlgorithm: + description: 'The TSIG Algorithm configured in the DNS supporting RFC2136. Used only when ``tsigSecretSecretRef`` and ``tsigKeyName`` are defined. Supported values are (case-insensitive): ``HMACMD5`` (default), ``HMACSHA1``, ``HMACSHA256`` or ``HMACSHA512``.' + type: string + tsigKeyName: + description: The TSIG Key name configured in the DNS. If ``tsigSecretSecretRef`` is defined, this field is required. + type: string + tsigSecretSecretRef: + description: The name of the secret containing the TSIG value. If ``tsigKeyName`` is defined, this field is required. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + route53: + description: Use the AWS Route53 API to manage DNS01 challenge records. + type: object + required: + - region + properties: + accessKeyID: + description: 'The AccessKeyID is used for authentication. Cannot be set when SecretAccessKeyID is set. If neither the Access Key nor Key ID are set, we fall-back to using env vars, shared credentials file or AWS Instance metadata, see: https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials' + type: string + accessKeyIDSecretRef: + description: 'The SecretAccessKey is used for authentication. If set, pull the AWS access key ID from a key within a Kubernetes Secret. Cannot be set when AccessKeyID is set. If neither the Access Key nor Key ID are set, we fall-back to using env vars, shared credentials file or AWS Instance metadata, see: https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials' + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + hostedZoneID: + description: If set, the provider will manage only this zone in Route53 and will not do an lookup using the route53:ListHostedZonesByName api call. + type: string + region: + description: Always set the region when using AccessKeyID and SecretAccessKey + type: string + role: + description: Role is a Role ARN which the Route53 provider will assume using either the explicit credentials AccessKeyID/SecretAccessKey or the inferred credentials from environment variables, shared credentials file or AWS Instance metadata + type: string + secretAccessKeySecretRef: + description: 'The SecretAccessKey is used for authentication. If neither the Access Key nor Key ID are set, we fall-back to using env vars, shared credentials file or AWS Instance metadata, see: https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials' + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + webhook: + description: Configure an external webhook based DNS01 challenge solver to manage DNS01 challenge records. + type: object + required: + - groupName + - solverName + properties: + config: + description: Additional configuration that should be passed to the webhook apiserver when challenges are processed. This can contain arbitrary JSON data. Secret values should not be specified in this stanza. If secret values are needed (e.g. credentials for a DNS service), you should use a SecretKeySelector to reference a Secret resource. For details on the schema of this field, consult the webhook provider implementation's documentation. + x-kubernetes-preserve-unknown-fields: true + groupName: + description: The API group name that should be used when POSTing ChallengePayload resources to the webhook apiserver. This should be the same as the GroupName specified in the webhook provider implementation. + type: string + solverName: + description: The name of the solver to use, as defined in the webhook provider implementation. This will typically be the name of the provider, e.g. 'cloudflare'. + type: string + http01: + description: Configures cert-manager to attempt to complete authorizations by performing the HTTP01 challenge flow. It is not possible to obtain certificates for wildcard domain names (e.g. `*.example.com`) using the HTTP01 challenge mechanism. + type: object + properties: + gatewayHTTPRoute: + description: The Gateway API is a sig-network community API that models service networking in Kubernetes (https://gateway-api.sigs.k8s.io/). The Gateway solver will create HTTPRoutes with the specified labels in the same namespace as the challenge. This solver is experimental, and fields / behaviour may change in the future. + type: object + properties: + labels: + description: Custom labels that will be applied to HTTPRoutes created by cert-manager while solving HTTP-01 challenges. + type: object + additionalProperties: + type: string + parentRefs: + description: 'When solving an HTTP-01 challenge, cert-manager creates an HTTPRoute. cert-manager needs to know which parentRefs should be used when creating the HTTPRoute. Usually, the parentRef references a Gateway. See: https://gateway-api.sigs.k8s.io/api-types/httproute/#attaching-to-gateways' + type: array + items: + description: "ParentReference identifies an API object (usually a Gateway) that can be considered a parent of this resource (usually a route). The only kind of parent resource with \"Core\" support is Gateway. This API may be extended in the future to support additional kinds of parent resources, such as HTTPRoute. \n The API object must be valid in the cluster; the Group and Kind must be registered in the cluster for this reference to be valid." + type: object + required: + - name + properties: + group: + description: "Group is the group of the referent. When unspecified, \"gateway.networking.k8s.io\" is inferred. To set the core API group (such as for a \"Service\" kind referent), Group must be explicitly set to \"\" (empty string). \n Support: Core" + type: string + default: gateway.networking.k8s.io + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + kind: + description: "Kind is kind of the referent. \n Support: Core (Gateway) \n Support: Implementation-specific (Other Resources)" + type: string + default: Gateway + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + name: + description: "Name is the name of the referent. \n Support: Core" + type: string + maxLength: 253 + minLength: 1 + namespace: + description: "Namespace is the namespace of the referent. When unspecified, this refers to the local namespace of the Route. \n Note that there are specific rules for ParentRefs which cross namespace boundaries. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example: Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable any other kind of cross-namespace reference. \n Support: Core" + type: string + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + port: + description: "Port is the network port this Route targets. It can be interpreted differently based on the type of parent resource. \n When the parent resource is a Gateway, this targets all listeners listening on the specified port that also support this kind of Route(and select this Route). It's not recommended to set `Port` unless the networking behaviors specified in a Route must apply to a specific port as opposed to a listener(s) whose port(s) may be changed. When both Port and SectionName are specified, the name and port of the selected listener must match both specified values. \n Implementations MAY choose to support other parent resources. Implementations supporting other types of parent resources MUST clearly document how/if Port is interpreted. \n For the purpose of status, an attachment is considered successful as long as the parent resource accepts it partially. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Extended \n " + type: integer + format: int32 + maximum: 65535 + minimum: 1 + sectionName: + description: "SectionName is the name of a section within the target resource. In the following resources, SectionName is interpreted as the following: \n * Gateway: Listener Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. \n Implementations MAY choose to support attaching Routes to other resources. If that is the case, they MUST clearly document how SectionName is interpreted. \n When unspecified (empty string), this will reference the entire resource. For the purpose of status, an attachment is considered successful if at least one section in the parent resource accepts it. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Core" + type: string + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + serviceType: + description: Optional service type for Kubernetes solver service. Supported values are NodePort or ClusterIP. If unset, defaults to NodePort. + type: string + ingress: + description: The ingress based HTTP01 challenge solver will solve challenges by creating or modifying Ingress resources in order to route requests for '/.well-known/acme-challenge/XYZ' to 'challenge solver' pods that are provisioned by cert-manager for each Challenge to be completed. + type: object + properties: + class: + description: This field configures the annotation `kubernetes.io/ingress.class` when creating Ingress resources to solve ACME challenges that use this challenge solver. Only one of `class`, `name` or `ingressClassName` may be specified. + type: string + ingressClassName: + description: This field configures the field `ingressClassName` on the created Ingress resources used to solve ACME challenges that use this challenge solver. This is the recommended way of configuring the ingress class. Only one of `class`, `name` or `ingressClassName` may be specified. + type: string + ingressTemplate: + description: Optional ingress template used to configure the ACME challenge solver ingress used for HTTP01 challenges. + type: object + properties: + metadata: + description: ObjectMeta overrides for the ingress used to solve HTTP01 challenges. Only the 'labels' and 'annotations' fields may be set. If labels or annotations overlap with in-built values, the values here will override the in-built values. + type: object + properties: + annotations: + description: Annotations that should be added to the created ACME HTTP01 solver ingress. + type: object + additionalProperties: + type: string + labels: + description: Labels that should be added to the created ACME HTTP01 solver ingress. + type: object + additionalProperties: + type: string + name: + description: The name of the ingress resource that should have ACME challenge solving routes inserted into it in order to solve HTTP01 challenges. This is typically used in conjunction with ingress controllers like ingress-gce, which maintains a 1:1 mapping between external IPs and ingress resources. Only one of `class`, `name` or `ingressClassName` may be specified. + type: string + podTemplate: + description: Optional pod template used to configure the ACME challenge solver pods used for HTTP01 challenges. + type: object + properties: + metadata: + description: ObjectMeta overrides for the pod used to solve HTTP01 challenges. Only the 'labels' and 'annotations' fields may be set. If labels or annotations overlap with in-built values, the values here will override the in-built values. + type: object + properties: + annotations: + description: Annotations that should be added to the create ACME HTTP01 solver pods. + type: object + additionalProperties: + type: string + labels: + description: Labels that should be added to the created ACME HTTP01 solver pods. + type: object + additionalProperties: + type: string + spec: + description: PodSpec defines overrides for the HTTP01 challenge solver pod. Check ACMEChallengeSolverHTTP01IngressPodSpec to find out currently supported fields. All other fields will be ignored. + type: object + properties: + affinity: + description: If specified, the pod's scheduling constraints + type: object + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for the pod. + type: object + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node matches the corresponding matchExpressions; the node(s) with the highest sum are the most preferred. + type: array + items: + description: An empty preferred scheduling term matches all objects with implicit weight 0 (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + type: object + required: + - preference + - weight + properties: + preference: + description: A node selector term, associated with the corresponding weight. + type: object + properties: + matchExpressions: + description: A list of node selector requirements by node's labels. + type: array + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchFields: + description: A list of node selector requirements by node's fields. + type: array + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + type: array + items: + type: string + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching the corresponding nodeSelectorTerm, in the range 1-100. + type: integer + format: int32 + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to an update), the system may or may not try to eventually evict the pod from its node. + type: object + required: + - nodeSelectorTerms + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. The terms are ORed. + type: array + items: + description: A null or empty node selector term matches no objects. The requirements of them are ANDed. The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + type: object + properties: + matchExpressions: + description: A list of node selector requirements by node's labels. + type: array + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchFields: + description: A list of node selector requirements by node's fields. + type: array + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + type: array + items: + type: string + x-kubernetes-map-type: atomic + x-kubernetes-map-type: atomic + podAffinity: + description: Describes pod affinity scheduling rules (e.g. co-locate this pod in the same node, zone, etc. as some other pod(s)). + type: object + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred. + type: array + items: + description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s) + type: object + required: + - podAffinityTerm + - weight + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated with the corresponding weight. + type: object + required: + - topologyKey + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + x-kubernetes-map-type: atomic + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace". + type: array + items: + type: string + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + weight: + description: weight associated with matching the corresponding podAffinityTerm, in the range 1-100. + type: integer + format: int32 + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied. + type: array + items: + description: Defines a set of pods (namely those matching the labelSelector relative to the given namespace(s)) that this pod should be co-located (affinity) or not co-located (anti-affinity) with, where co-located is defined as running on a node whose value of the label with key matches that of any node on which a pod of the set of pods is running + type: object + required: + - topologyKey + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + x-kubernetes-map-type: atomic + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace". + type: array + items: + type: string + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules (e.g. avoid putting this pod in the same node, zone, etc. as some other pod(s)). + type: object + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to nodes that satisfy the anti-affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling anti-affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred. + type: array + items: + description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s) + type: object + required: + - podAffinityTerm + - weight + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated with the corresponding weight. + type: object + required: + - topologyKey + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + x-kubernetes-map-type: atomic + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace". + type: array + items: + type: string + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + weight: + description: weight associated with matching the corresponding podAffinityTerm, in the range 1-100. + type: integer + format: int32 + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the anti-affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied. + type: array + items: + description: Defines a set of pods (namely those matching the labelSelector relative to the given namespace(s)) that this pod should be co-located (affinity) or not co-located (anti-affinity) with, where co-located is defined as running on a node whose value of the label with key matches that of any node on which a pod of the set of pods is running + type: object + required: + - topologyKey + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + x-kubernetes-map-type: atomic + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. + type: object + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + type: array + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: object + required: + - key + - operator + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + type: array + items: + type: string + matchLabels: + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + additionalProperties: + type: string + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace". + type: array + items: + type: string + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + imagePullSecrets: + description: If specified, the pod's imagePullSecrets + type: array + items: + description: LocalObjectReference contains enough information to let you locate the referenced object inside the same namespace. + type: object + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + x-kubernetes-map-type: atomic + nodeSelector: + description: 'NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node''s labels for the pod to be scheduled on that node. More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' + type: object + additionalProperties: + type: string + priorityClassName: + description: If specified, the pod's priorityClassName. + type: string + serviceAccountName: + description: If specified, the pod's service account + type: string + tolerations: + description: If specified, the pod's tolerations. + type: array + items: + description: The pod this Toleration is attached to tolerates any taint that matches the triple using the matching operator . + type: object + properties: + effect: + description: Effect indicates the taint effect to match. Empty means match all taint effects. When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies to. Empty means match all taint keys. If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to the value. Valid operators are Exists and Equal. Defaults to Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of time the toleration (which must be of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, it is not set, which means tolerate the taint forever (do not evict). Zero and negative values will be treated as 0 (evict immediately) by the system. + type: integer + format: int64 + value: + description: Value is the taint value the toleration matches to. If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + serviceType: + description: Optional service type for Kubernetes solver service. Supported values are NodePort or ClusterIP. If unset, defaults to NodePort. + type: string + selector: + description: Selector selects a set of DNSNames on the Certificate resource that should be solved using this challenge solver. If not specified, the solver will be treated as the 'default' solver with the lowest priority, i.e. if any other solver has a more specific match, it will be used instead. + type: object + properties: + dnsNames: + description: List of DNSNames that this solver will be used to solve. If specified and a match is found, a dnsNames selector will take precedence over a dnsZones selector. If multiple solvers match with the same dnsNames value, the solver with the most matching labels in matchLabels will be selected. If neither has more matches, the solver defined earlier in the list will be selected. + type: array + items: + type: string + dnsZones: + description: List of DNSZones that this solver will be used to solve. The most specific DNS zone match specified here will take precedence over other DNS zone matches, so a solver specifying sys.example.com will be selected over one specifying example.com for the domain www.sys.example.com. If multiple solvers match with the same dnsZones value, the solver with the most matching labels in matchLabels will be selected. If neither has more matches, the solver defined earlier in the list will be selected. + type: array + items: + type: string + matchLabels: + description: A label selector that is used to refine the set of certificate's that this challenge solver will apply to. + type: object + additionalProperties: + type: string + ca: + description: CA configures this issuer to sign certificates using a signing CA keypair stored in a Secret resource. This is used to build internal PKIs that are managed by cert-manager. + type: object + required: + - secretName + properties: + crlDistributionPoints: + description: The CRL distribution points is an X.509 v3 certificate extension which identifies the location of the CRL from which the revocation of this certificate can be checked. If not set, certificates will be issued without distribution points set. + type: array + items: + type: string + ocspServers: + description: The OCSP server list is an X.509 v3 extension that defines a list of URLs of OCSP responders. The OCSP responders can be queried for the revocation status of an issued certificate. If not set, the certificate will be issued with no OCSP servers set. For example, an OCSP server URL could be "http://ocsp.int-x3.letsencrypt.org". + type: array + items: + type: string + secretName: + description: SecretName is the name of the secret used to sign Certificates issued by this Issuer. + type: string + selfSigned: + description: SelfSigned configures this issuer to 'self sign' certificates using the private key used to create the CertificateRequest object. + type: object + properties: + crlDistributionPoints: + description: The CRL distribution points is an X.509 v3 certificate extension which identifies the location of the CRL from which the revocation of this certificate can be checked. If not set certificate will be issued without CDP. Values are strings. + type: array + items: + type: string + vault: + description: Vault configures this issuer to sign certificates using a HashiCorp Vault PKI backend. + type: object + required: + - auth + - path + - server + properties: + auth: + description: Auth configures how cert-manager authenticates with the Vault server. + type: object + properties: + appRole: + description: AppRole authenticates with Vault using the App Role auth mechanism, with the role and secret stored in a Kubernetes Secret resource. + type: object + required: + - path + - roleId + - secretRef + properties: + path: + description: 'Path where the App Role authentication backend is mounted in Vault, e.g: "approle"' + type: string + roleId: + description: RoleID configured in the App Role authentication backend when setting up the authentication backend in Vault. + type: string + secretRef: + description: Reference to a key in a Secret that contains the App Role secret used to authenticate with Vault. The `key` field must be specified and denotes which entry within the Secret resource is used as the app role secret. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + kubernetes: + description: Kubernetes authenticates with Vault by passing the ServiceAccount token stored in the named Secret resource to the Vault server. + type: object + required: + - role + properties: + mountPath: + description: The Vault mountPath here is the mount path to use when authenticating with Vault. For example, setting a value to `/v1/auth/foo`, will use the path `/v1/auth/foo/login` to authenticate with Vault. If unspecified, the default value "/v1/auth/kubernetes" will be used. + type: string + role: + description: A required field containing the Vault Role to assume. A Role binds a Kubernetes ServiceAccount with a set of Vault policies. + type: string + secretRef: + description: The required Secret field containing a Kubernetes ServiceAccount JWT used for authenticating with Vault. Use of 'ambient credentials' is not supported. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + serviceAccountRef: + description: A reference to a service account that will be used to request a bound token (also known as "projected token"). Compared to using "secretRef", using this field means that you don't rely on statically bound tokens. To use this field, you must configure an RBAC rule to let cert-manager request a token. + type: object + required: + - name + properties: + name: + description: Name of the ServiceAccount used to request a token. + type: string + tokenSecretRef: + description: TokenSecretRef authenticates with Vault by presenting a token. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + caBundle: + description: Base64-encoded bundle of PEM CAs which will be used to validate the certificate chain presented by Vault. Only used if using HTTPS to connect to Vault and ignored for HTTP connections. Mutually exclusive with CABundleSecretRef. If neither CABundle nor CABundleSecretRef are defined, the certificate bundle in the cert-manager controller container is used to validate the TLS connection. + type: string + format: byte + caBundleSecretRef: + description: Reference to a Secret containing a bundle of PEM-encoded CAs to use when verifying the certificate chain presented by Vault when using HTTPS. Mutually exclusive with CABundle. If neither CABundle nor CABundleSecretRef are defined, the certificate bundle in the cert-manager controller container is used to validate the TLS connection. If no key for the Secret is specified, cert-manager will default to 'ca.crt'. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Name of the vault namespace. Namespaces is a set of features within Vault Enterprise that allows Vault environments to support Secure Multi-tenancy. e.g: "ns1" More about namespaces can be found here https://www.vaultproject.io/docs/enterprise/namespaces' + type: string + path: + description: 'Path is the mount path of the Vault PKI backend''s `sign` endpoint, e.g: "my_pki_mount/sign/my-role-name".' + type: string + server: + description: 'Server is the connection address for the Vault server, e.g: "https://vault.example.com:8200".' + type: string + venafi: + description: Venafi configures this issuer to sign certificates using a Venafi TPP or Venafi Cloud policy zone. + type: object + required: + - zone + properties: + cloud: + description: Cloud specifies the Venafi cloud configuration settings. Only one of TPP or Cloud may be specified. + type: object + required: + - apiTokenSecretRef + properties: + apiTokenSecretRef: + description: APITokenSecretRef is a secret key selector for the Venafi Cloud API token. + type: object + required: + - name + properties: + key: + description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required. + type: string + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + url: + description: URL is the base URL for Venafi Cloud. Defaults to "https://api.venafi.cloud/v1". + type: string + tpp: + description: TPP specifies Trust Protection Platform configuration settings. Only one of TPP or Cloud may be specified. + type: object + required: + - credentialsRef + - url + properties: + caBundle: + description: Base64-encoded bundle of PEM CAs which will be used to validate the certificate chain presented by the TPP server. Only used if using HTTPS; ignored for HTTP. If undefined, the certificate bundle in the cert-manager controller container is used to validate the chain. + type: string + format: byte + credentialsRef: + description: CredentialsRef is a reference to a Secret containing the username and password for the TPP server. The secret must contain two keys, 'username' and 'password'. + type: object + required: + - name + properties: + name: + description: 'Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + url: + description: 'URL is the base URL for the vedsdk endpoint of the Venafi TPP instance, for example: "https://tpp.example.com/vedsdk".' + type: string + zone: + description: Zone is the Venafi Policy Zone to use for this issuer. All requests made to the Venafi platform will be restricted by the named zone policy. This field is required. + type: string + status: + description: Status of the Issuer. This is set and managed automatically. + type: object + properties: + acme: + description: ACME specific status options. This field should only be set if the Issuer is configured to use an ACME server to issue certificates. + type: object + properties: + lastPrivateKeyHash: + description: LastPrivateKeyHash is a hash of the private key associated with the latest registered ACME account, in order to track changes made to registered account associated with the Issuer + type: string + lastRegisteredEmail: + description: LastRegisteredEmail is the email associated with the latest registered ACME account, in order to track changes made to registered account associated with the Issuer + type: string + uri: + description: URI is the unique account identifier, which can also be used to retrieve account details from the CA + type: string + conditions: + description: List of status conditions to indicate the status of a CertificateRequest. Known condition types are `Ready`. + type: array + items: + description: IssuerCondition contains condition information for an Issuer. + type: object + required: + - status + - type + properties: + lastTransitionTime: + description: LastTransitionTime is the timestamp corresponding to the last status change of this condition. + type: string + format: date-time + message: + description: Message is a human readable description of the details of the last transition, complementing reason. + type: string + observedGeneration: + description: If set, this represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.condition[x].observedGeneration is 9, the condition is out of date with respect to the current state of the Issuer. + type: integer + format: int64 + reason: + description: Reason is a brief machine readable explanation for the condition's last transition. + type: string + status: + description: Status of the condition, one of (`True`, `False`, `Unknown`). + type: string + enum: + - "True" + - "False" + - Unknown + type: + description: Type of the condition, known values are (`Ready`). + type: string + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + served: true + storage: true +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: orders.acme.cert-manager.io + labels: + app: '{{ template "cert-manager.name" . }}' + app.kubernetes.io/name: '{{ template "cert-manager.name" . }}' + app.kubernetes.io/instance: '{{ .Release.Name }}' + # Generated labels {{- include "labels" . | nindent 4 }} +spec: + group: acme.cert-manager.io + names: + kind: Order + listKind: OrderList + plural: orders + singular: order + categories: + - cert-manager + - cert-manager-acme + scope: Namespaced + versions: + - name: v1 + subresources: + status: {} + additionalPrinterColumns: + - jsonPath: .status.state + name: State + type: string + - jsonPath: .spec.issuerRef.name + name: Issuer + priority: 1 + type: string + - jsonPath: .status.reason + name: Reason + priority: 1 + type: string + - jsonPath: .metadata.creationTimestamp + description: CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC. + name: Age + type: date + schema: + openAPIV3Schema: + description: Order is a type to represent an Order with an ACME server + type: object + required: + - metadata + - spec + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + type: object + required: + - issuerRef + - request + properties: + commonName: + description: CommonName is the common name as specified on the DER encoded CSR. If specified, this value must also be present in `dnsNames` or `ipAddresses`. This field must match the corresponding field on the DER encoded CSR. + type: string + dnsNames: + description: DNSNames is a list of DNS names that should be included as part of the Order validation process. This field must match the corresponding field on the DER encoded CSR. + type: array + items: + type: string + duration: + description: Duration is the duration for the not after date for the requested certificate. this is set on order creation as pe the ACME spec. + type: string + ipAddresses: + description: IPAddresses is a list of IP addresses that should be included as part of the Order validation process. This field must match the corresponding field on the DER encoded CSR. + type: array + items: + type: string + issuerRef: + description: IssuerRef references a properly configured ACME-type Issuer which should be used to create this Order. If the Issuer does not exist, processing will be retried. If the Issuer is not an 'ACME' Issuer, an error will be returned and the Order will be marked as failed. + type: object + required: + - name + properties: + group: + description: Group of the resource being referred to. + type: string + kind: + description: Kind of the resource being referred to. + type: string + name: + description: Name of the resource being referred to. + type: string + request: + description: Certificate signing request bytes in DER encoding. This will be used when finalizing the order. This field must be set on the order. + type: string + format: byte + status: + type: object + properties: + authorizations: + description: Authorizations contains data returned from the ACME server on what authorizations must be completed in order to validate the DNS names specified on the Order. + type: array + items: + description: ACMEAuthorization contains data returned from the ACME server on an authorization that must be completed in order validate a DNS name on an ACME Order resource. + type: object + required: + - url + properties: + challenges: + description: Challenges specifies the challenge types offered by the ACME server. One of these challenge types will be selected when validating the DNS name and an appropriate Challenge resource will be created to perform the ACME challenge process. + type: array + items: + description: Challenge specifies a challenge offered by the ACME server for an Order. An appropriate Challenge resource can be created to perform the ACME challenge process. + type: object + required: + - token + - type + - url + properties: + token: + description: Token is the token that must be presented for this challenge. This is used to compute the 'key' that must also be presented. + type: string + type: + description: Type is the type of challenge being offered, e.g. 'http-01', 'dns-01', 'tls-sni-01', etc. This is the raw value retrieved from the ACME server. Only 'http-01' and 'dns-01' are supported by cert-manager, other values will be ignored. + type: string + url: + description: URL is the URL of this challenge. It can be used to retrieve additional metadata about the Challenge from the ACME server. + type: string + identifier: + description: Identifier is the DNS name to be validated as part of this authorization + type: string + initialState: + description: InitialState is the initial state of the ACME authorization when first fetched from the ACME server. If an Authorization is already 'valid', the Order controller will not create a Challenge resource for the authorization. This will occur when working with an ACME server that enables 'authz reuse' (such as Let's Encrypt's production endpoint). If not set and 'identifier' is set, the state is assumed to be pending and a Challenge will be created. + type: string + enum: + - valid + - ready + - pending + - processing + - invalid + - expired + - errored + url: + description: URL is the URL of the Authorization that must be completed + type: string + wildcard: + description: Wildcard will be true if this authorization is for a wildcard DNS name. If this is true, the identifier will be the *non-wildcard* version of the DNS name. For example, if '*.example.com' is the DNS name being validated, this field will be 'true' and the 'identifier' field will be 'example.com'. + type: boolean + certificate: + description: Certificate is a copy of the PEM encoded certificate for this Order. This field will be populated after the order has been successfully finalized with the ACME server, and the order has transitioned to the 'valid' state. + type: string + format: byte + failureTime: + description: FailureTime stores the time that this order failed. This is used to influence garbage collection and back-off. + type: string + format: date-time + finalizeURL: + description: FinalizeURL of the Order. This is used to obtain certificates for this order once it has been completed. + type: string + reason: + description: Reason optionally provides more information about a why the order is in the current state. + type: string + state: + description: State contains the current state of this Order resource. States 'success' and 'expired' are 'final' + type: string + enum: + - valid + - ready + - pending + - processing + - invalid + - expired + - errored + url: + description: URL of the Order. This will initially be empty when the resource is first created. The Order controller will populate this field when the Order is first processed. This field will be immutable after it is initially set. + type: string + served: true + storage: true +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/deployment.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/deployment.yaml new file mode 100644 index 000000000..aea5736c0 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/deployment.yaml @@ -0,0 +1,204 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "cert-manager.fullname" . }} + namespace: {{ include "cert-manager.namespace" . }} + labels: + app: {{ template "cert-manager.name" . }} + app.kubernetes.io/name: {{ template "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} + {{- with .Values.deploymentAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + app.kubernetes.io/name: {{ template "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- with .Values.strategy }} + strategy: + {{- toYaml . | nindent 4 }} + {{- end }} + template: + metadata: + labels: + app: {{ template "cert-manager.name" . }} + app.kubernetes.io/name: {{ template "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 8 }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if and .Values.prometheus.enabled (not .Values.prometheus.servicemonitor.enabled) }} + {{- if not .Values.podAnnotations }} + annotations: + {{- end }} + prometheus.io/path: "/metrics" + prometheus.io/scrape: 'true' + prometheus.io/port: '9402' + {{- end }} + spec: + serviceAccountName: {{ template "cert-manager.serviceAccountName" . }} + {{- if hasKey .Values "automountServiceAccountToken" }} + automountServiceAccountToken: {{ .Values.automountServiceAccountToken }} + {{- end }} + {{- with .Values.global.priorityClassName }} + priorityClassName: {{ . | quote }} + {{- end }} + {{- with .Values.securityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.volumes }} + volumes: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: {{ .Chart.Name }}-controller + {{- with .Values.image }} + image: "{{- if .registry -}}{{ .registry }}/{{- end -}}{{ .repository }}{{- if (.digest) -}} @{{ .digest }}{{- else -}}:{{ default $.Chart.AppVersion .tag }} {{- end -}}" + {{- end }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + args: + {{- if .Values.global.logLevel }} + - --v={{ .Values.global.logLevel }} + {{- end }} + {{- if .Values.clusterResourceNamespace }} + - --cluster-resource-namespace={{ .Values.clusterResourceNamespace }} + {{- else }} + - --cluster-resource-namespace=$(POD_NAMESPACE) + {{- end }} + {{- with .Values.global.leaderElection }} + - --leader-election-namespace={{ .namespace }} + {{- if .leaseDuration }} + - --leader-election-lease-duration={{ .leaseDuration }} + {{- end }} + {{- if .renewDeadline }} + - --leader-election-renew-deadline={{ .renewDeadline }} + {{- end }} + {{- if .retryPeriod }} + - --leader-election-retry-period={{ .retryPeriod }} + {{- end }} + {{- end }} + {{- with .Values.acmesolver.image }} + - --acme-http01-solver-image={{- if .registry -}}{{ .registry }}/{{- end -}}{{ .repository }}{{- if (.digest) -}} @{{ .digest }}{{- else -}}:{{ default $.Chart.AppVersion .tag }} {{- end -}} + {{- end }} + {{- with .Values.extraArgs }} + {{- toYaml . | nindent 10 }} + {{- end }} + {{- with .Values.ingressShim }} + {{- if .defaultIssuerName }} + - --default-issuer-name={{ .defaultIssuerName }} + {{- end }} + {{- if .defaultIssuerKind }} + - --default-issuer-kind={{ .defaultIssuerKind }} + {{- end }} + {{- if .defaultIssuerGroup }} + - --default-issuer-group={{ .defaultIssuerGroup }} + {{- end }} + {{- end }} + {{- if .Values.featureGates }} + - --feature-gates={{ .Values.featureGates }} + {{- end }} + {{- if .Values.maxConcurrentChallenges }} + - --max-concurrent-challenges={{ .Values.maxConcurrentChallenges }} + {{- end }} + {{- if .Values.enableCertificateOwnerRef }} + - --enable-certificate-owner-ref=true + {{- end }} + {{- if .Values.dns01RecursiveNameserversOnly }} + - --dns01-recursive-nameservers-only=true + {{- end }} + {{- with .Values.dns01RecursiveNameservers }} + - --dns01-recursive-nameservers={{ . }} + {{- end }} + ports: + - containerPort: 9402 + name: http-metrics + protocol: TCP + - containerPort: 9403 + name: http-healthz + protocol: TCP + {{- with .Values.containerSecurityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.volumeMounts }} + volumeMounts: + {{- toYaml . | nindent 12 }} + {{- end }} + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- with .Values.extraEnv }} + {{- toYaml . | nindent 10 }} + {{- end }} + {{- with .Values.http_proxy }} + - name: HTTP_PROXY + value: {{ . }} + {{- end }} + {{- with .Values.https_proxy }} + - name: HTTPS_PROXY + value: {{ . }} + {{- end }} + {{- with .Values.no_proxy }} + - name: NO_PROXY + value: {{ . }} + {{- end }} + {{- with .Values.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + + {{- with .Values.livenessProbe }} + {{- if .enabled }} + # LivenessProbe settings are based on those used for the Kubernetes + # controller-manager. See: + # https://github.com/kubernetes/kubernetes/blob/806b30170c61a38fedd54cc9ede4cd6275a1ad3b/cmd/kubeadm/app/util/staticpod/utils.go#L241-L245 + livenessProbe: + httpGet: + port: http-healthz + path: /livez + scheme: HTTP + initialDelaySeconds: {{ .initialDelaySeconds }} + periodSeconds: {{ .periodSeconds }} + timeoutSeconds: {{ .timeoutSeconds }} + successThreshold: {{ .successThreshold }} + failureThreshold: {{ .failureThreshold }} + {{- end }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.podDnsPolicy }} + dnsPolicy: {{ . }} + {{- end }} + {{- with .Values.podDnsConfig }} + dnsConfig: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/networkpolicy-egress.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/networkpolicy-egress.yaml new file mode 100644 index 000000000..09712009d --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/networkpolicy-egress.yaml @@ -0,0 +1,23 @@ +{{- if .Values.webhook.networkPolicy.enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ template "webhook.fullname" . }}-allow-egress + namespace: {{ include "cert-manager.namespace" . }} +spec: + egress: + {{- with .Values.webhook.networkPolicy.egress }} + {{- toYaml . | nindent 2 }} + {{- end }} + podSelector: + matchLabels: + app: {{ include "webhook.name" . }} + app.kubernetes.io/name: {{ include "webhook.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "webhook" + {{- with .Values.webhook.podLabels }} + {{- toYaml . | nindent 6 }} + {{- end }} + policyTypes: + - Egress +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/networkpolicy-webhooks.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/networkpolicy-webhooks.yaml new file mode 100644 index 000000000..349877a8b --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/networkpolicy-webhooks.yaml @@ -0,0 +1,25 @@ +{{- if .Values.webhook.networkPolicy.enabled }} + +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ template "webhook.fullname" . }}-allow-ingress + namespace: {{ include "cert-manager.namespace" . }} +spec: + ingress: + {{- with .Values.webhook.networkPolicy.ingress }} + {{- toYaml . | nindent 2 }} + {{- end }} + podSelector: + matchLabels: + app: {{ include "webhook.name" . }} + app.kubernetes.io/name: {{ include "webhook.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "webhook" + {{- with .Values.webhook.podLabels }} + {{- toYaml . | nindent 6 }} + {{- end }} + policyTypes: + - Ingress + +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/poddisruptionbudget.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/poddisruptionbudget.yaml new file mode 100644 index 000000000..dab75ce68 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/poddisruptionbudget.yaml @@ -0,0 +1,26 @@ +{{- if .Values.podDisruptionBudget.enabled }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "cert-manager.fullname" . }} + namespace: {{ include "cert-manager.namespace" . }} + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} +spec: + selector: + matchLabels: + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + + {{- with .Values.podDisruptionBudget.minAvailable }} + minAvailable: {{ . }} + {{- end }} + {{- with .Values.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ . }} + {{- end }} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/psp-clusterrole.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/psp-clusterrole.yaml new file mode 100644 index 000000000..1d40a0238 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/psp-clusterrole.yaml @@ -0,0 +1,18 @@ +{{- if .Values.global.podSecurityPolicy.enabled }} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "cert-manager.fullname" . }}-psp + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} +rules: +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "cert-manager.fullname" . }} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/psp-clusterrolebinding.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/psp-clusterrolebinding.yaml new file mode 100644 index 000000000..4f09b6bf3 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/psp-clusterrolebinding.yaml @@ -0,0 +1,20 @@ +{{- if .Values.global.podSecurityPolicy.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "cert-manager.fullname" . }}-psp + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "cert-manager.fullname" . }}-psp +subjects: + - kind: ServiceAccount + name: {{ template "cert-manager.serviceAccountName" . }} + namespace: {{ include "cert-manager.namespace" . }} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/psp.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/psp.yaml new file mode 100644 index 000000000..9e99f5c76 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/psp.yaml @@ -0,0 +1,49 @@ +{{- if .Values.global.podSecurityPolicy.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "cert-manager.fullname" . }} + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} + annotations: + seccomp.security.alpha.kubernetes.io/allowedProfileNames: 'docker/default' + seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default' + {{- if .Values.global.podSecurityPolicy.useAppArmor }} + apparmor.security.beta.kubernetes.io/allowedProfileNames: 'runtime/default' + apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default' + {{- end }} +spec: + privileged: false + allowPrivilegeEscalation: false + allowedCapabilities: [] # default set of capabilities are implicitly allowed + volumes: + - 'configMap' + - 'emptyDir' + - 'projected' + - 'secret' + - 'downwardAPI' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'MustRunAs' + ranges: + - min: 1000 + max: 1000 + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'MustRunAs' + ranges: + - min: 1000 + max: 1000 + fsGroup: + rule: 'MustRunAs' + ranges: + - min: 1000 + max: 1000 +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/rbac.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/rbac.yaml new file mode 100644 index 000000000..830e37285 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/rbac.yaml @@ -0,0 +1,544 @@ +{{- if .Values.global.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "cert-manager.fullname" . }}:leaderelection + namespace: {{ .Values.global.leaderElection.namespace }} + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} +rules: + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + resourceNames: ["cert-manager-controller"] + verbs: ["get", "update", "patch"] + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["create"] + +--- + +# grant cert-manager permission to manage the leaderelection configmap in the +# leader election namespace +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "cert-manager.fullname" . }}:leaderelection + namespace: {{ .Values.global.leaderElection.namespace }} + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "cert-manager.fullname" . }}:leaderelection +subjects: + - apiGroup: "" + kind: ServiceAccount + name: {{ template "cert-manager.serviceAccountName" . }} + namespace: {{ include "cert-manager.namespace" . }} + +--- + +# Issuer controller role +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "cert-manager.fullname" . }}-controller-issuers + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} +rules: + - apiGroups: ["cert-manager.io"] + resources: ["issuers", "issuers/status"] + verbs: ["update", "patch"] + - apiGroups: ["cert-manager.io"] + resources: ["issuers"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list", "watch", "create", "update", "delete"] + - apiGroups: [""] + resources: ["events"] + verbs: ["create", "patch"] +--- + +# ClusterIssuer controller role +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "cert-manager.fullname" . }}-controller-clusterissuers + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} +rules: + - apiGroups: ["cert-manager.io"] + resources: ["clusterissuers", "clusterissuers/status"] + verbs: ["update", "patch"] + - apiGroups: ["cert-manager.io"] + resources: ["clusterissuers"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list", "watch", "create", "update", "delete"] + - apiGroups: [""] + resources: ["events"] + verbs: ["create", "patch"] + +--- + +# Certificates controller role +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "cert-manager.fullname" . }}-controller-certificates + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} +rules: + - apiGroups: ["cert-manager.io"] + resources: ["certificates", "certificates/status", "certificaterequests", "certificaterequests/status"] + verbs: ["update", "patch"] + - apiGroups: ["cert-manager.io"] + resources: ["certificates", "certificaterequests", "clusterissuers", "issuers"] + verbs: ["get", "list", "watch"] + # We require these rules to support users with the OwnerReferencesPermissionEnforcement + # admission controller enabled: + # https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#ownerreferencespermissionenforcement + - apiGroups: ["cert-manager.io"] + resources: ["certificates/finalizers", "certificaterequests/finalizers"] + verbs: ["update"] + - apiGroups: ["acme.cert-manager.io"] + resources: ["orders"] + verbs: ["create", "delete", "get", "list", "watch"] + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list", "watch", "create", "update", "delete", "patch"] + - apiGroups: [""] + resources: ["events"] + verbs: ["create", "patch"] + +--- + +# Orders controller role +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "cert-manager.fullname" . }}-controller-orders + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} +rules: + - apiGroups: ["acme.cert-manager.io"] + resources: ["orders", "orders/status"] + verbs: ["update", "patch"] + - apiGroups: ["acme.cert-manager.io"] + resources: ["orders", "challenges"] + verbs: ["get", "list", "watch"] + - apiGroups: ["cert-manager.io"] + resources: ["clusterissuers", "issuers"] + verbs: ["get", "list", "watch"] + - apiGroups: ["acme.cert-manager.io"] + resources: ["challenges"] + verbs: ["create", "delete"] + # We require these rules to support users with the OwnerReferencesPermissionEnforcement + # admission controller enabled: + # https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#ownerreferencespermissionenforcement + - apiGroups: ["acme.cert-manager.io"] + resources: ["orders/finalizers"] + verbs: ["update"] + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["events"] + verbs: ["create", "patch"] + +--- + +# Challenges controller role +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "cert-manager.fullname" . }}-controller-challenges + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} +rules: + # Use to update challenge resource status + - apiGroups: ["acme.cert-manager.io"] + resources: ["challenges", "challenges/status"] + verbs: ["update", "patch"] + # Used to watch challenge resources + - apiGroups: ["acme.cert-manager.io"] + resources: ["challenges"] + verbs: ["get", "list", "watch"] + # Used to watch challenges, issuer and clusterissuer resources + - apiGroups: ["cert-manager.io"] + resources: ["issuers", "clusterissuers"] + verbs: ["get", "list", "watch"] + # Need to be able to retrieve ACME account private key to complete challenges + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list", "watch"] + # Used to create events + - apiGroups: [""] + resources: ["events"] + verbs: ["create", "patch"] + # HTTP01 rules + - apiGroups: [""] + resources: ["pods", "services"] + verbs: ["get", "list", "watch", "create", "delete"] + - apiGroups: ["networking.k8s.io"] + resources: ["ingresses"] + verbs: ["get", "list", "watch", "create", "delete", "update"] + - apiGroups: [ "gateway.networking.k8s.io" ] + resources: [ "httproutes" ] + verbs: ["get", "list", "watch", "create", "delete", "update"] + # We require the ability to specify a custom hostname when we are creating + # new ingress resources. + # See: https://github.com/openshift/origin/blob/21f191775636f9acadb44fa42beeb4f75b255532/pkg/route/apiserver/admission/ingress_admission.go#L84-L148 + - apiGroups: ["route.openshift.io"] + resources: ["routes/custom-host"] + verbs: ["create"] + # We require these rules to support users with the OwnerReferencesPermissionEnforcement + # admission controller enabled: + # https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#ownerreferencespermissionenforcement + - apiGroups: ["acme.cert-manager.io"] + resources: ["challenges/finalizers"] + verbs: ["update"] + # DNS01 rules (duplicated above) + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list", "watch"] + +--- + +# ingress-shim controller role +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "cert-manager.fullname" . }}-controller-ingress-shim + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} +rules: + - apiGroups: ["cert-manager.io"] + resources: ["certificates", "certificaterequests"] + verbs: ["create", "update", "delete"] + - apiGroups: ["cert-manager.io"] + resources: ["certificates", "certificaterequests", "issuers", "clusterissuers"] + verbs: ["get", "list", "watch"] + - apiGroups: ["networking.k8s.io"] + resources: ["ingresses"] + verbs: ["get", "list", "watch"] + # We require these rules to support users with the OwnerReferencesPermissionEnforcement + # admission controller enabled: + # https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#ownerreferencespermissionenforcement + - apiGroups: ["networking.k8s.io"] + resources: ["ingresses/finalizers"] + verbs: ["update"] + - apiGroups: ["gateway.networking.k8s.io"] + resources: ["gateways", "httproutes"] + verbs: ["get", "list", "watch"] + - apiGroups: ["gateway.networking.k8s.io"] + resources: ["gateways/finalizers", "httproutes/finalizers"] + verbs: ["update"] + - apiGroups: [""] + resources: ["events"] + verbs: ["create", "patch"] + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "cert-manager.fullname" . }}-controller-issuers + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "cert-manager.fullname" . }}-controller-issuers +subjects: + - name: {{ template "cert-manager.serviceAccountName" . }} + namespace: {{ include "cert-manager.namespace" . }} + kind: ServiceAccount + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "cert-manager.fullname" . }}-controller-clusterissuers + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "cert-manager.fullname" . }}-controller-clusterissuers +subjects: + - name: {{ template "cert-manager.serviceAccountName" . }} + namespace: {{ include "cert-manager.namespace" . }} + kind: ServiceAccount + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "cert-manager.fullname" . }}-controller-certificates + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "cert-manager.fullname" . }}-controller-certificates +subjects: + - name: {{ template "cert-manager.serviceAccountName" . }} + namespace: {{ include "cert-manager.namespace" . }} + kind: ServiceAccount + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "cert-manager.fullname" . }}-controller-orders + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "cert-manager.fullname" . }}-controller-orders +subjects: + - name: {{ template "cert-manager.serviceAccountName" . }} + namespace: {{ include "cert-manager.namespace" . }} + kind: ServiceAccount + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "cert-manager.fullname" . }}-controller-challenges + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "cert-manager.fullname" . }}-controller-challenges +subjects: + - name: {{ template "cert-manager.serviceAccountName" . }} + namespace: {{ include "cert-manager.namespace" . }} + kind: ServiceAccount + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "cert-manager.fullname" . }}-controller-ingress-shim + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "cert-manager.fullname" . }}-controller-ingress-shim +subjects: + - name: {{ template "cert-manager.serviceAccountName" . }} + namespace: {{ include "cert-manager.namespace" . }} + kind: ServiceAccount + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "cert-manager.fullname" . }}-view + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} + {{- if .Values.global.rbac.aggregateClusterRoles }} + rbac.authorization.k8s.io/aggregate-to-view: "true" + rbac.authorization.k8s.io/aggregate-to-edit: "true" + rbac.authorization.k8s.io/aggregate-to-admin: "true" + {{- end }} +rules: + - apiGroups: ["cert-manager.io"] + resources: ["certificates", "certificaterequests", "issuers"] + verbs: ["get", "list", "watch"] + - apiGroups: ["acme.cert-manager.io"] + resources: ["challenges", "orders"] + verbs: ["get", "list", "watch"] + + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "cert-manager.fullname" . }}-edit + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} + {{- if .Values.global.rbac.aggregateClusterRoles }} + rbac.authorization.k8s.io/aggregate-to-edit: "true" + rbac.authorization.k8s.io/aggregate-to-admin: "true" + {{- end }} +rules: + - apiGroups: ["cert-manager.io"] + resources: ["certificates", "certificaterequests", "issuers"] + verbs: ["create", "delete", "deletecollection", "patch", "update"] + - apiGroups: ["cert-manager.io"] + resources: ["certificates/status"] + verbs: ["update"] + - apiGroups: ["acme.cert-manager.io"] + resources: ["challenges", "orders"] + verbs: ["create", "delete", "deletecollection", "patch", "update"] + +--- + +# Permission to approve CertificateRequests referencing cert-manager.io Issuers and ClusterIssuers +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "cert-manager.fullname" . }}-controller-approve:cert-manager-io + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "cert-manager" + {{- include "labels" . | nindent 4 }} +rules: + - apiGroups: ["cert-manager.io"] + resources: ["signers"] + verbs: ["approve"] + resourceNames: ["issuers.cert-manager.io/*", "clusterissuers.cert-manager.io/*"] + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "cert-manager.fullname" . }}-controller-approve:cert-manager-io + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "cert-manager" + {{- include "labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "cert-manager.fullname" . }}-controller-approve:cert-manager-io +subjects: + - name: {{ template "cert-manager.serviceAccountName" . }} + namespace: {{ include "cert-manager.namespace" . }} + kind: ServiceAccount + +--- + +# Permission to: +# - Update and sign CertificatSigningeRequests referencing cert-manager.io Issuers and ClusterIssuers +# - Perform SubjectAccessReviews to test whether users are able to reference Namespaced Issuers +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "cert-manager.fullname" . }}-controller-certificatesigningrequests + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "cert-manager" + {{- include "labels" . | nindent 4 }} +rules: + - apiGroups: ["certificates.k8s.io"] + resources: ["certificatesigningrequests"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: ["certificates.k8s.io"] + resources: ["certificatesigningrequests/status"] + verbs: ["update", "patch"] + - apiGroups: ["certificates.k8s.io"] + resources: ["signers"] + resourceNames: ["issuers.cert-manager.io/*", "clusterissuers.cert-manager.io/*"] + verbs: ["sign"] + - apiGroups: ["authorization.k8s.io"] + resources: ["subjectaccessreviews"] + verbs: ["create"] + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "cert-manager.fullname" . }}-controller-certificatesigningrequests + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "cert-manager" + {{- include "labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "cert-manager.fullname" . }}-controller-certificatesigningrequests +subjects: + - name: {{ template "cert-manager.serviceAccountName" . }} + namespace: {{ include "cert-manager.namespace" . }} + kind: ServiceAccount +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/service.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/service.yaml new file mode 100644 index 000000000..ec34d5878 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/service.yaml @@ -0,0 +1,31 @@ +{{- if .Values.prometheus.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "cert-manager.fullname" . }} + namespace: {{ include "cert-manager.namespace" . }} +{{- with .Values.serviceAnnotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} + {{- with .Values.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + type: ClusterIP + ports: + - protocol: TCP + port: 9402 + name: tcp-prometheus-servicemonitor + targetPort: {{ .Values.prometheus.servicemonitor.targetPort }} + selector: + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/serviceaccount.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/serviceaccount.yaml new file mode 100644 index 000000000..6026842ff --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/serviceaccount.yaml @@ -0,0 +1,25 @@ +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +{{- with .Values.global.imagePullSecrets }} +imagePullSecrets: + {{- toYaml . | nindent 2 }} +{{- end }} +automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} +metadata: + name: {{ template "cert-manager.serviceAccountName" . }} + namespace: {{ include "cert-manager.namespace" . }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} + {{- with .Values.serviceAccount.labels }} + {{ toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/servicemonitor.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/servicemonitor.yaml new file mode 100644 index 000000000..9d9e89992 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/servicemonitor.yaml @@ -0,0 +1,45 @@ +{{- if and .Values.prometheus.enabled .Values.prometheus.servicemonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "cert-manager.fullname" . }} +{{- if .Values.prometheus.servicemonitor.namespace }} + namespace: {{ .Values.prometheus.servicemonitor.namespace }} +{{- else }} + namespace: {{ include "cert-manager.namespace" . }} +{{- end }} + labels: + app: {{ include "cert-manager.name" . }} + app.kubernetes.io/name: {{ include "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" + {{- include "labels" . | nindent 4 }} + prometheus: {{ .Values.prometheus.servicemonitor.prometheusInstance }} + {{- with .Values.prometheus.servicemonitor.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{- if .Values.prometheus.servicemonitor.annotations }} + annotations: + {{- with .Values.prometheus.servicemonitor.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} +spec: + jobLabel: {{ template "cert-manager.fullname" . }} + selector: + matchLabels: + app.kubernetes.io/name: {{ template "cert-manager.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "controller" +{{- if .Values.prometheus.servicemonitor.namespace }} + namespaceSelector: + matchNames: + - {{ include "cert-manager.namespace" . }} +{{- end }} + endpoints: + - targetPort: {{ .Values.prometheus.servicemonitor.targetPort }} + path: {{ .Values.prometheus.servicemonitor.path }} + interval: {{ .Values.prometheus.servicemonitor.interval }} + scrapeTimeout: {{ .Values.prometheus.servicemonitor.scrapeTimeout }} + honorLabels: {{ .Values.prometheus.servicemonitor.honorLabels }} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/startupapicheck-job.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/startupapicheck-job.yaml new file mode 100644 index 000000000..a9b965e18 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/startupapicheck-job.yaml @@ -0,0 +1,88 @@ +{{- if .Values.startupapicheck.enabled }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "startupapicheck.fullname" . }} + namespace: {{ include "cert-manager.namespace" . }} + labels: + app: {{ include "startupapicheck.name" . }} + app.kubernetes.io/name: {{ include "startupapicheck.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "startupapicheck" + {{- include "labels" . | nindent 4 }} + {{- with .Values.startupapicheck.jobAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + backoffLimit: {{ .Values.startupapicheck.backoffLimit }} + template: + metadata: + labels: + app: {{ include "startupapicheck.name" . }} + app.kubernetes.io/name: {{ include "startupapicheck.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "startupapicheck" + {{- include "labels" . | nindent 8 }} + {{- with .Values.startupapicheck.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.startupapicheck.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + restartPolicy: OnFailure + serviceAccountName: {{ template "startupapicheck.serviceAccountName" . }} + {{- if hasKey .Values.startupapicheck "automountServiceAccountToken" }} + automountServiceAccountToken: {{ .Values.startupapicheck.automountServiceAccountToken }} + {{- end }} + {{- with .Values.global.priorityClassName }} + priorityClassName: {{ . | quote }} + {{- end }} + {{- with .Values.startupapicheck.securityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: {{ .Chart.Name }}-startupapicheck + {{- with .Values.startupapicheck.image }} + image: "{{- if .registry -}}{{ .registry }}/{{- end -}}{{ .repository }}{{- if (.digest) -}} @{{ .digest }}{{- else -}}:{{ default $.Chart.AppVersion .tag }} {{- end -}}" + {{- end }} + imagePullPolicy: {{ .Values.startupapicheck.image.pullPolicy }} + args: + - check + - api + - --wait={{ .Values.startupapicheck.timeout }} + {{- with .Values.startupapicheck.extraArgs }} + {{- toYaml . | nindent 10 }} + {{- end }} + {{- with .Values.startupapicheck.containerSecurityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.startupapicheck.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.startupapicheck.volumeMounts }} + volumeMounts: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.startupapicheck.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.startupapicheck.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.startupapicheck.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.startupapicheck.volumes }} + volumes: + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/startupapicheck-psp-clusterrole.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/startupapicheck-psp-clusterrole.yaml new file mode 100644 index 000000000..dacd4be27 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/startupapicheck-psp-clusterrole.yaml @@ -0,0 +1,24 @@ +{{- if .Values.startupapicheck.enabled }} +{{- if .Values.global.podSecurityPolicy.enabled }} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "startupapicheck.fullname" . }}-psp + labels: + app: {{ include "startupapicheck.name" . }} + app.kubernetes.io/name: {{ include "startupapicheck.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "startupapicheck" + {{- include "labels" . | nindent 4 }} + {{- with .Values.startupapicheck.rbac.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +rules: +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "startupapicheck.fullname" . }} +{{- end }} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/startupapicheck-psp-clusterrolebinding.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/startupapicheck-psp-clusterrolebinding.yaml new file mode 100644 index 000000000..54d5a42d6 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/startupapicheck-psp-clusterrolebinding.yaml @@ -0,0 +1,26 @@ +{{- if .Values.startupapicheck.enabled }} +{{- if .Values.global.podSecurityPolicy.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "startupapicheck.fullname" . }}-psp + labels: + app: {{ include "startupapicheck.name" . }} + app.kubernetes.io/name: {{ include "startupapicheck.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "startupapicheck" + {{- include "labels" . | nindent 4 }} + {{- with .Values.startupapicheck.rbac.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "startupapicheck.fullname" . }}-psp +subjects: + - kind: ServiceAccount + name: {{ template "startupapicheck.serviceAccountName" . }} + namespace: {{ include "cert-manager.namespace" . }} +{{- end }} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/startupapicheck-psp.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/startupapicheck-psp.yaml new file mode 100644 index 000000000..f09d60d63 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/startupapicheck-psp.yaml @@ -0,0 +1,51 @@ +{{- if .Values.startupapicheck.enabled }} +{{- if .Values.global.podSecurityPolicy.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "startupapicheck.fullname" . }} + labels: + app: {{ include "startupapicheck.name" . }} + app.kubernetes.io/name: {{ include "startupapicheck.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "startupapicheck" + {{- include "labels" . | nindent 4 }} + annotations: + seccomp.security.alpha.kubernetes.io/allowedProfileNames: 'docker/default' + seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default' + {{- if .Values.global.podSecurityPolicy.useAppArmor }} + apparmor.security.beta.kubernetes.io/allowedProfileNames: 'runtime/default' + apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default' + {{- end }} + {{- with .Values.startupapicheck.rbac.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + privileged: false + allowPrivilegeEscalation: false + allowedCapabilities: [] # default set of capabilities are implicitly allowed + volumes: + - 'projected' + - 'secret' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'MustRunAs' + ranges: + - min: 1000 + max: 1000 + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'MustRunAs' + ranges: + - min: 1000 + max: 1000 + fsGroup: + rule: 'MustRunAs' + ranges: + - min: 1000 + max: 1000 +{{- end }} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/startupapicheck-rbac.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/startupapicheck-rbac.yaml new file mode 100644 index 000000000..606e72564 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/startupapicheck-rbac.yaml @@ -0,0 +1,48 @@ +{{- if .Values.startupapicheck.enabled }} +{{- if .Values.global.rbac.create }} +# create certificate role +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "startupapicheck.fullname" . }}:create-cert + namespace: {{ include "cert-manager.namespace" . }} + labels: + app: {{ include "startupapicheck.name" . }} + app.kubernetes.io/name: {{ include "startupapicheck.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "startupapicheck" + {{- include "labels" . | nindent 4 }} + {{- with .Values.startupapicheck.rbac.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +rules: + - apiGroups: ["cert-manager.io"] + resources: ["certificates"] + verbs: ["create"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "startupapicheck.fullname" . }}:create-cert + namespace: {{ include "cert-manager.namespace" . }} + labels: + app: {{ include "startupapicheck.name" . }} + app.kubernetes.io/name: {{ include "startupapicheck.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "startupapicheck" + {{- include "labels" . | nindent 4 }} + {{- with .Values.startupapicheck.rbac.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "startupapicheck.fullname" . }}:create-cert +subjects: + - kind: ServiceAccount + name: {{ template "startupapicheck.serviceAccountName" . }} + namespace: {{ include "cert-manager.namespace" . }} +{{- end }} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/startupapicheck-serviceaccount.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/startupapicheck-serviceaccount.yaml new file mode 100644 index 000000000..8c417604a --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/startupapicheck-serviceaccount.yaml @@ -0,0 +1,27 @@ +{{- if .Values.startupapicheck.enabled }} +{{- if .Values.startupapicheck.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +automountServiceAccountToken: {{ .Values.startupapicheck.serviceAccount.automountServiceAccountToken }} +metadata: + name: {{ template "startupapicheck.serviceAccountName" . }} + namespace: {{ include "cert-manager.namespace" . }} + {{- with .Values.startupapicheck.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + app: {{ include "startupapicheck.name" . }} + app.kubernetes.io/name: {{ include "startupapicheck.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "startupapicheck" + {{- include "labels" . | nindent 4 }} + {{- with .Values.startupapicheck.serviceAccount.labels }} + {{ toYaml . | nindent 4 }} + {{- end }} +{{- with .Values.global.imagePullSecrets }} +imagePullSecrets: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-config.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-config.yaml new file mode 100644 index 000000000..f3f72f02e --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-config.yaml @@ -0,0 +1,25 @@ +{{- if .Values.webhook.config -}} + {{- if not .Values.webhook.config.apiVersion -}} + {{- fail "webhook.config.apiVersion must be set" -}} + {{- end -}} + + {{- if not .Values.webhook.config.kind -}} + {{- fail "webhook.config.kind must be set" -}} + {{- end -}} +{{- end -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "webhook.fullname" . }} + namespace: {{ include "cert-manager.namespace" . }} + labels: + app: {{ include "webhook.name" . }} + app.kubernetes.io/name: {{ include "webhook.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "webhook" + {{- include "labels" . | nindent 4 }} +data: + {{- if .Values.webhook.config }} + config.yaml: | + {{ .Values.webhook.config | toYaml | nindent 4 }} + {{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-deployment.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-deployment.yaml new file mode 100644 index 000000000..043c4b150 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-deployment.yaml @@ -0,0 +1,185 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "webhook.fullname" . }} + namespace: {{ include "cert-manager.namespace" . }} + labels: + app: {{ include "webhook.name" . }} + app.kubernetes.io/name: {{ include "webhook.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "webhook" + {{- include "labels" . | nindent 4 }} + {{- with .Values.webhook.deploymentAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.webhook.replicaCount }} + selector: + matchLabels: + app.kubernetes.io/name: {{ include "webhook.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "webhook" + {{- with .Values.webhook.strategy }} + strategy: + {{- toYaml . | nindent 4 }} + {{- end }} + template: + metadata: + labels: + app: {{ include "webhook.name" . }} + app.kubernetes.io/name: {{ include "webhook.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "webhook" + {{- include "labels" . | nindent 8 }} + {{- with .Values.webhook.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.webhook.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + serviceAccountName: {{ template "webhook.serviceAccountName" . }} + {{- if hasKey .Values.webhook "automountServiceAccountToken" }} + automountServiceAccountToken: {{ .Values.webhook.automountServiceAccountToken }} + {{- end }} + {{- with .Values.global.priorityClassName }} + priorityClassName: {{ . | quote }} + {{- end }} + {{- with .Values.webhook.securityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.webhook.hostNetwork }} + hostNetwork: true + {{- end }} + containers: + - name: {{ .Chart.Name }}-webhook + {{- with .Values.webhook.image }} + image: "{{- if .registry -}}{{ .registry }}/{{- end -}}{{ .repository }}{{- if (.digest) -}} @{{ .digest }}{{- else -}}:{{ default $.Chart.AppVersion .tag }} {{- end -}}" + {{- end }} + imagePullPolicy: {{ .Values.webhook.image.pullPolicy }} + args: + {{- if .Values.global.logLevel }} + - --v={{ .Values.global.logLevel }} + {{- end }} + {{- if .Values.webhook.config }} + - --config=/var/cert-manager/config/config.yaml + {{- end }} + {{- $config := default .Values.webhook.config "" }} + {{ if not $config.securePort -}} + - --secure-port={{ .Values.webhook.securePort }} + {{- end }} + {{- if .Values.featureGates }} + - --feature-gates={{ .Values.featureGates }} + {{- end }} + {{- $tlsConfig := default $config.tlsConfig "" }} + {{ if or (not $config.tlsConfig) (and (not $tlsConfig.dynamic) (not $tlsConfig.filesystem) ) -}} + - --dynamic-serving-ca-secret-namespace=$(POD_NAMESPACE) + - --dynamic-serving-ca-secret-name={{ template "webhook.fullname" . }}-ca + - --dynamic-serving-dns-names={{ template "webhook.fullname" . }} + - --dynamic-serving-dns-names={{ template "webhook.fullname" . }}.$(POD_NAMESPACE) + - --dynamic-serving-dns-names={{ template "webhook.fullname" . }}.$(POD_NAMESPACE).svc + {{ if .Values.webhook.url.host }} + - --dynamic-serving-dns-names={{ .Values.webhook.url.host }} + {{- end }} + {{- end }} + {{- with .Values.webhook.extraArgs }} + {{- toYaml . | nindent 10 }} + {{- end }} + ports: + - name: https + protocol: TCP + {{- if $config.securePort }} + containerPort: {{ $config.securePort }} + {{- else if .Values.webhook.securePort }} + containerPort: {{ .Values.webhook.securePort }} + {{- else }} + containerPort: 6443 + {{- end }} + - name: healthcheck + protocol: TCP + {{- if $config.healthzPort }} + containerPort: {{ $config.healthzPort }} + {{- else }} + containerPort: 6080 + {{- end }} + livenessProbe: + httpGet: + path: /livez + {{- if $config.healthzPort }} + port: {{ $config.healthzPort }} + {{- else }} + port: 6080 + {{- end }} + scheme: HTTP + initialDelaySeconds: {{ .Values.webhook.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.webhook.livenessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.webhook.livenessProbe.timeoutSeconds }} + successThreshold: {{ .Values.webhook.livenessProbe.successThreshold }} + failureThreshold: {{ .Values.webhook.livenessProbe.failureThreshold }} + readinessProbe: + httpGet: + path: /healthz + {{- if $config.healthzPort }} + port: {{ $config.healthzPort }} + {{- else }} + port: 6080 + {{- end }} + scheme: HTTP + initialDelaySeconds: {{ .Values.webhook.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.webhook.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.webhook.readinessProbe.timeoutSeconds }} + successThreshold: {{ .Values.webhook.readinessProbe.successThreshold }} + failureThreshold: {{ .Values.webhook.readinessProbe.failureThreshold }} + {{- with .Values.webhook.containerSecurityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- with .Values.webhook.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if or .Values.webhook.config .Values.webhook.volumeMounts }} + volumeMounts: + {{- if .Values.webhook.config }} + - name: config + mountPath: /var/cert-manager/config + {{- end }} + {{- if .Values.webhook.volumeMounts }} + {{- toYaml .Values.webhook.volumeMounts | nindent 12 }} + {{- end }} + {{- end }} + {{- with .Values.webhook.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.webhook.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.webhook.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.webhook.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if or .Values.webhook.config .Values.webhook.volumes }} + volumes: + {{- if .Values.webhook.config }} + - name: config + configMap: + name: {{ include "webhook.fullname" . }} + {{- end }} + {{- if .Values.webhook.volumes }} + {{- toYaml .Values.webhook.volumes | nindent 8 }} + {{- end }} + {{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-mutating-webhook.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-mutating-webhook.yaml new file mode 100644 index 000000000..f3db011ef --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-mutating-webhook.yaml @@ -0,0 +1,46 @@ +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + name: {{ include "webhook.fullname" . }} + labels: + app: {{ include "webhook.name" . }} + app.kubernetes.io/name: {{ include "webhook.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "webhook" + {{- include "labels" . | nindent 4 }} + annotations: + cert-manager.io/inject-ca-from-secret: {{ printf "%s/%s-ca" (include "cert-manager.namespace" .) (include "webhook.fullname" .) | quote }} + {{- with .Values.webhook.mutatingWebhookConfigurationAnnotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +webhooks: + - name: webhook.cert-manager.io + rules: + - apiGroups: + - "cert-manager.io" + - "acme.cert-manager.io" + apiVersions: + - "v1" + operations: + - CREATE + - UPDATE + resources: + - "*/*" + admissionReviewVersions: ["v1"] + # This webhook only accepts v1 cert-manager resources. + # Equivalent matchPolicy ensures that non-v1 resource requests are sent to + # this webhook (after the resources have been converted to v1). + matchPolicy: Equivalent + timeoutSeconds: {{ .Values.webhook.timeoutSeconds }} + failurePolicy: Fail + # Only include 'sideEffects' field in Kubernetes 1.12+ + sideEffects: None + clientConfig: + {{- if .Values.webhook.url.host }} + url: https://{{ .Values.webhook.url.host }}/mutate + {{- else }} + service: + name: {{ template "webhook.fullname" . }} + namespace: {{ include "cert-manager.namespace" . }} + path: /mutate + {{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-poddisruptionbudget.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-poddisruptionbudget.yaml new file mode 100644 index 000000000..c8a357cb1 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-poddisruptionbudget.yaml @@ -0,0 +1,26 @@ +{{- if .Values.webhook.podDisruptionBudget.enabled }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "webhook.fullname" . }} + namespace: {{ include "cert-manager.namespace" . }} + labels: + app: {{ include "webhook.name" . }} + app.kubernetes.io/name: {{ include "webhook.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "webhook" + {{- include "labels" . | nindent 4 }} +spec: + selector: + matchLabels: + app.kubernetes.io/name: {{ include "webhook.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "webhook" + + {{- with .Values.webhook.podDisruptionBudget.minAvailable }} + minAvailable: {{ . }} + {{- end }} + {{- with .Values.webhook.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ . }} + {{- end }} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-psp-clusterrole.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-psp-clusterrole.yaml new file mode 100644 index 000000000..f6fa4c55e --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-psp-clusterrole.yaml @@ -0,0 +1,18 @@ +{{- if .Values.global.podSecurityPolicy.enabled }} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "webhook.fullname" . }}-psp + labels: + app: {{ include "webhook.name" . }} + app.kubernetes.io/name: {{ include "webhook.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "webhook" + {{- include "labels" . | nindent 4 }} +rules: +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "webhook.fullname" . }} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-psp-clusterrolebinding.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-psp-clusterrolebinding.yaml new file mode 100644 index 000000000..858df8ff2 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-psp-clusterrolebinding.yaml @@ -0,0 +1,20 @@ +{{- if .Values.global.podSecurityPolicy.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "webhook.fullname" . }}-psp + labels: + app: {{ include "webhook.name" . }} + app.kubernetes.io/name: {{ include "webhook.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "webhook" + {{- include "labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "webhook.fullname" . }}-psp +subjects: + - kind: ServiceAccount + name: {{ template "webhook.serviceAccountName" . }} + namespace: {{ include "cert-manager.namespace" . }} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-psp.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-psp.yaml new file mode 100644 index 000000000..4d5d959df --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-psp.yaml @@ -0,0 +1,54 @@ +{{- if .Values.global.podSecurityPolicy.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "webhook.fullname" . }} + labels: + app: {{ include "webhook.name" . }} + app.kubernetes.io/name: {{ include "webhook.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "webhook" + {{- include "labels" . | nindent 4 }} + annotations: + seccomp.security.alpha.kubernetes.io/allowedProfileNames: 'docker/default' + seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default' + {{- if .Values.global.podSecurityPolicy.useAppArmor }} + apparmor.security.beta.kubernetes.io/allowedProfileNames: 'runtime/default' + apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default' + {{- end }} +spec: + privileged: false + allowPrivilegeEscalation: false + allowedCapabilities: [] # default set of capabilities are implicitly allowed + volumes: + - 'configMap' + - 'emptyDir' + - 'projected' + - 'secret' + - 'downwardAPI' + hostNetwork: {{ .Values.webhook.hostNetwork }} + {{- if .Values.webhook.hostNetwork }} + hostPorts: + - max: {{ .Values.webhook.securePort }} + min: {{ .Values.webhook.securePort }} + {{- end }} + hostIPC: false + hostPID: false + runAsUser: + rule: 'MustRunAs' + ranges: + - min: 1000 + max: 1000 + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'MustRunAs' + ranges: + - min: 1000 + max: 1000 + fsGroup: + rule: 'MustRunAs' + ranges: + - min: 1000 + max: 1000 +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-rbac.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-rbac.yaml new file mode 100644 index 000000000..b075ffd46 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-rbac.yaml @@ -0,0 +1,83 @@ +{{- if .Values.global.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "webhook.fullname" . }}:dynamic-serving + namespace: {{ include "cert-manager.namespace" . }} + labels: + app: {{ include "webhook.name" . }} + app.kubernetes.io/name: {{ include "webhook.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "webhook" + {{- include "labels" . | nindent 4 }} +rules: +- apiGroups: [""] + resources: ["secrets"] + resourceNames: + - '{{ template "webhook.fullname" . }}-ca' + verbs: ["get", "list", "watch", "update"] +# It's not possible to grant CREATE permission on a single resourceName. +- apiGroups: [""] + resources: ["secrets"] + verbs: ["create"] +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "webhook.fullname" . }}:dynamic-serving + namespace: {{ include "cert-manager.namespace" . }} + labels: + app: {{ include "webhook.name" . }} + app.kubernetes.io/name: {{ include "webhook.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "webhook" + {{- include "labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "webhook.fullname" . }}:dynamic-serving +subjects: +- apiGroup: "" + kind: ServiceAccount + name: {{ template "webhook.serviceAccountName" . }} + namespace: {{ include "cert-manager.namespace" . }} + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "webhook.fullname" . }}:subjectaccessreviews + labels: + app: {{ include "webhook.name" . }} + app.kubernetes.io/name: {{ include "webhook.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "webhook" + {{- include "labels" . | nindent 4 }} +rules: +- apiGroups: ["authorization.k8s.io"] + resources: ["subjectaccessreviews"] + verbs: ["create"] +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "webhook.fullname" . }}:subjectaccessreviews + labels: + app: {{ include "webhook.name" . }} + app.kubernetes.io/name: {{ include "webhook.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "webhook" + {{- include "labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "webhook.fullname" . }}:subjectaccessreviews +subjects: +- apiGroup: "" + kind: ServiceAccount + name: {{ template "webhook.serviceAccountName" . }} + namespace: {{ include "cert-manager.namespace" . }} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-service.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-service.yaml new file mode 100644 index 000000000..5f9395049 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-service.yaml @@ -0,0 +1,32 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "webhook.fullname" . }} + namespace: {{ include "cert-manager.namespace" . }} +{{- with .Values.webhook.serviceAnnotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} + labels: + app: {{ include "webhook.name" . }} + app.kubernetes.io/name: {{ include "webhook.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "webhook" + {{- include "labels" . | nindent 4 }} + {{- with .Values.webhook.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + type: {{ .Values.webhook.serviceType }} + {{- with .Values.webhook.loadBalancerIP }} + loadBalancerIP: {{ . }} + {{- end }} + ports: + - name: https + port: 443 + protocol: TCP + targetPort: "https" + selector: + app.kubernetes.io/name: {{ include "webhook.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "webhook" diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-serviceaccount.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-serviceaccount.yaml new file mode 100644 index 000000000..dff5c0672 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-serviceaccount.yaml @@ -0,0 +1,25 @@ +{{- if .Values.webhook.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +automountServiceAccountToken: {{ .Values.webhook.serviceAccount.automountServiceAccountToken }} +metadata: + name: {{ template "webhook.serviceAccountName" . }} + namespace: {{ include "cert-manager.namespace" . }} + {{- with .Values.webhook.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + app: {{ include "webhook.name" . }} + app.kubernetes.io/name: {{ include "webhook.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "webhook" + {{- include "labels" . | nindent 4 }} + {{- with .Values.webhook.serviceAccount.labels }} + {{ toYaml . | nindent 4 }} + {{- end }} +{{- with .Values.global.imagePullSecrets }} +imagePullSecrets: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-validating-webhook.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-validating-webhook.yaml new file mode 100644 index 000000000..a5d168e29 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/templates/webhook-validating-webhook.yaml @@ -0,0 +1,55 @@ +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: {{ include "webhook.fullname" . }} + labels: + app: {{ include "webhook.name" . }} + app.kubernetes.io/name: {{ include "webhook.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: "webhook" + {{- include "labels" . | nindent 4 }} + annotations: + cert-manager.io/inject-ca-from-secret: {{ printf "%s/%s-ca" (include "cert-manager.namespace" .) (include "webhook.fullname" .) | quote}} + {{- with .Values.webhook.validatingWebhookConfigurationAnnotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +webhooks: + - name: webhook.cert-manager.io + namespaceSelector: + matchExpressions: + - key: "cert-manager.io/disable-validation" + operator: "NotIn" + values: + - "true" + - key: "name" + operator: "NotIn" + values: + - {{ include "cert-manager.namespace" . }} + rules: + - apiGroups: + - "cert-manager.io" + - "acme.cert-manager.io" + apiVersions: + - "v1" + operations: + - CREATE + - UPDATE + resources: + - "*/*" + admissionReviewVersions: ["v1"] + # This webhook only accepts v1 cert-manager resources. + # Equivalent matchPolicy ensures that non-v1 resource requests are sent to + # this webhook (after the resources have been converted to v1). + matchPolicy: Equivalent + timeoutSeconds: {{ .Values.webhook.timeoutSeconds }} + failurePolicy: Fail + sideEffects: None + clientConfig: + {{- if .Values.webhook.url.host }} + url: https://{{ .Values.webhook.url.host }}/validate + {{- else }} + service: + name: {{ template "webhook.fullname" . }} + namespace: {{ include "cert-manager.namespace" . }} + path: /validate + {{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/values.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/values.yaml new file mode 100644 index 000000000..66df39a4b --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/charts/cert-manager/values.yaml @@ -0,0 +1,692 @@ +# Default values for cert-manager. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. +global: + # Reference to one or more secrets to be used when pulling images + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + imagePullSecrets: [] + # - name: "image-pull-secret" + + # Labels to apply to all resources + # Please note that this does not add labels to the resources created dynamically by the controllers. + # For these resources, you have to add the labels in the template in the cert-manager custom resource: + # eg. podTemplate/ ingressTemplate in ACMEChallengeSolverHTTP01Ingress + # ref: https://cert-manager.io/docs/reference/api-docs/#acme.cert-manager.io/v1.ACMEChallengeSolverHTTP01Ingress + # eg. secretTemplate in CertificateSpec + # ref: https://cert-manager.io/docs/reference/api-docs/#cert-manager.io/v1.CertificateSpec + commonLabels: {} + # team_name: dev + + # Optional priority class to be used for the cert-manager pods + priorityClassName: "" + rbac: + create: true + # Aggregate ClusterRoles to Kubernetes default user-facing roles. Ref: https://kubernetes.io/docs/reference/access-authn-authz/rbac/#user-facing-roles + aggregateClusterRoles: true + + podSecurityPolicy: + enabled: false + useAppArmor: true + + # Set the verbosity of cert-manager. Range of 0 - 6 with 6 being the most verbose. + logLevel: 2 + + leaderElection: + # Override the namespace used for the leader election lease + namespace: "kube-system" + + # The duration that non-leader candidates will wait after observing a + # leadership renewal until attempting to acquire leadership of a led but + # unrenewed leader slot. This is effectively the maximum duration that a + # leader can be stopped before it is replaced by another candidate. + # leaseDuration: 60s + + # The interval between attempts by the acting master to renew a leadership + # slot before it stops leading. This must be less than or equal to the + # lease duration. + # renewDeadline: 40s + + # The duration the clients should wait between attempting acquisition and + # renewal of a leadership. + # retryPeriod: 15s + +installCRDs: false + +replicaCount: 1 + +strategy: {} + # type: RollingUpdate + # rollingUpdate: + # maxSurge: 0 + # maxUnavailable: 1 + +podDisruptionBudget: + enabled: false + + minAvailable: 1 + # maxUnavailable: 1 + + # minAvailable and maxUnavailable can either be set to an integer (e.g. 1) + # or a percentage value (e.g. 25%) + +# Comma separated list of feature gates that should be enabled on the controller +# Note: do not use this field to pass feature gate values into webhook +# component as this behaviour relies on a bug that will be fixed in cert-manager 1.13 +# https://github.com/cert-manager/cert-manager/pull/6093 +# Use webhook.extraArgs to pass --feature-gates flag directly instead. +featureGates: "" + +# The maximum number of challenges that can be scheduled as 'processing' at once +maxConcurrentChallenges: 60 + +image: + repository: quay.io/jetstack/cert-manager-controller + # You can manage a registry with + # registry: quay.io + # repository: jetstack/cert-manager-controller + + # Override the image tag to deploy by setting this variable. + # If no value is set, the chart's appVersion will be used. + # tag: canary + + # Setting a digest will override any tag + # digest: sha256:0e072dddd1f7f8fc8909a2ca6f65e76c5f0d2fcfb8be47935ae3457e8bbceb20 + pullPolicy: IfNotPresent + +# Override the namespace used to store DNS provider credentials etc. for ClusterIssuer +# resources. By default, the same namespace as cert-manager is deployed within is +# used. This namespace will not be automatically created by the Helm chart. +clusterResourceNamespace: "" + +# This namespace allows you to define where the services will be installed into +# if not set then they will use the namespace of the release +# This is helpful when installing cert manager as a chart dependency (sub chart) +namespace: "" + +serviceAccount: + # Specifies whether a service account should be created + create: true + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + # name: "" + # Optional additional annotations to add to the controller's ServiceAccount + # annotations: {} + # Automount API credentials for a Service Account. + # Optional additional labels to add to the controller's ServiceAccount + # labels: {} + automountServiceAccountToken: true + +# Automounting API credentials for a particular pod +# automountServiceAccountToken: true + +# When this flag is enabled, secrets will be automatically removed when the certificate resource is deleted +enableCertificateOwnerRef: false + +# Setting Nameservers for DNS01 Self Check +# See: https://cert-manager.io/docs/configuration/acme/dns01/#setting-nameservers-for-dns01-self-check + +# Comma separated string with host and port of the recursive nameservers cert-manager should query +dns01RecursiveNameservers: "" + +# Forces cert-manager to only use the recursive nameservers for verification. +# Enabling this option could cause the DNS01 self check to take longer due to caching performed by the recursive nameservers +dns01RecursiveNameserversOnly: false + +# Additional command line flags to pass to cert-manager controller binary. +# To see all available flags run docker run quay.io/jetstack/cert-manager-controller: --help +extraArgs: [] + # Use this flag to enable or disable arbitrary controllers, for example, disable the CertificiateRequests approver + # - --controllers=*,-certificaterequests-approver + +extraEnv: [] +# - name: SOME_VAR +# value: 'some value' + +resources: {} + # requests: + # cpu: 10m + # memory: 32Mi + +# Pod Security Context +# ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ +securityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + +# Container Security Context to be set on the controller component container +# ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ +containerSecurityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + + +volumes: [] + +volumeMounts: [] + +# Optional additional annotations to add to the controller Deployment +# deploymentAnnotations: {} + +# Optional additional annotations to add to the controller Pods +# podAnnotations: {} + +podLabels: {} + +# Optional annotations to add to the controller Service +# serviceAnnotations: {} + +# Optional additional labels to add to the controller Service +# serviceLabels: {} + +# Optional DNS settings, useful if you have a public and private DNS zone for +# the same domain on Route 53. What follows is an example of ensuring +# cert-manager can access an ingress or DNS TXT records at all times. +# NOTE: This requires Kubernetes 1.10 or `CustomPodDNS` feature gate enabled for +# the cluster to work. +# podDnsPolicy: "None" +# podDnsConfig: +# nameservers: +# - "1.1.1.1" +# - "8.8.8.8" + +nodeSelector: + kubernetes.io/os: linux + +ingressShim: {} + # defaultIssuerName: "" + # defaultIssuerKind: "" + # defaultIssuerGroup: "" + +prometheus: + enabled: true + servicemonitor: + enabled: false + prometheusInstance: default + targetPort: 9402 + path: /metrics + interval: 60s + scrapeTimeout: 30s + labels: {} + annotations: {} + honorLabels: false + +# Use these variables to configure the HTTP_PROXY environment variables +# http_proxy: "http://proxy:8080" +# https_proxy: "https://proxy:8080" +# no_proxy: 127.0.0.1,localhost + +# A Kubernetes Affinty, if required; see https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#affinity-v1-core +# for example: +# affinity: +# nodeAffinity: +# requiredDuringSchedulingIgnoredDuringExecution: +# nodeSelectorTerms: +# - matchExpressions: +# - key: foo.bar.com/role +# operator: In +# values: +# - master +affinity: {} + +# A list of Kubernetes Tolerations, if required; see https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#toleration-v1-core +# for example: +# tolerations: +# - key: foo.bar.com/role +# operator: Equal +# value: master +# effect: NoSchedule +tolerations: [] + +# A list of Kubernetes TopologySpreadConstraints, if required; see https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#topologyspreadconstraint-v1-core +# for example: +# topologySpreadConstraints: +# - maxSkew: 2 +# topologyKey: topology.kubernetes.io/zone +# whenUnsatisfiable: ScheduleAnyway +# labelSelector: +# matchLabels: +# app.kubernetes.io/instance: cert-manager +# app.kubernetes.io/component: controller +topologySpreadConstraints: [] + +# LivenessProbe settings for the controller container of the controller Pod. +# +# Disabled by default, because the controller has a leader election mechanism +# which should cause it to exit if it is unable to renew its leader election +# record. +# LivenessProbe durations and thresholds are based on those used for the Kubernetes +# controller-manager. See: +# https://github.com/kubernetes/kubernetes/blob/806b30170c61a38fedd54cc9ede4cd6275a1ad3b/cmd/kubeadm/app/util/staticpod/utils.go#L241-L245 +livenessProbe: + enabled: false + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 15 + successThreshold: 1 + failureThreshold: 8 + +webhook: + replicaCount: 1 + timeoutSeconds: 10 + + # Used to configure options for the webhook pod. + # This allows setting options that'd usually be provided via flags. + # An APIVersion and Kind must be specified in your values.yaml file. + # Flags will override options that are set here. + config: + # apiVersion: webhook.config.cert-manager.io/v1alpha1 + # kind: WebhookConfiguration + + # The port that the webhook should listen on for requests. + # In GKE private clusters, by default kubernetes apiservers are allowed to + # talk to the cluster nodes only on 443 and 10250. so configuring + # securePort: 10250, will work out of the box without needing to add firewall + # rules or requiring NET_BIND_SERVICE capabilities to bind port numbers <1000. + # This should be uncommented and set as a default by the chart once we graduate + # the apiVersion of WebhookConfiguration past v1alpha1. + # securePort: 10250 + + strategy: {} + # type: RollingUpdate + # rollingUpdate: + # maxSurge: 0 + # maxUnavailable: 1 + + # Pod Security Context to be set on the webhook component Pod + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + securityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + + podDisruptionBudget: + enabled: false + + minAvailable: 1 + # maxUnavailable: 1 + + # minAvailable and maxUnavailable can either be set to an integer (e.g. 1) + # or a percentage value (e.g. 25%) + + # Container Security Context to be set on the webhook component container + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + containerSecurityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + + # Optional additional annotations to add to the webhook Deployment + # deploymentAnnotations: {} + + # Optional additional annotations to add to the webhook Pods + # podAnnotations: {} + + # Optional additional annotations to add to the webhook Service + # serviceAnnotations: {} + + # Optional additional annotations to add to the webhook MutatingWebhookConfiguration + # mutatingWebhookConfigurationAnnotations: {} + + # Optional additional annotations to add to the webhook ValidatingWebhookConfiguration + # validatingWebhookConfigurationAnnotations: {} + + # Additional command line flags to pass to cert-manager webhook binary. + # To see all available flags run docker run quay.io/jetstack/cert-manager-webhook: --help + extraArgs: [] + # Path to a file containing a WebhookConfiguration object used to configure the webhook + # - --config= + + resources: {} + # requests: + # cpu: 10m + # memory: 32Mi + + ## Liveness and readiness probe values + ## Ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes + ## + livenessProbe: + failureThreshold: 3 + initialDelaySeconds: 60 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + readinessProbe: + failureThreshold: 3 + initialDelaySeconds: 5 + periodSeconds: 5 + successThreshold: 1 + timeoutSeconds: 1 + + nodeSelector: + kubernetes.io/os: linux + + affinity: {} + + tolerations: [] + + topologySpreadConstraints: [] + + # Optional additional labels to add to the Webhook Pods + podLabels: {} + + # Optional additional labels to add to the Webhook Service + serviceLabels: {} + + image: + repository: quay.io/jetstack/cert-manager-webhook + # You can manage a registry with + # registry: quay.io + # repository: jetstack/cert-manager-webhook + + # Override the image tag to deploy by setting this variable. + # If no value is set, the chart's appVersion will be used. + # tag: canary + + # Setting a digest will override any tag + # digest: sha256:0e072dddd1f7f8fc8909a2ca6f65e76c5f0d2fcfb8be47935ae3457e8bbceb20 + + pullPolicy: IfNotPresent + + serviceAccount: + # Specifies whether a service account should be created + create: true + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + # name: "" + # Optional additional annotations to add to the controller's ServiceAccount + # annotations: {} + # Optional additional labels to add to the webhook's ServiceAccount + # labels: {} + # Automount API credentials for a Service Account. + automountServiceAccountToken: true + + # Automounting API credentials for a particular pod + # automountServiceAccountToken: true + + # The port that the webhook should listen on for requests. + # In GKE private clusters, by default kubernetes apiservers are allowed to + # talk to the cluster nodes only on 443 and 10250. so configuring + # securePort: 10250, will work out of the box without needing to add firewall + # rules or requiring NET_BIND_SERVICE capabilities to bind port numbers <1000 + securePort: 10250 + + # Specifies if the webhook should be started in hostNetwork mode. + # + # Required for use in some managed kubernetes clusters (such as AWS EKS) with custom + # CNI (such as calico), because control-plane managed by AWS cannot communicate + # with pods' IP CIDR and admission webhooks are not working + # + # Since the default port for the webhook conflicts with kubelet on the host + # network, `webhook.securePort` should be changed to an available port if + # running in hostNetwork mode. + hostNetwork: false + + # Specifies how the service should be handled. Useful if you want to expose the + # webhook to outside of the cluster. In some cases, the control plane cannot + # reach internal services. + serviceType: ClusterIP + # loadBalancerIP: + + # Overrides the mutating webhook and validating webhook so they reach the webhook + # service using the `url` field instead of a service. + url: {} + # host: + + # Enables default network policies for webhooks. + networkPolicy: + enabled: false + ingress: + - from: + - ipBlock: + cidr: 0.0.0.0/0 + egress: + - ports: + - port: 80 + protocol: TCP + - port: 443 + protocol: TCP + - port: 53 + protocol: TCP + - port: 53 + protocol: UDP + # On OpenShift and OKD, the Kubernetes API server listens on + # port 6443. + - port: 6443 + protocol: TCP + to: + - ipBlock: + cidr: 0.0.0.0/0 + + volumes: [] + volumeMounts: [] + +cainjector: + enabled: true + replicaCount: 1 + + strategy: {} + # type: RollingUpdate + # rollingUpdate: + # maxSurge: 0 + # maxUnavailable: 1 + + # Pod Security Context to be set on the cainjector component Pod + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + securityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + + podDisruptionBudget: + enabled: false + + minAvailable: 1 + # maxUnavailable: 1 + + # minAvailable and maxUnavailable can either be set to an integer (e.g. 1) + # or a percentage value (e.g. 25%) + + # Container Security Context to be set on the cainjector component container + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + containerSecurityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + + + # Optional additional annotations to add to the cainjector Deployment + # deploymentAnnotations: {} + + # Optional additional annotations to add to the cainjector Pods + # podAnnotations: {} + + # Additional command line flags to pass to cert-manager cainjector binary. + # To see all available flags run docker run quay.io/jetstack/cert-manager-cainjector: --help + extraArgs: [] + # Enable profiling for cainjector + # - --enable-profiling=true + + resources: {} + # requests: + # cpu: 10m + # memory: 32Mi + + nodeSelector: + kubernetes.io/os: linux + + affinity: {} + + tolerations: [] + + topologySpreadConstraints: [] + + # Optional additional labels to add to the CA Injector Pods + podLabels: {} + + image: + repository: quay.io/jetstack/cert-manager-cainjector + # You can manage a registry with + # registry: quay.io + # repository: jetstack/cert-manager-cainjector + + # Override the image tag to deploy by setting this variable. + # If no value is set, the chart's appVersion will be used. + # tag: canary + + # Setting a digest will override any tag + # digest: sha256:0e072dddd1f7f8fc8909a2ca6f65e76c5f0d2fcfb8be47935ae3457e8bbceb20 + + pullPolicy: IfNotPresent + + serviceAccount: + # Specifies whether a service account should be created + create: true + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + # name: "" + # Optional additional annotations to add to the controller's ServiceAccount + # annotations: {} + # Automount API credentials for a Service Account. + # Optional additional labels to add to the cainjector's ServiceAccount + # labels: {} + automountServiceAccountToken: true + + # Automounting API credentials for a particular pod + # automountServiceAccountToken: true + + volumes: [] + volumeMounts: [] + +acmesolver: + image: + repository: quay.io/jetstack/cert-manager-acmesolver + # You can manage a registry with + # registry: quay.io + # repository: jetstack/cert-manager-acmesolver + + # Override the image tag to deploy by setting this variable. + # If no value is set, the chart's appVersion will be used. + # tag: canary + + # Setting a digest will override any tag + # digest: sha256:0e072dddd1f7f8fc8909a2ca6f65e76c5f0d2fcfb8be47935ae3457e8bbceb20 + +# This startupapicheck is a Helm post-install hook that waits for the webhook +# endpoints to become available. +# The check is implemented using a Kubernetes Job- if you are injecting mesh +# sidecar proxies into cert-manager pods, you probably want to ensure that they +# are not injected into this Job's pod. Otherwise the installation may time out +# due to the Job never being completed because the sidecar proxy does not exit. +# See https://github.com/cert-manager/cert-manager/pull/4414 for context. +startupapicheck: + enabled: true + + # Pod Security Context to be set on the startupapicheck component Pod + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + securityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + + # Container Security Context to be set on the controller component container + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + containerSecurityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + + # Timeout for 'kubectl check api' command + timeout: 1m + + # Job backoffLimit + backoffLimit: 4 + + # Optional additional annotations to add to the startupapicheck Job + jobAnnotations: + helm.sh/hook: post-install + helm.sh/hook-weight: "1" + helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded + + # Optional additional annotations to add to the startupapicheck Pods + # podAnnotations: {} + + # Additional command line flags to pass to startupapicheck binary. + # To see all available flags run docker run quay.io/jetstack/cert-manager-ctl: --help + extraArgs: [] + + resources: {} + # requests: + # cpu: 10m + # memory: 32Mi + + nodeSelector: + kubernetes.io/os: linux + + affinity: {} + + tolerations: [] + + # Optional additional labels to add to the startupapicheck Pods + podLabels: {} + + image: + repository: quay.io/jetstack/cert-manager-ctl + # You can manage a registry with + # registry: quay.io + # repository: jetstack/cert-manager-ctl + + # Override the image tag to deploy by setting this variable. + # If no value is set, the chart's appVersion will be used. + # tag: canary + + # Setting a digest will override any tag + # digest: sha256:0e072dddd1f7f8fc8909a2ca6f65e76c5f0d2fcfb8be47935ae3457e8bbceb20 + + pullPolicy: IfNotPresent + + rbac: + # annotations for the startup API Check job RBAC and PSP resources + annotations: + helm.sh/hook: post-install + helm.sh/hook-weight: "-5" + helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded + + # Automounting API credentials for a particular pod + # automountServiceAccountToken: true + + serviceAccount: + # Specifies whether a service account should be created + create: true + + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + # name: "" + + # Optional additional annotations to add to the Job's ServiceAccount + annotations: + helm.sh/hook: post-install + helm.sh/hook-weight: "-5" + helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded + + # Automount API credentials for a Service Account. + automountServiceAccountToken: true + + # Optional additional labels to add to the startupapicheck's ServiceAccount + # labels: {} + + volumes: [] + volumeMounts: [] diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/crds/redis-cluster.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/crds/redis-cluster.yaml new file mode 100644 index 000000000..d6b10f5c5 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/crds/redis-cluster.yaml @@ -0,0 +1,13686 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.1 + creationTimestamp: null + name: redisclusters.redis.redis.opstreelabs.in +spec: + group: redis.redis.opstreelabs.in + names: + kind: RedisCluster + listKind: RedisClusterList + plural: redisclusters + singular: rediscluster + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Current cluster node count + jsonPath: .spec.clusterSize + name: ClusterSize + type: integer + - description: Overridden Leader replica count + jsonPath: .spec.redisLeader.CommonAttributes.Replicas + name: LeaderReplicas + type: integer + - description: Overridden Follower replica count + jsonPath: .spec.redisFollower.CommonAttributes.Replicas + name: FollowerReplicas + type: integer + - description: Age of Cluster + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: RedisCluster is the Schema for the redisclusters API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: RedisClusterSpec defines the desired state of RedisCluster + properties: + TLS: + description: TLS Configuration for redis instances + properties: + ca: + type: string + cert: + type: string + key: + type: string + secret: + description: Reference to secret which contains the certificates + properties: + defaultMode: + description: 'defaultMode is Optional: mode bits used to set + permissions on created files by default. Must be an octal + value between 0000 and 0777 or a decimal value between 0 + and 511. YAML accepts both octal and decimal values, JSON + requires decimal values for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect + the file mode, like fsGroup, and the result can be other + mode bits set.' + format: int32 + type: integer + items: + description: items If unspecified, each key-value pair in + the Data field of the referenced Secret will be projected + into the volume as a file whose name is the key and content + is the value. If specified, the listed keys will be projected + into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the + Secret, the volume setup will error unless it is marked + optional. Paths must be relative and may not contain the + '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used to set + permissions on this file. Must be an octal value between + 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires + decimal values for mode bits. If not specified, the + volume defaultMode will be used. This might be in + conflict with other options that affect the file mode, + like fsGroup, and the result can be other mode bits + set.' + format: int32 + type: integer + path: + description: path is the relative path of the file to + map the key to. May not be an absolute path. May not + contain the path element '..'. May not start with + the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the Secret or + its keys must be defined + type: boolean + secretName: + description: 'secretName is the name of the secret in the + pod''s namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + type: string + type: object + required: + - secret + type: object + clusterSize: + format: int32 + type: integer + clusterVersion: + default: v7 + type: string + kubernetesConfig: + description: KubernetesConfig will be the JSON struct for Basic Redis + Config + properties: + ignoreAnnotations: + items: + type: string + type: array + image: + type: string + imagePullPolicy: + description: PullPolicy describes a policy for if/when to pull + a container image + type: string + imagePullSecrets: + items: + description: LocalObjectReference contains enough information + to let you locate the referenced object inside the same namespace. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + type: array + redisSecret: + description: ExistingPasswordSecret is the struct to access the + existing secret + properties: + key: + type: string + name: + type: string + type: object + resources: + description: ResourceRequirements describes the compute resource + requirements. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + service: + description: ServiceConfig define the type of service to be created + and its annotations + properties: + annotations: + additionalProperties: + type: string + type: object + serviceType: + enum: + - LoadBalancer + - NodePort + - ClusterIP + type: string + type: object + updateStrategy: + description: StatefulSetUpdateStrategy indicates the strategy + that the StatefulSet controller will use to perform updates. + It includes any additional parameters necessary to perform the + update for the indicated strategy. + properties: + rollingUpdate: + description: RollingUpdate is used to communicate parameters + when Type is RollingUpdateStatefulSetStrategyType. + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + description: 'The maximum number of pods that can be unavailable + during the update. Value can be an absolute number (ex: + 5) or a percentage of desired pods (ex: 10%). Absolute + number is calculated from percentage by rounding up. + This can not be 0. Defaults to 1. This field is alpha-level + and is only honored by servers that enable the MaxUnavailableStatefulSet + feature. The field applies to all pods in the range + 0 to Replicas-1. That means if there is any unavailable + pod in the range 0 to Replicas-1, it will be counted + towards MaxUnavailable.' + x-kubernetes-int-or-string: true + partition: + description: Partition indicates the ordinal at which + the StatefulSet should be partitioned for updates. During + a rolling update, all pods from ordinal Replicas-1 to + Partition are updated. All pods from ordinal Partition-1 + to 0 remain untouched. This is helpful in being able + to do a canary based deployment. The default value is + 0. + format: int32 + type: integer + type: object + type: + description: Type indicates the type of the StatefulSetUpdateStrategy. + Default is RollingUpdate. + type: string + type: object + required: + - image + type: object + persistenceEnabled: + type: boolean + priorityClassName: + type: string + redisExporter: + description: RedisExporter interface will have the information for + redis exporter related stuff + properties: + enabled: + type: boolean + env: + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + image: + type: string + imagePullPolicy: + description: PullPolicy describes a policy for if/when to pull + a container image + type: string + port: + default: 9121 + type: integer + resources: + description: ResourceRequirements describes the compute resource + requirements. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: SecurityContext holds security configuration that + will be applied to a container. Some fields are present in both + SecurityContext and PodSecurityContext. When both are set, + the values in SecurityContext take precedence. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a + process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the + container runtime. Note that this field cannot be set when + spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in + privileged containers are essentially equivalent to root + on the host. Defaults to false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use + for the containers. The default is DefaultProcMount which + uses the container runtime defaults for readonly paths and + masked paths. This requires the ProcMountType feature flag + to be enabled. Note that this field cannot be set when spec.os.name + is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when + spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail + to start the container if it does. If unset or false, no + such validation will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata if + unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. Note + that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must + be preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must be set if type is "Localhost". Must NOT + be set for any other type. + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a + profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile + should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also be + set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + required: + - image + type: object + redisFollower: + description: RedisFollower interface will have the redis follower + configuration + properties: + affinity: + description: Affinity is a group of affinity scheduling rules. + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for + the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node matches the corresponding matchExpressions; + the node(s) with the highest sum are the most preferred. + items: + description: An empty preferred scheduling term matches + all objects with implicit weight 0 (i.e. it's a no-op). + A null preferred scheduling term matches no objects + (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated with + the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + description: Weight associated with matching the + corresponding nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the affinity requirements + specified by this field cease to be met at some point + during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from + its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: A null or empty node selector term + matches no objects. The requirements of them are + ANDed. The TopologySelectorTerm type implements + a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. + co-locate this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum are + the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod + label keys to select which pods will be taken + into consideration. The keys are used to lookup + values from the incoming pod labels, those + key-value labels are merged with `LabelSelector` + as `key in (value)` to select the group of + existing pods which pods will be taken into + consideration for the incoming pod's pod (anti) + affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value + is empty. The same key is forbidden to exist + in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature + gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod + label keys to select which pods will be taken + into consideration. The keys are used to lookup + values from the incoming pod labels, those + key-value labels are merged with `LabelSelector` + as `key notin (value)` to select the group + of existing pods which pods will be taken + into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist + in the incoming pod labels will be ignored. + The default value is empty. The same key is + forbidden to exist in both MismatchLabelKeys + and LabelSelector. Also, MismatchLabelKeys + cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling + MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by + this field and the ones listed in the namespaces + field. null selector and null or empty namespaces + list means "this pod's namespace". An empty + selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. + The term is applied to the union of the namespaces + listed in this field and the ones selected + by namespaceSelector. null or empty namespaces + list and null namespaceSelector means "this + pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the + corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the affinity requirements + specified by this field cease to be met at some point + during pod execution (e.g. due to a pod label update), + the system may or may not try to eventually evict the + pod from its node. When there are multiple elements, + the lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not + co-located (anti-affinity) with, where co-located + is defined as running on a node whose value of the + label with key matches that of any node + on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key in (value)` to select + the group of existing pods which pods will be + taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MatchLabelKeys and LabelSelector. Also, + MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key notin (value)` to + select the group of existing pods which pods will + be taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MismatchLabelKeys and LabelSelector. Also, + MismatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules + (e.g. avoid putting this pod in the same node, zone, etc. + as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the anti-affinity expressions + specified by this field, but it may choose a node that + violates one or more of the expressions. The node that + is most preferred is the one with the greatest sum of + weights, i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + anti-affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum are + the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod + label keys to select which pods will be taken + into consideration. The keys are used to lookup + values from the incoming pod labels, those + key-value labels are merged with `LabelSelector` + as `key in (value)` to select the group of + existing pods which pods will be taken into + consideration for the incoming pod's pod (anti) + affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value + is empty. The same key is forbidden to exist + in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature + gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod + label keys to select which pods will be taken + into consideration. The keys are used to lookup + values from the incoming pod labels, those + key-value labels are merged with `LabelSelector` + as `key notin (value)` to select the group + of existing pods which pods will be taken + into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist + in the incoming pod labels will be ignored. + The default value is empty. The same key is + forbidden to exist in both MismatchLabelKeys + and LabelSelector. Also, MismatchLabelKeys + cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling + MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by + this field and the ones listed in the namespaces + field. null selector and null or empty namespaces + list means "this pod's namespace". An empty + selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. + The term is applied to the union of the namespaces + listed in this field and the ones selected + by namespaceSelector. null or empty namespaces + list and null namespaceSelector means "this + pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the + corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified + by this field are not met at scheduling time, the pod + will not be scheduled onto the node. If the anti-affinity + requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod + label update), the system may or may not try to eventually + evict the pod from its node. When there are multiple + elements, the lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not + co-located (anti-affinity) with, where co-located + is defined as running on a node whose value of the + label with key matches that of any node + on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key in (value)` to select + the group of existing pods which pods will be + taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MatchLabelKeys and LabelSelector. Also, + MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key notin (value)` to + select the group of existing pods which pods will + be taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MismatchLabelKeys and LabelSelector. Also, + MismatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + livenessProbe: + description: Probe describes a health check to be performed against + a container to determine whether it is alive or ready to receive + traffic. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside + the container, the working directory for the command is + root ('/') in the container's filesystem. The command + is simply exec'd, it is not run inside a shell, so traditional + shell instructions ('|', etc) won't work. To use a shell, + you need to explicitly call out to that shell. Exit + status of 0 is treated as live/healthy and non-zero + is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to + be considered failed after having succeeded. Defaults to + 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. + properties: + port: + description: Port number of the gRPC service. Number must + be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place + in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior is + defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the + pod IP. You probably want to set "Host" in httpHeaders + instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP + allows repeated headers. + items: + description: HTTPHeader describes a custom header to + be used in HTTP probes + properties: + name: + description: The header field name. This will be + canonicalized upon output, so case-variant names + will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the + container. Number must be in the range 1 to 65535. Name + must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started + before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to + be considered successful after having failed. Defaults to + 1. Must be 1 for liveness and startup. Minimum value is + 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP + port. + properties: + host: + description: 'Optional: Host name to connect to, defaults + to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the + container. Number must be in the range 1 to 65535. Name + must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to + terminate gracefully upon probe failure. The grace period + is the duration in seconds after the processes running in + the pod are sent a termination signal and the time when + the processes are forcibly halted with a kill signal. Set + this value longer than the expected cleanup time for your + process. If this value is nil, the pod's terminationGracePeriodSeconds + will be used. Otherwise, this value overrides the value + provided by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the kill signal + (no opportunity to shut down). This is a beta field and + requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is + used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times + out. Defaults to 1 second. Minimum value is 1. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + nodeSelector: + additionalProperties: + type: string + type: object + pdb: + description: RedisPodDisruptionBudget configure a PodDisruptionBudget + on the resource (leader/follower) + properties: + enabled: + type: boolean + maxUnavailable: + format: int32 + type: integer + minAvailable: + format: int32 + type: integer + type: object + readinessProbe: + description: Probe describes a health check to be performed against + a container to determine whether it is alive or ready to receive + traffic. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside + the container, the working directory for the command is + root ('/') in the container's filesystem. The command + is simply exec'd, it is not run inside a shell, so traditional + shell instructions ('|', etc) won't work. To use a shell, + you need to explicitly call out to that shell. Exit + status of 0 is treated as live/healthy and non-zero + is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to + be considered failed after having succeeded. Defaults to + 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. + properties: + port: + description: Port number of the gRPC service. Number must + be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place + in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior is + defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the + pod IP. You probably want to set "Host" in httpHeaders + instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP + allows repeated headers. + items: + description: HTTPHeader describes a custom header to + be used in HTTP probes + properties: + name: + description: The header field name. This will be + canonicalized upon output, so case-variant names + will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the + container. Number must be in the range 1 to 65535. Name + must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started + before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to + be considered successful after having failed. Defaults to + 1. Must be 1 for liveness and startup. Minimum value is + 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP + port. + properties: + host: + description: 'Optional: Host name to connect to, defaults + to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the + container. Number must be in the range 1 to 65535. Name + must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to + terminate gracefully upon probe failure. The grace period + is the duration in seconds after the processes running in + the pod are sent a termination signal and the time when + the processes are forcibly halted with a kill signal. Set + this value longer than the expected cleanup time for your + process. If this value is nil, the pod's terminationGracePeriodSeconds + will be used. Otherwise, this value overrides the value + provided by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the kill signal + (no opportunity to shut down). This is a beta field and + requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is + used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times + out. Defaults to 1 second. Minimum value is 1. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + redisConfig: + description: RedisConfig defines the external configuration of + Redis + properties: + additionalRedisConfig: + type: string + type: object + replicas: + format: int32 + type: integer + tolerations: + items: + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using + the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. + Empty means match all taint effects. When specified, allowed + values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match + all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to + the value. Valid operators are Exists and Equal. Defaults + to Equal. Exists is equivalent to wildcard for value, + so that a pod can tolerate all taints of a particular + category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of + time the toleration (which must be of effect NoExecute, + otherwise this field is ignored) tolerates the taint. + By default, it is not set, which means tolerate the taint + forever (do not evict). Zero and negative values will + be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + type: object + redisLeader: + description: RedisLeader interface will have the redis leader configuration + properties: + affinity: + description: Affinity is a group of affinity scheduling rules. + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for + the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node matches the corresponding matchExpressions; + the node(s) with the highest sum are the most preferred. + items: + description: An empty preferred scheduling term matches + all objects with implicit weight 0 (i.e. it's a no-op). + A null preferred scheduling term matches no objects + (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated with + the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + description: Weight associated with matching the + corresponding nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the affinity requirements + specified by this field cease to be met at some point + during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from + its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: A null or empty node selector term + matches no objects. The requirements of them are + ANDed. The TopologySelectorTerm type implements + a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. + co-locate this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum are + the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod + label keys to select which pods will be taken + into consideration. The keys are used to lookup + values from the incoming pod labels, those + key-value labels are merged with `LabelSelector` + as `key in (value)` to select the group of + existing pods which pods will be taken into + consideration for the incoming pod's pod (anti) + affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value + is empty. The same key is forbidden to exist + in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature + gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod + label keys to select which pods will be taken + into consideration. The keys are used to lookup + values from the incoming pod labels, those + key-value labels are merged with `LabelSelector` + as `key notin (value)` to select the group + of existing pods which pods will be taken + into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist + in the incoming pod labels will be ignored. + The default value is empty. The same key is + forbidden to exist in both MismatchLabelKeys + and LabelSelector. Also, MismatchLabelKeys + cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling + MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by + this field and the ones listed in the namespaces + field. null selector and null or empty namespaces + list means "this pod's namespace". An empty + selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. + The term is applied to the union of the namespaces + listed in this field and the ones selected + by namespaceSelector. null or empty namespaces + list and null namespaceSelector means "this + pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the + corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the affinity requirements + specified by this field cease to be met at some point + during pod execution (e.g. due to a pod label update), + the system may or may not try to eventually evict the + pod from its node. When there are multiple elements, + the lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not + co-located (anti-affinity) with, where co-located + is defined as running on a node whose value of the + label with key matches that of any node + on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key in (value)` to select + the group of existing pods which pods will be + taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MatchLabelKeys and LabelSelector. Also, + MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key notin (value)` to + select the group of existing pods which pods will + be taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MismatchLabelKeys and LabelSelector. Also, + MismatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules + (e.g. avoid putting this pod in the same node, zone, etc. + as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the anti-affinity expressions + specified by this field, but it may choose a node that + violates one or more of the expressions. The node that + is most preferred is the one with the greatest sum of + weights, i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + anti-affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum are + the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod + label keys to select which pods will be taken + into consideration. The keys are used to lookup + values from the incoming pod labels, those + key-value labels are merged with `LabelSelector` + as `key in (value)` to select the group of + existing pods which pods will be taken into + consideration for the incoming pod's pod (anti) + affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value + is empty. The same key is forbidden to exist + in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature + gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod + label keys to select which pods will be taken + into consideration. The keys are used to lookup + values from the incoming pod labels, those + key-value labels are merged with `LabelSelector` + as `key notin (value)` to select the group + of existing pods which pods will be taken + into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist + in the incoming pod labels will be ignored. + The default value is empty. The same key is + forbidden to exist in both MismatchLabelKeys + and LabelSelector. Also, MismatchLabelKeys + cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling + MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by + this field and the ones listed in the namespaces + field. null selector and null or empty namespaces + list means "this pod's namespace". An empty + selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. + The term is applied to the union of the namespaces + listed in this field and the ones selected + by namespaceSelector. null or empty namespaces + list and null namespaceSelector means "this + pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the + corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified + by this field are not met at scheduling time, the pod + will not be scheduled onto the node. If the anti-affinity + requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod + label update), the system may or may not try to eventually + evict the pod from its node. When there are multiple + elements, the lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not + co-located (anti-affinity) with, where co-located + is defined as running on a node whose value of the + label with key matches that of any node + on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key in (value)` to select + the group of existing pods which pods will be + taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MatchLabelKeys and LabelSelector. Also, + MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key notin (value)` to + select the group of existing pods which pods will + be taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MismatchLabelKeys and LabelSelector. Also, + MismatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + livenessProbe: + description: Probe describes a health check to be performed against + a container to determine whether it is alive or ready to receive + traffic. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside + the container, the working directory for the command is + root ('/') in the container's filesystem. The command + is simply exec'd, it is not run inside a shell, so traditional + shell instructions ('|', etc) won't work. To use a shell, + you need to explicitly call out to that shell. Exit + status of 0 is treated as live/healthy and non-zero + is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to + be considered failed after having succeeded. Defaults to + 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. + properties: + port: + description: Port number of the gRPC service. Number must + be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place + in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior is + defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the + pod IP. You probably want to set "Host" in httpHeaders + instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP + allows repeated headers. + items: + description: HTTPHeader describes a custom header to + be used in HTTP probes + properties: + name: + description: The header field name. This will be + canonicalized upon output, so case-variant names + will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the + container. Number must be in the range 1 to 65535. Name + must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started + before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to + be considered successful after having failed. Defaults to + 1. Must be 1 for liveness and startup. Minimum value is + 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP + port. + properties: + host: + description: 'Optional: Host name to connect to, defaults + to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the + container. Number must be in the range 1 to 65535. Name + must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to + terminate gracefully upon probe failure. The grace period + is the duration in seconds after the processes running in + the pod are sent a termination signal and the time when + the processes are forcibly halted with a kill signal. Set + this value longer than the expected cleanup time for your + process. If this value is nil, the pod's terminationGracePeriodSeconds + will be used. Otherwise, this value overrides the value + provided by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the kill signal + (no opportunity to shut down). This is a beta field and + requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is + used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times + out. Defaults to 1 second. Minimum value is 1. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + nodeSelector: + additionalProperties: + type: string + type: object + pdb: + description: RedisPodDisruptionBudget configure a PodDisruptionBudget + on the resource (leader/follower) + properties: + enabled: + type: boolean + maxUnavailable: + format: int32 + type: integer + minAvailable: + format: int32 + type: integer + type: object + readinessProbe: + description: Probe describes a health check to be performed against + a container to determine whether it is alive or ready to receive + traffic. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside + the container, the working directory for the command is + root ('/') in the container's filesystem. The command + is simply exec'd, it is not run inside a shell, so traditional + shell instructions ('|', etc) won't work. To use a shell, + you need to explicitly call out to that shell. Exit + status of 0 is treated as live/healthy and non-zero + is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to + be considered failed after having succeeded. Defaults to + 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. + properties: + port: + description: Port number of the gRPC service. Number must + be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place + in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior is + defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the + pod IP. You probably want to set "Host" in httpHeaders + instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP + allows repeated headers. + items: + description: HTTPHeader describes a custom header to + be used in HTTP probes + properties: + name: + description: The header field name. This will be + canonicalized upon output, so case-variant names + will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the + container. Number must be in the range 1 to 65535. Name + must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started + before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to + be considered successful after having failed. Defaults to + 1. Must be 1 for liveness and startup. Minimum value is + 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP + port. + properties: + host: + description: 'Optional: Host name to connect to, defaults + to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the + container. Number must be in the range 1 to 65535. Name + must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to + terminate gracefully upon probe failure. The grace period + is the duration in seconds after the processes running in + the pod are sent a termination signal and the time when + the processes are forcibly halted with a kill signal. Set + this value longer than the expected cleanup time for your + process. If this value is nil, the pod's terminationGracePeriodSeconds + will be used. Otherwise, this value overrides the value + provided by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the kill signal + (no opportunity to shut down). This is a beta field and + requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is + used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times + out. Defaults to 1 second. Minimum value is 1. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + redisConfig: + description: RedisConfig defines the external configuration of + Redis + properties: + additionalRedisConfig: + type: string + type: object + replicas: + format: int32 + type: integer + tolerations: + items: + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using + the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. + Empty means match all taint effects. When specified, allowed + values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match + all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to + the value. Valid operators are Exists and Equal. Defaults + to Equal. Exists is equivalent to wildcard for value, + so that a pod can tolerate all taints of a particular + category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of + time the toleration (which must be of effect NoExecute, + otherwise this field is ignored) tolerates the taint. + By default, it is not set, which means tolerate the taint + forever (do not evict). Zero and negative values will + be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + type: object + resources: + description: ResourceRequirements describes the compute resource requirements. + properties: + claims: + description: "Claims lists the names of resources, defined in + spec.resourceClaims, that are used by this container. \n This + is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be set + for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims + of the Pod where this field is used. It makes that resource + available inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources + allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: PodSecurityContext holds pod-level security attributes + and common container settings. Some fields are also present in container.securityContext. Field + values of container.securityContext take precedence over field values + of PodSecurityContext. + properties: + fsGroup: + description: "A special supplemental group that applies to all + containers in a pod. Some volume types allow the Kubelet to + change the ownership of that volume to be owned by the pod: + \n 1. The owning GID will be the FSGroup 2. The setgid bit is + set (new files created in the volume will be owned by FSGroup) + 3. The permission bits are OR'd with rw-rw---- \n If unset, + the Kubelet will not modify the ownership and permissions of + any volume. Note that this field cannot be set when spec.os.name + is windows." + format: int64 + type: integer + fsGroupChangePolicy: + description: 'fsGroupChangePolicy defines behavior of changing + ownership and permission of the volume before being exposed + inside Pod. This field will only apply to volume types which + support fsGroup based ownership(and permissions). It will have + no effect on ephemeral volume types such as: secret, configmaps + and emptydir. Valid values are "OnRootMismatch" and "Always". + If not specified, "Always" is used. Note that this field cannot + be set when spec.os.name is windows.' + type: string + runAsGroup: + description: The GID to run the entrypoint of the container process. + Uses runtime default if unset. May also be set in SecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail to start + the container if it does. If unset or false, no such validation + will be performed. May also be set in SecurityContext. If set + in both SecurityContext and PodSecurityContext, the value specified + in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in SecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. Note that this field cannot + be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in SecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to + the container. + type: string + role: + description: Role is a SELinux role label that applies to + the container. + type: string + type: + description: Type is a SELinux type label that applies to + the container. + type: string + user: + description: User is a SELinux user label that applies to + the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by the containers in this + pod. Note that this field cannot be set when spec.os.name is + windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must be + preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must be set if type is "Localhost". Must NOT be + set for any other type. + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a profile + defined in a file on the node should be used. RuntimeDefault + - the container runtime default profile should be used. + Unconfined - no profile should be applied." + type: string + required: + - type + type: object + supplementalGroups: + description: A list of groups applied to the first process run + in each container, in addition to the container's primary GID, + the fsGroup (if specified), and group memberships defined in + the container image for the uid of the container process. If + unspecified, no additional groups are added to any container. + Note that group memberships defined in the container image for + the uid of the container process are still effective, even if + they are not included in this list. Note that this field cannot + be set when spec.os.name is windows. + items: + format: int64 + type: integer + type: array + sysctls: + description: Sysctls hold a list of namespaced sysctls used for + the pod. Pods with unsupported sysctls (by the container runtime) + might fail to launch. Note that this field cannot be set when + spec.os.name is windows. + items: + description: Sysctl defines a kernel parameter to be set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + description: The Windows specific settings applied to all containers. + If unspecified, the options within a container's SecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named by + the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA + credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. All of a Pod's containers + must have the same effective HostProcess value (it is not + allowed to have a mix of HostProcess containers and non-HostProcess + containers). In addition, if HostProcess is true then HostNetwork + must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in PodSecurityContext. + If set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: string + type: object + type: object + serviceAccountName: + type: string + sidecars: + items: + description: Sidecar for each Redis pods + properties: + env: + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be + a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. + If a variable cannot be resolved, the reference in the + input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) + syntax: i.e. "$$(VAR_NAME)" will produce the string + literal "$(VAR_NAME)". Escaped references will never + be expanded, regardless of whether the variable exists + or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its + key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + image: + type: string + imagePullPolicy: + description: PullPolicy describes a policy for if/when to pull + a container image + type: string + name: + type: string + resources: + description: ResourceRequirements describes the compute resource + requirements. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only + be set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where this + field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests + cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + required: + - image + - name + type: object + type: array + storage: + description: Storage is the inteface to add pvc and pv support in + redis + properties: + keepAfterDelete: + type: boolean + volumeClaimTemplate: + description: PersistentVolumeClaim is a user's request for and + claim to a persistent volume + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this + representation of an object. Servers should convert recognized + schemas to the latest internal value, and may reject unrecognized + values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST + resource this object represents. Servers may infer this + from the endpoint the client submits requests to. Cannot + be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + description: 'Standard object''s metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata' + type: object + spec: + description: 'spec defines the desired characteristics of + a volume requested by a pod author. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + accessModes: + description: 'accessModes contains the desired access + modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'dataSource field can be used to specify + either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) If the provisioner + or an external controller can support the specified + data source, it will create a new volume based on the + contents of the specified data source. When the AnyVolumeDataSource + feature gate is enabled, dataSource contents will be + copied to dataSourceRef, and dataSourceRef contents + will be copied to dataSource when dataSourceRef.namespace + is not specified. If the namespace is specified, then + dataSourceRef will not be copied to dataSource.' + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + dataSourceRef: + description: 'dataSourceRef specifies the object from + which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty + API group (non core object) or a PersistentVolumeClaim + object. When this field is specified, volume binding + will only succeed if the type of the specified object + matches some installed volume populator or dynamic provisioner. + This field will replace the functionality of the dataSource + field and as such if both fields are non-empty, they + must have the same value. For backwards compatibility, + when namespace isn''t specified in dataSourceRef, both + fields (dataSource and dataSourceRef) will be set to + the same value automatically if one of them is empty + and the other is non-empty. When namespace is specified + in dataSourceRef, dataSource isn''t set to the same + value and must be empty. There are three important differences + between dataSource and dataSourceRef: * While dataSource + only allows two specific types of objects, dataSourceRef allows + any non-core object, as well as PersistentVolumeClaim + objects. * While dataSource ignores disallowed values + (dropping them), dataSourceRef preserves all values, + and generates an error if a disallowed value is specified. + * While dataSource only allows local objects, dataSourceRef + allows objects in any namespaces. (Beta) Using this + field requires the AnyVolumeDataSource feature gate + to be enabled. (Alpha) Using the namespace field of + dataSourceRef requires the CrossNamespaceVolumeDataSource + feature gate to be enabled.' + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + namespace: + description: Namespace is the namespace of resource + being referenced Note that when a namespace is specified, + a gateway.networking.k8s.io/ReferenceGrant object + is required in the referent namespace to allow that + namespace's owner to accept the reference. See the + ReferenceGrant documentation for details. (Alpha) + This field requires the CrossNamespaceVolumeDataSource + feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: 'resources represents the minimum resources + the volume should have. If RecoverVolumeExpansionFailure + feature is enabled users are allowed to specify resource + requirements that are lower than previous value but + must still be higher than capacity recorded in the status + field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount + of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount + of compute resources required. If Requests is omitted + for a container, it defaults to Limits if that is + explicitly specified, otherwise to an implementation-defined + value. Requests cannot exceed Limits. More info: + https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + selector: + description: selector is a label query over volumes to + consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, + NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values + array must be non-empty. If the operator is + Exists or DoesNotExist, the values array must + be empty. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field + is "key", the operator is "In", and the values array + contains only "value". The requirements are ANDed. + type: object + type: object + storageClassName: + description: 'storageClassName is the name of the StorageClass + required by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + type: string + volumeAttributesClassName: + description: 'volumeAttributesClassName may be used to + set the VolumeAttributesClass used by this claim. If + specified, the CSI driver will create or update the + volume with the attributes defined in the corresponding + VolumeAttributesClass. This has a different purpose + than storageClassName, it can be changed after the claim + is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it''s not allowed to + reset this field to empty string once it is set. If + unspecified and the PersistentVolumeClaim is unbound, + the default VolumeAttributesClass will be set by the + persistentvolume controller if it exists. If the resource + referred to by volumeAttributesClass does not exist, + this PersistentVolumeClaim will be set to a Pending + state, as reflected by the modifyVolumeStatus field, + until such as a resource exists. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + (Alpha) Using this field requires the VolumeAttributesClass + feature gate to be enabled.' + type: string + volumeMode: + description: volumeMode defines what type of volume is + required by the claim. Value of Filesystem is implied + when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to the + PersistentVolume backing this claim. + type: string + type: object + status: + description: 'status represents the current information/status + of a persistent volume claim. Read-only. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + accessModes: + description: 'accessModes contains the actual access modes + the volume backing the PVC has. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + allocatedResourceStatuses: + additionalProperties: + description: When a controller receives persistentvolume + claim update with ClaimResourceStatus for a resource + that it does not recognizes, then it should ignore + that update and let other controllers handle it. + type: string + description: "allocatedResourceStatuses stores status + of resource being resized for the given PVC. Key names + follow standard Kubernetes label syntax. Valid values + are either: \t* Un-prefixed keys: \t\t- storage - the + capacity of the volume. \t* Custom resources must use + implementation-defined prefixed names such as \"example.com/my-custom-resource\" + Apart from above values - keys that are unprefixed or + have kubernetes.io prefix are considered reserved and + hence may not be used. \n ClaimResourceStatus can be + in any of following states: \t- ControllerResizeInProgress: + \t\tState set when resize controller starts resizing + the volume in control-plane. \t- ControllerResizeFailed: + \t\tState set when resize has failed in resize controller + with a terminal error. \t- NodeResizePending: \t\tState + set when resize controller has finished resizing the + volume but further resizing of \t\tvolume is needed + on the node. \t- NodeResizeInProgress: \t\tState set + when kubelet starts resizing the volume. \t- NodeResizeFailed: + \t\tState set when resizing has failed in kubelet with + a terminal error. Transient errors don't set \t\tNodeResizeFailed. + For example: if expanding a PVC for more capacity - + this field can be one of the following states: \t- pvc.status.allocatedResourceStatus['storage'] + = \"ControllerResizeInProgress\" - pvc.status.allocatedResourceStatus['storage'] + = \"ControllerResizeFailed\" - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizePending\" - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizeInProgress\" - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizeFailed\" When this field is not set, it + means that no resize operation is in progress for the + given PVC. \n A controller that receives PVC update + with previously unknown resourceName or ClaimResourceStatus + should ignore the update for the purpose it was designed. + For example - a controller that only is responsible + for resizing capacity of the volume, should ignore PVC + updates that change other valid resources associated + with PVC. \n This is an alpha field and requires enabling + RecoverVolumeExpansionFailure feature." + type: object + x-kubernetes-map-type: granular + allocatedResources: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: "allocatedResources tracks the resources + allocated to a PVC including its capacity. Key names + follow standard Kubernetes label syntax. Valid values + are either: \t* Un-prefixed keys: \t\t- storage - the + capacity of the volume. \t* Custom resources must use + implementation-defined prefixed names such as \"example.com/my-custom-resource\" + Apart from above values - keys that are unprefixed or + have kubernetes.io prefix are considered reserved and + hence may not be used. \n Capacity reported here may + be larger than the actual capacity when a volume expansion + operation is requested. For storage quota, the larger + value from allocatedResources and PVC.spec.resources + is used. If allocatedResources is not set, PVC.spec.resources + alone is used for quota calculation. If a volume expansion + capacity request is lowered, allocatedResources is only + lowered if there are no expansion operations in progress + and if the actual volume capacity is equal or lower + than the requested capacity. \n A controller that receives + PVC update with previously unknown resourceName should + ignore the update for the purpose it was designed. For + example - a controller that only is responsible for + resizing capacity of the volume, should ignore PVC updates + that change other valid resources associated with PVC. + \n This is an alpha field and requires enabling RecoverVolumeExpansionFailure + feature." + type: object + capacity: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: capacity represents the actual resources + of the underlying volume. + type: object + conditions: + description: conditions is the current Condition of persistent + volume claim. If underlying persistent volume is being + resized then the Condition will be set to 'ResizeStarted'. + items: + description: PersistentVolumeClaimCondition contains + details about state of pvc + properties: + lastProbeTime: + description: lastProbeTime is the time we probed + the condition. + format: date-time + type: string + lastTransitionTime: + description: lastTransitionTime is the time the + condition transitioned from one status to another. + format: date-time + type: string + message: + description: message is the human-readable message + indicating details about last transition. + type: string + reason: + description: reason is a unique, this should be + a short, machine understandable string that gives + the reason for condition's last transition. If + it reports "ResizeStarted" that means the underlying + persistent volume is being resized. + type: string + status: + type: string + type: + description: PersistentVolumeClaimConditionType + is a valid value of PersistentVolumeClaimCondition.Type + type: string + required: + - status + - type + type: object + type: array + currentVolumeAttributesClassName: + description: currentVolumeAttributesClassName is the current + name of the VolumeAttributesClass the PVC is using. + When unset, there is no VolumeAttributeClass applied + to this PersistentVolumeClaim This is an alpha field + and requires enabling VolumeAttributesClass feature. + type: string + modifyVolumeStatus: + description: ModifyVolumeStatus represents the status + object of ControllerModifyVolume operation. When this + is unset, there is no ModifyVolume operation being attempted. + This is an alpha field and requires enabling VolumeAttributesClass + feature. + properties: + status: + description: "status is the status of the ControllerModifyVolume + operation. It can be in any of following states: + \ - Pending Pending indicates that the PersistentVolumeClaim + cannot be modified due to unmet requirements, such + as the specified VolumeAttributesClass not existing. + \ - InProgress InProgress indicates that the + volume is being modified. - Infeasible Infeasible + indicates that the request has been rejected as + invalid by the CSI driver. To \t resolve the error, + a valid VolumeAttributesClass needs to be specified. + Note: New statuses can be added in the future. Consumers + should check for unknown statuses and fail appropriately." + type: string + targetVolumeAttributesClassName: + description: targetVolumeAttributesClassName is the + name of the VolumeAttributesClass the PVC currently + being reconciled + type: string + required: + - status + type: object + phase: + description: phase represents the current phase of PersistentVolumeClaim. + type: string + type: object + type: object + volumeMount: + description: Additional Volume is provided by user that is mounted + on the pods + properties: + mountPath: + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: Path within the container at which the + volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts + are propagated from the host to container and the + other way around. When not set, MountPropagationNone + is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise + (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's + volume should be mounted. Defaults to "" (volume's + root). + type: string + subPathExpr: + description: Expanded path within the volume from which + the container's volume should be mounted. Behaves + similarly to SubPath but environment variable references + $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). SubPathExpr and SubPath + are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + volume: + items: + description: Volume represents a named volume in a pod that + may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: 'awsElasticBlockStore represents an AWS + Disk resource that is attached to a kubelet''s host + machine and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + properties: + fsType: + description: 'fsType is the filesystem type of the + volume that you want to mount. Tip: Ensure that + the filesystem type is supported by the host operating + system. Examples: "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. More info: + https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem + from compromising the machine' + type: string + partition: + description: 'partition is the partition in the + volume that you want to mount. If omitted, the + default is to mount by volume name. Examples: + For volume /dev/sda1, you specify the partition + as "1". Similarly, the volume partition for /dev/sda + is "0" (or you can leave the property empty).' + format: int32 + type: integer + readOnly: + description: 'readOnly value true will force the + readOnly setting in VolumeMounts. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: boolean + volumeID: + description: 'volumeID is unique ID of the persistent + disk resource in AWS (Amazon EBS volume). More + info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data Disk + mount on the host and bind mount to the pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching mode: + None, Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data disk + in the blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in + the blob storage + type: string + fsType: + description: fsType is Filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: multiple + blob disks per storage account Dedicated: single + blob disk per storage account Managed: azure + managed data disk (only in managed availability + set). defaults to shared' + type: string + readOnly: + description: readOnly Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File Service + mount on the host and bind mount to the pod. + properties: + readOnly: + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret that + contains Azure Storage Account Name and Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount on the + host that shares a pod's lifetime + properties: + monitors: + description: 'monitors is Required: Monitors is + a collection of Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + items: + type: string + type: array + path: + description: 'path is Optional: Used as the mounted + root, rather than the full Ceph tree, default + is /' + type: string + readOnly: + description: 'readOnly is Optional: Defaults to + false (read/write). ReadOnly here will force the + ReadOnly setting in VolumeMounts. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: boolean + secretFile: + description: 'secretFile is Optional: SecretFile + is the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + secretRef: + description: 'secretRef is Optional: SecretRef is + reference to the authentication secret for User, + default is empty. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + user: + description: 'user is optional: User is the rados + user name, default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + required: + - monitors + type: object + cinder: + description: 'cinder represents a cinder volume attached + and mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + properties: + fsType: + description: 'fsType is the filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Examples: "ext4", "xfs", "ntfs". + Implicitly inferred to be "ext4" if unspecified. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + readOnly: + description: 'readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: boolean + secretRef: + description: 'secretRef is optional: points to a + secret object containing parameters used to connect + to OpenStack.' + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + volumeID: + description: 'volumeID used to identify the volume + in cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that should + populate this volume + properties: + defaultMode: + description: 'defaultMode is optional: mode bits + used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or + a decimal value between 0 and 511. YAML accepts + both octal and decimal values, JSON requires decimal + values for mode bits. Defaults to 0644. Directories + within the path are not affected by this setting. + This might be in conflict with other options that + affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + items: + description: items if unspecified, each key-value + pair in the Data field of the referenced ConfigMap + will be projected into the volume as a file whose + name is the key and content is the value. If specified, + the listed keys will be projected into the specified + paths, and unlisted keys will not be present. + If a key is specified which is not present in + the ConfigMap, the volume setup will error unless + it is marked optional. Paths must be relative + and may not contain the '..' path or start with + '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits + used to set permissions on this file. Must + be an octal value between 0000 and 0777 + or a decimal value between 0 and 511. YAML + accepts both octal and decimal values, JSON + requires decimal values for mode bits. If + not specified, the volume defaultMode will + be used. This might be in conflict with + other options that affect the file mode, + like fsGroup, and the result can be other + mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of + the file to map the key to. May not be an + absolute path. May not contain the path + element '..'. May not start with the string + '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + csi: + description: csi (Container Storage Interface) represents + ephemeral storage that is handled by certain external + CSI drivers (Beta feature). + properties: + driver: + description: driver is the name of the CSI driver + that handles this volume. Consult with your admin + for the correct name as registered in the cluster. + type: string + fsType: + description: fsType to mount. Ex. "ext4", "xfs", + "ntfs". If not provided, the empty value is passed + to the associated CSI driver which will determine + the default filesystem to apply. + type: string + nodePublishSecretRef: + description: nodePublishSecretRef is a reference + to the secret object containing sensitive information + to pass to the CSI driver to complete the CSI + NodePublishVolume and NodeUnpublishVolume calls. + This field is optional, and may be empty if no + secret is required. If the secret object contains + more than one secret, all secret references are + passed. + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + readOnly: + description: readOnly specifies a read-only configuration + for the volume. Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: volumeAttributes stores driver-specific + properties that are passed to the CSI driver. + Consult your driver's documentation for supported + values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about + the pod that should populate this volume + properties: + defaultMode: + description: 'Optional: mode bits to use on created + files by default. Must be a Optional: mode bits + used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or + a decimal value between 0 and 511. YAML accepts + both octal and decimal values, JSON requires decimal + values for mode bits. Defaults to 0644. Directories + within the path are not affected by this setting. + This might be in conflict with other options that + affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + items: + description: Items is a list of downward API volume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing the + pod field + properties: + fieldRef: + description: 'Required: Selects a field of + the pod: only annotations, labels, name + and namespace are supported.' + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: mode bits used to + set permissions on this file, must be an + octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both + octal and decimal values, JSON requires + decimal values for mode bits. If not specified, + the volume defaultMode will be used. This + might be in conflict with other options + that affect the file mode, like fsGroup, + and the result can be other mode bits set.' + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. Must + not be absolute or contain the ''..'' path. + Must be utf-8 encoded. The first item of + the relative path must not start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, requests.cpu and requests.memory) + are currently supported.' + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + emptyDir: + description: 'emptyDir represents a temporary directory + that shares a pod''s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + properties: + medium: + description: 'medium represents what type of storage + medium should back this directory. The default + is "" which means to use the node''s default medium. + Must be an empty string (default) or Memory. More + info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: 'sizeLimit is the total amount of local + storage required for this EmptyDir volume. The + size limit is also applicable for memory medium. + The maximum usage on memory medium EmptyDir would + be the minimum value between the SizeLimit specified + here and the sum of memory limits of all containers + in a pod. The default is nil which means that + the limit is undefined. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: "ephemeral represents a volume that is + handled by a cluster storage driver. The volume's + lifecycle is tied to the pod that defines it - it + will be created before the pod starts, and deleted + when the pod is removed. \n Use this if: a) the volume + is only needed while the pod runs, b) features of + normal volumes like restoring from snapshot or capacity + \ tracking are needed, c) the storage driver is + specified through a storage class, and d) the storage + driver supports dynamic volume provisioning through + \ a PersistentVolumeClaim (see EphemeralVolumeSource + for more information on the connection between + this volume type and PersistentVolumeClaim). \n + Use PersistentVolumeClaim or one of the vendor-specific + APIs for volumes that persist for longer than the + lifecycle of an individual pod. \n Use CSI for light-weight + local ephemeral volumes if the CSI driver is meant + to be used that way - see the documentation of the + driver for more information. \n A pod can use both + types of ephemeral volumes and persistent volumes + at the same time." + properties: + volumeClaimTemplate: + description: "Will be used to create a stand-alone + PVC to provision the volume. The pod in which + this EphemeralVolumeSource is embedded will be + the owner of the PVC, i.e. the PVC will be deleted + together with the pod. The name of the PVC will + be `-` where `` + is the name from the `PodSpec.Volumes` array entry. + Pod validation will reject the pod if the concatenated + name is not valid for a PVC (for example, too + long). \n An existing PVC with that name that + is not owned by the pod will *not* be used for + the pod to avoid using an unrelated volume by + mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created + PVC is meant to be used by the pod, the PVC has + to updated with an owner reference to the pod + once the pod exists. Normally this should not + be necessary, but it may be useful when manually + reconstructing a broken cluster. \n This field + is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. \n Required, + must not be nil." + properties: + metadata: + description: May contain labels and annotations + that will be copied into the PVC when creating + it. No other fields are allowed and will be + rejected during validation. + type: object + spec: + description: The specification for the PersistentVolumeClaim. + The entire content is copied unchanged into + the PVC that gets created from this template. + The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: 'accessModes contains the desired + access modes the volume should have. More + info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'dataSource field can be used + to specify either: * An existing VolumeSnapshot + object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller + can support the specified data source, + it will create a new volume based on the + contents of the specified data source. + When the AnyVolumeDataSource feature gate + is enabled, dataSource contents will be + copied to dataSourceRef, and dataSourceRef + contents will be copied to dataSource + when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef + will not be copied to dataSource.' + properties: + apiGroup: + description: APIGroup is the group for + the resource being referenced. If + APIGroup is not specified, the specified + Kind must be in the core API group. + For any other third-party types, APIGroup + is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + required: + - kind + - name + type: object + dataSourceRef: + description: 'dataSourceRef specifies the + object from which to populate the volume + with data, if a non-empty volume is desired. + This may be any object from a non-empty + API group (non core object) or a PersistentVolumeClaim + object. When this field is specified, + volume binding will only succeed if the + type of the specified object matches some + installed volume populator or dynamic + provisioner. This field will replace the + functionality of the dataSource field + and as such if both fields are non-empty, + they must have the same value. For backwards + compatibility, when namespace isn''t specified + in dataSourceRef, both fields (dataSource + and dataSourceRef) will be set to the + same value automatically if one of them + is empty and the other is non-empty. When + namespace is specified in dataSourceRef, + dataSource isn''t set to the same value + and must be empty. There are three important + differences between dataSource and dataSourceRef: + * While dataSource only allows two specific + types of objects, dataSourceRef allows + any non-core object, as well as PersistentVolumeClaim + objects. * While dataSource ignores disallowed + values (dropping them), dataSourceRef preserves + all values, and generates an error if + a disallowed value is specified. * While + dataSource only allows local objects, + dataSourceRef allows objects in any + namespaces. (Beta) Using this field requires + the AnyVolumeDataSource feature gate to + be enabled. (Alpha) Using the namespace + field of dataSourceRef requires the CrossNamespaceVolumeDataSource + feature gate to be enabled.' + properties: + apiGroup: + description: APIGroup is the group for + the resource being referenced. If + APIGroup is not specified, the specified + Kind must be in the core API group. + For any other third-party types, APIGroup + is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + namespace: + description: Namespace is the namespace + of resource being referenced Note + that when a namespace is specified, + a gateway.networking.k8s.io/ReferenceGrant + object is required in the referent + namespace to allow that namespace's + owner to accept the reference. See + the ReferenceGrant documentation for + details. (Alpha) This field requires + the CrossNamespaceVolumeDataSource + feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: 'resources represents the minimum + resources the volume should have. If RecoverVolumeExpansionFailure + feature is enabled users are allowed to + specify resource requirements that are + lower than previous value but must still + be higher than capacity recorded in the + status field of the claim. More info: + https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum + amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the + minimum amount of compute resources + required. If Requests is omitted for + a container, it defaults to Limits + if that is explicitly specified, otherwise + to an implementation-defined value. + Requests cannot exceed Limits. More + info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + selector: + description: selector is a label query over + volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. + This array is replaced during + a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of + {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + storageClassName: + description: 'storageClassName is the name + of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + type: string + volumeAttributesClassName: + description: 'volumeAttributesClassName + may be used to set the VolumeAttributesClass + used by this claim. If specified, the + CSI driver will create or update the volume + with the attributes defined in the corresponding + VolumeAttributesClass. This has a different + purpose than storageClassName, it can + be changed after the claim is created. + An empty string value means that no VolumeAttributesClass + will be applied to the claim but it''s + not allowed to reset this field to empty + string once it is set. If unspecified + and the PersistentVolumeClaim is unbound, + the default VolumeAttributesClass will + be set by the persistentvolume controller + if it exists. If the resource referred + to by volumeAttributesClass does not exist, + this PersistentVolumeClaim will be set + to a Pending state, as reflected by the + modifyVolumeStatus field, until such as + a resource exists. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + (Alpha) Using this field requires the + VolumeAttributesClass feature gate to + be enabled.' + type: string + volumeMode: + description: volumeMode defines what type + of volume is required by the claim. Value + of Filesystem is implied when not included + in claim spec. + type: string + volumeName: + description: volumeName is the binding reference + to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource + that is attached to a kubelet's host machine and then + exposed to the pod. + properties: + fsType: + description: 'fsType is the filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. TODO: how + do we prevent errors in the filesystem from compromising + the machine' + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: 'readOnly is Optional: Defaults to + false (read/write). ReadOnly here will force the + ReadOnly setting in VolumeMounts.' + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target + worldwide names (WWNs)' + items: + type: string + type: array + wwids: + description: 'wwids Optional: FC volume world wide + identifiers (wwids) Either wwids or combination + of targetWWNs and lun must be set, but not both + simultaneously.' + items: + type: string + type: array + type: object + flexVolume: + description: flexVolume represents a generic volume + resource that is provisioned/attached using an exec + based plugin. + properties: + driver: + description: driver is the name of the driver to + use for this volume. + type: string + fsType: + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". The + default filesystem depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field holds + extra command options if any.' + type: object + readOnly: + description: 'readOnly is Optional: defaults to + false (read/write). ReadOnly here will force the + ReadOnly setting in VolumeMounts.' + type: boolean + secretRef: + description: 'secretRef is Optional: secretRef is + reference to the secret object containing sensitive + information to pass to the plugin scripts. This + may be empty if no secret object is specified. + If the secret object contains more than one secret, + all secrets are passed to the plugin scripts.' + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume attached + to a kubelet's host machine. This depends on the Flocker + control service being running + properties: + datasetName: + description: datasetName is Name of the dataset + stored as metadata -> name on the dataset for + Flocker should be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. + This is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: 'gcePersistentDisk represents a GCE Disk + resource that is attached to a kubelet''s host machine + and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + properties: + fsType: + description: 'fsType is filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem + from compromising the machine' + type: string + partition: + description: 'partition is the partition in the + volume that you want to mount. If omitted, the + default is to mount by volume name. Examples: + For volume /dev/sda1, you specify the partition + as "1". Similarly, the volume partition for /dev/sda + is "0" (or you can leave the property empty). + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + format: int32 + type: integer + pdName: + description: 'pdName is unique name of the PD resource + in GCE. Used to identify the disk in GCE. More + info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: string + readOnly: + description: 'readOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. More + info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: boolean + required: + - pdName + type: object + gitRepo: + description: 'gitRepo represents a git repository at + a particular revision. DEPRECATED: GitRepo is deprecated. + To provision a container with a git repo, mount an + EmptyDir into an InitContainer that clones the repo + using git, then mount the EmptyDir into the Pod''s + container.' + properties: + directory: + description: directory is the target directory name. + Must not contain or start with '..'. If '.' is + supplied, the volume directory will be the git + repository. Otherwise, if specified, the volume + will contain the git repository in the subdirectory + with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the + specified revision. + type: string + required: + - repository + type: object + glusterfs: + description: 'glusterfs represents a Glusterfs mount + on the host that shares a pod''s lifetime. More info: + https://examples.k8s.io/volumes/glusterfs/README.md' + properties: + endpoints: + description: 'endpoints is the endpoint name that + details Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + path: + description: 'path is the Glusterfs volume path. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + readOnly: + description: 'readOnly here will force the Glusterfs + volume to be mounted with read-only permissions. + Defaults to false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: 'hostPath represents a pre-existing file + or directory on the host machine that is directly + exposed to the container. This is generally used for + system agents or other privileged things that are + allowed to see the host machine. Most containers will + NOT need this. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- TODO(jonesdl) We need to restrict who can use + host directory mounts and who can/can not mount host + directories as read/write.' + properties: + path: + description: 'path of the directory on the host. + If the path is a symlink, it will follow the link + to the real path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + type: + description: 'type for HostPath Volume Defaults + to "" More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + required: + - path + type: object + iscsi: + description: 'iscsi represents an ISCSI Disk resource + that is attached to a kubelet''s host machine and + then exposed to the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md' + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether support + iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support + iSCSI Session CHAP authentication + type: boolean + fsType: + description: 'fsType is the filesystem type of the + volume that you want to mount. Tip: Ensure that + the filesystem type is supported by the host operating + system. Examples: "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. More info: + https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem + from compromising the machine' + type: string + initiatorName: + description: initiatorName is the custom iSCSI Initiator + Name. If initiatorName is specified with iscsiInterface + simultaneously, new iSCSI interface : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified Name. + type: string + iscsiInterface: + description: iscsiInterface is the interface Name + that uses an iSCSI transport. Defaults to 'default' + (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: portals is the iSCSI Target Portal + List. The portal is either an IP or ip_addr:port + if the port is other than default (typically TCP + ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: readOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for iSCSI + target and initiator authentication + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + targetPortal: + description: targetPortal is iSCSI Target Portal. + The Portal is either an IP or ip_addr:port if + the port is other than default (typically TCP + ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: 'name of the volume. Must be a DNS_LABEL + and unique within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + nfs: + description: 'nfs represents an NFS mount on the host + that shares a pod''s lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + properties: + path: + description: 'path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + readOnly: + description: 'readOnly here will force the NFS export + to be mounted with read-only permissions. Defaults + to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: boolean + server: + description: 'server is the hostname or IP address + of the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: 'persistentVolumeClaimVolumeSource represents + a reference to a PersistentVolumeClaim in the same + namespace. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + claimName: + description: 'claimName is the name of a PersistentVolumeClaim + in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + type: string + readOnly: + description: readOnly Will force the ReadOnly setting + in VolumeMounts. Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents a PhotonController + persistent disk attached and mounted on kubelets host + machine + properties: + fsType: + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon + Controller persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx volume + attached and mounted on kubelets host machine + properties: + fsType: + description: fSType represents the filesystem type + to mount Must be a filesystem type supported by + the host operating system. Ex. "ext4", "xfs". + Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx + volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources + secrets, configmaps, and downward API + properties: + defaultMode: + description: defaultMode are the mode bits used + to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or + a decimal value between 0 and 511. YAML accepts + both octal and decimal values, JSON requires decimal + values for mode bits. Directories within the path + are not affected by this setting. This might be + in conflict with other options that affect the + file mode, like fsGroup, and the result can be + other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume projections + items: + description: Projection that may be projected + along with other supported volume types + properties: + clusterTrustBundle: + description: "ClusterTrustBundle allows a + pod to access the `.spec.trustBundle` field + of ClusterTrustBundle objects in an auto-updating + file. \n Alpha, gated by the ClusterTrustBundleProjection + feature gate. \n ClusterTrustBundle objects + can either be selected by name, or by the + combination of signer name and a label selector. + \n Kubelet performs aggressive normalization + of the PEM contents written into the pod + filesystem. Esoteric PEM features such + as inter-block comments and block headers + are stripped. Certificates are deduplicated. + The ordering of certificates within the + file is arbitrary, and Kubelet may change + the order over time." + properties: + labelSelector: + description: Select all ClusterTrustBundles + that match this label selector. Only + has effect if signerName is set. Mutually-exclusive + with name. If unset, interpreted as + "match nothing". If set but empty, + interpreted as "match everything". + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a + set of values. Valid operators + are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values + array must be non-empty. If + the operator is Exists or + DoesNotExist, the values array + must be empty. This array + is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map + of {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + name: + description: Select a single ClusterTrustBundle + by object name. Mutually-exclusive + with signerName and labelSelector. + type: string + optional: + description: If true, don't block pod + startup if the referenced ClusterTrustBundle(s) + aren't available. If using name, then + the named ClusterTrustBundle is allowed + not to exist. If using signerName, + then the combination of signerName and + labelSelector is allowed to match zero + ClusterTrustBundles. + type: boolean + path: + description: Relative path from the volume + root to write the bundle. + type: string + signerName: + description: Select all ClusterTrustBundles + that match this signer name. Mutually-exclusive + with name. The contents of all selected + ClusterTrustBundles will be unified + and deduplicated. + type: string + required: + - path + type: object + configMap: + description: configMap information about the + configMap data to project + properties: + items: + description: items if unspecified, each + key-value pair in the Data field of + the referenced ConfigMap will be projected + into the volume as a file whose name + is the key and content is the value. + If specified, the listed keys will be + projected into the specified paths, + and unlisted keys will not be present. + If a key is specified which is not present + in the ConfigMap, the volume setup will + error unless it is marked optional. + Paths must be relative and may not contain + the '..' path or start with '..'. + items: + description: Maps a string key to a + path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: + mode bits used to set permissions + on this file. Must be an octal + value between 0000 and 0777 or + a decimal value between 0 and + 511. YAML accepts both octal and + decimal values, JSON requires + decimal values for mode bits. + If not specified, the volume defaultMode + will be used. This might be in + conflict with other options that + affect the file mode, like fsGroup, + and the result can be other mode + bits set.' + format: int32 + type: integer + path: + description: path is the relative + path of the file to map the key + to. May not be an absolute path. + May not contain the path element + '..'. May not start with the string + '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: optional specify whether + the ConfigMap or its keys must be defined + type: boolean + type: object + downwardAPI: + description: downwardAPI information about + the downwardAPI data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects + a field of the pod: only annotations, + labels, name and namespace are + supported.' + properties: + apiVersion: + description: Version of the + schema the FieldPath is written + in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field + to select in the specified + API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: mode bits + used to set permissions on this + file, must be an octal value between + 0000 and 0777 or a decimal value + between 0 and 511. YAML accepts + both octal and decimal values, + JSON requires decimal values for + mode bits. If not specified, the + volume defaultMode will be used. + This might be in conflict with + other options that affect the + file mode, like fsGroup, and the + result can be other mode bits + set.' + format: int32 + type: integer + path: + description: 'Required: Path is the + relative path name of the file + to be created. Must not be absolute + or contain the ''..'' path. Must + be utf-8 encoded. The first item + of the relative path must not + start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource + of the container: only resources + limits and requests (limits.cpu, + limits.memory, requests.cpu and + requests.memory) are currently + supported.' + properties: + containerName: + description: 'Container name: + required for volumes, optional + for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource + to select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + secret: + description: secret information about the + secret data to project + properties: + items: + description: items if unspecified, each + key-value pair in the Data field of + the referenced Secret will be projected + into the volume as a file whose name + is the key and content is the value. + If specified, the listed keys will be + projected into the specified paths, + and unlisted keys will not be present. + If a key is specified which is not present + in the Secret, the volume setup will + error unless it is marked optional. + Paths must be relative and may not contain + the '..' path or start with '..'. + items: + description: Maps a string key to a + path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: + mode bits used to set permissions + on this file. Must be an octal + value between 0000 and 0777 or + a decimal value between 0 and + 511. YAML accepts both octal and + decimal values, JSON requires + decimal values for mode bits. + If not specified, the volume defaultMode + will be used. This might be in + conflict with other options that + affect the file mode, like fsGroup, + and the result can be other mode + bits set.' + format: int32 + type: integer + path: + description: path is the relative + path of the file to map the key + to. May not be an absolute path. + May not contain the path element + '..'. May not start with the string + '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: optional field specify whether + the Secret or its key must be defined + type: boolean + type: object + serviceAccountToken: + description: serviceAccountToken is information + about the serviceAccountToken data to project + properties: + audience: + description: audience is the intended + audience of the token. A recipient of + a token must identify itself with an + identifier specified in the audience + of the token, and otherwise should reject + the token. The audience defaults to + the identifier of the apiserver. + type: string + expirationSeconds: + description: expirationSeconds is the + requested duration of validity of the + service account token. As the token + approaches expiration, the kubelet volume + plugin will proactively rotate the service + account token. The kubelet will start + trying to rotate the token if the token + is older than 80 percent of its time + to live or if the token is older than + 24 hours.Defaults to 1 hour and must + be at least 10 minutes. + format: int64 + type: integer + path: + description: path is the path relative + to the mount point of the file to project + the token into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: quobyte represents a Quobyte mount on the + host that shares a pod's lifetime + properties: + group: + description: group to map volume access to Default + is no group + type: string + readOnly: + description: readOnly here will force the Quobyte + volume to be mounted with read-only permissions. + Defaults to false. + type: boolean + registry: + description: registry represents a single or multiple + Quobyte Registry services specified as a string + as host:port pair (multiple entries are separated + with commas) which acts as the central registry + for volumes + type: string + tenant: + description: tenant owning the given Quobyte volume + in the Backend Used with dynamically provisioned + Quobyte volumes, value is set by the plugin + type: string + user: + description: user to map volume access to Defaults + to serivceaccount user + type: string + volume: + description: volume is a string that references + an already created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: 'rbd represents a Rados Block Device mount + on the host that shares a pod''s lifetime. More info: + https://examples.k8s.io/volumes/rbd/README.md' + properties: + fsType: + description: 'fsType is the filesystem type of the + volume that you want to mount. Tip: Ensure that + the filesystem type is supported by the host operating + system. Examples: "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. More info: + https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem + from compromising the machine' + type: string + image: + description: 'image is the rados image name. More + info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + keyring: + description: 'keyring is the path to key ring for + RBDUser. Default is /etc/ceph/keyring. More info: + https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + monitors: + description: 'monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + items: + type: string + type: array + pool: + description: 'pool is the rados pool name. Default + is rbd. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + readOnly: + description: 'readOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. More + info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: boolean + secretRef: + description: 'secretRef is name of the authentication + secret for RBDUser. If provided overrides keyring. + Default is nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + user: + description: 'user is the rados user name. Default + is admin. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent + volume attached and mounted on Kubernetes nodes. + properties: + fsType: + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". Default + is "xfs". + type: string + gateway: + description: gateway is the host address of the + ScaleIO API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the + ScaleIO Protection Domain for the configured storage. + type: string + readOnly: + description: readOnly Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. + type: boolean + secretRef: + description: secretRef references to the secret + for ScaleIO user and other sensitive information. + If this is not provided, Login operation will + fail. + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + sslEnabled: + description: sslEnabled Flag enable/disable SSL + communication with Gateway, default false + type: boolean + storageMode: + description: storageMode indicates whether the storage + for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage + Pool associated with the protection domain. + type: string + system: + description: system is the name of the storage system + as configured in ScaleIO. + type: string + volumeName: + description: volumeName is the name of a volume + already created in the ScaleIO system that is + associated with this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: 'secret represents a secret that should + populate this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + properties: + defaultMode: + description: 'defaultMode is Optional: mode bits + used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or + a decimal value between 0 and 511. YAML accepts + both octal and decimal values, JSON requires decimal + values for mode bits. Defaults to 0644. Directories + within the path are not affected by this setting. + This might be in conflict with other options that + affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + items: + description: items If unspecified, each key-value + pair in the Data field of the referenced Secret + will be projected into the volume as a file whose + name is the key and content is the value. If specified, + the listed keys will be projected into the specified + paths, and unlisted keys will not be present. + If a key is specified which is not present in + the Secret, the volume setup will error unless + it is marked optional. Paths must be relative + and may not contain the '..' path or start with + '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits + used to set permissions on this file. Must + be an octal value between 0000 and 0777 + or a decimal value between 0 and 511. YAML + accepts both octal and decimal values, JSON + requires decimal values for mode bits. If + not specified, the volume defaultMode will + be used. This might be in conflict with + other options that affect the file mode, + like fsGroup, and the result can be other + mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of + the file to map the key to. May not be an + absolute path. May not contain the path + element '..'. May not start with the string + '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the + Secret or its keys must be defined + type: boolean + secretName: + description: 'secretName is the name of the secret + in the pod''s namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + type: string + type: object + storageos: + description: storageOS represents a StorageOS volume + attached and mounted on Kubernetes nodes. + properties: + fsType: + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + readOnly: + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. + type: boolean + secretRef: + description: secretRef specifies the secret to use + for obtaining the StorageOS API credentials. If + not specified, default values will be attempted. + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + volumeName: + description: volumeName is the human-readable name + of the StorageOS volume. Volume names are only + unique within a namespace. + type: string + volumeNamespace: + description: volumeNamespace specifies the scope + of the volume within StorageOS. If no namespace + is specified then the Pod's namespace will be + used. This allows the Kubernetes name scoping + to be mirrored within StorageOS for tighter integration. + Set VolumeName to any name to override the default + behaviour. Set to "default" if you are not using + namespaces within StorageOS. Namespaces that do + not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere volume + attached and mounted on kubelets host machine + properties: + fsType: + description: fsType is filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy + Based Management (SPBM) profile ID associated + with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage Policy + Based Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies + vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + type: object + type: object + required: + - clusterSize + - kubernetesConfig + type: object + status: + description: RedisClusterStatus defines the observed state of RedisCluster + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: Current cluster node count + jsonPath: .spec.clusterSize + name: ClusterSize + type: integer + - description: Number of ready leader replicas + jsonPath: .status.readyLeaderReplicas + name: ReadyLeaderReplicas + type: integer + - description: Number of ready follower replicas + jsonPath: .status.readyFollowerReplicas + name: ReadyFollowerReplicas + type: integer + - description: The current state of the Redis Cluster + jsonPath: .status.state + name: State + priority: 1 + type: string + - description: Age of Cluster + jsonPath: .metadata.creationTimestamp + name: Age + priority: 1 + type: date + - description: The reason for the current state + jsonPath: .status.reason + name: Reason + priority: 1 + type: string + name: v1beta2 + schema: + openAPIV3Schema: + description: RedisCluster is the Schema for the redisclusters API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: RedisClusterSpec defines the desired state of RedisCluster + properties: + TLS: + description: TLS Configuration for redis instances + properties: + ca: + type: string + cert: + type: string + key: + type: string + secret: + description: Reference to secret which contains the certificates + properties: + defaultMode: + description: 'defaultMode is Optional: mode bits used to set + permissions on created files by default. Must be an octal + value between 0000 and 0777 or a decimal value between 0 + and 511. YAML accepts both octal and decimal values, JSON + requires decimal values for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect + the file mode, like fsGroup, and the result can be other + mode bits set.' + format: int32 + type: integer + items: + description: items If unspecified, each key-value pair in + the Data field of the referenced Secret will be projected + into the volume as a file whose name is the key and content + is the value. If specified, the listed keys will be projected + into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the + Secret, the volume setup will error unless it is marked + optional. Paths must be relative and may not contain the + '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used to set + permissions on this file. Must be an octal value between + 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires + decimal values for mode bits. If not specified, the + volume defaultMode will be used. This might be in + conflict with other options that affect the file mode, + like fsGroup, and the result can be other mode bits + set.' + format: int32 + type: integer + path: + description: path is the relative path of the file to + map the key to. May not be an absolute path. May not + contain the path element '..'. May not start with + the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the Secret or + its keys must be defined + type: boolean + secretName: + description: 'secretName is the name of the secret in the + pod''s namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + type: string + type: object + required: + - secret + type: object + acl: + properties: + secret: + description: "Adapts a Secret into a volume. \n The contents of + the target Secret's Data field will be presented in a volume + as files using the keys in the Data field as the file names. + Secret volumes support ownership management and SELinux relabeling." + properties: + defaultMode: + description: 'defaultMode is Optional: mode bits used to set + permissions on created files by default. Must be an octal + value between 0000 and 0777 or a decimal value between 0 + and 511. YAML accepts both octal and decimal values, JSON + requires decimal values for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect + the file mode, like fsGroup, and the result can be other + mode bits set.' + format: int32 + type: integer + items: + description: items If unspecified, each key-value pair in + the Data field of the referenced Secret will be projected + into the volume as a file whose name is the key and content + is the value. If specified, the listed keys will be projected + into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the + Secret, the volume setup will error unless it is marked + optional. Paths must be relative and may not contain the + '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used to set + permissions on this file. Must be an octal value between + 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires + decimal values for mode bits. If not specified, the + volume defaultMode will be used. This might be in + conflict with other options that affect the file mode, + like fsGroup, and the result can be other mode bits + set.' + format: int32 + type: integer + path: + description: path is the relative path of the file to + map the key to. May not be an absolute path. May not + contain the path element '..'. May not start with + the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the Secret or + its keys must be defined + type: boolean + secretName: + description: 'secretName is the name of the secret in the + pod''s namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + type: string + type: object + type: object + clusterSize: + format: int32 + type: integer + clusterVersion: + default: v7 + type: string + env: + items: + description: EnvVar represents an environment variable present in + a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded using + the previously defined environment variables in the container + and any service environment variables. If a variable cannot + be resolved, the reference in the input string will be unchanged. + Double $$ are reduced to a single $, which allows for escaping + the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the + string literal "$(VAR_NAME)". Escaped references will never + be expanded, regardless of whether the variable exists or + not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. Cannot + be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, `metadata.annotations['''']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, + status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath is + written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified + API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed + resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + hostNetwork: + type: boolean + initContainer: + description: InitContainer for each Redis pods + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + enabled: + type: boolean + env: + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + image: + type: string + imagePullPolicy: + description: PullPolicy describes a policy for if/when to pull + a container image + type: string + resources: + description: ResourceRequirements describes the compute resource + requirements. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: SecurityContext holds security configuration that + will be applied to a container. Some fields are present in both + SecurityContext and PodSecurityContext. When both are set, + the values in SecurityContext take precedence. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a + process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the + container runtime. Note that this field cannot be set when + spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in + privileged containers are essentially equivalent to root + on the host. Defaults to false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use + for the containers. The default is DefaultProcMount which + uses the container runtime defaults for readonly paths and + masked paths. This requires the ProcMountType feature flag + to be enabled. Note that this field cannot be set when spec.os.name + is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when + spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail + to start the container if it does. If unset or false, no + such validation will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata if + unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. Note + that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must + be preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must be set if type is "Localhost". Must NOT + be set for any other type. + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a + profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile + should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also be + set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + required: + - image + type: object + kubernetesConfig: + description: KubernetesConfig will be the JSON struct for Basic Redis + Config + properties: + ignoreAnnotations: + items: + type: string + type: array + image: + type: string + imagePullPolicy: + description: PullPolicy describes a policy for if/when to pull + a container image + type: string + imagePullSecrets: + items: + description: LocalObjectReference contains enough information + to let you locate the referenced object inside the same namespace. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + type: array + redisSecret: + description: ExistingPasswordSecret is the struct to access the + existing secret + properties: + key: + type: string + name: + type: string + type: object + resources: + description: ResourceRequirements describes the compute resource + requirements. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + service: + description: ServiceConfig define the type of service to be created + and its annotations + properties: + annotations: + additionalProperties: + type: string + type: object + serviceType: + enum: + - LoadBalancer + - NodePort + - ClusterIP + type: string + type: object + updateStrategy: + description: StatefulSetUpdateStrategy indicates the strategy + that the StatefulSet controller will use to perform updates. + It includes any additional parameters necessary to perform the + update for the indicated strategy. + properties: + rollingUpdate: + description: RollingUpdate is used to communicate parameters + when Type is RollingUpdateStatefulSetStrategyType. + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + description: 'The maximum number of pods that can be unavailable + during the update. Value can be an absolute number (ex: + 5) or a percentage of desired pods (ex: 10%). Absolute + number is calculated from percentage by rounding up. + This can not be 0. Defaults to 1. This field is alpha-level + and is only honored by servers that enable the MaxUnavailableStatefulSet + feature. The field applies to all pods in the range + 0 to Replicas-1. That means if there is any unavailable + pod in the range 0 to Replicas-1, it will be counted + towards MaxUnavailable.' + x-kubernetes-int-or-string: true + partition: + description: Partition indicates the ordinal at which + the StatefulSet should be partitioned for updates. During + a rolling update, all pods from ordinal Replicas-1 to + Partition are updated. All pods from ordinal Partition-1 + to 0 remain untouched. This is helpful in being able + to do a canary based deployment. The default value is + 0. + format: int32 + type: integer + type: object + type: + description: Type indicates the type of the StatefulSetUpdateStrategy. + Default is RollingUpdate. + type: string + type: object + required: + - image + type: object + persistenceEnabled: + type: boolean + podSecurityContext: + description: PodSecurityContext holds pod-level security attributes + and common container settings. Some fields are also present in container.securityContext. Field + values of container.securityContext take precedence over field values + of PodSecurityContext. + properties: + fsGroup: + description: "A special supplemental group that applies to all + containers in a pod. Some volume types allow the Kubelet to + change the ownership of that volume to be owned by the pod: + \n 1. The owning GID will be the FSGroup 2. The setgid bit is + set (new files created in the volume will be owned by FSGroup) + 3. The permission bits are OR'd with rw-rw---- \n If unset, + the Kubelet will not modify the ownership and permissions of + any volume. Note that this field cannot be set when spec.os.name + is windows." + format: int64 + type: integer + fsGroupChangePolicy: + description: 'fsGroupChangePolicy defines behavior of changing + ownership and permission of the volume before being exposed + inside Pod. This field will only apply to volume types which + support fsGroup based ownership(and permissions). It will have + no effect on ephemeral volume types such as: secret, configmaps + and emptydir. Valid values are "OnRootMismatch" and "Always". + If not specified, "Always" is used. Note that this field cannot + be set when spec.os.name is windows.' + type: string + runAsGroup: + description: The GID to run the entrypoint of the container process. + Uses runtime default if unset. May also be set in SecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail to start + the container if it does. If unset or false, no such validation + will be performed. May also be set in SecurityContext. If set + in both SecurityContext and PodSecurityContext, the value specified + in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in SecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. Note that this field cannot + be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in SecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to + the container. + type: string + role: + description: Role is a SELinux role label that applies to + the container. + type: string + type: + description: Type is a SELinux type label that applies to + the container. + type: string + user: + description: User is a SELinux user label that applies to + the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by the containers in this + pod. Note that this field cannot be set when spec.os.name is + windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must be + preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must be set if type is "Localhost". Must NOT be + set for any other type. + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a profile + defined in a file on the node should be used. RuntimeDefault + - the container runtime default profile should be used. + Unconfined - no profile should be applied." + type: string + required: + - type + type: object + supplementalGroups: + description: A list of groups applied to the first process run + in each container, in addition to the container's primary GID, + the fsGroup (if specified), and group memberships defined in + the container image for the uid of the container process. If + unspecified, no additional groups are added to any container. + Note that group memberships defined in the container image for + the uid of the container process are still effective, even if + they are not included in this list. Note that this field cannot + be set when spec.os.name is windows. + items: + format: int64 + type: integer + type: array + sysctls: + description: Sysctls hold a list of namespaced sysctls used for + the pod. Pods with unsupported sysctls (by the container runtime) + might fail to launch. Note that this field cannot be set when + spec.os.name is windows. + items: + description: Sysctl defines a kernel parameter to be set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + description: The Windows specific settings applied to all containers. + If unspecified, the options within a container's SecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named by + the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA + credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. All of a Pod's containers + must have the same effective HostProcess value (it is not + allowed to have a mix of HostProcess containers and non-HostProcess + containers). In addition, if HostProcess is true then HostNetwork + must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in PodSecurityContext. + If set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: string + type: object + type: object + port: + default: 6379 + type: integer + priorityClassName: + type: string + redisExporter: + description: RedisExporter interface will have the information for + redis exporter related stuff + properties: + enabled: + type: boolean + env: + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + image: + type: string + imagePullPolicy: + description: PullPolicy describes a policy for if/when to pull + a container image + type: string + port: + default: 9121 + type: integer + resources: + description: ResourceRequirements describes the compute resource + requirements. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: SecurityContext holds security configuration that + will be applied to a container. Some fields are present in both + SecurityContext and PodSecurityContext. When both are set, + the values in SecurityContext take precedence. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a + process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the + container runtime. Note that this field cannot be set when + spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in + privileged containers are essentially equivalent to root + on the host. Defaults to false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use + for the containers. The default is DefaultProcMount which + uses the container runtime defaults for readonly paths and + masked paths. This requires the ProcMountType feature flag + to be enabled. Note that this field cannot be set when spec.os.name + is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when + spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail + to start the container if it does. If unset or false, no + such validation will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata if + unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. Note + that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must + be preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must be set if type is "Localhost". Must NOT + be set for any other type. + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a + profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile + should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also be + set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + required: + - image + type: object + redisFollower: + description: RedisFollower interface will have the redis follower + configuration + properties: + affinity: + description: Affinity is a group of affinity scheduling rules. + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for + the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node matches the corresponding matchExpressions; + the node(s) with the highest sum are the most preferred. + items: + description: An empty preferred scheduling term matches + all objects with implicit weight 0 (i.e. it's a no-op). + A null preferred scheduling term matches no objects + (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated with + the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + description: Weight associated with matching the + corresponding nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the affinity requirements + specified by this field cease to be met at some point + during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from + its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: A null or empty node selector term + matches no objects. The requirements of them are + ANDed. The TopologySelectorTerm type implements + a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. + co-locate this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum are + the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod + label keys to select which pods will be taken + into consideration. The keys are used to lookup + values from the incoming pod labels, those + key-value labels are merged with `LabelSelector` + as `key in (value)` to select the group of + existing pods which pods will be taken into + consideration for the incoming pod's pod (anti) + affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value + is empty. The same key is forbidden to exist + in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature + gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod + label keys to select which pods will be taken + into consideration. The keys are used to lookup + values from the incoming pod labels, those + key-value labels are merged with `LabelSelector` + as `key notin (value)` to select the group + of existing pods which pods will be taken + into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist + in the incoming pod labels will be ignored. + The default value is empty. The same key is + forbidden to exist in both MismatchLabelKeys + and LabelSelector. Also, MismatchLabelKeys + cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling + MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by + this field and the ones listed in the namespaces + field. null selector and null or empty namespaces + list means "this pod's namespace". An empty + selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. + The term is applied to the union of the namespaces + listed in this field and the ones selected + by namespaceSelector. null or empty namespaces + list and null namespaceSelector means "this + pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the + corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the affinity requirements + specified by this field cease to be met at some point + during pod execution (e.g. due to a pod label update), + the system may or may not try to eventually evict the + pod from its node. When there are multiple elements, + the lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not + co-located (anti-affinity) with, where co-located + is defined as running on a node whose value of the + label with key matches that of any node + on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key in (value)` to select + the group of existing pods which pods will be + taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MatchLabelKeys and LabelSelector. Also, + MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key notin (value)` to + select the group of existing pods which pods will + be taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MismatchLabelKeys and LabelSelector. Also, + MismatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules + (e.g. avoid putting this pod in the same node, zone, etc. + as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the anti-affinity expressions + specified by this field, but it may choose a node that + violates one or more of the expressions. The node that + is most preferred is the one with the greatest sum of + weights, i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + anti-affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum are + the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod + label keys to select which pods will be taken + into consideration. The keys are used to lookup + values from the incoming pod labels, those + key-value labels are merged with `LabelSelector` + as `key in (value)` to select the group of + existing pods which pods will be taken into + consideration for the incoming pod's pod (anti) + affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value + is empty. The same key is forbidden to exist + in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature + gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod + label keys to select which pods will be taken + into consideration. The keys are used to lookup + values from the incoming pod labels, those + key-value labels are merged with `LabelSelector` + as `key notin (value)` to select the group + of existing pods which pods will be taken + into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist + in the incoming pod labels will be ignored. + The default value is empty. The same key is + forbidden to exist in both MismatchLabelKeys + and LabelSelector. Also, MismatchLabelKeys + cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling + MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by + this field and the ones listed in the namespaces + field. null selector and null or empty namespaces + list means "this pod's namespace". An empty + selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. + The term is applied to the union of the namespaces + listed in this field and the ones selected + by namespaceSelector. null or empty namespaces + list and null namespaceSelector means "this + pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the + corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified + by this field are not met at scheduling time, the pod + will not be scheduled onto the node. If the anti-affinity + requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod + label update), the system may or may not try to eventually + evict the pod from its node. When there are multiple + elements, the lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not + co-located (anti-affinity) with, where co-located + is defined as running on a node whose value of the + label with key matches that of any node + on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key in (value)` to select + the group of existing pods which pods will be + taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MatchLabelKeys and LabelSelector. Also, + MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key notin (value)` to + select the group of existing pods which pods will + be taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MismatchLabelKeys and LabelSelector. Also, + MismatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + livenessProbe: + description: Probe describes a health check to be performed against + a container to determine whether it is alive or ready to receive + traffic. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside + the container, the working directory for the command is + root ('/') in the container's filesystem. The command + is simply exec'd, it is not run inside a shell, so traditional + shell instructions ('|', etc) won't work. To use a shell, + you need to explicitly call out to that shell. Exit + status of 0 is treated as live/healthy and non-zero + is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to + be considered failed after having succeeded. Defaults to + 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. + properties: + port: + description: Port number of the gRPC service. Number must + be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place + in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior is + defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the + pod IP. You probably want to set "Host" in httpHeaders + instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP + allows repeated headers. + items: + description: HTTPHeader describes a custom header to + be used in HTTP probes + properties: + name: + description: The header field name. This will be + canonicalized upon output, so case-variant names + will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the + container. Number must be in the range 1 to 65535. Name + must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started + before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to + be considered successful after having failed. Defaults to + 1. Must be 1 for liveness and startup. Minimum value is + 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP + port. + properties: + host: + description: 'Optional: Host name to connect to, defaults + to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the + container. Number must be in the range 1 to 65535. Name + must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to + terminate gracefully upon probe failure. The grace period + is the duration in seconds after the processes running in + the pod are sent a termination signal and the time when + the processes are forcibly halted with a kill signal. Set + this value longer than the expected cleanup time for your + process. If this value is nil, the pod's terminationGracePeriodSeconds + will be used. Otherwise, this value overrides the value + provided by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the kill signal + (no opportunity to shut down). This is a beta field and + requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is + used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times + out. Defaults to 1 second. Minimum value is 1. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + nodeSelector: + additionalProperties: + type: string + type: object + pdb: + description: RedisPodDisruptionBudget configure a PodDisruptionBudget + on the resource (leader/follower) + properties: + enabled: + type: boolean + maxUnavailable: + format: int32 + type: integer + minAvailable: + format: int32 + type: integer + type: object + readinessProbe: + description: Probe describes a health check to be performed against + a container to determine whether it is alive or ready to receive + traffic. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside + the container, the working directory for the command is + root ('/') in the container's filesystem. The command + is simply exec'd, it is not run inside a shell, so traditional + shell instructions ('|', etc) won't work. To use a shell, + you need to explicitly call out to that shell. Exit + status of 0 is treated as live/healthy and non-zero + is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to + be considered failed after having succeeded. Defaults to + 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. + properties: + port: + description: Port number of the gRPC service. Number must + be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place + in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior is + defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the + pod IP. You probably want to set "Host" in httpHeaders + instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP + allows repeated headers. + items: + description: HTTPHeader describes a custom header to + be used in HTTP probes + properties: + name: + description: The header field name. This will be + canonicalized upon output, so case-variant names + will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the + container. Number must be in the range 1 to 65535. Name + must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started + before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to + be considered successful after having failed. Defaults to + 1. Must be 1 for liveness and startup. Minimum value is + 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP + port. + properties: + host: + description: 'Optional: Host name to connect to, defaults + to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the + container. Number must be in the range 1 to 65535. Name + must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to + terminate gracefully upon probe failure. The grace period + is the duration in seconds after the processes running in + the pod are sent a termination signal and the time when + the processes are forcibly halted with a kill signal. Set + this value longer than the expected cleanup time for your + process. If this value is nil, the pod's terminationGracePeriodSeconds + will be used. Otherwise, this value overrides the value + provided by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the kill signal + (no opportunity to shut down). This is a beta field and + requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is + used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times + out. Defaults to 1 second. Minimum value is 1. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + redisConfig: + description: RedisConfig defines the external configuration of + Redis + properties: + additionalRedisConfig: + type: string + type: object + replicas: + format: int32 + type: integer + securityContext: + description: SecurityContext holds security configuration that + will be applied to a container. Some fields are present in both + SecurityContext and PodSecurityContext. When both are set, + the values in SecurityContext take precedence. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a + process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the + container runtime. Note that this field cannot be set when + spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in + privileged containers are essentially equivalent to root + on the host. Defaults to false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use + for the containers. The default is DefaultProcMount which + uses the container runtime defaults for readonly paths and + masked paths. This requires the ProcMountType feature flag + to be enabled. Note that this field cannot be set when spec.os.name + is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when + spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail + to start the container if it does. If unset or false, no + such validation will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata if + unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. Note + that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must + be preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must be set if type is "Localhost". Must NOT + be set for any other type. + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a + profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile + should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also be + set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using + the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. + Empty means match all taint effects. When specified, allowed + values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match + all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to + the value. Valid operators are Exists and Equal. Defaults + to Equal. Exists is equivalent to wildcard for value, + so that a pod can tolerate all taints of a particular + category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of + time the toleration (which must be of effect NoExecute, + otherwise this field is ignored) tolerates the taint. + By default, it is not set, which means tolerate the taint + forever (do not evict). Zero and negative values will + be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + type: object + redisLeader: + description: RedisLeader interface will have the redis leader configuration + properties: + affinity: + description: Affinity is a group of affinity scheduling rules. + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for + the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node matches the corresponding matchExpressions; + the node(s) with the highest sum are the most preferred. + items: + description: An empty preferred scheduling term matches + all objects with implicit weight 0 (i.e. it's a no-op). + A null preferred scheduling term matches no objects + (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated with + the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + description: Weight associated with matching the + corresponding nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the affinity requirements + specified by this field cease to be met at some point + during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from + its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: A null or empty node selector term + matches no objects. The requirements of them are + ANDed. The TopologySelectorTerm type implements + a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. + co-locate this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum are + the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod + label keys to select which pods will be taken + into consideration. The keys are used to lookup + values from the incoming pod labels, those + key-value labels are merged with `LabelSelector` + as `key in (value)` to select the group of + existing pods which pods will be taken into + consideration for the incoming pod's pod (anti) + affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value + is empty. The same key is forbidden to exist + in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature + gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod + label keys to select which pods will be taken + into consideration. The keys are used to lookup + values from the incoming pod labels, those + key-value labels are merged with `LabelSelector` + as `key notin (value)` to select the group + of existing pods which pods will be taken + into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist + in the incoming pod labels will be ignored. + The default value is empty. The same key is + forbidden to exist in both MismatchLabelKeys + and LabelSelector. Also, MismatchLabelKeys + cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling + MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by + this field and the ones listed in the namespaces + field. null selector and null or empty namespaces + list means "this pod's namespace". An empty + selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. + The term is applied to the union of the namespaces + listed in this field and the ones selected + by namespaceSelector. null or empty namespaces + list and null namespaceSelector means "this + pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the + corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the affinity requirements + specified by this field cease to be met at some point + during pod execution (e.g. due to a pod label update), + the system may or may not try to eventually evict the + pod from its node. When there are multiple elements, + the lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not + co-located (anti-affinity) with, where co-located + is defined as running on a node whose value of the + label with key matches that of any node + on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key in (value)` to select + the group of existing pods which pods will be + taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MatchLabelKeys and LabelSelector. Also, + MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key notin (value)` to + select the group of existing pods which pods will + be taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MismatchLabelKeys and LabelSelector. Also, + MismatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules + (e.g. avoid putting this pod in the same node, zone, etc. + as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the anti-affinity expressions + specified by this field, but it may choose a node that + violates one or more of the expressions. The node that + is most preferred is the one with the greatest sum of + weights, i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + anti-affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum are + the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod + label keys to select which pods will be taken + into consideration. The keys are used to lookup + values from the incoming pod labels, those + key-value labels are merged with `LabelSelector` + as `key in (value)` to select the group of + existing pods which pods will be taken into + consideration for the incoming pod's pod (anti) + affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value + is empty. The same key is forbidden to exist + in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature + gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod + label keys to select which pods will be taken + into consideration. The keys are used to lookup + values from the incoming pod labels, those + key-value labels are merged with `LabelSelector` + as `key notin (value)` to select the group + of existing pods which pods will be taken + into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist + in the incoming pod labels will be ignored. + The default value is empty. The same key is + forbidden to exist in both MismatchLabelKeys + and LabelSelector. Also, MismatchLabelKeys + cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling + MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by + this field and the ones listed in the namespaces + field. null selector and null or empty namespaces + list means "this pod's namespace". An empty + selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. + The term is applied to the union of the namespaces + listed in this field and the ones selected + by namespaceSelector. null or empty namespaces + list and null namespaceSelector means "this + pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the + corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified + by this field are not met at scheduling time, the pod + will not be scheduled onto the node. If the anti-affinity + requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod + label update), the system may or may not try to eventually + evict the pod from its node. When there are multiple + elements, the lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not + co-located (anti-affinity) with, where co-located + is defined as running on a node whose value of the + label with key matches that of any node + on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key in (value)` to select + the group of existing pods which pods will be + taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MatchLabelKeys and LabelSelector. Also, + MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key notin (value)` to + select the group of existing pods which pods will + be taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MismatchLabelKeys and LabelSelector. Also, + MismatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + livenessProbe: + description: Probe describes a health check to be performed against + a container to determine whether it is alive or ready to receive + traffic. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside + the container, the working directory for the command is + root ('/') in the container's filesystem. The command + is simply exec'd, it is not run inside a shell, so traditional + shell instructions ('|', etc) won't work. To use a shell, + you need to explicitly call out to that shell. Exit + status of 0 is treated as live/healthy and non-zero + is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to + be considered failed after having succeeded. Defaults to + 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. + properties: + port: + description: Port number of the gRPC service. Number must + be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place + in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior is + defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the + pod IP. You probably want to set "Host" in httpHeaders + instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP + allows repeated headers. + items: + description: HTTPHeader describes a custom header to + be used in HTTP probes + properties: + name: + description: The header field name. This will be + canonicalized upon output, so case-variant names + will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the + container. Number must be in the range 1 to 65535. Name + must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started + before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to + be considered successful after having failed. Defaults to + 1. Must be 1 for liveness and startup. Minimum value is + 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP + port. + properties: + host: + description: 'Optional: Host name to connect to, defaults + to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the + container. Number must be in the range 1 to 65535. Name + must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to + terminate gracefully upon probe failure. The grace period + is the duration in seconds after the processes running in + the pod are sent a termination signal and the time when + the processes are forcibly halted with a kill signal. Set + this value longer than the expected cleanup time for your + process. If this value is nil, the pod's terminationGracePeriodSeconds + will be used. Otherwise, this value overrides the value + provided by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the kill signal + (no opportunity to shut down). This is a beta field and + requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is + used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times + out. Defaults to 1 second. Minimum value is 1. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + nodeSelector: + additionalProperties: + type: string + type: object + pdb: + description: RedisPodDisruptionBudget configure a PodDisruptionBudget + on the resource (leader/follower) + properties: + enabled: + type: boolean + maxUnavailable: + format: int32 + type: integer + minAvailable: + format: int32 + type: integer + type: object + readinessProbe: + description: Probe describes a health check to be performed against + a container to determine whether it is alive or ready to receive + traffic. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside + the container, the working directory for the command is + root ('/') in the container's filesystem. The command + is simply exec'd, it is not run inside a shell, so traditional + shell instructions ('|', etc) won't work. To use a shell, + you need to explicitly call out to that shell. Exit + status of 0 is treated as live/healthy and non-zero + is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to + be considered failed after having succeeded. Defaults to + 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. + properties: + port: + description: Port number of the gRPC service. Number must + be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place + in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior is + defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the + pod IP. You probably want to set "Host" in httpHeaders + instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP + allows repeated headers. + items: + description: HTTPHeader describes a custom header to + be used in HTTP probes + properties: + name: + description: The header field name. This will be + canonicalized upon output, so case-variant names + will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the + container. Number must be in the range 1 to 65535. Name + must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started + before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to + be considered successful after having failed. Defaults to + 1. Must be 1 for liveness and startup. Minimum value is + 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP + port. + properties: + host: + description: 'Optional: Host name to connect to, defaults + to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the + container. Number must be in the range 1 to 65535. Name + must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to + terminate gracefully upon probe failure. The grace period + is the duration in seconds after the processes running in + the pod are sent a termination signal and the time when + the processes are forcibly halted with a kill signal. Set + this value longer than the expected cleanup time for your + process. If this value is nil, the pod's terminationGracePeriodSeconds + will be used. Otherwise, this value overrides the value + provided by the pod spec. Value must be non-negative integer. + The value zero indicates stop immediately via the kill signal + (no opportunity to shut down). This is a beta field and + requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is + used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times + out. Defaults to 1 second. Minimum value is 1. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + redisConfig: + description: RedisConfig defines the external configuration of + Redis + properties: + additionalRedisConfig: + type: string + type: object + replicas: + format: int32 + type: integer + securityContext: + description: SecurityContext holds security configuration that + will be applied to a container. Some fields are present in both + SecurityContext and PodSecurityContext. When both are set, + the values in SecurityContext take precedence. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a + process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the + container runtime. Note that this field cannot be set when + spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in + privileged containers are essentially equivalent to root + on the host. Defaults to false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use + for the containers. The default is DefaultProcMount which + uses the container runtime defaults for readonly paths and + masked paths. This requires the ProcMountType feature flag + to be enabled. Note that this field cannot be set when spec.os.name + is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when + spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail + to start the container if it does. If unset or false, no + such validation will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata if + unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. Note + that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must + be preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must be set if type is "Localhost". Must NOT + be set for any other type. + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a + profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile + should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also be + set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using + the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. + Empty means match all taint effects. When specified, allowed + values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match + all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to + the value. Valid operators are Exists and Equal. Defaults + to Equal. Exists is equivalent to wildcard for value, + so that a pod can tolerate all taints of a particular + category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of + time the toleration (which must be of effect NoExecute, + otherwise this field is ignored) tolerates the taint. + By default, it is not set, which means tolerate the taint + forever (do not evict). Zero and negative values will + be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + type: object + resources: + description: ResourceRequirements describes the compute resource requirements. + properties: + claims: + description: "Claims lists the names of resources, defined in + spec.resourceClaims, that are used by this container. \n This + is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be set + for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims + of the Pod where this field is used. It makes that resource + available inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources + allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + serviceAccountName: + type: string + sidecars: + items: + description: Sidecar for each Redis pods + properties: + command: + items: + type: string + type: array + env: + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be + a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. + If a variable cannot be resolved, the reference in the + input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) + syntax: i.e. "$$(VAR_NAME)" will produce the string + literal "$(VAR_NAME)". Escaped references will never + be expanded, regardless of whether the variable exists + or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its + key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + image: + type: string + imagePullPolicy: + description: PullPolicy describes a policy for if/when to pull + a container image + type: string + mountPath: + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: Path within the container at which the volume + should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are + propagated from the host to container and the other + way around. When not set, MountPropagationNone is used. + This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise + (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's + volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which + the container's volume should be mounted. Behaves similarly + to SubPath but environment variable references $(VAR_NAME) + are expanded using the container's environment. Defaults + to "" (volume's root). SubPathExpr and SubPath are mutually + exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + name: + type: string + ports: + items: + description: ContainerPort represents a network port in a + single container. + properties: + containerPort: + description: Number of port to expose on the pod's IP + address. This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port to. + type: string + hostPort: + description: Number of port to expose on the host. If + specified, this must be a valid port number, 0 < x < + 65536. If HostNetwork is specified, this must match + ContainerPort. Most containers do not need this. + format: int32 + type: integer + name: + description: If specified, this must be an IANA_SVC_NAME + and unique within the pod. Each named port in a pod + must have a unique name. Name for the port that can + be referred to by services. + type: string + protocol: + default: TCP + description: Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + resources: + description: ResourceRequirements describes the compute resource + requirements. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only + be set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where this + field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests + cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: SecurityContext holds security configuration that + will be applied to a container. Some fields are present in + both SecurityContext and PodSecurityContext. When both are + set, the values in SecurityContext take precedence. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether + a process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by + the container runtime. Note that this field cannot be + set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes + in privileged containers are essentially equivalent to + root on the host. Defaults to false. Note that this field + cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to + use for the containers. The default is DefaultProcMount + which uses the container runtime defaults for readonly + paths and masked paths. This requires the ProcMountType + feature flag to be enabled. Note that this field cannot + be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root + filesystem. Default is false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a + non-root user. If true, the Kubelet will validate the + image at runtime to ensure that it does not run as UID + 0 (root) and fail to start the container if it does. If + unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both + SecurityContext and PodSecurityContext, the value specified + in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata + if unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a + random SELinux context for each container. May also be + set in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. + Note that this field cannot be set when spec.os.name is + windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile + must be preconfigured on the node to work. Must be + a descending path, relative to the kubelet's configured + seccomp profile location. Must be set if type is "Localhost". + Must NOT be set for any other type. + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - + a profile defined in a file on the node should be + used. RuntimeDefault - the container runtime default + profile should be used. Unconfined - no profile should + be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also + be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set + in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + required: + - image + - name + type: object + type: array + storage: + description: Node-conf needs to be added only in redis cluster + properties: + keepAfterDelete: + type: boolean + nodeConfVolume: + default: false + type: boolean + nodeConfVolumeClaimTemplate: + description: PersistentVolumeClaim is a user's request for and + claim to a persistent volume + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this + representation of an object. Servers should convert recognized + schemas to the latest internal value, and may reject unrecognized + values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST + resource this object represents. Servers may infer this + from the endpoint the client submits requests to. Cannot + be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + description: 'Standard object''s metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata' + type: object + spec: + description: 'spec defines the desired characteristics of + a volume requested by a pod author. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + accessModes: + description: 'accessModes contains the desired access + modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'dataSource field can be used to specify + either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) If the provisioner + or an external controller can support the specified + data source, it will create a new volume based on the + contents of the specified data source. When the AnyVolumeDataSource + feature gate is enabled, dataSource contents will be + copied to dataSourceRef, and dataSourceRef contents + will be copied to dataSource when dataSourceRef.namespace + is not specified. If the namespace is specified, then + dataSourceRef will not be copied to dataSource.' + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + dataSourceRef: + description: 'dataSourceRef specifies the object from + which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty + API group (non core object) or a PersistentVolumeClaim + object. When this field is specified, volume binding + will only succeed if the type of the specified object + matches some installed volume populator or dynamic provisioner. + This field will replace the functionality of the dataSource + field and as such if both fields are non-empty, they + must have the same value. For backwards compatibility, + when namespace isn''t specified in dataSourceRef, both + fields (dataSource and dataSourceRef) will be set to + the same value automatically if one of them is empty + and the other is non-empty. When namespace is specified + in dataSourceRef, dataSource isn''t set to the same + value and must be empty. There are three important differences + between dataSource and dataSourceRef: * While dataSource + only allows two specific types of objects, dataSourceRef allows + any non-core object, as well as PersistentVolumeClaim + objects. * While dataSource ignores disallowed values + (dropping them), dataSourceRef preserves all values, + and generates an error if a disallowed value is specified. + * While dataSource only allows local objects, dataSourceRef + allows objects in any namespaces. (Beta) Using this + field requires the AnyVolumeDataSource feature gate + to be enabled. (Alpha) Using the namespace field of + dataSourceRef requires the CrossNamespaceVolumeDataSource + feature gate to be enabled.' + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + namespace: + description: Namespace is the namespace of resource + being referenced Note that when a namespace is specified, + a gateway.networking.k8s.io/ReferenceGrant object + is required in the referent namespace to allow that + namespace's owner to accept the reference. See the + ReferenceGrant documentation for details. (Alpha) + This field requires the CrossNamespaceVolumeDataSource + feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: 'resources represents the minimum resources + the volume should have. If RecoverVolumeExpansionFailure + feature is enabled users are allowed to specify resource + requirements that are lower than previous value but + must still be higher than capacity recorded in the status + field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount + of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount + of compute resources required. If Requests is omitted + for a container, it defaults to Limits if that is + explicitly specified, otherwise to an implementation-defined + value. Requests cannot exceed Limits. More info: + https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + selector: + description: selector is a label query over volumes to + consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, + NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values + array must be non-empty. If the operator is + Exists or DoesNotExist, the values array must + be empty. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field + is "key", the operator is "In", and the values array + contains only "value". The requirements are ANDed. + type: object + type: object + storageClassName: + description: 'storageClassName is the name of the StorageClass + required by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + type: string + volumeAttributesClassName: + description: 'volumeAttributesClassName may be used to + set the VolumeAttributesClass used by this claim. If + specified, the CSI driver will create or update the + volume with the attributes defined in the corresponding + VolumeAttributesClass. This has a different purpose + than storageClassName, it can be changed after the claim + is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it''s not allowed to + reset this field to empty string once it is set. If + unspecified and the PersistentVolumeClaim is unbound, + the default VolumeAttributesClass will be set by the + persistentvolume controller if it exists. If the resource + referred to by volumeAttributesClass does not exist, + this PersistentVolumeClaim will be set to a Pending + state, as reflected by the modifyVolumeStatus field, + until such as a resource exists. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + (Alpha) Using this field requires the VolumeAttributesClass + feature gate to be enabled.' + type: string + volumeMode: + description: volumeMode defines what type of volume is + required by the claim. Value of Filesystem is implied + when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to the + PersistentVolume backing this claim. + type: string + type: object + status: + description: 'status represents the current information/status + of a persistent volume claim. Read-only. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + accessModes: + description: 'accessModes contains the actual access modes + the volume backing the PVC has. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + allocatedResourceStatuses: + additionalProperties: + description: When a controller receives persistentvolume + claim update with ClaimResourceStatus for a resource + that it does not recognizes, then it should ignore + that update and let other controllers handle it. + type: string + description: "allocatedResourceStatuses stores status + of resource being resized for the given PVC. Key names + follow standard Kubernetes label syntax. Valid values + are either: \t* Un-prefixed keys: \t\t- storage - the + capacity of the volume. \t* Custom resources must use + implementation-defined prefixed names such as \"example.com/my-custom-resource\" + Apart from above values - keys that are unprefixed or + have kubernetes.io prefix are considered reserved and + hence may not be used. \n ClaimResourceStatus can be + in any of following states: \t- ControllerResizeInProgress: + \t\tState set when resize controller starts resizing + the volume in control-plane. \t- ControllerResizeFailed: + \t\tState set when resize has failed in resize controller + with a terminal error. \t- NodeResizePending: \t\tState + set when resize controller has finished resizing the + volume but further resizing of \t\tvolume is needed + on the node. \t- NodeResizeInProgress: \t\tState set + when kubelet starts resizing the volume. \t- NodeResizeFailed: + \t\tState set when resizing has failed in kubelet with + a terminal error. Transient errors don't set \t\tNodeResizeFailed. + For example: if expanding a PVC for more capacity - + this field can be one of the following states: \t- pvc.status.allocatedResourceStatus['storage'] + = \"ControllerResizeInProgress\" - pvc.status.allocatedResourceStatus['storage'] + = \"ControllerResizeFailed\" - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizePending\" - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizeInProgress\" - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizeFailed\" When this field is not set, it + means that no resize operation is in progress for the + given PVC. \n A controller that receives PVC update + with previously unknown resourceName or ClaimResourceStatus + should ignore the update for the purpose it was designed. + For example - a controller that only is responsible + for resizing capacity of the volume, should ignore PVC + updates that change other valid resources associated + with PVC. \n This is an alpha field and requires enabling + RecoverVolumeExpansionFailure feature." + type: object + x-kubernetes-map-type: granular + allocatedResources: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: "allocatedResources tracks the resources + allocated to a PVC including its capacity. Key names + follow standard Kubernetes label syntax. Valid values + are either: \t* Un-prefixed keys: \t\t- storage - the + capacity of the volume. \t* Custom resources must use + implementation-defined prefixed names such as \"example.com/my-custom-resource\" + Apart from above values - keys that are unprefixed or + have kubernetes.io prefix are considered reserved and + hence may not be used. \n Capacity reported here may + be larger than the actual capacity when a volume expansion + operation is requested. For storage quota, the larger + value from allocatedResources and PVC.spec.resources + is used. If allocatedResources is not set, PVC.spec.resources + alone is used for quota calculation. If a volume expansion + capacity request is lowered, allocatedResources is only + lowered if there are no expansion operations in progress + and if the actual volume capacity is equal or lower + than the requested capacity. \n A controller that receives + PVC update with previously unknown resourceName should + ignore the update for the purpose it was designed. For + example - a controller that only is responsible for + resizing capacity of the volume, should ignore PVC updates + that change other valid resources associated with PVC. + \n This is an alpha field and requires enabling RecoverVolumeExpansionFailure + feature." + type: object + capacity: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: capacity represents the actual resources + of the underlying volume. + type: object + conditions: + description: conditions is the current Condition of persistent + volume claim. If underlying persistent volume is being + resized then the Condition will be set to 'ResizeStarted'. + items: + description: PersistentVolumeClaimCondition contains + details about state of pvc + properties: + lastProbeTime: + description: lastProbeTime is the time we probed + the condition. + format: date-time + type: string + lastTransitionTime: + description: lastTransitionTime is the time the + condition transitioned from one status to another. + format: date-time + type: string + message: + description: message is the human-readable message + indicating details about last transition. + type: string + reason: + description: reason is a unique, this should be + a short, machine understandable string that gives + the reason for condition's last transition. If + it reports "ResizeStarted" that means the underlying + persistent volume is being resized. + type: string + status: + type: string + type: + description: PersistentVolumeClaimConditionType + is a valid value of PersistentVolumeClaimCondition.Type + type: string + required: + - status + - type + type: object + type: array + currentVolumeAttributesClassName: + description: currentVolumeAttributesClassName is the current + name of the VolumeAttributesClass the PVC is using. + When unset, there is no VolumeAttributeClass applied + to this PersistentVolumeClaim This is an alpha field + and requires enabling VolumeAttributesClass feature. + type: string + modifyVolumeStatus: + description: ModifyVolumeStatus represents the status + object of ControllerModifyVolume operation. When this + is unset, there is no ModifyVolume operation being attempted. + This is an alpha field and requires enabling VolumeAttributesClass + feature. + properties: + status: + description: "status is the status of the ControllerModifyVolume + operation. It can be in any of following states: + \ - Pending Pending indicates that the PersistentVolumeClaim + cannot be modified due to unmet requirements, such + as the specified VolumeAttributesClass not existing. + \ - InProgress InProgress indicates that the + volume is being modified. - Infeasible Infeasible + indicates that the request has been rejected as + invalid by the CSI driver. To \t resolve the error, + a valid VolumeAttributesClass needs to be specified. + Note: New statuses can be added in the future. Consumers + should check for unknown statuses and fail appropriately." + type: string + targetVolumeAttributesClassName: + description: targetVolumeAttributesClassName is the + name of the VolumeAttributesClass the PVC currently + being reconciled + type: string + required: + - status + type: object + phase: + description: phase represents the current phase of PersistentVolumeClaim. + type: string + type: object + type: object + volumeClaimTemplate: + description: PersistentVolumeClaim is a user's request for and + claim to a persistent volume + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this + representation of an object. Servers should convert recognized + schemas to the latest internal value, and may reject unrecognized + values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST + resource this object represents. Servers may infer this + from the endpoint the client submits requests to. Cannot + be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + description: 'Standard object''s metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata' + type: object + spec: + description: 'spec defines the desired characteristics of + a volume requested by a pod author. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + accessModes: + description: 'accessModes contains the desired access + modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'dataSource field can be used to specify + either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) If the provisioner + or an external controller can support the specified + data source, it will create a new volume based on the + contents of the specified data source. When the AnyVolumeDataSource + feature gate is enabled, dataSource contents will be + copied to dataSourceRef, and dataSourceRef contents + will be copied to dataSource when dataSourceRef.namespace + is not specified. If the namespace is specified, then + dataSourceRef will not be copied to dataSource.' + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + dataSourceRef: + description: 'dataSourceRef specifies the object from + which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty + API group (non core object) or a PersistentVolumeClaim + object. When this field is specified, volume binding + will only succeed if the type of the specified object + matches some installed volume populator or dynamic provisioner. + This field will replace the functionality of the dataSource + field and as such if both fields are non-empty, they + must have the same value. For backwards compatibility, + when namespace isn''t specified in dataSourceRef, both + fields (dataSource and dataSourceRef) will be set to + the same value automatically if one of them is empty + and the other is non-empty. When namespace is specified + in dataSourceRef, dataSource isn''t set to the same + value and must be empty. There are three important differences + between dataSource and dataSourceRef: * While dataSource + only allows two specific types of objects, dataSourceRef allows + any non-core object, as well as PersistentVolumeClaim + objects. * While dataSource ignores disallowed values + (dropping them), dataSourceRef preserves all values, + and generates an error if a disallowed value is specified. + * While dataSource only allows local objects, dataSourceRef + allows objects in any namespaces. (Beta) Using this + field requires the AnyVolumeDataSource feature gate + to be enabled. (Alpha) Using the namespace field of + dataSourceRef requires the CrossNamespaceVolumeDataSource + feature gate to be enabled.' + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + namespace: + description: Namespace is the namespace of resource + being referenced Note that when a namespace is specified, + a gateway.networking.k8s.io/ReferenceGrant object + is required in the referent namespace to allow that + namespace's owner to accept the reference. See the + ReferenceGrant documentation for details. (Alpha) + This field requires the CrossNamespaceVolumeDataSource + feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: 'resources represents the minimum resources + the volume should have. If RecoverVolumeExpansionFailure + feature is enabled users are allowed to specify resource + requirements that are lower than previous value but + must still be higher than capacity recorded in the status + field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount + of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount + of compute resources required. If Requests is omitted + for a container, it defaults to Limits if that is + explicitly specified, otherwise to an implementation-defined + value. Requests cannot exceed Limits. More info: + https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + selector: + description: selector is a label query over volumes to + consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, + NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values + array must be non-empty. If the operator is + Exists or DoesNotExist, the values array must + be empty. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field + is "key", the operator is "In", and the values array + contains only "value". The requirements are ANDed. + type: object + type: object + storageClassName: + description: 'storageClassName is the name of the StorageClass + required by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + type: string + volumeAttributesClassName: + description: 'volumeAttributesClassName may be used to + set the VolumeAttributesClass used by this claim. If + specified, the CSI driver will create or update the + volume with the attributes defined in the corresponding + VolumeAttributesClass. This has a different purpose + than storageClassName, it can be changed after the claim + is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it''s not allowed to + reset this field to empty string once it is set. If + unspecified and the PersistentVolumeClaim is unbound, + the default VolumeAttributesClass will be set by the + persistentvolume controller if it exists. If the resource + referred to by volumeAttributesClass does not exist, + this PersistentVolumeClaim will be set to a Pending + state, as reflected by the modifyVolumeStatus field, + until such as a resource exists. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + (Alpha) Using this field requires the VolumeAttributesClass + feature gate to be enabled.' + type: string + volumeMode: + description: volumeMode defines what type of volume is + required by the claim. Value of Filesystem is implied + when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to the + PersistentVolume backing this claim. + type: string + type: object + status: + description: 'status represents the current information/status + of a persistent volume claim. Read-only. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + accessModes: + description: 'accessModes contains the actual access modes + the volume backing the PVC has. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + allocatedResourceStatuses: + additionalProperties: + description: When a controller receives persistentvolume + claim update with ClaimResourceStatus for a resource + that it does not recognizes, then it should ignore + that update and let other controllers handle it. + type: string + description: "allocatedResourceStatuses stores status + of resource being resized for the given PVC. Key names + follow standard Kubernetes label syntax. Valid values + are either: \t* Un-prefixed keys: \t\t- storage - the + capacity of the volume. \t* Custom resources must use + implementation-defined prefixed names such as \"example.com/my-custom-resource\" + Apart from above values - keys that are unprefixed or + have kubernetes.io prefix are considered reserved and + hence may not be used. \n ClaimResourceStatus can be + in any of following states: \t- ControllerResizeInProgress: + \t\tState set when resize controller starts resizing + the volume in control-plane. \t- ControllerResizeFailed: + \t\tState set when resize has failed in resize controller + with a terminal error. \t- NodeResizePending: \t\tState + set when resize controller has finished resizing the + volume but further resizing of \t\tvolume is needed + on the node. \t- NodeResizeInProgress: \t\tState set + when kubelet starts resizing the volume. \t- NodeResizeFailed: + \t\tState set when resizing has failed in kubelet with + a terminal error. Transient errors don't set \t\tNodeResizeFailed. + For example: if expanding a PVC for more capacity - + this field can be one of the following states: \t- pvc.status.allocatedResourceStatus['storage'] + = \"ControllerResizeInProgress\" - pvc.status.allocatedResourceStatus['storage'] + = \"ControllerResizeFailed\" - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizePending\" - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizeInProgress\" - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizeFailed\" When this field is not set, it + means that no resize operation is in progress for the + given PVC. \n A controller that receives PVC update + with previously unknown resourceName or ClaimResourceStatus + should ignore the update for the purpose it was designed. + For example - a controller that only is responsible + for resizing capacity of the volume, should ignore PVC + updates that change other valid resources associated + with PVC. \n This is an alpha field and requires enabling + RecoverVolumeExpansionFailure feature." + type: object + x-kubernetes-map-type: granular + allocatedResources: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: "allocatedResources tracks the resources + allocated to a PVC including its capacity. Key names + follow standard Kubernetes label syntax. Valid values + are either: \t* Un-prefixed keys: \t\t- storage - the + capacity of the volume. \t* Custom resources must use + implementation-defined prefixed names such as \"example.com/my-custom-resource\" + Apart from above values - keys that are unprefixed or + have kubernetes.io prefix are considered reserved and + hence may not be used. \n Capacity reported here may + be larger than the actual capacity when a volume expansion + operation is requested. For storage quota, the larger + value from allocatedResources and PVC.spec.resources + is used. If allocatedResources is not set, PVC.spec.resources + alone is used for quota calculation. If a volume expansion + capacity request is lowered, allocatedResources is only + lowered if there are no expansion operations in progress + and if the actual volume capacity is equal or lower + than the requested capacity. \n A controller that receives + PVC update with previously unknown resourceName should + ignore the update for the purpose it was designed. For + example - a controller that only is responsible for + resizing capacity of the volume, should ignore PVC updates + that change other valid resources associated with PVC. + \n This is an alpha field and requires enabling RecoverVolumeExpansionFailure + feature." + type: object + capacity: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: capacity represents the actual resources + of the underlying volume. + type: object + conditions: + description: conditions is the current Condition of persistent + volume claim. If underlying persistent volume is being + resized then the Condition will be set to 'ResizeStarted'. + items: + description: PersistentVolumeClaimCondition contains + details about state of pvc + properties: + lastProbeTime: + description: lastProbeTime is the time we probed + the condition. + format: date-time + type: string + lastTransitionTime: + description: lastTransitionTime is the time the + condition transitioned from one status to another. + format: date-time + type: string + message: + description: message is the human-readable message + indicating details about last transition. + type: string + reason: + description: reason is a unique, this should be + a short, machine understandable string that gives + the reason for condition's last transition. If + it reports "ResizeStarted" that means the underlying + persistent volume is being resized. + type: string + status: + type: string + type: + description: PersistentVolumeClaimConditionType + is a valid value of PersistentVolumeClaimCondition.Type + type: string + required: + - status + - type + type: object + type: array + currentVolumeAttributesClassName: + description: currentVolumeAttributesClassName is the current + name of the VolumeAttributesClass the PVC is using. + When unset, there is no VolumeAttributeClass applied + to this PersistentVolumeClaim This is an alpha field + and requires enabling VolumeAttributesClass feature. + type: string + modifyVolumeStatus: + description: ModifyVolumeStatus represents the status + object of ControllerModifyVolume operation. When this + is unset, there is no ModifyVolume operation being attempted. + This is an alpha field and requires enabling VolumeAttributesClass + feature. + properties: + status: + description: "status is the status of the ControllerModifyVolume + operation. It can be in any of following states: + \ - Pending Pending indicates that the PersistentVolumeClaim + cannot be modified due to unmet requirements, such + as the specified VolumeAttributesClass not existing. + \ - InProgress InProgress indicates that the + volume is being modified. - Infeasible Infeasible + indicates that the request has been rejected as + invalid by the CSI driver. To \t resolve the error, + a valid VolumeAttributesClass needs to be specified. + Note: New statuses can be added in the future. Consumers + should check for unknown statuses and fail appropriately." + type: string + targetVolumeAttributesClassName: + description: targetVolumeAttributesClassName is the + name of the VolumeAttributesClass the PVC currently + being reconciled + type: string + required: + - status + type: object + phase: + description: phase represents the current phase of PersistentVolumeClaim. + type: string + type: object + type: object + volumeMount: + description: Additional Volume is provided by user that is mounted + on the pods + properties: + mountPath: + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: Path within the container at which the + volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts + are propagated from the host to container and the + other way around. When not set, MountPropagationNone + is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise + (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's + volume should be mounted. Defaults to "" (volume's + root). + type: string + subPathExpr: + description: Expanded path within the volume from which + the container's volume should be mounted. Behaves + similarly to SubPath but environment variable references + $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). SubPathExpr and SubPath + are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + volume: + items: + description: Volume represents a named volume in a pod that + may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: 'awsElasticBlockStore represents an AWS + Disk resource that is attached to a kubelet''s host + machine and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + properties: + fsType: + description: 'fsType is the filesystem type of the + volume that you want to mount. Tip: Ensure that + the filesystem type is supported by the host operating + system. Examples: "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. More info: + https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem + from compromising the machine' + type: string + partition: + description: 'partition is the partition in the + volume that you want to mount. If omitted, the + default is to mount by volume name. Examples: + For volume /dev/sda1, you specify the partition + as "1". Similarly, the volume partition for /dev/sda + is "0" (or you can leave the property empty).' + format: int32 + type: integer + readOnly: + description: 'readOnly value true will force the + readOnly setting in VolumeMounts. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: boolean + volumeID: + description: 'volumeID is unique ID of the persistent + disk resource in AWS (Amazon EBS volume). More + info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data Disk + mount on the host and bind mount to the pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching mode: + None, Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data disk + in the blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in + the blob storage + type: string + fsType: + description: fsType is Filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: multiple + blob disks per storage account Dedicated: single + blob disk per storage account Managed: azure + managed data disk (only in managed availability + set). defaults to shared' + type: string + readOnly: + description: readOnly Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File Service + mount on the host and bind mount to the pod. + properties: + readOnly: + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret that + contains Azure Storage Account Name and Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount on the + host that shares a pod's lifetime + properties: + monitors: + description: 'monitors is Required: Monitors is + a collection of Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + items: + type: string + type: array + path: + description: 'path is Optional: Used as the mounted + root, rather than the full Ceph tree, default + is /' + type: string + readOnly: + description: 'readOnly is Optional: Defaults to + false (read/write). ReadOnly here will force the + ReadOnly setting in VolumeMounts. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: boolean + secretFile: + description: 'secretFile is Optional: SecretFile + is the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + secretRef: + description: 'secretRef is Optional: SecretRef is + reference to the authentication secret for User, + default is empty. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + user: + description: 'user is optional: User is the rados + user name, default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + required: + - monitors + type: object + cinder: + description: 'cinder represents a cinder volume attached + and mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + properties: + fsType: + description: 'fsType is the filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Examples: "ext4", "xfs", "ntfs". + Implicitly inferred to be "ext4" if unspecified. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + readOnly: + description: 'readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: boolean + secretRef: + description: 'secretRef is optional: points to a + secret object containing parameters used to connect + to OpenStack.' + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + volumeID: + description: 'volumeID used to identify the volume + in cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that should + populate this volume + properties: + defaultMode: + description: 'defaultMode is optional: mode bits + used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or + a decimal value between 0 and 511. YAML accepts + both octal and decimal values, JSON requires decimal + values for mode bits. Defaults to 0644. Directories + within the path are not affected by this setting. + This might be in conflict with other options that + affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + items: + description: items if unspecified, each key-value + pair in the Data field of the referenced ConfigMap + will be projected into the volume as a file whose + name is the key and content is the value. If specified, + the listed keys will be projected into the specified + paths, and unlisted keys will not be present. + If a key is specified which is not present in + the ConfigMap, the volume setup will error unless + it is marked optional. Paths must be relative + and may not contain the '..' path or start with + '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits + used to set permissions on this file. Must + be an octal value between 0000 and 0777 + or a decimal value between 0 and 511. YAML + accepts both octal and decimal values, JSON + requires decimal values for mode bits. If + not specified, the volume defaultMode will + be used. This might be in conflict with + other options that affect the file mode, + like fsGroup, and the result can be other + mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of + the file to map the key to. May not be an + absolute path. May not contain the path + element '..'. May not start with the string + '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + csi: + description: csi (Container Storage Interface) represents + ephemeral storage that is handled by certain external + CSI drivers (Beta feature). + properties: + driver: + description: driver is the name of the CSI driver + that handles this volume. Consult with your admin + for the correct name as registered in the cluster. + type: string + fsType: + description: fsType to mount. Ex. "ext4", "xfs", + "ntfs". If not provided, the empty value is passed + to the associated CSI driver which will determine + the default filesystem to apply. + type: string + nodePublishSecretRef: + description: nodePublishSecretRef is a reference + to the secret object containing sensitive information + to pass to the CSI driver to complete the CSI + NodePublishVolume and NodeUnpublishVolume calls. + This field is optional, and may be empty if no + secret is required. If the secret object contains + more than one secret, all secret references are + passed. + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + readOnly: + description: readOnly specifies a read-only configuration + for the volume. Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: volumeAttributes stores driver-specific + properties that are passed to the CSI driver. + Consult your driver's documentation for supported + values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about + the pod that should populate this volume + properties: + defaultMode: + description: 'Optional: mode bits to use on created + files by default. Must be a Optional: mode bits + used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or + a decimal value between 0 and 511. YAML accepts + both octal and decimal values, JSON requires decimal + values for mode bits. Defaults to 0644. Directories + within the path are not affected by this setting. + This might be in conflict with other options that + affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + items: + description: Items is a list of downward API volume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing the + pod field + properties: + fieldRef: + description: 'Required: Selects a field of + the pod: only annotations, labels, name + and namespace are supported.' + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: mode bits used to + set permissions on this file, must be an + octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both + octal and decimal values, JSON requires + decimal values for mode bits. If not specified, + the volume defaultMode will be used. This + might be in conflict with other options + that affect the file mode, like fsGroup, + and the result can be other mode bits set.' + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. Must + not be absolute or contain the ''..'' path. + Must be utf-8 encoded. The first item of + the relative path must not start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, requests.cpu and requests.memory) + are currently supported.' + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + emptyDir: + description: 'emptyDir represents a temporary directory + that shares a pod''s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + properties: + medium: + description: 'medium represents what type of storage + medium should back this directory. The default + is "" which means to use the node''s default medium. + Must be an empty string (default) or Memory. More + info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: 'sizeLimit is the total amount of local + storage required for this EmptyDir volume. The + size limit is also applicable for memory medium. + The maximum usage on memory medium EmptyDir would + be the minimum value between the SizeLimit specified + here and the sum of memory limits of all containers + in a pod. The default is nil which means that + the limit is undefined. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: "ephemeral represents a volume that is + handled by a cluster storage driver. The volume's + lifecycle is tied to the pod that defines it - it + will be created before the pod starts, and deleted + when the pod is removed. \n Use this if: a) the volume + is only needed while the pod runs, b) features of + normal volumes like restoring from snapshot or capacity + \ tracking are needed, c) the storage driver is + specified through a storage class, and d) the storage + driver supports dynamic volume provisioning through + \ a PersistentVolumeClaim (see EphemeralVolumeSource + for more information on the connection between + this volume type and PersistentVolumeClaim). \n + Use PersistentVolumeClaim or one of the vendor-specific + APIs for volumes that persist for longer than the + lifecycle of an individual pod. \n Use CSI for light-weight + local ephemeral volumes if the CSI driver is meant + to be used that way - see the documentation of the + driver for more information. \n A pod can use both + types of ephemeral volumes and persistent volumes + at the same time." + properties: + volumeClaimTemplate: + description: "Will be used to create a stand-alone + PVC to provision the volume. The pod in which + this EphemeralVolumeSource is embedded will be + the owner of the PVC, i.e. the PVC will be deleted + together with the pod. The name of the PVC will + be `-` where `` + is the name from the `PodSpec.Volumes` array entry. + Pod validation will reject the pod if the concatenated + name is not valid for a PVC (for example, too + long). \n An existing PVC with that name that + is not owned by the pod will *not* be used for + the pod to avoid using an unrelated volume by + mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created + PVC is meant to be used by the pod, the PVC has + to updated with an owner reference to the pod + once the pod exists. Normally this should not + be necessary, but it may be useful when manually + reconstructing a broken cluster. \n This field + is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. \n Required, + must not be nil." + properties: + metadata: + description: May contain labels and annotations + that will be copied into the PVC when creating + it. No other fields are allowed and will be + rejected during validation. + type: object + spec: + description: The specification for the PersistentVolumeClaim. + The entire content is copied unchanged into + the PVC that gets created from this template. + The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: 'accessModes contains the desired + access modes the volume should have. More + info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'dataSource field can be used + to specify either: * An existing VolumeSnapshot + object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller + can support the specified data source, + it will create a new volume based on the + contents of the specified data source. + When the AnyVolumeDataSource feature gate + is enabled, dataSource contents will be + copied to dataSourceRef, and dataSourceRef + contents will be copied to dataSource + when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef + will not be copied to dataSource.' + properties: + apiGroup: + description: APIGroup is the group for + the resource being referenced. If + APIGroup is not specified, the specified + Kind must be in the core API group. + For any other third-party types, APIGroup + is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + required: + - kind + - name + type: object + dataSourceRef: + description: 'dataSourceRef specifies the + object from which to populate the volume + with data, if a non-empty volume is desired. + This may be any object from a non-empty + API group (non core object) or a PersistentVolumeClaim + object. When this field is specified, + volume binding will only succeed if the + type of the specified object matches some + installed volume populator or dynamic + provisioner. This field will replace the + functionality of the dataSource field + and as such if both fields are non-empty, + they must have the same value. For backwards + compatibility, when namespace isn''t specified + in dataSourceRef, both fields (dataSource + and dataSourceRef) will be set to the + same value automatically if one of them + is empty and the other is non-empty. When + namespace is specified in dataSourceRef, + dataSource isn''t set to the same value + and must be empty. There are three important + differences between dataSource and dataSourceRef: + * While dataSource only allows two specific + types of objects, dataSourceRef allows + any non-core object, as well as PersistentVolumeClaim + objects. * While dataSource ignores disallowed + values (dropping them), dataSourceRef preserves + all values, and generates an error if + a disallowed value is specified. * While + dataSource only allows local objects, + dataSourceRef allows objects in any + namespaces. (Beta) Using this field requires + the AnyVolumeDataSource feature gate to + be enabled. (Alpha) Using the namespace + field of dataSourceRef requires the CrossNamespaceVolumeDataSource + feature gate to be enabled.' + properties: + apiGroup: + description: APIGroup is the group for + the resource being referenced. If + APIGroup is not specified, the specified + Kind must be in the core API group. + For any other third-party types, APIGroup + is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + namespace: + description: Namespace is the namespace + of resource being referenced Note + that when a namespace is specified, + a gateway.networking.k8s.io/ReferenceGrant + object is required in the referent + namespace to allow that namespace's + owner to accept the reference. See + the ReferenceGrant documentation for + details. (Alpha) This field requires + the CrossNamespaceVolumeDataSource + feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: 'resources represents the minimum + resources the volume should have. If RecoverVolumeExpansionFailure + feature is enabled users are allowed to + specify resource requirements that are + lower than previous value but must still + be higher than capacity recorded in the + status field of the claim. More info: + https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum + amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the + minimum amount of compute resources + required. If Requests is omitted for + a container, it defaults to Limits + if that is explicitly specified, otherwise + to an implementation-defined value. + Requests cannot exceed Limits. More + info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + selector: + description: selector is a label query over + volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. + This array is replaced during + a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of + {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + storageClassName: + description: 'storageClassName is the name + of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + type: string + volumeAttributesClassName: + description: 'volumeAttributesClassName + may be used to set the VolumeAttributesClass + used by this claim. If specified, the + CSI driver will create or update the volume + with the attributes defined in the corresponding + VolumeAttributesClass. This has a different + purpose than storageClassName, it can + be changed after the claim is created. + An empty string value means that no VolumeAttributesClass + will be applied to the claim but it''s + not allowed to reset this field to empty + string once it is set. If unspecified + and the PersistentVolumeClaim is unbound, + the default VolumeAttributesClass will + be set by the persistentvolume controller + if it exists. If the resource referred + to by volumeAttributesClass does not exist, + this PersistentVolumeClaim will be set + to a Pending state, as reflected by the + modifyVolumeStatus field, until such as + a resource exists. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + (Alpha) Using this field requires the + VolumeAttributesClass feature gate to + be enabled.' + type: string + volumeMode: + description: volumeMode defines what type + of volume is required by the claim. Value + of Filesystem is implied when not included + in claim spec. + type: string + volumeName: + description: volumeName is the binding reference + to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource + that is attached to a kubelet's host machine and then + exposed to the pod. + properties: + fsType: + description: 'fsType is the filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. TODO: how + do we prevent errors in the filesystem from compromising + the machine' + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: 'readOnly is Optional: Defaults to + false (read/write). ReadOnly here will force the + ReadOnly setting in VolumeMounts.' + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target + worldwide names (WWNs)' + items: + type: string + type: array + wwids: + description: 'wwids Optional: FC volume world wide + identifiers (wwids) Either wwids or combination + of targetWWNs and lun must be set, but not both + simultaneously.' + items: + type: string + type: array + type: object + flexVolume: + description: flexVolume represents a generic volume + resource that is provisioned/attached using an exec + based plugin. + properties: + driver: + description: driver is the name of the driver to + use for this volume. + type: string + fsType: + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". The + default filesystem depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field holds + extra command options if any.' + type: object + readOnly: + description: 'readOnly is Optional: defaults to + false (read/write). ReadOnly here will force the + ReadOnly setting in VolumeMounts.' + type: boolean + secretRef: + description: 'secretRef is Optional: secretRef is + reference to the secret object containing sensitive + information to pass to the plugin scripts. This + may be empty if no secret object is specified. + If the secret object contains more than one secret, + all secrets are passed to the plugin scripts.' + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume attached + to a kubelet's host machine. This depends on the Flocker + control service being running + properties: + datasetName: + description: datasetName is Name of the dataset + stored as metadata -> name on the dataset for + Flocker should be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. + This is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: 'gcePersistentDisk represents a GCE Disk + resource that is attached to a kubelet''s host machine + and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + properties: + fsType: + description: 'fsType is filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem + from compromising the machine' + type: string + partition: + description: 'partition is the partition in the + volume that you want to mount. If omitted, the + default is to mount by volume name. Examples: + For volume /dev/sda1, you specify the partition + as "1". Similarly, the volume partition for /dev/sda + is "0" (or you can leave the property empty). + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + format: int32 + type: integer + pdName: + description: 'pdName is unique name of the PD resource + in GCE. Used to identify the disk in GCE. More + info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: string + readOnly: + description: 'readOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. More + info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: boolean + required: + - pdName + type: object + gitRepo: + description: 'gitRepo represents a git repository at + a particular revision. DEPRECATED: GitRepo is deprecated. + To provision a container with a git repo, mount an + EmptyDir into an InitContainer that clones the repo + using git, then mount the EmptyDir into the Pod''s + container.' + properties: + directory: + description: directory is the target directory name. + Must not contain or start with '..'. If '.' is + supplied, the volume directory will be the git + repository. Otherwise, if specified, the volume + will contain the git repository in the subdirectory + with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the + specified revision. + type: string + required: + - repository + type: object + glusterfs: + description: 'glusterfs represents a Glusterfs mount + on the host that shares a pod''s lifetime. More info: + https://examples.k8s.io/volumes/glusterfs/README.md' + properties: + endpoints: + description: 'endpoints is the endpoint name that + details Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + path: + description: 'path is the Glusterfs volume path. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + readOnly: + description: 'readOnly here will force the Glusterfs + volume to be mounted with read-only permissions. + Defaults to false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: 'hostPath represents a pre-existing file + or directory on the host machine that is directly + exposed to the container. This is generally used for + system agents or other privileged things that are + allowed to see the host machine. Most containers will + NOT need this. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- TODO(jonesdl) We need to restrict who can use + host directory mounts and who can/can not mount host + directories as read/write.' + properties: + path: + description: 'path of the directory on the host. + If the path is a symlink, it will follow the link + to the real path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + type: + description: 'type for HostPath Volume Defaults + to "" More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + required: + - path + type: object + iscsi: + description: 'iscsi represents an ISCSI Disk resource + that is attached to a kubelet''s host machine and + then exposed to the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md' + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether support + iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support + iSCSI Session CHAP authentication + type: boolean + fsType: + description: 'fsType is the filesystem type of the + volume that you want to mount. Tip: Ensure that + the filesystem type is supported by the host operating + system. Examples: "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. More info: + https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem + from compromising the machine' + type: string + initiatorName: + description: initiatorName is the custom iSCSI Initiator + Name. If initiatorName is specified with iscsiInterface + simultaneously, new iSCSI interface : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified Name. + type: string + iscsiInterface: + description: iscsiInterface is the interface Name + that uses an iSCSI transport. Defaults to 'default' + (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: portals is the iSCSI Target Portal + List. The portal is either an IP or ip_addr:port + if the port is other than default (typically TCP + ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: readOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for iSCSI + target and initiator authentication + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + targetPortal: + description: targetPortal is iSCSI Target Portal. + The Portal is either an IP or ip_addr:port if + the port is other than default (typically TCP + ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: 'name of the volume. Must be a DNS_LABEL + and unique within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + nfs: + description: 'nfs represents an NFS mount on the host + that shares a pod''s lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + properties: + path: + description: 'path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + readOnly: + description: 'readOnly here will force the NFS export + to be mounted with read-only permissions. Defaults + to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: boolean + server: + description: 'server is the hostname or IP address + of the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: 'persistentVolumeClaimVolumeSource represents + a reference to a PersistentVolumeClaim in the same + namespace. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + claimName: + description: 'claimName is the name of a PersistentVolumeClaim + in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + type: string + readOnly: + description: readOnly Will force the ReadOnly setting + in VolumeMounts. Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents a PhotonController + persistent disk attached and mounted on kubelets host + machine + properties: + fsType: + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon + Controller persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx volume + attached and mounted on kubelets host machine + properties: + fsType: + description: fSType represents the filesystem type + to mount Must be a filesystem type supported by + the host operating system. Ex. "ext4", "xfs". + Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx + volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources + secrets, configmaps, and downward API + properties: + defaultMode: + description: defaultMode are the mode bits used + to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or + a decimal value between 0 and 511. YAML accepts + both octal and decimal values, JSON requires decimal + values for mode bits. Directories within the path + are not affected by this setting. This might be + in conflict with other options that affect the + file mode, like fsGroup, and the result can be + other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume projections + items: + description: Projection that may be projected + along with other supported volume types + properties: + clusterTrustBundle: + description: "ClusterTrustBundle allows a + pod to access the `.spec.trustBundle` field + of ClusterTrustBundle objects in an auto-updating + file. \n Alpha, gated by the ClusterTrustBundleProjection + feature gate. \n ClusterTrustBundle objects + can either be selected by name, or by the + combination of signer name and a label selector. + \n Kubelet performs aggressive normalization + of the PEM contents written into the pod + filesystem. Esoteric PEM features such + as inter-block comments and block headers + are stripped. Certificates are deduplicated. + The ordering of certificates within the + file is arbitrary, and Kubelet may change + the order over time." + properties: + labelSelector: + description: Select all ClusterTrustBundles + that match this label selector. Only + has effect if signerName is set. Mutually-exclusive + with name. If unset, interpreted as + "match nothing". If set but empty, + interpreted as "match everything". + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a + set of values. Valid operators + are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values + array must be non-empty. If + the operator is Exists or + DoesNotExist, the values array + must be empty. This array + is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map + of {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + name: + description: Select a single ClusterTrustBundle + by object name. Mutually-exclusive + with signerName and labelSelector. + type: string + optional: + description: If true, don't block pod + startup if the referenced ClusterTrustBundle(s) + aren't available. If using name, then + the named ClusterTrustBundle is allowed + not to exist. If using signerName, + then the combination of signerName and + labelSelector is allowed to match zero + ClusterTrustBundles. + type: boolean + path: + description: Relative path from the volume + root to write the bundle. + type: string + signerName: + description: Select all ClusterTrustBundles + that match this signer name. Mutually-exclusive + with name. The contents of all selected + ClusterTrustBundles will be unified + and deduplicated. + type: string + required: + - path + type: object + configMap: + description: configMap information about the + configMap data to project + properties: + items: + description: items if unspecified, each + key-value pair in the Data field of + the referenced ConfigMap will be projected + into the volume as a file whose name + is the key and content is the value. + If specified, the listed keys will be + projected into the specified paths, + and unlisted keys will not be present. + If a key is specified which is not present + in the ConfigMap, the volume setup will + error unless it is marked optional. + Paths must be relative and may not contain + the '..' path or start with '..'. + items: + description: Maps a string key to a + path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: + mode bits used to set permissions + on this file. Must be an octal + value between 0000 and 0777 or + a decimal value between 0 and + 511. YAML accepts both octal and + decimal values, JSON requires + decimal values for mode bits. + If not specified, the volume defaultMode + will be used. This might be in + conflict with other options that + affect the file mode, like fsGroup, + and the result can be other mode + bits set.' + format: int32 + type: integer + path: + description: path is the relative + path of the file to map the key + to. May not be an absolute path. + May not contain the path element + '..'. May not start with the string + '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: optional specify whether + the ConfigMap or its keys must be defined + type: boolean + type: object + downwardAPI: + description: downwardAPI information about + the downwardAPI data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects + a field of the pod: only annotations, + labels, name and namespace are + supported.' + properties: + apiVersion: + description: Version of the + schema the FieldPath is written + in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field + to select in the specified + API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: mode bits + used to set permissions on this + file, must be an octal value between + 0000 and 0777 or a decimal value + between 0 and 511. YAML accepts + both octal and decimal values, + JSON requires decimal values for + mode bits. If not specified, the + volume defaultMode will be used. + This might be in conflict with + other options that affect the + file mode, like fsGroup, and the + result can be other mode bits + set.' + format: int32 + type: integer + path: + description: 'Required: Path is the + relative path name of the file + to be created. Must not be absolute + or contain the ''..'' path. Must + be utf-8 encoded. The first item + of the relative path must not + start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource + of the container: only resources + limits and requests (limits.cpu, + limits.memory, requests.cpu and + requests.memory) are currently + supported.' + properties: + containerName: + description: 'Container name: + required for volumes, optional + for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource + to select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + secret: + description: secret information about the + secret data to project + properties: + items: + description: items if unspecified, each + key-value pair in the Data field of + the referenced Secret will be projected + into the volume as a file whose name + is the key and content is the value. + If specified, the listed keys will be + projected into the specified paths, + and unlisted keys will not be present. + If a key is specified which is not present + in the Secret, the volume setup will + error unless it is marked optional. + Paths must be relative and may not contain + the '..' path or start with '..'. + items: + description: Maps a string key to a + path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: + mode bits used to set permissions + on this file. Must be an octal + value between 0000 and 0777 or + a decimal value between 0 and + 511. YAML accepts both octal and + decimal values, JSON requires + decimal values for mode bits. + If not specified, the volume defaultMode + will be used. This might be in + conflict with other options that + affect the file mode, like fsGroup, + and the result can be other mode + bits set.' + format: int32 + type: integer + path: + description: path is the relative + path of the file to map the key + to. May not be an absolute path. + May not contain the path element + '..'. May not start with the string + '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: optional field specify whether + the Secret or its key must be defined + type: boolean + type: object + serviceAccountToken: + description: serviceAccountToken is information + about the serviceAccountToken data to project + properties: + audience: + description: audience is the intended + audience of the token. A recipient of + a token must identify itself with an + identifier specified in the audience + of the token, and otherwise should reject + the token. The audience defaults to + the identifier of the apiserver. + type: string + expirationSeconds: + description: expirationSeconds is the + requested duration of validity of the + service account token. As the token + approaches expiration, the kubelet volume + plugin will proactively rotate the service + account token. The kubelet will start + trying to rotate the token if the token + is older than 80 percent of its time + to live or if the token is older than + 24 hours.Defaults to 1 hour and must + be at least 10 minutes. + format: int64 + type: integer + path: + description: path is the path relative + to the mount point of the file to project + the token into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: quobyte represents a Quobyte mount on the + host that shares a pod's lifetime + properties: + group: + description: group to map volume access to Default + is no group + type: string + readOnly: + description: readOnly here will force the Quobyte + volume to be mounted with read-only permissions. + Defaults to false. + type: boolean + registry: + description: registry represents a single or multiple + Quobyte Registry services specified as a string + as host:port pair (multiple entries are separated + with commas) which acts as the central registry + for volumes + type: string + tenant: + description: tenant owning the given Quobyte volume + in the Backend Used with dynamically provisioned + Quobyte volumes, value is set by the plugin + type: string + user: + description: user to map volume access to Defaults + to serivceaccount user + type: string + volume: + description: volume is a string that references + an already created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: 'rbd represents a Rados Block Device mount + on the host that shares a pod''s lifetime. More info: + https://examples.k8s.io/volumes/rbd/README.md' + properties: + fsType: + description: 'fsType is the filesystem type of the + volume that you want to mount. Tip: Ensure that + the filesystem type is supported by the host operating + system. Examples: "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. More info: + https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem + from compromising the machine' + type: string + image: + description: 'image is the rados image name. More + info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + keyring: + description: 'keyring is the path to key ring for + RBDUser. Default is /etc/ceph/keyring. More info: + https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + monitors: + description: 'monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + items: + type: string + type: array + pool: + description: 'pool is the rados pool name. Default + is rbd. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + readOnly: + description: 'readOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. More + info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: boolean + secretRef: + description: 'secretRef is name of the authentication + secret for RBDUser. If provided overrides keyring. + Default is nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + user: + description: 'user is the rados user name. Default + is admin. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent + volume attached and mounted on Kubernetes nodes. + properties: + fsType: + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". Default + is "xfs". + type: string + gateway: + description: gateway is the host address of the + ScaleIO API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the + ScaleIO Protection Domain for the configured storage. + type: string + readOnly: + description: readOnly Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. + type: boolean + secretRef: + description: secretRef references to the secret + for ScaleIO user and other sensitive information. + If this is not provided, Login operation will + fail. + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + sslEnabled: + description: sslEnabled Flag enable/disable SSL + communication with Gateway, default false + type: boolean + storageMode: + description: storageMode indicates whether the storage + for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage + Pool associated with the protection domain. + type: string + system: + description: system is the name of the storage system + as configured in ScaleIO. + type: string + volumeName: + description: volumeName is the name of a volume + already created in the ScaleIO system that is + associated with this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: 'secret represents a secret that should + populate this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + properties: + defaultMode: + description: 'defaultMode is Optional: mode bits + used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or + a decimal value between 0 and 511. YAML accepts + both octal and decimal values, JSON requires decimal + values for mode bits. Defaults to 0644. Directories + within the path are not affected by this setting. + This might be in conflict with other options that + affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + items: + description: items If unspecified, each key-value + pair in the Data field of the referenced Secret + will be projected into the volume as a file whose + name is the key and content is the value. If specified, + the listed keys will be projected into the specified + paths, and unlisted keys will not be present. + If a key is specified which is not present in + the Secret, the volume setup will error unless + it is marked optional. Paths must be relative + and may not contain the '..' path or start with + '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits + used to set permissions on this file. Must + be an octal value between 0000 and 0777 + or a decimal value between 0 and 511. YAML + accepts both octal and decimal values, JSON + requires decimal values for mode bits. If + not specified, the volume defaultMode will + be used. This might be in conflict with + other options that affect the file mode, + like fsGroup, and the result can be other + mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of + the file to map the key to. May not be an + absolute path. May not contain the path + element '..'. May not start with the string + '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the + Secret or its keys must be defined + type: boolean + secretName: + description: 'secretName is the name of the secret + in the pod''s namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + type: string + type: object + storageos: + description: storageOS represents a StorageOS volume + attached and mounted on Kubernetes nodes. + properties: + fsType: + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + readOnly: + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. + type: boolean + secretRef: + description: secretRef specifies the secret to use + for obtaining the StorageOS API credentials. If + not specified, default values will be attempted. + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + volumeName: + description: volumeName is the human-readable name + of the StorageOS volume. Volume names are only + unique within a namespace. + type: string + volumeNamespace: + description: volumeNamespace specifies the scope + of the volume within StorageOS. If no namespace + is specified then the Pod's namespace will be + used. This allows the Kubernetes name scoping + to be mirrored within StorageOS for tighter integration. + Set VolumeName to any name to override the default + behaviour. Set to "default" if you are not using + namespaces within StorageOS. Namespaces that do + not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere volume + attached and mounted on kubelets host machine + properties: + fsType: + description: fsType is filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy + Based Management (SPBM) profile ID associated + with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage Policy + Based Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies + vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + type: object + type: object + required: + - clusterSize + - kubernetesConfig + type: object + status: + description: RedisClusterStatus defines the observed state of RedisCluster + properties: + readyFollowerReplicas: + default: 0 + format: int32 + type: integer + readyLeaderReplicas: + default: 0 + format: int32 + type: integer + reason: + type: string + state: + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/crds/redis-replication.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/crds/redis-replication.yaml new file mode 100644 index 000000000..e14a87912 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/crds/redis-replication.yaml @@ -0,0 +1,9978 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.1 + creationTimestamp: null + name: redisreplications.redis.redis.opstreelabs.in +spec: + group: redis.redis.opstreelabs.in + names: + kind: RedisReplication + listKind: RedisReplicationList + plural: redisreplications + singular: redisreplication + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + description: Redis is the Schema for the redis API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + properties: + TLS: + description: TLS Configuration for redis instances + properties: + ca: + type: string + cert: + type: string + key: + type: string + secret: + description: Reference to secret which contains the certificates + properties: + defaultMode: + description: 'defaultMode is Optional: mode bits used to set + permissions on created files by default. Must be an octal + value between 0000 and 0777 or a decimal value between 0 + and 511. YAML accepts both octal and decimal values, JSON + requires decimal values for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect + the file mode, like fsGroup, and the result can be other + mode bits set.' + format: int32 + type: integer + items: + description: items If unspecified, each key-value pair in + the Data field of the referenced Secret will be projected + into the volume as a file whose name is the key and content + is the value. If specified, the listed keys will be projected + into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the + Secret, the volume setup will error unless it is marked + optional. Paths must be relative and may not contain the + '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used to set + permissions on this file. Must be an octal value between + 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires + decimal values for mode bits. If not specified, the + volume defaultMode will be used. This might be in + conflict with other options that affect the file mode, + like fsGroup, and the result can be other mode bits + set.' + format: int32 + type: integer + path: + description: path is the relative path of the file to + map the key to. May not be an absolute path. May not + contain the path element '..'. May not start with + the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the Secret or + its keys must be defined + type: boolean + secretName: + description: 'secretName is the name of the secret in the + pod''s namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + type: string + type: object + required: + - secret + type: object + affinity: + description: Affinity is a group of affinity scheduling rules. + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for the + pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the affinity expressions specified by + this field, but it may choose a node that violates one or + more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node matches + the corresponding matchExpressions; the node(s) with the + highest sum are the most preferred. + items: + description: An empty preferred scheduling term matches + all objects with implicit weight 0 (i.e. it's a no-op). + A null preferred scheduling term matches no objects (i.e. + is also a no-op). + properties: + preference: + description: A node selector term, associated with the + corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + description: Weight associated with matching the corresponding + nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this + field are not met at scheduling time, the pod will not be + scheduled onto the node. If the affinity requirements specified + by this field cease to be met at some point during pod execution + (e.g. due to an update), the system may or may not try to + eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: A null or empty node selector term matches + no objects. The requirements of them are ANDed. The + TopologySelectorTerm type implements a subset of the + NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. co-locate + this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the affinity expressions specified by + this field, but it may choose a node that violates one or + more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node has + pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key in (value)` to select + the group of existing pods which pods will be + taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MatchLabelKeys and LabelSelector. Also, + MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key notin (value)` to + select the group of existing pods which pods will + be taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MismatchLabelKeys and LabelSelector. Also, + MismatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding + podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this + field are not met at scheduling time, the pod will not be + scheduled onto the node. If the affinity requirements specified + by this field cease to be met at some point during pod execution + (e.g. due to a pod label update), the system may or may + not try to eventually evict the pod from its node. When + there are multiple elements, the lists of nodes corresponding + to each podAffinityTerm are intersected, i.e. all terms + must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not co-located + (anti-affinity) with, where co-located is defined as running + on a node whose value of the label with key + matches that of any node on which a pod of the set of + pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod label keys + to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged with + `LabelSelector` as `key in (value)` to select the + group of existing pods which pods will be taken into + consideration for the incoming pod's pod (anti) affinity. + Keys that don't exist in the incoming pod labels will + be ignored. The default value is empty. The same key + is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires enabling + MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged with + `LabelSelector` as `key notin (value)` to select the + group of existing pods which pods will be taken into + consideration for the incoming pod's pod (anti) affinity. + Keys that don't exist in the incoming pod labels will + be ignored. The default value is empty. The same key + is forbidden to exist in both MismatchLabelKeys and + LabelSelector. Also, MismatchLabelKeys cannot be set + when LabelSelector isn't set. This is an alpha field + and requires enabling MatchLabelKeysInPodAffinity + feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied to the + union of the namespaces selected by this field and + the ones listed in the namespaces field. null selector + and null or empty namespaces list means "this pod's + namespace". An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace + names that the term applies to. The term is applied + to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. null or + empty namespaces list and null namespaceSelector means + "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where + co-located is defined as running on a node whose value + of the label with key topologyKey matches that of + any node on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules (e.g. + avoid putting this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the anti-affinity expressions specified + by this field, but it may choose a node that violates one + or more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node has + pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key in (value)` to select + the group of existing pods which pods will be + taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MatchLabelKeys and LabelSelector. Also, + MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key notin (value)` to + select the group of existing pods which pods will + be taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MismatchLabelKeys and LabelSelector. Also, + MismatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding + podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the anti-affinity requirements + specified by this field cease to be met at some point during + pod execution (e.g. due to a pod label update), the system + may or may not try to eventually evict the pod from its + node. When there are multiple elements, the lists of nodes + corresponding to each podAffinityTerm are intersected, i.e. + all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not co-located + (anti-affinity) with, where co-located is defined as running + on a node whose value of the label with key + matches that of any node on which a pod of the set of + pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod label keys + to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged with + `LabelSelector` as `key in (value)` to select the + group of existing pods which pods will be taken into + consideration for the incoming pod's pod (anti) affinity. + Keys that don't exist in the incoming pod labels will + be ignored. The default value is empty. The same key + is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires enabling + MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged with + `LabelSelector` as `key notin (value)` to select the + group of existing pods which pods will be taken into + consideration for the incoming pod's pod (anti) affinity. + Keys that don't exist in the incoming pod labels will + be ignored. The default value is empty. The same key + is forbidden to exist in both MismatchLabelKeys and + LabelSelector. Also, MismatchLabelKeys cannot be set + when LabelSelector isn't set. This is an alpha field + and requires enabling MatchLabelKeysInPodAffinity + feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied to the + union of the namespaces selected by this field and + the ones listed in the namespaces field. null selector + and null or empty namespaces list means "this pod's + namespace". An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace + names that the term applies to. The term is applied + to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. null or + empty namespaces list and null namespaceSelector means + "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where + co-located is defined as running on a node whose value + of the label with key topologyKey matches that of + any node on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + clusterSize: + format: int32 + type: integer + kubernetesConfig: + description: KubernetesConfig will be the JSON struct for Basic Redis + Config + properties: + ignoreAnnotations: + items: + type: string + type: array + image: + type: string + imagePullPolicy: + description: PullPolicy describes a policy for if/when to pull + a container image + type: string + imagePullSecrets: + items: + description: LocalObjectReference contains enough information + to let you locate the referenced object inside the same namespace. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + type: array + redisSecret: + description: ExistingPasswordSecret is the struct to access the + existing secret + properties: + key: + type: string + name: + type: string + type: object + resources: + description: ResourceRequirements describes the compute resource + requirements. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + service: + description: ServiceConfig define the type of service to be created + and its annotations + properties: + annotations: + additionalProperties: + type: string + type: object + serviceType: + enum: + - LoadBalancer + - NodePort + - ClusterIP + type: string + type: object + updateStrategy: + description: StatefulSetUpdateStrategy indicates the strategy + that the StatefulSet controller will use to perform updates. + It includes any additional parameters necessary to perform the + update for the indicated strategy. + properties: + rollingUpdate: + description: RollingUpdate is used to communicate parameters + when Type is RollingUpdateStatefulSetStrategyType. + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + description: 'The maximum number of pods that can be unavailable + during the update. Value can be an absolute number (ex: + 5) or a percentage of desired pods (ex: 10%). Absolute + number is calculated from percentage by rounding up. + This can not be 0. Defaults to 1. This field is alpha-level + and is only honored by servers that enable the MaxUnavailableStatefulSet + feature. The field applies to all pods in the range + 0 to Replicas-1. That means if there is any unavailable + pod in the range 0 to Replicas-1, it will be counted + towards MaxUnavailable.' + x-kubernetes-int-or-string: true + partition: + description: Partition indicates the ordinal at which + the StatefulSet should be partitioned for updates. During + a rolling update, all pods from ordinal Replicas-1 to + Partition are updated. All pods from ordinal Partition-1 + to 0 remain untouched. This is helpful in being able + to do a canary based deployment. The default value is + 0. + format: int32 + type: integer + type: object + type: + description: Type indicates the type of the StatefulSetUpdateStrategy. + Default is RollingUpdate. + type: string + type: object + required: + - image + type: object + livenessProbe: + description: Probe describes a health check to be performed against + a container to determine whether it is alive or ready to receive + traffic. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside + the container, the working directory for the command is + root ('/') in the container's filesystem. The command is + simply exec'd, it is not run inside a shell, so traditional + shell instructions ('|', etc) won't work. To use a shell, + you need to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be + considered failed after having succeeded. Defaults to 3. Minimum + value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. + properties: + port: + description: Port number of the gRPC service. Number must + be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place + in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior is defined + by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod + IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows + repeated headers. + items: + description: HTTPHeader describes a custom header to be + used in HTTP probes + properties: + name: + description: The header field name. This will be canonicalized + upon output, so case-variant names will be understood + as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. + Number must be in the range 1 to 65535. Name must be an + IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults + to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started + before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default + to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be + considered successful after having failed. Defaults to 1. Must + be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults + to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. + Number must be in the range 1 to 65535. Name must be an + IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate + gracefully upon probe failure. The grace period is the duration + in seconds after the processes running in the pod are sent a + termination signal and the time when the processes are forcibly + halted with a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, the pod's + terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. Value must + be non-negative integer. The value zero indicates stop immediately + via the kill signal (no opportunity to shut down). This is a + beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + nodeSelector: + additionalProperties: + type: string + type: object + priorityClassName: + type: string + readinessProbe: + description: Probe describes a health check to be performed against + a container to determine whether it is alive or ready to receive + traffic. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside + the container, the working directory for the command is + root ('/') in the container's filesystem. The command is + simply exec'd, it is not run inside a shell, so traditional + shell instructions ('|', etc) won't work. To use a shell, + you need to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be + considered failed after having succeeded. Defaults to 3. Minimum + value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. + properties: + port: + description: Port number of the gRPC service. Number must + be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place + in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior is defined + by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod + IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows + repeated headers. + items: + description: HTTPHeader describes a custom header to be + used in HTTP probes + properties: + name: + description: The header field name. This will be canonicalized + upon output, so case-variant names will be understood + as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. + Number must be in the range 1 to 65535. Name must be an + IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults + to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started + before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default + to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be + considered successful after having failed. Defaults to 1. Must + be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults + to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. + Number must be in the range 1 to 65535. Name must be an + IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate + gracefully upon probe failure. The grace period is the duration + in seconds after the processes running in the pod are sent a + termination signal and the time when the processes are forcibly + halted with a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, the pod's + terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. Value must + be non-negative integer. The value zero indicates stop immediately + via the kill signal (no opportunity to shut down). This is a + beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + redisConfig: + description: RedisConfig defines the external configuration of Redis + properties: + additionalRedisConfig: + type: string + type: object + redisExporter: + description: RedisExporter interface will have the information for + redis exporter related stuff + properties: + enabled: + type: boolean + env: + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + image: + type: string + imagePullPolicy: + description: PullPolicy describes a policy for if/when to pull + a container image + type: string + port: + default: 9121 + type: integer + resources: + description: ResourceRequirements describes the compute resource + requirements. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: SecurityContext holds security configuration that + will be applied to a container. Some fields are present in both + SecurityContext and PodSecurityContext. When both are set, + the values in SecurityContext take precedence. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a + process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the + container runtime. Note that this field cannot be set when + spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in + privileged containers are essentially equivalent to root + on the host. Defaults to false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use + for the containers. The default is DefaultProcMount which + uses the container runtime defaults for readonly paths and + masked paths. This requires the ProcMountType feature flag + to be enabled. Note that this field cannot be set when spec.os.name + is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when + spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail + to start the container if it does. If unset or false, no + such validation will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata if + unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. Note + that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must + be preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must be set if type is "Localhost". Must NOT + be set for any other type. + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a + profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile + should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also be + set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + required: + - image + type: object + securityContext: + description: PodSecurityContext holds pod-level security attributes + and common container settings. Some fields are also present in container.securityContext. Field + values of container.securityContext take precedence over field values + of PodSecurityContext. + properties: + fsGroup: + description: "A special supplemental group that applies to all + containers in a pod. Some volume types allow the Kubelet to + change the ownership of that volume to be owned by the pod: + \n 1. The owning GID will be the FSGroup 2. The setgid bit is + set (new files created in the volume will be owned by FSGroup) + 3. The permission bits are OR'd with rw-rw---- \n If unset, + the Kubelet will not modify the ownership and permissions of + any volume. Note that this field cannot be set when spec.os.name + is windows." + format: int64 + type: integer + fsGroupChangePolicy: + description: 'fsGroupChangePolicy defines behavior of changing + ownership and permission of the volume before being exposed + inside Pod. This field will only apply to volume types which + support fsGroup based ownership(and permissions). It will have + no effect on ephemeral volume types such as: secret, configmaps + and emptydir. Valid values are "OnRootMismatch" and "Always". + If not specified, "Always" is used. Note that this field cannot + be set when spec.os.name is windows.' + type: string + runAsGroup: + description: The GID to run the entrypoint of the container process. + Uses runtime default if unset. May also be set in SecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail to start + the container if it does. If unset or false, no such validation + will be performed. May also be set in SecurityContext. If set + in both SecurityContext and PodSecurityContext, the value specified + in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in SecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. Note that this field cannot + be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in SecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to + the container. + type: string + role: + description: Role is a SELinux role label that applies to + the container. + type: string + type: + description: Type is a SELinux type label that applies to + the container. + type: string + user: + description: User is a SELinux user label that applies to + the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by the containers in this + pod. Note that this field cannot be set when spec.os.name is + windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must be + preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must be set if type is "Localhost". Must NOT be + set for any other type. + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a profile + defined in a file on the node should be used. RuntimeDefault + - the container runtime default profile should be used. + Unconfined - no profile should be applied." + type: string + required: + - type + type: object + supplementalGroups: + description: A list of groups applied to the first process run + in each container, in addition to the container's primary GID, + the fsGroup (if specified), and group memberships defined in + the container image for the uid of the container process. If + unspecified, no additional groups are added to any container. + Note that group memberships defined in the container image for + the uid of the container process are still effective, even if + they are not included in this list. Note that this field cannot + be set when spec.os.name is windows. + items: + format: int64 + type: integer + type: array + sysctls: + description: Sysctls hold a list of namespaced sysctls used for + the pod. Pods with unsupported sysctls (by the container runtime) + might fail to launch. Note that this field cannot be set when + spec.os.name is windows. + items: + description: Sysctl defines a kernel parameter to be set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + description: The Windows specific settings applied to all containers. + If unspecified, the options within a container's SecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named by + the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA + credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. All of a Pod's containers + must have the same effective HostProcess value (it is not + allowed to have a mix of HostProcess containers and non-HostProcess + containers). In addition, if HostProcess is true then HostNetwork + must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in PodSecurityContext. + If set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: string + type: object + type: object + serviceAccountName: + type: string + sidecars: + items: + description: Sidecar for each Redis pods + properties: + env: + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be + a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. + If a variable cannot be resolved, the reference in the + input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) + syntax: i.e. "$$(VAR_NAME)" will produce the string + literal "$(VAR_NAME)". Escaped references will never + be expanded, regardless of whether the variable exists + or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its + key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + image: + type: string + imagePullPolicy: + description: PullPolicy describes a policy for if/when to pull + a container image + type: string + name: + type: string + resources: + description: ResourceRequirements describes the compute resource + requirements. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only + be set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where this + field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests + cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + required: + - image + - name + type: object + type: array + storage: + description: Storage is the inteface to add pvc and pv support in + redis + properties: + keepAfterDelete: + type: boolean + volumeClaimTemplate: + description: PersistentVolumeClaim is a user's request for and + claim to a persistent volume + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this + representation of an object. Servers should convert recognized + schemas to the latest internal value, and may reject unrecognized + values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST + resource this object represents. Servers may infer this + from the endpoint the client submits requests to. Cannot + be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + description: 'Standard object''s metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata' + type: object + spec: + description: 'spec defines the desired characteristics of + a volume requested by a pod author. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + accessModes: + description: 'accessModes contains the desired access + modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'dataSource field can be used to specify + either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) If the provisioner + or an external controller can support the specified + data source, it will create a new volume based on the + contents of the specified data source. When the AnyVolumeDataSource + feature gate is enabled, dataSource contents will be + copied to dataSourceRef, and dataSourceRef contents + will be copied to dataSource when dataSourceRef.namespace + is not specified. If the namespace is specified, then + dataSourceRef will not be copied to dataSource.' + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + dataSourceRef: + description: 'dataSourceRef specifies the object from + which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty + API group (non core object) or a PersistentVolumeClaim + object. When this field is specified, volume binding + will only succeed if the type of the specified object + matches some installed volume populator or dynamic provisioner. + This field will replace the functionality of the dataSource + field and as such if both fields are non-empty, they + must have the same value. For backwards compatibility, + when namespace isn''t specified in dataSourceRef, both + fields (dataSource and dataSourceRef) will be set to + the same value automatically if one of them is empty + and the other is non-empty. When namespace is specified + in dataSourceRef, dataSource isn''t set to the same + value and must be empty. There are three important differences + between dataSource and dataSourceRef: * While dataSource + only allows two specific types of objects, dataSourceRef allows + any non-core object, as well as PersistentVolumeClaim + objects. * While dataSource ignores disallowed values + (dropping them), dataSourceRef preserves all values, + and generates an error if a disallowed value is specified. + * While dataSource only allows local objects, dataSourceRef + allows objects in any namespaces. (Beta) Using this + field requires the AnyVolumeDataSource feature gate + to be enabled. (Alpha) Using the namespace field of + dataSourceRef requires the CrossNamespaceVolumeDataSource + feature gate to be enabled.' + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + namespace: + description: Namespace is the namespace of resource + being referenced Note that when a namespace is specified, + a gateway.networking.k8s.io/ReferenceGrant object + is required in the referent namespace to allow that + namespace's owner to accept the reference. See the + ReferenceGrant documentation for details. (Alpha) + This field requires the CrossNamespaceVolumeDataSource + feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: 'resources represents the minimum resources + the volume should have. If RecoverVolumeExpansionFailure + feature is enabled users are allowed to specify resource + requirements that are lower than previous value but + must still be higher than capacity recorded in the status + field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount + of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount + of compute resources required. If Requests is omitted + for a container, it defaults to Limits if that is + explicitly specified, otherwise to an implementation-defined + value. Requests cannot exceed Limits. More info: + https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + selector: + description: selector is a label query over volumes to + consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, + NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values + array must be non-empty. If the operator is + Exists or DoesNotExist, the values array must + be empty. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field + is "key", the operator is "In", and the values array + contains only "value". The requirements are ANDed. + type: object + type: object + storageClassName: + description: 'storageClassName is the name of the StorageClass + required by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + type: string + volumeAttributesClassName: + description: 'volumeAttributesClassName may be used to + set the VolumeAttributesClass used by this claim. If + specified, the CSI driver will create or update the + volume with the attributes defined in the corresponding + VolumeAttributesClass. This has a different purpose + than storageClassName, it can be changed after the claim + is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it''s not allowed to + reset this field to empty string once it is set. If + unspecified and the PersistentVolumeClaim is unbound, + the default VolumeAttributesClass will be set by the + persistentvolume controller if it exists. If the resource + referred to by volumeAttributesClass does not exist, + this PersistentVolumeClaim will be set to a Pending + state, as reflected by the modifyVolumeStatus field, + until such as a resource exists. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + (Alpha) Using this field requires the VolumeAttributesClass + feature gate to be enabled.' + type: string + volumeMode: + description: volumeMode defines what type of volume is + required by the claim. Value of Filesystem is implied + when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to the + PersistentVolume backing this claim. + type: string + type: object + status: + description: 'status represents the current information/status + of a persistent volume claim. Read-only. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + accessModes: + description: 'accessModes contains the actual access modes + the volume backing the PVC has. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + allocatedResourceStatuses: + additionalProperties: + description: When a controller receives persistentvolume + claim update with ClaimResourceStatus for a resource + that it does not recognizes, then it should ignore + that update and let other controllers handle it. + type: string + description: "allocatedResourceStatuses stores status + of resource being resized for the given PVC. Key names + follow standard Kubernetes label syntax. Valid values + are either: \t* Un-prefixed keys: \t\t- storage - the + capacity of the volume. \t* Custom resources must use + implementation-defined prefixed names such as \"example.com/my-custom-resource\" + Apart from above values - keys that are unprefixed or + have kubernetes.io prefix are considered reserved and + hence may not be used. \n ClaimResourceStatus can be + in any of following states: \t- ControllerResizeInProgress: + \t\tState set when resize controller starts resizing + the volume in control-plane. \t- ControllerResizeFailed: + \t\tState set when resize has failed in resize controller + with a terminal error. \t- NodeResizePending: \t\tState + set when resize controller has finished resizing the + volume but further resizing of \t\tvolume is needed + on the node. \t- NodeResizeInProgress: \t\tState set + when kubelet starts resizing the volume. \t- NodeResizeFailed: + \t\tState set when resizing has failed in kubelet with + a terminal error. Transient errors don't set \t\tNodeResizeFailed. + For example: if expanding a PVC for more capacity - + this field can be one of the following states: \t- pvc.status.allocatedResourceStatus['storage'] + = \"ControllerResizeInProgress\" - pvc.status.allocatedResourceStatus['storage'] + = \"ControllerResizeFailed\" - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizePending\" - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizeInProgress\" - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizeFailed\" When this field is not set, it + means that no resize operation is in progress for the + given PVC. \n A controller that receives PVC update + with previously unknown resourceName or ClaimResourceStatus + should ignore the update for the purpose it was designed. + For example - a controller that only is responsible + for resizing capacity of the volume, should ignore PVC + updates that change other valid resources associated + with PVC. \n This is an alpha field and requires enabling + RecoverVolumeExpansionFailure feature." + type: object + x-kubernetes-map-type: granular + allocatedResources: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: "allocatedResources tracks the resources + allocated to a PVC including its capacity. Key names + follow standard Kubernetes label syntax. Valid values + are either: \t* Un-prefixed keys: \t\t- storage - the + capacity of the volume. \t* Custom resources must use + implementation-defined prefixed names such as \"example.com/my-custom-resource\" + Apart from above values - keys that are unprefixed or + have kubernetes.io prefix are considered reserved and + hence may not be used. \n Capacity reported here may + be larger than the actual capacity when a volume expansion + operation is requested. For storage quota, the larger + value from allocatedResources and PVC.spec.resources + is used. If allocatedResources is not set, PVC.spec.resources + alone is used for quota calculation. If a volume expansion + capacity request is lowered, allocatedResources is only + lowered if there are no expansion operations in progress + and if the actual volume capacity is equal or lower + than the requested capacity. \n A controller that receives + PVC update with previously unknown resourceName should + ignore the update for the purpose it was designed. For + example - a controller that only is responsible for + resizing capacity of the volume, should ignore PVC updates + that change other valid resources associated with PVC. + \n This is an alpha field and requires enabling RecoverVolumeExpansionFailure + feature." + type: object + capacity: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: capacity represents the actual resources + of the underlying volume. + type: object + conditions: + description: conditions is the current Condition of persistent + volume claim. If underlying persistent volume is being + resized then the Condition will be set to 'ResizeStarted'. + items: + description: PersistentVolumeClaimCondition contains + details about state of pvc + properties: + lastProbeTime: + description: lastProbeTime is the time we probed + the condition. + format: date-time + type: string + lastTransitionTime: + description: lastTransitionTime is the time the + condition transitioned from one status to another. + format: date-time + type: string + message: + description: message is the human-readable message + indicating details about last transition. + type: string + reason: + description: reason is a unique, this should be + a short, machine understandable string that gives + the reason for condition's last transition. If + it reports "ResizeStarted" that means the underlying + persistent volume is being resized. + type: string + status: + type: string + type: + description: PersistentVolumeClaimConditionType + is a valid value of PersistentVolumeClaimCondition.Type + type: string + required: + - status + - type + type: object + type: array + currentVolumeAttributesClassName: + description: currentVolumeAttributesClassName is the current + name of the VolumeAttributesClass the PVC is using. + When unset, there is no VolumeAttributeClass applied + to this PersistentVolumeClaim This is an alpha field + and requires enabling VolumeAttributesClass feature. + type: string + modifyVolumeStatus: + description: ModifyVolumeStatus represents the status + object of ControllerModifyVolume operation. When this + is unset, there is no ModifyVolume operation being attempted. + This is an alpha field and requires enabling VolumeAttributesClass + feature. + properties: + status: + description: "status is the status of the ControllerModifyVolume + operation. It can be in any of following states: + \ - Pending Pending indicates that the PersistentVolumeClaim + cannot be modified due to unmet requirements, such + as the specified VolumeAttributesClass not existing. + \ - InProgress InProgress indicates that the + volume is being modified. - Infeasible Infeasible + indicates that the request has been rejected as + invalid by the CSI driver. To \t resolve the error, + a valid VolumeAttributesClass needs to be specified. + Note: New statuses can be added in the future. Consumers + should check for unknown statuses and fail appropriately." + type: string + targetVolumeAttributesClassName: + description: targetVolumeAttributesClassName is the + name of the VolumeAttributesClass the PVC currently + being reconciled + type: string + required: + - status + type: object + phase: + description: phase represents the current phase of PersistentVolumeClaim. + type: string + type: object + type: object + volumeMount: + description: Additional Volume is provided by user that is mounted + on the pods + properties: + mountPath: + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: Path within the container at which the + volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts + are propagated from the host to container and the + other way around. When not set, MountPropagationNone + is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise + (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's + volume should be mounted. Defaults to "" (volume's + root). + type: string + subPathExpr: + description: Expanded path within the volume from which + the container's volume should be mounted. Behaves + similarly to SubPath but environment variable references + $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). SubPathExpr and SubPath + are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + volume: + items: + description: Volume represents a named volume in a pod that + may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: 'awsElasticBlockStore represents an AWS + Disk resource that is attached to a kubelet''s host + machine and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + properties: + fsType: + description: 'fsType is the filesystem type of the + volume that you want to mount. Tip: Ensure that + the filesystem type is supported by the host operating + system. Examples: "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. More info: + https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem + from compromising the machine' + type: string + partition: + description: 'partition is the partition in the + volume that you want to mount. If omitted, the + default is to mount by volume name. Examples: + For volume /dev/sda1, you specify the partition + as "1". Similarly, the volume partition for /dev/sda + is "0" (or you can leave the property empty).' + format: int32 + type: integer + readOnly: + description: 'readOnly value true will force the + readOnly setting in VolumeMounts. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: boolean + volumeID: + description: 'volumeID is unique ID of the persistent + disk resource in AWS (Amazon EBS volume). More + info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data Disk + mount on the host and bind mount to the pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching mode: + None, Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data disk + in the blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in + the blob storage + type: string + fsType: + description: fsType is Filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: multiple + blob disks per storage account Dedicated: single + blob disk per storage account Managed: azure + managed data disk (only in managed availability + set). defaults to shared' + type: string + readOnly: + description: readOnly Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File Service + mount on the host and bind mount to the pod. + properties: + readOnly: + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret that + contains Azure Storage Account Name and Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount on the + host that shares a pod's lifetime + properties: + monitors: + description: 'monitors is Required: Monitors is + a collection of Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + items: + type: string + type: array + path: + description: 'path is Optional: Used as the mounted + root, rather than the full Ceph tree, default + is /' + type: string + readOnly: + description: 'readOnly is Optional: Defaults to + false (read/write). ReadOnly here will force the + ReadOnly setting in VolumeMounts. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: boolean + secretFile: + description: 'secretFile is Optional: SecretFile + is the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + secretRef: + description: 'secretRef is Optional: SecretRef is + reference to the authentication secret for User, + default is empty. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + user: + description: 'user is optional: User is the rados + user name, default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + required: + - monitors + type: object + cinder: + description: 'cinder represents a cinder volume attached + and mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + properties: + fsType: + description: 'fsType is the filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Examples: "ext4", "xfs", "ntfs". + Implicitly inferred to be "ext4" if unspecified. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + readOnly: + description: 'readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: boolean + secretRef: + description: 'secretRef is optional: points to a + secret object containing parameters used to connect + to OpenStack.' + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + volumeID: + description: 'volumeID used to identify the volume + in cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that should + populate this volume + properties: + defaultMode: + description: 'defaultMode is optional: mode bits + used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or + a decimal value between 0 and 511. YAML accepts + both octal and decimal values, JSON requires decimal + values for mode bits. Defaults to 0644. Directories + within the path are not affected by this setting. + This might be in conflict with other options that + affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + items: + description: items if unspecified, each key-value + pair in the Data field of the referenced ConfigMap + will be projected into the volume as a file whose + name is the key and content is the value. If specified, + the listed keys will be projected into the specified + paths, and unlisted keys will not be present. + If a key is specified which is not present in + the ConfigMap, the volume setup will error unless + it is marked optional. Paths must be relative + and may not contain the '..' path or start with + '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits + used to set permissions on this file. Must + be an octal value between 0000 and 0777 + or a decimal value between 0 and 511. YAML + accepts both octal and decimal values, JSON + requires decimal values for mode bits. If + not specified, the volume defaultMode will + be used. This might be in conflict with + other options that affect the file mode, + like fsGroup, and the result can be other + mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of + the file to map the key to. May not be an + absolute path. May not contain the path + element '..'. May not start with the string + '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + csi: + description: csi (Container Storage Interface) represents + ephemeral storage that is handled by certain external + CSI drivers (Beta feature). + properties: + driver: + description: driver is the name of the CSI driver + that handles this volume. Consult with your admin + for the correct name as registered in the cluster. + type: string + fsType: + description: fsType to mount. Ex. "ext4", "xfs", + "ntfs". If not provided, the empty value is passed + to the associated CSI driver which will determine + the default filesystem to apply. + type: string + nodePublishSecretRef: + description: nodePublishSecretRef is a reference + to the secret object containing sensitive information + to pass to the CSI driver to complete the CSI + NodePublishVolume and NodeUnpublishVolume calls. + This field is optional, and may be empty if no + secret is required. If the secret object contains + more than one secret, all secret references are + passed. + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + readOnly: + description: readOnly specifies a read-only configuration + for the volume. Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: volumeAttributes stores driver-specific + properties that are passed to the CSI driver. + Consult your driver's documentation for supported + values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about + the pod that should populate this volume + properties: + defaultMode: + description: 'Optional: mode bits to use on created + files by default. Must be a Optional: mode bits + used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or + a decimal value between 0 and 511. YAML accepts + both octal and decimal values, JSON requires decimal + values for mode bits. Defaults to 0644. Directories + within the path are not affected by this setting. + This might be in conflict with other options that + affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + items: + description: Items is a list of downward API volume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing the + pod field + properties: + fieldRef: + description: 'Required: Selects a field of + the pod: only annotations, labels, name + and namespace are supported.' + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: mode bits used to + set permissions on this file, must be an + octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both + octal and decimal values, JSON requires + decimal values for mode bits. If not specified, + the volume defaultMode will be used. This + might be in conflict with other options + that affect the file mode, like fsGroup, + and the result can be other mode bits set.' + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. Must + not be absolute or contain the ''..'' path. + Must be utf-8 encoded. The first item of + the relative path must not start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, requests.cpu and requests.memory) + are currently supported.' + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + emptyDir: + description: 'emptyDir represents a temporary directory + that shares a pod''s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + properties: + medium: + description: 'medium represents what type of storage + medium should back this directory. The default + is "" which means to use the node''s default medium. + Must be an empty string (default) or Memory. More + info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: 'sizeLimit is the total amount of local + storage required for this EmptyDir volume. The + size limit is also applicable for memory medium. + The maximum usage on memory medium EmptyDir would + be the minimum value between the SizeLimit specified + here and the sum of memory limits of all containers + in a pod. The default is nil which means that + the limit is undefined. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: "ephemeral represents a volume that is + handled by a cluster storage driver. The volume's + lifecycle is tied to the pod that defines it - it + will be created before the pod starts, and deleted + when the pod is removed. \n Use this if: a) the volume + is only needed while the pod runs, b) features of + normal volumes like restoring from snapshot or capacity + \ tracking are needed, c) the storage driver is + specified through a storage class, and d) the storage + driver supports dynamic volume provisioning through + \ a PersistentVolumeClaim (see EphemeralVolumeSource + for more information on the connection between + this volume type and PersistentVolumeClaim). \n + Use PersistentVolumeClaim or one of the vendor-specific + APIs for volumes that persist for longer than the + lifecycle of an individual pod. \n Use CSI for light-weight + local ephemeral volumes if the CSI driver is meant + to be used that way - see the documentation of the + driver for more information. \n A pod can use both + types of ephemeral volumes and persistent volumes + at the same time." + properties: + volumeClaimTemplate: + description: "Will be used to create a stand-alone + PVC to provision the volume. The pod in which + this EphemeralVolumeSource is embedded will be + the owner of the PVC, i.e. the PVC will be deleted + together with the pod. The name of the PVC will + be `-` where `` + is the name from the `PodSpec.Volumes` array entry. + Pod validation will reject the pod if the concatenated + name is not valid for a PVC (for example, too + long). \n An existing PVC with that name that + is not owned by the pod will *not* be used for + the pod to avoid using an unrelated volume by + mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created + PVC is meant to be used by the pod, the PVC has + to updated with an owner reference to the pod + once the pod exists. Normally this should not + be necessary, but it may be useful when manually + reconstructing a broken cluster. \n This field + is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. \n Required, + must not be nil." + properties: + metadata: + description: May contain labels and annotations + that will be copied into the PVC when creating + it. No other fields are allowed and will be + rejected during validation. + type: object + spec: + description: The specification for the PersistentVolumeClaim. + The entire content is copied unchanged into + the PVC that gets created from this template. + The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: 'accessModes contains the desired + access modes the volume should have. More + info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'dataSource field can be used + to specify either: * An existing VolumeSnapshot + object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller + can support the specified data source, + it will create a new volume based on the + contents of the specified data source. + When the AnyVolumeDataSource feature gate + is enabled, dataSource contents will be + copied to dataSourceRef, and dataSourceRef + contents will be copied to dataSource + when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef + will not be copied to dataSource.' + properties: + apiGroup: + description: APIGroup is the group for + the resource being referenced. If + APIGroup is not specified, the specified + Kind must be in the core API group. + For any other third-party types, APIGroup + is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + required: + - kind + - name + type: object + dataSourceRef: + description: 'dataSourceRef specifies the + object from which to populate the volume + with data, if a non-empty volume is desired. + This may be any object from a non-empty + API group (non core object) or a PersistentVolumeClaim + object. When this field is specified, + volume binding will only succeed if the + type of the specified object matches some + installed volume populator or dynamic + provisioner. This field will replace the + functionality of the dataSource field + and as such if both fields are non-empty, + they must have the same value. For backwards + compatibility, when namespace isn''t specified + in dataSourceRef, both fields (dataSource + and dataSourceRef) will be set to the + same value automatically if one of them + is empty and the other is non-empty. When + namespace is specified in dataSourceRef, + dataSource isn''t set to the same value + and must be empty. There are three important + differences between dataSource and dataSourceRef: + * While dataSource only allows two specific + types of objects, dataSourceRef allows + any non-core object, as well as PersistentVolumeClaim + objects. * While dataSource ignores disallowed + values (dropping them), dataSourceRef preserves + all values, and generates an error if + a disallowed value is specified. * While + dataSource only allows local objects, + dataSourceRef allows objects in any + namespaces. (Beta) Using this field requires + the AnyVolumeDataSource feature gate to + be enabled. (Alpha) Using the namespace + field of dataSourceRef requires the CrossNamespaceVolumeDataSource + feature gate to be enabled.' + properties: + apiGroup: + description: APIGroup is the group for + the resource being referenced. If + APIGroup is not specified, the specified + Kind must be in the core API group. + For any other third-party types, APIGroup + is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + namespace: + description: Namespace is the namespace + of resource being referenced Note + that when a namespace is specified, + a gateway.networking.k8s.io/ReferenceGrant + object is required in the referent + namespace to allow that namespace's + owner to accept the reference. See + the ReferenceGrant documentation for + details. (Alpha) This field requires + the CrossNamespaceVolumeDataSource + feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: 'resources represents the minimum + resources the volume should have. If RecoverVolumeExpansionFailure + feature is enabled users are allowed to + specify resource requirements that are + lower than previous value but must still + be higher than capacity recorded in the + status field of the claim. More info: + https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum + amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the + minimum amount of compute resources + required. If Requests is omitted for + a container, it defaults to Limits + if that is explicitly specified, otherwise + to an implementation-defined value. + Requests cannot exceed Limits. More + info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + selector: + description: selector is a label query over + volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. + This array is replaced during + a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of + {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + storageClassName: + description: 'storageClassName is the name + of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + type: string + volumeAttributesClassName: + description: 'volumeAttributesClassName + may be used to set the VolumeAttributesClass + used by this claim. If specified, the + CSI driver will create or update the volume + with the attributes defined in the corresponding + VolumeAttributesClass. This has a different + purpose than storageClassName, it can + be changed after the claim is created. + An empty string value means that no VolumeAttributesClass + will be applied to the claim but it''s + not allowed to reset this field to empty + string once it is set. If unspecified + and the PersistentVolumeClaim is unbound, + the default VolumeAttributesClass will + be set by the persistentvolume controller + if it exists. If the resource referred + to by volumeAttributesClass does not exist, + this PersistentVolumeClaim will be set + to a Pending state, as reflected by the + modifyVolumeStatus field, until such as + a resource exists. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + (Alpha) Using this field requires the + VolumeAttributesClass feature gate to + be enabled.' + type: string + volumeMode: + description: volumeMode defines what type + of volume is required by the claim. Value + of Filesystem is implied when not included + in claim spec. + type: string + volumeName: + description: volumeName is the binding reference + to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource + that is attached to a kubelet's host machine and then + exposed to the pod. + properties: + fsType: + description: 'fsType is the filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. TODO: how + do we prevent errors in the filesystem from compromising + the machine' + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: 'readOnly is Optional: Defaults to + false (read/write). ReadOnly here will force the + ReadOnly setting in VolumeMounts.' + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target + worldwide names (WWNs)' + items: + type: string + type: array + wwids: + description: 'wwids Optional: FC volume world wide + identifiers (wwids) Either wwids or combination + of targetWWNs and lun must be set, but not both + simultaneously.' + items: + type: string + type: array + type: object + flexVolume: + description: flexVolume represents a generic volume + resource that is provisioned/attached using an exec + based plugin. + properties: + driver: + description: driver is the name of the driver to + use for this volume. + type: string + fsType: + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". The + default filesystem depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field holds + extra command options if any.' + type: object + readOnly: + description: 'readOnly is Optional: defaults to + false (read/write). ReadOnly here will force the + ReadOnly setting in VolumeMounts.' + type: boolean + secretRef: + description: 'secretRef is Optional: secretRef is + reference to the secret object containing sensitive + information to pass to the plugin scripts. This + may be empty if no secret object is specified. + If the secret object contains more than one secret, + all secrets are passed to the plugin scripts.' + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume attached + to a kubelet's host machine. This depends on the Flocker + control service being running + properties: + datasetName: + description: datasetName is Name of the dataset + stored as metadata -> name on the dataset for + Flocker should be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. + This is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: 'gcePersistentDisk represents a GCE Disk + resource that is attached to a kubelet''s host machine + and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + properties: + fsType: + description: 'fsType is filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem + from compromising the machine' + type: string + partition: + description: 'partition is the partition in the + volume that you want to mount. If omitted, the + default is to mount by volume name. Examples: + For volume /dev/sda1, you specify the partition + as "1". Similarly, the volume partition for /dev/sda + is "0" (or you can leave the property empty). + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + format: int32 + type: integer + pdName: + description: 'pdName is unique name of the PD resource + in GCE. Used to identify the disk in GCE. More + info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: string + readOnly: + description: 'readOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. More + info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: boolean + required: + - pdName + type: object + gitRepo: + description: 'gitRepo represents a git repository at + a particular revision. DEPRECATED: GitRepo is deprecated. + To provision a container with a git repo, mount an + EmptyDir into an InitContainer that clones the repo + using git, then mount the EmptyDir into the Pod''s + container.' + properties: + directory: + description: directory is the target directory name. + Must not contain or start with '..'. If '.' is + supplied, the volume directory will be the git + repository. Otherwise, if specified, the volume + will contain the git repository in the subdirectory + with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the + specified revision. + type: string + required: + - repository + type: object + glusterfs: + description: 'glusterfs represents a Glusterfs mount + on the host that shares a pod''s lifetime. More info: + https://examples.k8s.io/volumes/glusterfs/README.md' + properties: + endpoints: + description: 'endpoints is the endpoint name that + details Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + path: + description: 'path is the Glusterfs volume path. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + readOnly: + description: 'readOnly here will force the Glusterfs + volume to be mounted with read-only permissions. + Defaults to false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: 'hostPath represents a pre-existing file + or directory on the host machine that is directly + exposed to the container. This is generally used for + system agents or other privileged things that are + allowed to see the host machine. Most containers will + NOT need this. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- TODO(jonesdl) We need to restrict who can use + host directory mounts and who can/can not mount host + directories as read/write.' + properties: + path: + description: 'path of the directory on the host. + If the path is a symlink, it will follow the link + to the real path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + type: + description: 'type for HostPath Volume Defaults + to "" More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + required: + - path + type: object + iscsi: + description: 'iscsi represents an ISCSI Disk resource + that is attached to a kubelet''s host machine and + then exposed to the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md' + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether support + iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support + iSCSI Session CHAP authentication + type: boolean + fsType: + description: 'fsType is the filesystem type of the + volume that you want to mount. Tip: Ensure that + the filesystem type is supported by the host operating + system. Examples: "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. More info: + https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem + from compromising the machine' + type: string + initiatorName: + description: initiatorName is the custom iSCSI Initiator + Name. If initiatorName is specified with iscsiInterface + simultaneously, new iSCSI interface : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified Name. + type: string + iscsiInterface: + description: iscsiInterface is the interface Name + that uses an iSCSI transport. Defaults to 'default' + (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: portals is the iSCSI Target Portal + List. The portal is either an IP or ip_addr:port + if the port is other than default (typically TCP + ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: readOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for iSCSI + target and initiator authentication + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + targetPortal: + description: targetPortal is iSCSI Target Portal. + The Portal is either an IP or ip_addr:port if + the port is other than default (typically TCP + ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: 'name of the volume. Must be a DNS_LABEL + and unique within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + nfs: + description: 'nfs represents an NFS mount on the host + that shares a pod''s lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + properties: + path: + description: 'path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + readOnly: + description: 'readOnly here will force the NFS export + to be mounted with read-only permissions. Defaults + to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: boolean + server: + description: 'server is the hostname or IP address + of the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: 'persistentVolumeClaimVolumeSource represents + a reference to a PersistentVolumeClaim in the same + namespace. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + claimName: + description: 'claimName is the name of a PersistentVolumeClaim + in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + type: string + readOnly: + description: readOnly Will force the ReadOnly setting + in VolumeMounts. Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents a PhotonController + persistent disk attached and mounted on kubelets host + machine + properties: + fsType: + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon + Controller persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx volume + attached and mounted on kubelets host machine + properties: + fsType: + description: fSType represents the filesystem type + to mount Must be a filesystem type supported by + the host operating system. Ex. "ext4", "xfs". + Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx + volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources + secrets, configmaps, and downward API + properties: + defaultMode: + description: defaultMode are the mode bits used + to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or + a decimal value between 0 and 511. YAML accepts + both octal and decimal values, JSON requires decimal + values for mode bits. Directories within the path + are not affected by this setting. This might be + in conflict with other options that affect the + file mode, like fsGroup, and the result can be + other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume projections + items: + description: Projection that may be projected + along with other supported volume types + properties: + clusterTrustBundle: + description: "ClusterTrustBundle allows a + pod to access the `.spec.trustBundle` field + of ClusterTrustBundle objects in an auto-updating + file. \n Alpha, gated by the ClusterTrustBundleProjection + feature gate. \n ClusterTrustBundle objects + can either be selected by name, or by the + combination of signer name and a label selector. + \n Kubelet performs aggressive normalization + of the PEM contents written into the pod + filesystem. Esoteric PEM features such + as inter-block comments and block headers + are stripped. Certificates are deduplicated. + The ordering of certificates within the + file is arbitrary, and Kubelet may change + the order over time." + properties: + labelSelector: + description: Select all ClusterTrustBundles + that match this label selector. Only + has effect if signerName is set. Mutually-exclusive + with name. If unset, interpreted as + "match nothing". If set but empty, + interpreted as "match everything". + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a + set of values. Valid operators + are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values + array must be non-empty. If + the operator is Exists or + DoesNotExist, the values array + must be empty. This array + is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map + of {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + name: + description: Select a single ClusterTrustBundle + by object name. Mutually-exclusive + with signerName and labelSelector. + type: string + optional: + description: If true, don't block pod + startup if the referenced ClusterTrustBundle(s) + aren't available. If using name, then + the named ClusterTrustBundle is allowed + not to exist. If using signerName, + then the combination of signerName and + labelSelector is allowed to match zero + ClusterTrustBundles. + type: boolean + path: + description: Relative path from the volume + root to write the bundle. + type: string + signerName: + description: Select all ClusterTrustBundles + that match this signer name. Mutually-exclusive + with name. The contents of all selected + ClusterTrustBundles will be unified + and deduplicated. + type: string + required: + - path + type: object + configMap: + description: configMap information about the + configMap data to project + properties: + items: + description: items if unspecified, each + key-value pair in the Data field of + the referenced ConfigMap will be projected + into the volume as a file whose name + is the key and content is the value. + If specified, the listed keys will be + projected into the specified paths, + and unlisted keys will not be present. + If a key is specified which is not present + in the ConfigMap, the volume setup will + error unless it is marked optional. + Paths must be relative and may not contain + the '..' path or start with '..'. + items: + description: Maps a string key to a + path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: + mode bits used to set permissions + on this file. Must be an octal + value between 0000 and 0777 or + a decimal value between 0 and + 511. YAML accepts both octal and + decimal values, JSON requires + decimal values for mode bits. + If not specified, the volume defaultMode + will be used. This might be in + conflict with other options that + affect the file mode, like fsGroup, + and the result can be other mode + bits set.' + format: int32 + type: integer + path: + description: path is the relative + path of the file to map the key + to. May not be an absolute path. + May not contain the path element + '..'. May not start with the string + '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: optional specify whether + the ConfigMap or its keys must be defined + type: boolean + type: object + downwardAPI: + description: downwardAPI information about + the downwardAPI data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects + a field of the pod: only annotations, + labels, name and namespace are + supported.' + properties: + apiVersion: + description: Version of the + schema the FieldPath is written + in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field + to select in the specified + API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: mode bits + used to set permissions on this + file, must be an octal value between + 0000 and 0777 or a decimal value + between 0 and 511. YAML accepts + both octal and decimal values, + JSON requires decimal values for + mode bits. If not specified, the + volume defaultMode will be used. + This might be in conflict with + other options that affect the + file mode, like fsGroup, and the + result can be other mode bits + set.' + format: int32 + type: integer + path: + description: 'Required: Path is the + relative path name of the file + to be created. Must not be absolute + or contain the ''..'' path. Must + be utf-8 encoded. The first item + of the relative path must not + start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource + of the container: only resources + limits and requests (limits.cpu, + limits.memory, requests.cpu and + requests.memory) are currently + supported.' + properties: + containerName: + description: 'Container name: + required for volumes, optional + for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource + to select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + secret: + description: secret information about the + secret data to project + properties: + items: + description: items if unspecified, each + key-value pair in the Data field of + the referenced Secret will be projected + into the volume as a file whose name + is the key and content is the value. + If specified, the listed keys will be + projected into the specified paths, + and unlisted keys will not be present. + If a key is specified which is not present + in the Secret, the volume setup will + error unless it is marked optional. + Paths must be relative and may not contain + the '..' path or start with '..'. + items: + description: Maps a string key to a + path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: + mode bits used to set permissions + on this file. Must be an octal + value between 0000 and 0777 or + a decimal value between 0 and + 511. YAML accepts both octal and + decimal values, JSON requires + decimal values for mode bits. + If not specified, the volume defaultMode + will be used. This might be in + conflict with other options that + affect the file mode, like fsGroup, + and the result can be other mode + bits set.' + format: int32 + type: integer + path: + description: path is the relative + path of the file to map the key + to. May not be an absolute path. + May not contain the path element + '..'. May not start with the string + '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: optional field specify whether + the Secret or its key must be defined + type: boolean + type: object + serviceAccountToken: + description: serviceAccountToken is information + about the serviceAccountToken data to project + properties: + audience: + description: audience is the intended + audience of the token. A recipient of + a token must identify itself with an + identifier specified in the audience + of the token, and otherwise should reject + the token. The audience defaults to + the identifier of the apiserver. + type: string + expirationSeconds: + description: expirationSeconds is the + requested duration of validity of the + service account token. As the token + approaches expiration, the kubelet volume + plugin will proactively rotate the service + account token. The kubelet will start + trying to rotate the token if the token + is older than 80 percent of its time + to live or if the token is older than + 24 hours.Defaults to 1 hour and must + be at least 10 minutes. + format: int64 + type: integer + path: + description: path is the path relative + to the mount point of the file to project + the token into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: quobyte represents a Quobyte mount on the + host that shares a pod's lifetime + properties: + group: + description: group to map volume access to Default + is no group + type: string + readOnly: + description: readOnly here will force the Quobyte + volume to be mounted with read-only permissions. + Defaults to false. + type: boolean + registry: + description: registry represents a single or multiple + Quobyte Registry services specified as a string + as host:port pair (multiple entries are separated + with commas) which acts as the central registry + for volumes + type: string + tenant: + description: tenant owning the given Quobyte volume + in the Backend Used with dynamically provisioned + Quobyte volumes, value is set by the plugin + type: string + user: + description: user to map volume access to Defaults + to serivceaccount user + type: string + volume: + description: volume is a string that references + an already created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: 'rbd represents a Rados Block Device mount + on the host that shares a pod''s lifetime. More info: + https://examples.k8s.io/volumes/rbd/README.md' + properties: + fsType: + description: 'fsType is the filesystem type of the + volume that you want to mount. Tip: Ensure that + the filesystem type is supported by the host operating + system. Examples: "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. More info: + https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem + from compromising the machine' + type: string + image: + description: 'image is the rados image name. More + info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + keyring: + description: 'keyring is the path to key ring for + RBDUser. Default is /etc/ceph/keyring. More info: + https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + monitors: + description: 'monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + items: + type: string + type: array + pool: + description: 'pool is the rados pool name. Default + is rbd. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + readOnly: + description: 'readOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. More + info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: boolean + secretRef: + description: 'secretRef is name of the authentication + secret for RBDUser. If provided overrides keyring. + Default is nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + user: + description: 'user is the rados user name. Default + is admin. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent + volume attached and mounted on Kubernetes nodes. + properties: + fsType: + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". Default + is "xfs". + type: string + gateway: + description: gateway is the host address of the + ScaleIO API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the + ScaleIO Protection Domain for the configured storage. + type: string + readOnly: + description: readOnly Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. + type: boolean + secretRef: + description: secretRef references to the secret + for ScaleIO user and other sensitive information. + If this is not provided, Login operation will + fail. + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + sslEnabled: + description: sslEnabled Flag enable/disable SSL + communication with Gateway, default false + type: boolean + storageMode: + description: storageMode indicates whether the storage + for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage + Pool associated with the protection domain. + type: string + system: + description: system is the name of the storage system + as configured in ScaleIO. + type: string + volumeName: + description: volumeName is the name of a volume + already created in the ScaleIO system that is + associated with this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: 'secret represents a secret that should + populate this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + properties: + defaultMode: + description: 'defaultMode is Optional: mode bits + used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or + a decimal value between 0 and 511. YAML accepts + both octal and decimal values, JSON requires decimal + values for mode bits. Defaults to 0644. Directories + within the path are not affected by this setting. + This might be in conflict with other options that + affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + items: + description: items If unspecified, each key-value + pair in the Data field of the referenced Secret + will be projected into the volume as a file whose + name is the key and content is the value. If specified, + the listed keys will be projected into the specified + paths, and unlisted keys will not be present. + If a key is specified which is not present in + the Secret, the volume setup will error unless + it is marked optional. Paths must be relative + and may not contain the '..' path or start with + '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits + used to set permissions on this file. Must + be an octal value between 0000 and 0777 + or a decimal value between 0 and 511. YAML + accepts both octal and decimal values, JSON + requires decimal values for mode bits. If + not specified, the volume defaultMode will + be used. This might be in conflict with + other options that affect the file mode, + like fsGroup, and the result can be other + mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of + the file to map the key to. May not be an + absolute path. May not contain the path + element '..'. May not start with the string + '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the + Secret or its keys must be defined + type: boolean + secretName: + description: 'secretName is the name of the secret + in the pod''s namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + type: string + type: object + storageos: + description: storageOS represents a StorageOS volume + attached and mounted on Kubernetes nodes. + properties: + fsType: + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + readOnly: + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. + type: boolean + secretRef: + description: secretRef specifies the secret to use + for obtaining the StorageOS API credentials. If + not specified, default values will be attempted. + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + volumeName: + description: volumeName is the human-readable name + of the StorageOS volume. Volume names are only + unique within a namespace. + type: string + volumeNamespace: + description: volumeNamespace specifies the scope + of the volume within StorageOS. If no namespace + is specified then the Pod's namespace will be + used. This allows the Kubernetes name scoping + to be mirrored within StorageOS for tighter integration. + Set VolumeName to any name to override the default + behaviour. Set to "default" if you are not using + namespaces within StorageOS. Namespaces that do + not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere volume + attached and mounted on kubelets host machine + properties: + fsType: + description: fsType is filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy + Based Management (SPBM) profile ID associated + with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage Policy + Based Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies + vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + type: object + type: object + tolerations: + items: + description: The pod this Toleration is attached to tolerates any + taint that matches the triple using the matching + operator . + properties: + effect: + description: Effect indicates the taint effect to match. Empty + means match all taint effects. When specified, allowed values + are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match all + values and all keys. + type: string + operator: + description: Operator represents a key's relationship to the + value. Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod + can tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of time + the toleration (which must be of effect NoExecute, otherwise + this field is ignored) tolerates the taint. By default, it + is not set, which means tolerate the taint forever (do not + evict). Zero and negative values will be treated as 0 (evict + immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + required: + - clusterSize + - kubernetesConfig + type: object + status: + description: RedisStatus defines the observed state of Redis + properties: + masterNode: + type: string + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} + - name: v1beta2 + schema: + openAPIV3Schema: + description: Redis is the Schema for the redis API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + properties: + TLS: + description: TLS Configuration for redis instances + properties: + ca: + type: string + cert: + type: string + key: + type: string + secret: + description: Reference to secret which contains the certificates + properties: + defaultMode: + description: 'defaultMode is Optional: mode bits used to set + permissions on created files by default. Must be an octal + value between 0000 and 0777 or a decimal value between 0 + and 511. YAML accepts both octal and decimal values, JSON + requires decimal values for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect + the file mode, like fsGroup, and the result can be other + mode bits set.' + format: int32 + type: integer + items: + description: items If unspecified, each key-value pair in + the Data field of the referenced Secret will be projected + into the volume as a file whose name is the key and content + is the value. If specified, the listed keys will be projected + into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the + Secret, the volume setup will error unless it is marked + optional. Paths must be relative and may not contain the + '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used to set + permissions on this file. Must be an octal value between + 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires + decimal values for mode bits. If not specified, the + volume defaultMode will be used. This might be in + conflict with other options that affect the file mode, + like fsGroup, and the result can be other mode bits + set.' + format: int32 + type: integer + path: + description: path is the relative path of the file to + map the key to. May not be an absolute path. May not + contain the path element '..'. May not start with + the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the Secret or + its keys must be defined + type: boolean + secretName: + description: 'secretName is the name of the secret in the + pod''s namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + type: string + type: object + required: + - secret + type: object + acl: + properties: + secret: + description: "Adapts a Secret into a volume. \n The contents of + the target Secret's Data field will be presented in a volume + as files using the keys in the Data field as the file names. + Secret volumes support ownership management and SELinux relabeling." + properties: + defaultMode: + description: 'defaultMode is Optional: mode bits used to set + permissions on created files by default. Must be an octal + value between 0000 and 0777 or a decimal value between 0 + and 511. YAML accepts both octal and decimal values, JSON + requires decimal values for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect + the file mode, like fsGroup, and the result can be other + mode bits set.' + format: int32 + type: integer + items: + description: items If unspecified, each key-value pair in + the Data field of the referenced Secret will be projected + into the volume as a file whose name is the key and content + is the value. If specified, the listed keys will be projected + into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the + Secret, the volume setup will error unless it is marked + optional. Paths must be relative and may not contain the + '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used to set + permissions on this file. Must be an octal value between + 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires + decimal values for mode bits. If not specified, the + volume defaultMode will be used. This might be in + conflict with other options that affect the file mode, + like fsGroup, and the result can be other mode bits + set.' + format: int32 + type: integer + path: + description: path is the relative path of the file to + map the key to. May not be an absolute path. May not + contain the path element '..'. May not start with + the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the Secret or + its keys must be defined + type: boolean + secretName: + description: 'secretName is the name of the secret in the + pod''s namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + type: string + type: object + type: object + affinity: + description: Affinity is a group of affinity scheduling rules. + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for the + pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the affinity expressions specified by + this field, but it may choose a node that violates one or + more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node matches + the corresponding matchExpressions; the node(s) with the + highest sum are the most preferred. + items: + description: An empty preferred scheduling term matches + all objects with implicit weight 0 (i.e. it's a no-op). + A null preferred scheduling term matches no objects (i.e. + is also a no-op). + properties: + preference: + description: A node selector term, associated with the + corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + description: Weight associated with matching the corresponding + nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this + field are not met at scheduling time, the pod will not be + scheduled onto the node. If the affinity requirements specified + by this field cease to be met at some point during pod execution + (e.g. due to an update), the system may or may not try to + eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: A null or empty node selector term matches + no objects. The requirements of them are ANDed. The + TopologySelectorTerm type implements a subset of the + NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. co-locate + this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the affinity expressions specified by + this field, but it may choose a node that violates one or + more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node has + pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key in (value)` to select + the group of existing pods which pods will be + taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MatchLabelKeys and LabelSelector. Also, + MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key notin (value)` to + select the group of existing pods which pods will + be taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MismatchLabelKeys and LabelSelector. Also, + MismatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding + podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this + field are not met at scheduling time, the pod will not be + scheduled onto the node. If the affinity requirements specified + by this field cease to be met at some point during pod execution + (e.g. due to a pod label update), the system may or may + not try to eventually evict the pod from its node. When + there are multiple elements, the lists of nodes corresponding + to each podAffinityTerm are intersected, i.e. all terms + must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not co-located + (anti-affinity) with, where co-located is defined as running + on a node whose value of the label with key + matches that of any node on which a pod of the set of + pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod label keys + to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged with + `LabelSelector` as `key in (value)` to select the + group of existing pods which pods will be taken into + consideration for the incoming pod's pod (anti) affinity. + Keys that don't exist in the incoming pod labels will + be ignored. The default value is empty. The same key + is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires enabling + MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged with + `LabelSelector` as `key notin (value)` to select the + group of existing pods which pods will be taken into + consideration for the incoming pod's pod (anti) affinity. + Keys that don't exist in the incoming pod labels will + be ignored. The default value is empty. The same key + is forbidden to exist in both MismatchLabelKeys and + LabelSelector. Also, MismatchLabelKeys cannot be set + when LabelSelector isn't set. This is an alpha field + and requires enabling MatchLabelKeysInPodAffinity + feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied to the + union of the namespaces selected by this field and + the ones listed in the namespaces field. null selector + and null or empty namespaces list means "this pod's + namespace". An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace + names that the term applies to. The term is applied + to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. null or + empty namespaces list and null namespaceSelector means + "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where + co-located is defined as running on a node whose value + of the label with key topologyKey matches that of + any node on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules (e.g. + avoid putting this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the anti-affinity expressions specified + by this field, but it may choose a node that violates one + or more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node has + pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key in (value)` to select + the group of existing pods which pods will be + taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MatchLabelKeys and LabelSelector. Also, + MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key notin (value)` to + select the group of existing pods which pods will + be taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MismatchLabelKeys and LabelSelector. Also, + MismatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding + podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the anti-affinity requirements + specified by this field cease to be met at some point during + pod execution (e.g. due to a pod label update), the system + may or may not try to eventually evict the pod from its + node. When there are multiple elements, the lists of nodes + corresponding to each podAffinityTerm are intersected, i.e. + all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not co-located + (anti-affinity) with, where co-located is defined as running + on a node whose value of the label with key + matches that of any node on which a pod of the set of + pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod label keys + to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged with + `LabelSelector` as `key in (value)` to select the + group of existing pods which pods will be taken into + consideration for the incoming pod's pod (anti) affinity. + Keys that don't exist in the incoming pod labels will + be ignored. The default value is empty. The same key + is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires enabling + MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged with + `LabelSelector` as `key notin (value)` to select the + group of existing pods which pods will be taken into + consideration for the incoming pod's pod (anti) affinity. + Keys that don't exist in the incoming pod labels will + be ignored. The default value is empty. The same key + is forbidden to exist in both MismatchLabelKeys and + LabelSelector. Also, MismatchLabelKeys cannot be set + when LabelSelector isn't set. This is an alpha field + and requires enabling MatchLabelKeysInPodAffinity + feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied to the + union of the namespaces selected by this field and + the ones listed in the namespaces field. null selector + and null or empty namespaces list means "this pod's + namespace". An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace + names that the term applies to. The term is applied + to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. null or + empty namespaces list and null namespaceSelector means + "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where + co-located is defined as running on a node whose value + of the label with key topologyKey matches that of + any node on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + clusterSize: + format: int32 + type: integer + env: + items: + description: EnvVar represents an environment variable present in + a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded using + the previously defined environment variables in the container + and any service environment variables. If a variable cannot + be resolved, the reference in the input string will be unchanged. + Double $$ are reduced to a single $, which allows for escaping + the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the + string literal "$(VAR_NAME)". Escaped references will never + be expanded, regardless of whether the variable exists or + not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. Cannot + be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, `metadata.annotations['''']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, + status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath is + written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified + API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed + resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + initContainer: + description: InitContainer for each Redis pods + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + enabled: + type: boolean + env: + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + image: + type: string + imagePullPolicy: + description: PullPolicy describes a policy for if/when to pull + a container image + type: string + resources: + description: ResourceRequirements describes the compute resource + requirements. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: SecurityContext holds security configuration that + will be applied to a container. Some fields are present in both + SecurityContext and PodSecurityContext. When both are set, + the values in SecurityContext take precedence. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a + process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the + container runtime. Note that this field cannot be set when + spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in + privileged containers are essentially equivalent to root + on the host. Defaults to false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use + for the containers. The default is DefaultProcMount which + uses the container runtime defaults for readonly paths and + masked paths. This requires the ProcMountType feature flag + to be enabled. Note that this field cannot be set when spec.os.name + is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when + spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail + to start the container if it does. If unset or false, no + such validation will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata if + unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. Note + that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must + be preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must be set if type is "Localhost". Must NOT + be set for any other type. + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a + profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile + should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also be + set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + required: + - image + type: object + kubernetesConfig: + description: KubernetesConfig will be the JSON struct for Basic Redis + Config + properties: + ignoreAnnotations: + items: + type: string + type: array + image: + type: string + imagePullPolicy: + description: PullPolicy describes a policy for if/when to pull + a container image + type: string + imagePullSecrets: + items: + description: LocalObjectReference contains enough information + to let you locate the referenced object inside the same namespace. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + type: array + redisSecret: + description: ExistingPasswordSecret is the struct to access the + existing secret + properties: + key: + type: string + name: + type: string + type: object + resources: + description: ResourceRequirements describes the compute resource + requirements. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + service: + description: ServiceConfig define the type of service to be created + and its annotations + properties: + annotations: + additionalProperties: + type: string + type: object + serviceType: + enum: + - LoadBalancer + - NodePort + - ClusterIP + type: string + type: object + updateStrategy: + description: StatefulSetUpdateStrategy indicates the strategy + that the StatefulSet controller will use to perform updates. + It includes any additional parameters necessary to perform the + update for the indicated strategy. + properties: + rollingUpdate: + description: RollingUpdate is used to communicate parameters + when Type is RollingUpdateStatefulSetStrategyType. + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + description: 'The maximum number of pods that can be unavailable + during the update. Value can be an absolute number (ex: + 5) or a percentage of desired pods (ex: 10%). Absolute + number is calculated from percentage by rounding up. + This can not be 0. Defaults to 1. This field is alpha-level + and is only honored by servers that enable the MaxUnavailableStatefulSet + feature. The field applies to all pods in the range + 0 to Replicas-1. That means if there is any unavailable + pod in the range 0 to Replicas-1, it will be counted + towards MaxUnavailable.' + x-kubernetes-int-or-string: true + partition: + description: Partition indicates the ordinal at which + the StatefulSet should be partitioned for updates. During + a rolling update, all pods from ordinal Replicas-1 to + Partition are updated. All pods from ordinal Partition-1 + to 0 remain untouched. This is helpful in being able + to do a canary based deployment. The default value is + 0. + format: int32 + type: integer + type: object + type: + description: Type indicates the type of the StatefulSetUpdateStrategy. + Default is RollingUpdate. + type: string + type: object + required: + - image + type: object + livenessProbe: + description: Probe describes a health check to be performed against + a container to determine whether it is alive or ready to receive + traffic. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside + the container, the working directory for the command is + root ('/') in the container's filesystem. The command is + simply exec'd, it is not run inside a shell, so traditional + shell instructions ('|', etc) won't work. To use a shell, + you need to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be + considered failed after having succeeded. Defaults to 3. Minimum + value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. + properties: + port: + description: Port number of the gRPC service. Number must + be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place + in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior is defined + by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod + IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows + repeated headers. + items: + description: HTTPHeader describes a custom header to be + used in HTTP probes + properties: + name: + description: The header field name. This will be canonicalized + upon output, so case-variant names will be understood + as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. + Number must be in the range 1 to 65535. Name must be an + IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults + to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started + before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default + to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be + considered successful after having failed. Defaults to 1. Must + be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults + to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. + Number must be in the range 1 to 65535. Name must be an + IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate + gracefully upon probe failure. The grace period is the duration + in seconds after the processes running in the pod are sent a + termination signal and the time when the processes are forcibly + halted with a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, the pod's + terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. Value must + be non-negative integer. The value zero indicates stop immediately + via the kill signal (no opportunity to shut down). This is a + beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + nodeSelector: + additionalProperties: + type: string + type: object + podSecurityContext: + description: PodSecurityContext holds pod-level security attributes + and common container settings. Some fields are also present in container.securityContext. Field + values of container.securityContext take precedence over field values + of PodSecurityContext. + properties: + fsGroup: + description: "A special supplemental group that applies to all + containers in a pod. Some volume types allow the Kubelet to + change the ownership of that volume to be owned by the pod: + \n 1. The owning GID will be the FSGroup 2. The setgid bit is + set (new files created in the volume will be owned by FSGroup) + 3. The permission bits are OR'd with rw-rw---- \n If unset, + the Kubelet will not modify the ownership and permissions of + any volume. Note that this field cannot be set when spec.os.name + is windows." + format: int64 + type: integer + fsGroupChangePolicy: + description: 'fsGroupChangePolicy defines behavior of changing + ownership and permission of the volume before being exposed + inside Pod. This field will only apply to volume types which + support fsGroup based ownership(and permissions). It will have + no effect on ephemeral volume types such as: secret, configmaps + and emptydir. Valid values are "OnRootMismatch" and "Always". + If not specified, "Always" is used. Note that this field cannot + be set when spec.os.name is windows.' + type: string + runAsGroup: + description: The GID to run the entrypoint of the container process. + Uses runtime default if unset. May also be set in SecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail to start + the container if it does. If unset or false, no such validation + will be performed. May also be set in SecurityContext. If set + in both SecurityContext and PodSecurityContext, the value specified + in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in SecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. Note that this field cannot + be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in SecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to + the container. + type: string + role: + description: Role is a SELinux role label that applies to + the container. + type: string + type: + description: Type is a SELinux type label that applies to + the container. + type: string + user: + description: User is a SELinux user label that applies to + the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by the containers in this + pod. Note that this field cannot be set when spec.os.name is + windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must be + preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must be set if type is "Localhost". Must NOT be + set for any other type. + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a profile + defined in a file on the node should be used. RuntimeDefault + - the container runtime default profile should be used. + Unconfined - no profile should be applied." + type: string + required: + - type + type: object + supplementalGroups: + description: A list of groups applied to the first process run + in each container, in addition to the container's primary GID, + the fsGroup (if specified), and group memberships defined in + the container image for the uid of the container process. If + unspecified, no additional groups are added to any container. + Note that group memberships defined in the container image for + the uid of the container process are still effective, even if + they are not included in this list. Note that this field cannot + be set when spec.os.name is windows. + items: + format: int64 + type: integer + type: array + sysctls: + description: Sysctls hold a list of namespaced sysctls used for + the pod. Pods with unsupported sysctls (by the container runtime) + might fail to launch. Note that this field cannot be set when + spec.os.name is windows. + items: + description: Sysctl defines a kernel parameter to be set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + description: The Windows specific settings applied to all containers. + If unspecified, the options within a container's SecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named by + the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA + credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. All of a Pod's containers + must have the same effective HostProcess value (it is not + allowed to have a mix of HostProcess containers and non-HostProcess + containers). In addition, if HostProcess is true then HostNetwork + must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in PodSecurityContext. + If set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: string + type: object + type: object + priorityClassName: + type: string + readinessProbe: + description: Probe describes a health check to be performed against + a container to determine whether it is alive or ready to receive + traffic. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside + the container, the working directory for the command is + root ('/') in the container's filesystem. The command is + simply exec'd, it is not run inside a shell, so traditional + shell instructions ('|', etc) won't work. To use a shell, + you need to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be + considered failed after having succeeded. Defaults to 3. Minimum + value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. + properties: + port: + description: Port number of the gRPC service. Number must + be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place + in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior is defined + by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod + IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows + repeated headers. + items: + description: HTTPHeader describes a custom header to be + used in HTTP probes + properties: + name: + description: The header field name. This will be canonicalized + upon output, so case-variant names will be understood + as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. + Number must be in the range 1 to 65535. Name must be an + IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults + to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started + before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default + to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be + considered successful after having failed. Defaults to 1. Must + be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults + to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. + Number must be in the range 1 to 65535. Name must be an + IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate + gracefully upon probe failure. The grace period is the duration + in seconds after the processes running in the pod are sent a + termination signal and the time when the processes are forcibly + halted with a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, the pod's + terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. Value must + be non-negative integer. The value zero indicates stop immediately + via the kill signal (no opportunity to shut down). This is a + beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + redisConfig: + description: RedisConfig defines the external configuration of Redis + properties: + additionalRedisConfig: + type: string + type: object + redisExporter: + description: RedisExporter interface will have the information for + redis exporter related stuff + properties: + enabled: + type: boolean + env: + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + image: + type: string + imagePullPolicy: + description: PullPolicy describes a policy for if/when to pull + a container image + type: string + port: + default: 9121 + type: integer + resources: + description: ResourceRequirements describes the compute resource + requirements. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: SecurityContext holds security configuration that + will be applied to a container. Some fields are present in both + SecurityContext and PodSecurityContext. When both are set, + the values in SecurityContext take precedence. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a + process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the + container runtime. Note that this field cannot be set when + spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in + privileged containers are essentially equivalent to root + on the host. Defaults to false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use + for the containers. The default is DefaultProcMount which + uses the container runtime defaults for readonly paths and + masked paths. This requires the ProcMountType feature flag + to be enabled. Note that this field cannot be set when spec.os.name + is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when + spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail + to start the container if it does. If unset or false, no + such validation will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata if + unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. Note + that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must + be preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must be set if type is "Localhost". Must NOT + be set for any other type. + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a + profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile + should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also be + set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + required: + - image + type: object + securityContext: + description: SecurityContext holds security configuration that will + be applied to a container. Some fields are present in both SecurityContext + and PodSecurityContext. When both are set, the values in SecurityContext + take precedence. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a process + can gain more privileges than its parent process. This bool + directly controls if the no_new_privs flag will be set on the + container process. AllowPrivilegeEscalation is true always when + the container is: 1) run as Privileged 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container + runtime. Note that this field cannot be set when spec.os.name + is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in privileged + containers are essentially equivalent to root on the host. Defaults + to false. Note that this field cannot be set when spec.os.name + is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use for + the containers. The default is DefaultProcMount which uses the + container runtime defaults for readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when spec.os.name + is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container process. + Uses runtime default if unset. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence. Note that this + field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail to start + the container if it does. If unset or false, no such validation + will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when spec.os.name + is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence. Note that this + field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to + the container. + type: string + role: + description: Role is a SELinux role label that applies to + the container. + type: string + type: + description: Type is a SELinux type label that applies to + the container. + type: string + user: + description: User is a SELinux user label that applies to + the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. If + seccomp options are provided at both the pod & container level, + the container options override the pod options. Note that this + field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must be + preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must be set if type is "Localhost". Must NOT be + set for any other type. + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a profile + defined in a file on the node should be used. RuntimeDefault + - the container runtime default profile should be used. + Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will + be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named by + the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA + credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. All of a Pod's containers + must have the same effective HostProcess value (it is not + allowed to have a mix of HostProcess containers and non-HostProcess + containers). In addition, if HostProcess is true then HostNetwork + must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in PodSecurityContext. + If set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: string + type: object + type: object + serviceAccountName: + type: string + sidecars: + items: + description: Sidecar for each Redis pods + properties: + command: + items: + type: string + type: array + env: + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be + a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. + If a variable cannot be resolved, the reference in the + input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) + syntax: i.e. "$$(VAR_NAME)" will produce the string + literal "$(VAR_NAME)". Escaped references will never + be expanded, regardless of whether the variable exists + or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its + key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + image: + type: string + imagePullPolicy: + description: PullPolicy describes a policy for if/when to pull + a container image + type: string + mountPath: + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: Path within the container at which the volume + should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are + propagated from the host to container and the other + way around. When not set, MountPropagationNone is used. + This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise + (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's + volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which + the container's volume should be mounted. Behaves similarly + to SubPath but environment variable references $(VAR_NAME) + are expanded using the container's environment. Defaults + to "" (volume's root). SubPathExpr and SubPath are mutually + exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + name: + type: string + ports: + items: + description: ContainerPort represents a network port in a + single container. + properties: + containerPort: + description: Number of port to expose on the pod's IP + address. This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port to. + type: string + hostPort: + description: Number of port to expose on the host. If + specified, this must be a valid port number, 0 < x < + 65536. If HostNetwork is specified, this must match + ContainerPort. Most containers do not need this. + format: int32 + type: integer + name: + description: If specified, this must be an IANA_SVC_NAME + and unique within the pod. Each named port in a pod + must have a unique name. Name for the port that can + be referred to by services. + type: string + protocol: + default: TCP + description: Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + resources: + description: ResourceRequirements describes the compute resource + requirements. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only + be set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where this + field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests + cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: SecurityContext holds security configuration that + will be applied to a container. Some fields are present in + both SecurityContext and PodSecurityContext. When both are + set, the values in SecurityContext take precedence. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether + a process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by + the container runtime. Note that this field cannot be + set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes + in privileged containers are essentially equivalent to + root on the host. Defaults to false. Note that this field + cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to + use for the containers. The default is DefaultProcMount + which uses the container runtime defaults for readonly + paths and masked paths. This requires the ProcMountType + feature flag to be enabled. Note that this field cannot + be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root + filesystem. Default is false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a + non-root user. If true, the Kubelet will validate the + image at runtime to ensure that it does not run as UID + 0 (root) and fail to start the container if it does. If + unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both + SecurityContext and PodSecurityContext, the value specified + in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata + if unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a + random SELinux context for each container. May also be + set in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. + Note that this field cannot be set when spec.os.name is + windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile + must be preconfigured on the node to work. Must be + a descending path, relative to the kubelet's configured + seccomp profile location. Must be set if type is "Localhost". + Must NOT be set for any other type. + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - + a profile defined in a file on the node should be + used. RuntimeDefault - the container runtime default + profile should be used. Unconfined - no profile should + be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also + be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set + in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + required: + - image + - name + type: object + type: array + storage: + description: Storage is the inteface to add pvc and pv support in + redis + properties: + keepAfterDelete: + type: boolean + volumeClaimTemplate: + description: PersistentVolumeClaim is a user's request for and + claim to a persistent volume + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this + representation of an object. Servers should convert recognized + schemas to the latest internal value, and may reject unrecognized + values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST + resource this object represents. Servers may infer this + from the endpoint the client submits requests to. Cannot + be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + description: 'Standard object''s metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata' + type: object + spec: + description: 'spec defines the desired characteristics of + a volume requested by a pod author. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + accessModes: + description: 'accessModes contains the desired access + modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'dataSource field can be used to specify + either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) If the provisioner + or an external controller can support the specified + data source, it will create a new volume based on the + contents of the specified data source. When the AnyVolumeDataSource + feature gate is enabled, dataSource contents will be + copied to dataSourceRef, and dataSourceRef contents + will be copied to dataSource when dataSourceRef.namespace + is not specified. If the namespace is specified, then + dataSourceRef will not be copied to dataSource.' + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + dataSourceRef: + description: 'dataSourceRef specifies the object from + which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty + API group (non core object) or a PersistentVolumeClaim + object. When this field is specified, volume binding + will only succeed if the type of the specified object + matches some installed volume populator or dynamic provisioner. + This field will replace the functionality of the dataSource + field and as such if both fields are non-empty, they + must have the same value. For backwards compatibility, + when namespace isn''t specified in dataSourceRef, both + fields (dataSource and dataSourceRef) will be set to + the same value automatically if one of them is empty + and the other is non-empty. When namespace is specified + in dataSourceRef, dataSource isn''t set to the same + value and must be empty. There are three important differences + between dataSource and dataSourceRef: * While dataSource + only allows two specific types of objects, dataSourceRef allows + any non-core object, as well as PersistentVolumeClaim + objects. * While dataSource ignores disallowed values + (dropping them), dataSourceRef preserves all values, + and generates an error if a disallowed value is specified. + * While dataSource only allows local objects, dataSourceRef + allows objects in any namespaces. (Beta) Using this + field requires the AnyVolumeDataSource feature gate + to be enabled. (Alpha) Using the namespace field of + dataSourceRef requires the CrossNamespaceVolumeDataSource + feature gate to be enabled.' + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + namespace: + description: Namespace is the namespace of resource + being referenced Note that when a namespace is specified, + a gateway.networking.k8s.io/ReferenceGrant object + is required in the referent namespace to allow that + namespace's owner to accept the reference. See the + ReferenceGrant documentation for details. (Alpha) + This field requires the CrossNamespaceVolumeDataSource + feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: 'resources represents the minimum resources + the volume should have. If RecoverVolumeExpansionFailure + feature is enabled users are allowed to specify resource + requirements that are lower than previous value but + must still be higher than capacity recorded in the status + field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount + of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount + of compute resources required. If Requests is omitted + for a container, it defaults to Limits if that is + explicitly specified, otherwise to an implementation-defined + value. Requests cannot exceed Limits. More info: + https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + selector: + description: selector is a label query over volumes to + consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, + NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values + array must be non-empty. If the operator is + Exists or DoesNotExist, the values array must + be empty. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field + is "key", the operator is "In", and the values array + contains only "value". The requirements are ANDed. + type: object + type: object + storageClassName: + description: 'storageClassName is the name of the StorageClass + required by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + type: string + volumeAttributesClassName: + description: 'volumeAttributesClassName may be used to + set the VolumeAttributesClass used by this claim. If + specified, the CSI driver will create or update the + volume with the attributes defined in the corresponding + VolumeAttributesClass. This has a different purpose + than storageClassName, it can be changed after the claim + is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it''s not allowed to + reset this field to empty string once it is set. If + unspecified and the PersistentVolumeClaim is unbound, + the default VolumeAttributesClass will be set by the + persistentvolume controller if it exists. If the resource + referred to by volumeAttributesClass does not exist, + this PersistentVolumeClaim will be set to a Pending + state, as reflected by the modifyVolumeStatus field, + until such as a resource exists. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + (Alpha) Using this field requires the VolumeAttributesClass + feature gate to be enabled.' + type: string + volumeMode: + description: volumeMode defines what type of volume is + required by the claim. Value of Filesystem is implied + when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to the + PersistentVolume backing this claim. + type: string + type: object + status: + description: 'status represents the current information/status + of a persistent volume claim. Read-only. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + accessModes: + description: 'accessModes contains the actual access modes + the volume backing the PVC has. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + allocatedResourceStatuses: + additionalProperties: + description: When a controller receives persistentvolume + claim update with ClaimResourceStatus for a resource + that it does not recognizes, then it should ignore + that update and let other controllers handle it. + type: string + description: "allocatedResourceStatuses stores status + of resource being resized for the given PVC. Key names + follow standard Kubernetes label syntax. Valid values + are either: \t* Un-prefixed keys: \t\t- storage - the + capacity of the volume. \t* Custom resources must use + implementation-defined prefixed names such as \"example.com/my-custom-resource\" + Apart from above values - keys that are unprefixed or + have kubernetes.io prefix are considered reserved and + hence may not be used. \n ClaimResourceStatus can be + in any of following states: \t- ControllerResizeInProgress: + \t\tState set when resize controller starts resizing + the volume in control-plane. \t- ControllerResizeFailed: + \t\tState set when resize has failed in resize controller + with a terminal error. \t- NodeResizePending: \t\tState + set when resize controller has finished resizing the + volume but further resizing of \t\tvolume is needed + on the node. \t- NodeResizeInProgress: \t\tState set + when kubelet starts resizing the volume. \t- NodeResizeFailed: + \t\tState set when resizing has failed in kubelet with + a terminal error. Transient errors don't set \t\tNodeResizeFailed. + For example: if expanding a PVC for more capacity - + this field can be one of the following states: \t- pvc.status.allocatedResourceStatus['storage'] + = \"ControllerResizeInProgress\" - pvc.status.allocatedResourceStatus['storage'] + = \"ControllerResizeFailed\" - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizePending\" - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizeInProgress\" - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizeFailed\" When this field is not set, it + means that no resize operation is in progress for the + given PVC. \n A controller that receives PVC update + with previously unknown resourceName or ClaimResourceStatus + should ignore the update for the purpose it was designed. + For example - a controller that only is responsible + for resizing capacity of the volume, should ignore PVC + updates that change other valid resources associated + with PVC. \n This is an alpha field and requires enabling + RecoverVolumeExpansionFailure feature." + type: object + x-kubernetes-map-type: granular + allocatedResources: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: "allocatedResources tracks the resources + allocated to a PVC including its capacity. Key names + follow standard Kubernetes label syntax. Valid values + are either: \t* Un-prefixed keys: \t\t- storage - the + capacity of the volume. \t* Custom resources must use + implementation-defined prefixed names such as \"example.com/my-custom-resource\" + Apart from above values - keys that are unprefixed or + have kubernetes.io prefix are considered reserved and + hence may not be used. \n Capacity reported here may + be larger than the actual capacity when a volume expansion + operation is requested. For storage quota, the larger + value from allocatedResources and PVC.spec.resources + is used. If allocatedResources is not set, PVC.spec.resources + alone is used for quota calculation. If a volume expansion + capacity request is lowered, allocatedResources is only + lowered if there are no expansion operations in progress + and if the actual volume capacity is equal or lower + than the requested capacity. \n A controller that receives + PVC update with previously unknown resourceName should + ignore the update for the purpose it was designed. For + example - a controller that only is responsible for + resizing capacity of the volume, should ignore PVC updates + that change other valid resources associated with PVC. + \n This is an alpha field and requires enabling RecoverVolumeExpansionFailure + feature." + type: object + capacity: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: capacity represents the actual resources + of the underlying volume. + type: object + conditions: + description: conditions is the current Condition of persistent + volume claim. If underlying persistent volume is being + resized then the Condition will be set to 'ResizeStarted'. + items: + description: PersistentVolumeClaimCondition contains + details about state of pvc + properties: + lastProbeTime: + description: lastProbeTime is the time we probed + the condition. + format: date-time + type: string + lastTransitionTime: + description: lastTransitionTime is the time the + condition transitioned from one status to another. + format: date-time + type: string + message: + description: message is the human-readable message + indicating details about last transition. + type: string + reason: + description: reason is a unique, this should be + a short, machine understandable string that gives + the reason for condition's last transition. If + it reports "ResizeStarted" that means the underlying + persistent volume is being resized. + type: string + status: + type: string + type: + description: PersistentVolumeClaimConditionType + is a valid value of PersistentVolumeClaimCondition.Type + type: string + required: + - status + - type + type: object + type: array + currentVolumeAttributesClassName: + description: currentVolumeAttributesClassName is the current + name of the VolumeAttributesClass the PVC is using. + When unset, there is no VolumeAttributeClass applied + to this PersistentVolumeClaim This is an alpha field + and requires enabling VolumeAttributesClass feature. + type: string + modifyVolumeStatus: + description: ModifyVolumeStatus represents the status + object of ControllerModifyVolume operation. When this + is unset, there is no ModifyVolume operation being attempted. + This is an alpha field and requires enabling VolumeAttributesClass + feature. + properties: + status: + description: "status is the status of the ControllerModifyVolume + operation. It can be in any of following states: + \ - Pending Pending indicates that the PersistentVolumeClaim + cannot be modified due to unmet requirements, such + as the specified VolumeAttributesClass not existing. + \ - InProgress InProgress indicates that the + volume is being modified. - Infeasible Infeasible + indicates that the request has been rejected as + invalid by the CSI driver. To \t resolve the error, + a valid VolumeAttributesClass needs to be specified. + Note: New statuses can be added in the future. Consumers + should check for unknown statuses and fail appropriately." + type: string + targetVolumeAttributesClassName: + description: targetVolumeAttributesClassName is the + name of the VolumeAttributesClass the PVC currently + being reconciled + type: string + required: + - status + type: object + phase: + description: phase represents the current phase of PersistentVolumeClaim. + type: string + type: object + type: object + volumeMount: + description: Additional Volume is provided by user that is mounted + on the pods + properties: + mountPath: + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: Path within the container at which the + volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts + are propagated from the host to container and the + other way around. When not set, MountPropagationNone + is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise + (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's + volume should be mounted. Defaults to "" (volume's + root). + type: string + subPathExpr: + description: Expanded path within the volume from which + the container's volume should be mounted. Behaves + similarly to SubPath but environment variable references + $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). SubPathExpr and SubPath + are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + volume: + items: + description: Volume represents a named volume in a pod that + may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: 'awsElasticBlockStore represents an AWS + Disk resource that is attached to a kubelet''s host + machine and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + properties: + fsType: + description: 'fsType is the filesystem type of the + volume that you want to mount. Tip: Ensure that + the filesystem type is supported by the host operating + system. Examples: "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. More info: + https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem + from compromising the machine' + type: string + partition: + description: 'partition is the partition in the + volume that you want to mount. If omitted, the + default is to mount by volume name. Examples: + For volume /dev/sda1, you specify the partition + as "1". Similarly, the volume partition for /dev/sda + is "0" (or you can leave the property empty).' + format: int32 + type: integer + readOnly: + description: 'readOnly value true will force the + readOnly setting in VolumeMounts. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: boolean + volumeID: + description: 'volumeID is unique ID of the persistent + disk resource in AWS (Amazon EBS volume). More + info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data Disk + mount on the host and bind mount to the pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching mode: + None, Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data disk + in the blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in + the blob storage + type: string + fsType: + description: fsType is Filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: multiple + blob disks per storage account Dedicated: single + blob disk per storage account Managed: azure + managed data disk (only in managed availability + set). defaults to shared' + type: string + readOnly: + description: readOnly Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File Service + mount on the host and bind mount to the pod. + properties: + readOnly: + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret that + contains Azure Storage Account Name and Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount on the + host that shares a pod's lifetime + properties: + monitors: + description: 'monitors is Required: Monitors is + a collection of Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + items: + type: string + type: array + path: + description: 'path is Optional: Used as the mounted + root, rather than the full Ceph tree, default + is /' + type: string + readOnly: + description: 'readOnly is Optional: Defaults to + false (read/write). ReadOnly here will force the + ReadOnly setting in VolumeMounts. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: boolean + secretFile: + description: 'secretFile is Optional: SecretFile + is the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + secretRef: + description: 'secretRef is Optional: SecretRef is + reference to the authentication secret for User, + default is empty. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + user: + description: 'user is optional: User is the rados + user name, default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + required: + - monitors + type: object + cinder: + description: 'cinder represents a cinder volume attached + and mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + properties: + fsType: + description: 'fsType is the filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Examples: "ext4", "xfs", "ntfs". + Implicitly inferred to be "ext4" if unspecified. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + readOnly: + description: 'readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: boolean + secretRef: + description: 'secretRef is optional: points to a + secret object containing parameters used to connect + to OpenStack.' + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + volumeID: + description: 'volumeID used to identify the volume + in cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that should + populate this volume + properties: + defaultMode: + description: 'defaultMode is optional: mode bits + used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or + a decimal value between 0 and 511. YAML accepts + both octal and decimal values, JSON requires decimal + values for mode bits. Defaults to 0644. Directories + within the path are not affected by this setting. + This might be in conflict with other options that + affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + items: + description: items if unspecified, each key-value + pair in the Data field of the referenced ConfigMap + will be projected into the volume as a file whose + name is the key and content is the value. If specified, + the listed keys will be projected into the specified + paths, and unlisted keys will not be present. + If a key is specified which is not present in + the ConfigMap, the volume setup will error unless + it is marked optional. Paths must be relative + and may not contain the '..' path or start with + '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits + used to set permissions on this file. Must + be an octal value between 0000 and 0777 + or a decimal value between 0 and 511. YAML + accepts both octal and decimal values, JSON + requires decimal values for mode bits. If + not specified, the volume defaultMode will + be used. This might be in conflict with + other options that affect the file mode, + like fsGroup, and the result can be other + mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of + the file to map the key to. May not be an + absolute path. May not contain the path + element '..'. May not start with the string + '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + csi: + description: csi (Container Storage Interface) represents + ephemeral storage that is handled by certain external + CSI drivers (Beta feature). + properties: + driver: + description: driver is the name of the CSI driver + that handles this volume. Consult with your admin + for the correct name as registered in the cluster. + type: string + fsType: + description: fsType to mount. Ex. "ext4", "xfs", + "ntfs". If not provided, the empty value is passed + to the associated CSI driver which will determine + the default filesystem to apply. + type: string + nodePublishSecretRef: + description: nodePublishSecretRef is a reference + to the secret object containing sensitive information + to pass to the CSI driver to complete the CSI + NodePublishVolume and NodeUnpublishVolume calls. + This field is optional, and may be empty if no + secret is required. If the secret object contains + more than one secret, all secret references are + passed. + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + readOnly: + description: readOnly specifies a read-only configuration + for the volume. Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: volumeAttributes stores driver-specific + properties that are passed to the CSI driver. + Consult your driver's documentation for supported + values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about + the pod that should populate this volume + properties: + defaultMode: + description: 'Optional: mode bits to use on created + files by default. Must be a Optional: mode bits + used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or + a decimal value between 0 and 511. YAML accepts + both octal and decimal values, JSON requires decimal + values for mode bits. Defaults to 0644. Directories + within the path are not affected by this setting. + This might be in conflict with other options that + affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + items: + description: Items is a list of downward API volume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing the + pod field + properties: + fieldRef: + description: 'Required: Selects a field of + the pod: only annotations, labels, name + and namespace are supported.' + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: mode bits used to + set permissions on this file, must be an + octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both + octal and decimal values, JSON requires + decimal values for mode bits. If not specified, + the volume defaultMode will be used. This + might be in conflict with other options + that affect the file mode, like fsGroup, + and the result can be other mode bits set.' + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. Must + not be absolute or contain the ''..'' path. + Must be utf-8 encoded. The first item of + the relative path must not start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, requests.cpu and requests.memory) + are currently supported.' + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + emptyDir: + description: 'emptyDir represents a temporary directory + that shares a pod''s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + properties: + medium: + description: 'medium represents what type of storage + medium should back this directory. The default + is "" which means to use the node''s default medium. + Must be an empty string (default) or Memory. More + info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: 'sizeLimit is the total amount of local + storage required for this EmptyDir volume. The + size limit is also applicable for memory medium. + The maximum usage on memory medium EmptyDir would + be the minimum value between the SizeLimit specified + here and the sum of memory limits of all containers + in a pod. The default is nil which means that + the limit is undefined. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: "ephemeral represents a volume that is + handled by a cluster storage driver. The volume's + lifecycle is tied to the pod that defines it - it + will be created before the pod starts, and deleted + when the pod is removed. \n Use this if: a) the volume + is only needed while the pod runs, b) features of + normal volumes like restoring from snapshot or capacity + \ tracking are needed, c) the storage driver is + specified through a storage class, and d) the storage + driver supports dynamic volume provisioning through + \ a PersistentVolumeClaim (see EphemeralVolumeSource + for more information on the connection between + this volume type and PersistentVolumeClaim). \n + Use PersistentVolumeClaim or one of the vendor-specific + APIs for volumes that persist for longer than the + lifecycle of an individual pod. \n Use CSI for light-weight + local ephemeral volumes if the CSI driver is meant + to be used that way - see the documentation of the + driver for more information. \n A pod can use both + types of ephemeral volumes and persistent volumes + at the same time." + properties: + volumeClaimTemplate: + description: "Will be used to create a stand-alone + PVC to provision the volume. The pod in which + this EphemeralVolumeSource is embedded will be + the owner of the PVC, i.e. the PVC will be deleted + together with the pod. The name of the PVC will + be `-` where `` + is the name from the `PodSpec.Volumes` array entry. + Pod validation will reject the pod if the concatenated + name is not valid for a PVC (for example, too + long). \n An existing PVC with that name that + is not owned by the pod will *not* be used for + the pod to avoid using an unrelated volume by + mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created + PVC is meant to be used by the pod, the PVC has + to updated with an owner reference to the pod + once the pod exists. Normally this should not + be necessary, but it may be useful when manually + reconstructing a broken cluster. \n This field + is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. \n Required, + must not be nil." + properties: + metadata: + description: May contain labels and annotations + that will be copied into the PVC when creating + it. No other fields are allowed and will be + rejected during validation. + type: object + spec: + description: The specification for the PersistentVolumeClaim. + The entire content is copied unchanged into + the PVC that gets created from this template. + The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: 'accessModes contains the desired + access modes the volume should have. More + info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'dataSource field can be used + to specify either: * An existing VolumeSnapshot + object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller + can support the specified data source, + it will create a new volume based on the + contents of the specified data source. + When the AnyVolumeDataSource feature gate + is enabled, dataSource contents will be + copied to dataSourceRef, and dataSourceRef + contents will be copied to dataSource + when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef + will not be copied to dataSource.' + properties: + apiGroup: + description: APIGroup is the group for + the resource being referenced. If + APIGroup is not specified, the specified + Kind must be in the core API group. + For any other third-party types, APIGroup + is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + required: + - kind + - name + type: object + dataSourceRef: + description: 'dataSourceRef specifies the + object from which to populate the volume + with data, if a non-empty volume is desired. + This may be any object from a non-empty + API group (non core object) or a PersistentVolumeClaim + object. When this field is specified, + volume binding will only succeed if the + type of the specified object matches some + installed volume populator or dynamic + provisioner. This field will replace the + functionality of the dataSource field + and as such if both fields are non-empty, + they must have the same value. For backwards + compatibility, when namespace isn''t specified + in dataSourceRef, both fields (dataSource + and dataSourceRef) will be set to the + same value automatically if one of them + is empty and the other is non-empty. When + namespace is specified in dataSourceRef, + dataSource isn''t set to the same value + and must be empty. There are three important + differences between dataSource and dataSourceRef: + * While dataSource only allows two specific + types of objects, dataSourceRef allows + any non-core object, as well as PersistentVolumeClaim + objects. * While dataSource ignores disallowed + values (dropping them), dataSourceRef preserves + all values, and generates an error if + a disallowed value is specified. * While + dataSource only allows local objects, + dataSourceRef allows objects in any + namespaces. (Beta) Using this field requires + the AnyVolumeDataSource feature gate to + be enabled. (Alpha) Using the namespace + field of dataSourceRef requires the CrossNamespaceVolumeDataSource + feature gate to be enabled.' + properties: + apiGroup: + description: APIGroup is the group for + the resource being referenced. If + APIGroup is not specified, the specified + Kind must be in the core API group. + For any other third-party types, APIGroup + is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + namespace: + description: Namespace is the namespace + of resource being referenced Note + that when a namespace is specified, + a gateway.networking.k8s.io/ReferenceGrant + object is required in the referent + namespace to allow that namespace's + owner to accept the reference. See + the ReferenceGrant documentation for + details. (Alpha) This field requires + the CrossNamespaceVolumeDataSource + feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: 'resources represents the minimum + resources the volume should have. If RecoverVolumeExpansionFailure + feature is enabled users are allowed to + specify resource requirements that are + lower than previous value but must still + be higher than capacity recorded in the + status field of the claim. More info: + https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum + amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the + minimum amount of compute resources + required. If Requests is omitted for + a container, it defaults to Limits + if that is explicitly specified, otherwise + to an implementation-defined value. + Requests cannot exceed Limits. More + info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + selector: + description: selector is a label query over + volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. + This array is replaced during + a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of + {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + storageClassName: + description: 'storageClassName is the name + of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + type: string + volumeAttributesClassName: + description: 'volumeAttributesClassName + may be used to set the VolumeAttributesClass + used by this claim. If specified, the + CSI driver will create or update the volume + with the attributes defined in the corresponding + VolumeAttributesClass. This has a different + purpose than storageClassName, it can + be changed after the claim is created. + An empty string value means that no VolumeAttributesClass + will be applied to the claim but it''s + not allowed to reset this field to empty + string once it is set. If unspecified + and the PersistentVolumeClaim is unbound, + the default VolumeAttributesClass will + be set by the persistentvolume controller + if it exists. If the resource referred + to by volumeAttributesClass does not exist, + this PersistentVolumeClaim will be set + to a Pending state, as reflected by the + modifyVolumeStatus field, until such as + a resource exists. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + (Alpha) Using this field requires the + VolumeAttributesClass feature gate to + be enabled.' + type: string + volumeMode: + description: volumeMode defines what type + of volume is required by the claim. Value + of Filesystem is implied when not included + in claim spec. + type: string + volumeName: + description: volumeName is the binding reference + to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource + that is attached to a kubelet's host machine and then + exposed to the pod. + properties: + fsType: + description: 'fsType is the filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. TODO: how + do we prevent errors in the filesystem from compromising + the machine' + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: 'readOnly is Optional: Defaults to + false (read/write). ReadOnly here will force the + ReadOnly setting in VolumeMounts.' + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target + worldwide names (WWNs)' + items: + type: string + type: array + wwids: + description: 'wwids Optional: FC volume world wide + identifiers (wwids) Either wwids or combination + of targetWWNs and lun must be set, but not both + simultaneously.' + items: + type: string + type: array + type: object + flexVolume: + description: flexVolume represents a generic volume + resource that is provisioned/attached using an exec + based plugin. + properties: + driver: + description: driver is the name of the driver to + use for this volume. + type: string + fsType: + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". The + default filesystem depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field holds + extra command options if any.' + type: object + readOnly: + description: 'readOnly is Optional: defaults to + false (read/write). ReadOnly here will force the + ReadOnly setting in VolumeMounts.' + type: boolean + secretRef: + description: 'secretRef is Optional: secretRef is + reference to the secret object containing sensitive + information to pass to the plugin scripts. This + may be empty if no secret object is specified. + If the secret object contains more than one secret, + all secrets are passed to the plugin scripts.' + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume attached + to a kubelet's host machine. This depends on the Flocker + control service being running + properties: + datasetName: + description: datasetName is Name of the dataset + stored as metadata -> name on the dataset for + Flocker should be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. + This is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: 'gcePersistentDisk represents a GCE Disk + resource that is attached to a kubelet''s host machine + and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + properties: + fsType: + description: 'fsType is filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem + from compromising the machine' + type: string + partition: + description: 'partition is the partition in the + volume that you want to mount. If omitted, the + default is to mount by volume name. Examples: + For volume /dev/sda1, you specify the partition + as "1". Similarly, the volume partition for /dev/sda + is "0" (or you can leave the property empty). + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + format: int32 + type: integer + pdName: + description: 'pdName is unique name of the PD resource + in GCE. Used to identify the disk in GCE. More + info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: string + readOnly: + description: 'readOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. More + info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: boolean + required: + - pdName + type: object + gitRepo: + description: 'gitRepo represents a git repository at + a particular revision. DEPRECATED: GitRepo is deprecated. + To provision a container with a git repo, mount an + EmptyDir into an InitContainer that clones the repo + using git, then mount the EmptyDir into the Pod''s + container.' + properties: + directory: + description: directory is the target directory name. + Must not contain or start with '..'. If '.' is + supplied, the volume directory will be the git + repository. Otherwise, if specified, the volume + will contain the git repository in the subdirectory + with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the + specified revision. + type: string + required: + - repository + type: object + glusterfs: + description: 'glusterfs represents a Glusterfs mount + on the host that shares a pod''s lifetime. More info: + https://examples.k8s.io/volumes/glusterfs/README.md' + properties: + endpoints: + description: 'endpoints is the endpoint name that + details Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + path: + description: 'path is the Glusterfs volume path. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + readOnly: + description: 'readOnly here will force the Glusterfs + volume to be mounted with read-only permissions. + Defaults to false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: 'hostPath represents a pre-existing file + or directory on the host machine that is directly + exposed to the container. This is generally used for + system agents or other privileged things that are + allowed to see the host machine. Most containers will + NOT need this. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- TODO(jonesdl) We need to restrict who can use + host directory mounts and who can/can not mount host + directories as read/write.' + properties: + path: + description: 'path of the directory on the host. + If the path is a symlink, it will follow the link + to the real path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + type: + description: 'type for HostPath Volume Defaults + to "" More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + required: + - path + type: object + iscsi: + description: 'iscsi represents an ISCSI Disk resource + that is attached to a kubelet''s host machine and + then exposed to the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md' + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether support + iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support + iSCSI Session CHAP authentication + type: boolean + fsType: + description: 'fsType is the filesystem type of the + volume that you want to mount. Tip: Ensure that + the filesystem type is supported by the host operating + system. Examples: "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. More info: + https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem + from compromising the machine' + type: string + initiatorName: + description: initiatorName is the custom iSCSI Initiator + Name. If initiatorName is specified with iscsiInterface + simultaneously, new iSCSI interface : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified Name. + type: string + iscsiInterface: + description: iscsiInterface is the interface Name + that uses an iSCSI transport. Defaults to 'default' + (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: portals is the iSCSI Target Portal + List. The portal is either an IP or ip_addr:port + if the port is other than default (typically TCP + ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: readOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for iSCSI + target and initiator authentication + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + targetPortal: + description: targetPortal is iSCSI Target Portal. + The Portal is either an IP or ip_addr:port if + the port is other than default (typically TCP + ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: 'name of the volume. Must be a DNS_LABEL + and unique within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + nfs: + description: 'nfs represents an NFS mount on the host + that shares a pod''s lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + properties: + path: + description: 'path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + readOnly: + description: 'readOnly here will force the NFS export + to be mounted with read-only permissions. Defaults + to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: boolean + server: + description: 'server is the hostname or IP address + of the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: 'persistentVolumeClaimVolumeSource represents + a reference to a PersistentVolumeClaim in the same + namespace. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + claimName: + description: 'claimName is the name of a PersistentVolumeClaim + in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + type: string + readOnly: + description: readOnly Will force the ReadOnly setting + in VolumeMounts. Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents a PhotonController + persistent disk attached and mounted on kubelets host + machine + properties: + fsType: + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon + Controller persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx volume + attached and mounted on kubelets host machine + properties: + fsType: + description: fSType represents the filesystem type + to mount Must be a filesystem type supported by + the host operating system. Ex. "ext4", "xfs". + Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx + volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources + secrets, configmaps, and downward API + properties: + defaultMode: + description: defaultMode are the mode bits used + to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or + a decimal value between 0 and 511. YAML accepts + both octal and decimal values, JSON requires decimal + values for mode bits. Directories within the path + are not affected by this setting. This might be + in conflict with other options that affect the + file mode, like fsGroup, and the result can be + other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume projections + items: + description: Projection that may be projected + along with other supported volume types + properties: + clusterTrustBundle: + description: "ClusterTrustBundle allows a + pod to access the `.spec.trustBundle` field + of ClusterTrustBundle objects in an auto-updating + file. \n Alpha, gated by the ClusterTrustBundleProjection + feature gate. \n ClusterTrustBundle objects + can either be selected by name, or by the + combination of signer name and a label selector. + \n Kubelet performs aggressive normalization + of the PEM contents written into the pod + filesystem. Esoteric PEM features such + as inter-block comments and block headers + are stripped. Certificates are deduplicated. + The ordering of certificates within the + file is arbitrary, and Kubelet may change + the order over time." + properties: + labelSelector: + description: Select all ClusterTrustBundles + that match this label selector. Only + has effect if signerName is set. Mutually-exclusive + with name. If unset, interpreted as + "match nothing". If set but empty, + interpreted as "match everything". + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a + set of values. Valid operators + are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values + array must be non-empty. If + the operator is Exists or + DoesNotExist, the values array + must be empty. This array + is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map + of {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + name: + description: Select a single ClusterTrustBundle + by object name. Mutually-exclusive + with signerName and labelSelector. + type: string + optional: + description: If true, don't block pod + startup if the referenced ClusterTrustBundle(s) + aren't available. If using name, then + the named ClusterTrustBundle is allowed + not to exist. If using signerName, + then the combination of signerName and + labelSelector is allowed to match zero + ClusterTrustBundles. + type: boolean + path: + description: Relative path from the volume + root to write the bundle. + type: string + signerName: + description: Select all ClusterTrustBundles + that match this signer name. Mutually-exclusive + with name. The contents of all selected + ClusterTrustBundles will be unified + and deduplicated. + type: string + required: + - path + type: object + configMap: + description: configMap information about the + configMap data to project + properties: + items: + description: items if unspecified, each + key-value pair in the Data field of + the referenced ConfigMap will be projected + into the volume as a file whose name + is the key and content is the value. + If specified, the listed keys will be + projected into the specified paths, + and unlisted keys will not be present. + If a key is specified which is not present + in the ConfigMap, the volume setup will + error unless it is marked optional. + Paths must be relative and may not contain + the '..' path or start with '..'. + items: + description: Maps a string key to a + path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: + mode bits used to set permissions + on this file. Must be an octal + value between 0000 and 0777 or + a decimal value between 0 and + 511. YAML accepts both octal and + decimal values, JSON requires + decimal values for mode bits. + If not specified, the volume defaultMode + will be used. This might be in + conflict with other options that + affect the file mode, like fsGroup, + and the result can be other mode + bits set.' + format: int32 + type: integer + path: + description: path is the relative + path of the file to map the key + to. May not be an absolute path. + May not contain the path element + '..'. May not start with the string + '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: optional specify whether + the ConfigMap or its keys must be defined + type: boolean + type: object + downwardAPI: + description: downwardAPI information about + the downwardAPI data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects + a field of the pod: only annotations, + labels, name and namespace are + supported.' + properties: + apiVersion: + description: Version of the + schema the FieldPath is written + in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field + to select in the specified + API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: mode bits + used to set permissions on this + file, must be an octal value between + 0000 and 0777 or a decimal value + between 0 and 511. YAML accepts + both octal and decimal values, + JSON requires decimal values for + mode bits. If not specified, the + volume defaultMode will be used. + This might be in conflict with + other options that affect the + file mode, like fsGroup, and the + result can be other mode bits + set.' + format: int32 + type: integer + path: + description: 'Required: Path is the + relative path name of the file + to be created. Must not be absolute + or contain the ''..'' path. Must + be utf-8 encoded. The first item + of the relative path must not + start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource + of the container: only resources + limits and requests (limits.cpu, + limits.memory, requests.cpu and + requests.memory) are currently + supported.' + properties: + containerName: + description: 'Container name: + required for volumes, optional + for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource + to select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + secret: + description: secret information about the + secret data to project + properties: + items: + description: items if unspecified, each + key-value pair in the Data field of + the referenced Secret will be projected + into the volume as a file whose name + is the key and content is the value. + If specified, the listed keys will be + projected into the specified paths, + and unlisted keys will not be present. + If a key is specified which is not present + in the Secret, the volume setup will + error unless it is marked optional. + Paths must be relative and may not contain + the '..' path or start with '..'. + items: + description: Maps a string key to a + path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: + mode bits used to set permissions + on this file. Must be an octal + value between 0000 and 0777 or + a decimal value between 0 and + 511. YAML accepts both octal and + decimal values, JSON requires + decimal values for mode bits. + If not specified, the volume defaultMode + will be used. This might be in + conflict with other options that + affect the file mode, like fsGroup, + and the result can be other mode + bits set.' + format: int32 + type: integer + path: + description: path is the relative + path of the file to map the key + to. May not be an absolute path. + May not contain the path element + '..'. May not start with the string + '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: optional field specify whether + the Secret or its key must be defined + type: boolean + type: object + serviceAccountToken: + description: serviceAccountToken is information + about the serviceAccountToken data to project + properties: + audience: + description: audience is the intended + audience of the token. A recipient of + a token must identify itself with an + identifier specified in the audience + of the token, and otherwise should reject + the token. The audience defaults to + the identifier of the apiserver. + type: string + expirationSeconds: + description: expirationSeconds is the + requested duration of validity of the + service account token. As the token + approaches expiration, the kubelet volume + plugin will proactively rotate the service + account token. The kubelet will start + trying to rotate the token if the token + is older than 80 percent of its time + to live or if the token is older than + 24 hours.Defaults to 1 hour and must + be at least 10 minutes. + format: int64 + type: integer + path: + description: path is the path relative + to the mount point of the file to project + the token into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: quobyte represents a Quobyte mount on the + host that shares a pod's lifetime + properties: + group: + description: group to map volume access to Default + is no group + type: string + readOnly: + description: readOnly here will force the Quobyte + volume to be mounted with read-only permissions. + Defaults to false. + type: boolean + registry: + description: registry represents a single or multiple + Quobyte Registry services specified as a string + as host:port pair (multiple entries are separated + with commas) which acts as the central registry + for volumes + type: string + tenant: + description: tenant owning the given Quobyte volume + in the Backend Used with dynamically provisioned + Quobyte volumes, value is set by the plugin + type: string + user: + description: user to map volume access to Defaults + to serivceaccount user + type: string + volume: + description: volume is a string that references + an already created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: 'rbd represents a Rados Block Device mount + on the host that shares a pod''s lifetime. More info: + https://examples.k8s.io/volumes/rbd/README.md' + properties: + fsType: + description: 'fsType is the filesystem type of the + volume that you want to mount. Tip: Ensure that + the filesystem type is supported by the host operating + system. Examples: "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. More info: + https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem + from compromising the machine' + type: string + image: + description: 'image is the rados image name. More + info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + keyring: + description: 'keyring is the path to key ring for + RBDUser. Default is /etc/ceph/keyring. More info: + https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + monitors: + description: 'monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + items: + type: string + type: array + pool: + description: 'pool is the rados pool name. Default + is rbd. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + readOnly: + description: 'readOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. More + info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: boolean + secretRef: + description: 'secretRef is name of the authentication + secret for RBDUser. If provided overrides keyring. + Default is nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + user: + description: 'user is the rados user name. Default + is admin. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent + volume attached and mounted on Kubernetes nodes. + properties: + fsType: + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". Default + is "xfs". + type: string + gateway: + description: gateway is the host address of the + ScaleIO API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the + ScaleIO Protection Domain for the configured storage. + type: string + readOnly: + description: readOnly Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. + type: boolean + secretRef: + description: secretRef references to the secret + for ScaleIO user and other sensitive information. + If this is not provided, Login operation will + fail. + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + sslEnabled: + description: sslEnabled Flag enable/disable SSL + communication with Gateway, default false + type: boolean + storageMode: + description: storageMode indicates whether the storage + for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage + Pool associated with the protection domain. + type: string + system: + description: system is the name of the storage system + as configured in ScaleIO. + type: string + volumeName: + description: volumeName is the name of a volume + already created in the ScaleIO system that is + associated with this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: 'secret represents a secret that should + populate this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + properties: + defaultMode: + description: 'defaultMode is Optional: mode bits + used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or + a decimal value between 0 and 511. YAML accepts + both octal and decimal values, JSON requires decimal + values for mode bits. Defaults to 0644. Directories + within the path are not affected by this setting. + This might be in conflict with other options that + affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + items: + description: items If unspecified, each key-value + pair in the Data field of the referenced Secret + will be projected into the volume as a file whose + name is the key and content is the value. If specified, + the listed keys will be projected into the specified + paths, and unlisted keys will not be present. + If a key is specified which is not present in + the Secret, the volume setup will error unless + it is marked optional. Paths must be relative + and may not contain the '..' path or start with + '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits + used to set permissions on this file. Must + be an octal value between 0000 and 0777 + or a decimal value between 0 and 511. YAML + accepts both octal and decimal values, JSON + requires decimal values for mode bits. If + not specified, the volume defaultMode will + be used. This might be in conflict with + other options that affect the file mode, + like fsGroup, and the result can be other + mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of + the file to map the key to. May not be an + absolute path. May not contain the path + element '..'. May not start with the string + '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the + Secret or its keys must be defined + type: boolean + secretName: + description: 'secretName is the name of the secret + in the pod''s namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + type: string + type: object + storageos: + description: storageOS represents a StorageOS volume + attached and mounted on Kubernetes nodes. + properties: + fsType: + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + readOnly: + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. + type: boolean + secretRef: + description: secretRef specifies the secret to use + for obtaining the StorageOS API credentials. If + not specified, default values will be attempted. + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + volumeName: + description: volumeName is the human-readable name + of the StorageOS volume. Volume names are only + unique within a namespace. + type: string + volumeNamespace: + description: volumeNamespace specifies the scope + of the volume within StorageOS. If no namespace + is specified then the Pod's namespace will be + used. This allows the Kubernetes name scoping + to be mirrored within StorageOS for tighter integration. + Set VolumeName to any name to override the default + behaviour. Set to "default" if you are not using + namespaces within StorageOS. Namespaces that do + not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere volume + attached and mounted on kubelets host machine + properties: + fsType: + description: fsType is filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy + Based Management (SPBM) profile ID associated + with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage Policy + Based Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies + vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + type: object + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + description: The pod this Toleration is attached to tolerates any + taint that matches the triple using the matching + operator . + properties: + effect: + description: Effect indicates the taint effect to match. Empty + means match all taint effects. When specified, allowed values + are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match all + values and all keys. + type: string + operator: + description: Operator represents a key's relationship to the + value. Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod + can tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of time + the toleration (which must be of effect NoExecute, otherwise + this field is ignored) tolerates the taint. By default, it + is not set, which means tolerate the taint forever (do not + evict). Zero and negative values will be treated as 0 (evict + immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + required: + - clusterSize + - kubernetesConfig + type: object + status: + description: RedisStatus defines the observed state of Redis + properties: + masterNode: + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/crds/redis-sentinel.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/crds/redis-sentinel.yaml new file mode 100644 index 000000000..42305a4ed --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/crds/redis-sentinel.yaml @@ -0,0 +1,7043 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.1 + creationTimestamp: null + name: redissentinels.redis.redis.opstreelabs.in +spec: + group: redis.redis.opstreelabs.in + names: + kind: RedisSentinel + listKind: RedisSentinelList + plural: redissentinels + singular: redissentinel + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + description: Redis is the Schema for the redis API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + properties: + TLS: + description: TLS Configuration for redis instances + properties: + ca: + type: string + cert: + type: string + key: + type: string + secret: + description: Reference to secret which contains the certificates + properties: + defaultMode: + description: 'defaultMode is Optional: mode bits used to set + permissions on created files by default. Must be an octal + value between 0000 and 0777 or a decimal value between 0 + and 511. YAML accepts both octal and decimal values, JSON + requires decimal values for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect + the file mode, like fsGroup, and the result can be other + mode bits set.' + format: int32 + type: integer + items: + description: items If unspecified, each key-value pair in + the Data field of the referenced Secret will be projected + into the volume as a file whose name is the key and content + is the value. If specified, the listed keys will be projected + into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the + Secret, the volume setup will error unless it is marked + optional. Paths must be relative and may not contain the + '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used to set + permissions on this file. Must be an octal value between + 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires + decimal values for mode bits. If not specified, the + volume defaultMode will be used. This might be in + conflict with other options that affect the file mode, + like fsGroup, and the result can be other mode bits + set.' + format: int32 + type: integer + path: + description: path is the relative path of the file to + map the key to. May not be an absolute path. May not + contain the path element '..'. May not start with + the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the Secret or + its keys must be defined + type: boolean + secretName: + description: 'secretName is the name of the secret in the + pod''s namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + type: string + type: object + required: + - secret + type: object + affinity: + description: Affinity is a group of affinity scheduling rules. + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for the + pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the affinity expressions specified by + this field, but it may choose a node that violates one or + more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node matches + the corresponding matchExpressions; the node(s) with the + highest sum are the most preferred. + items: + description: An empty preferred scheduling term matches + all objects with implicit weight 0 (i.e. it's a no-op). + A null preferred scheduling term matches no objects (i.e. + is also a no-op). + properties: + preference: + description: A node selector term, associated with the + corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + description: Weight associated with matching the corresponding + nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this + field are not met at scheduling time, the pod will not be + scheduled onto the node. If the affinity requirements specified + by this field cease to be met at some point during pod execution + (e.g. due to an update), the system may or may not try to + eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: A null or empty node selector term matches + no objects. The requirements of them are ANDed. The + TopologySelectorTerm type implements a subset of the + NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. co-locate + this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the affinity expressions specified by + this field, but it may choose a node that violates one or + more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node has + pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key in (value)` to select + the group of existing pods which pods will be + taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MatchLabelKeys and LabelSelector. Also, + MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key notin (value)` to + select the group of existing pods which pods will + be taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MismatchLabelKeys and LabelSelector. Also, + MismatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding + podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this + field are not met at scheduling time, the pod will not be + scheduled onto the node. If the affinity requirements specified + by this field cease to be met at some point during pod execution + (e.g. due to a pod label update), the system may or may + not try to eventually evict the pod from its node. When + there are multiple elements, the lists of nodes corresponding + to each podAffinityTerm are intersected, i.e. all terms + must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not co-located + (anti-affinity) with, where co-located is defined as running + on a node whose value of the label with key + matches that of any node on which a pod of the set of + pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod label keys + to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged with + `LabelSelector` as `key in (value)` to select the + group of existing pods which pods will be taken into + consideration for the incoming pod's pod (anti) affinity. + Keys that don't exist in the incoming pod labels will + be ignored. The default value is empty. The same key + is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires enabling + MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged with + `LabelSelector` as `key notin (value)` to select the + group of existing pods which pods will be taken into + consideration for the incoming pod's pod (anti) affinity. + Keys that don't exist in the incoming pod labels will + be ignored. The default value is empty. The same key + is forbidden to exist in both MismatchLabelKeys and + LabelSelector. Also, MismatchLabelKeys cannot be set + when LabelSelector isn't set. This is an alpha field + and requires enabling MatchLabelKeysInPodAffinity + feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied to the + union of the namespaces selected by this field and + the ones listed in the namespaces field. null selector + and null or empty namespaces list means "this pod's + namespace". An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace + names that the term applies to. The term is applied + to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. null or + empty namespaces list and null namespaceSelector means + "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where + co-located is defined as running on a node whose value + of the label with key topologyKey matches that of + any node on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules (e.g. + avoid putting this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the anti-affinity expressions specified + by this field, but it may choose a node that violates one + or more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node has + pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key in (value)` to select + the group of existing pods which pods will be + taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MatchLabelKeys and LabelSelector. Also, + MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key notin (value)` to + select the group of existing pods which pods will + be taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MismatchLabelKeys and LabelSelector. Also, + MismatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding + podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the anti-affinity requirements + specified by this field cease to be met at some point during + pod execution (e.g. due to a pod label update), the system + may or may not try to eventually evict the pod from its + node. When there are multiple elements, the lists of nodes + corresponding to each podAffinityTerm are intersected, i.e. + all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not co-located + (anti-affinity) with, where co-located is defined as running + on a node whose value of the label with key + matches that of any node on which a pod of the set of + pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod label keys + to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged with + `LabelSelector` as `key in (value)` to select the + group of existing pods which pods will be taken into + consideration for the incoming pod's pod (anti) affinity. + Keys that don't exist in the incoming pod labels will + be ignored. The default value is empty. The same key + is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires enabling + MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged with + `LabelSelector` as `key notin (value)` to select the + group of existing pods which pods will be taken into + consideration for the incoming pod's pod (anti) affinity. + Keys that don't exist in the incoming pod labels will + be ignored. The default value is empty. The same key + is forbidden to exist in both MismatchLabelKeys and + LabelSelector. Also, MismatchLabelKeys cannot be set + when LabelSelector isn't set. This is an alpha field + and requires enabling MatchLabelKeysInPodAffinity + feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied to the + union of the namespaces selected by this field and + the ones listed in the namespaces field. null selector + and null or empty namespaces list means "this pod's + namespace". An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace + names that the term applies to. The term is applied + to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. null or + empty namespaces list and null namespaceSelector means + "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where + co-located is defined as running on a node whose value + of the label with key topologyKey matches that of + any node on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + clusterSize: + format: int32 + minimum: 1 + type: integer + kubernetesConfig: + description: KubernetesConfig will be the JSON struct for Basic Redis + Config + properties: + ignoreAnnotations: + items: + type: string + type: array + image: + type: string + imagePullPolicy: + description: PullPolicy describes a policy for if/when to pull + a container image + type: string + imagePullSecrets: + items: + description: LocalObjectReference contains enough information + to let you locate the referenced object inside the same namespace. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + type: array + redisSecret: + description: ExistingPasswordSecret is the struct to access the + existing secret + properties: + key: + type: string + name: + type: string + type: object + resources: + description: ResourceRequirements describes the compute resource + requirements. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + service: + description: ServiceConfig define the type of service to be created + and its annotations + properties: + annotations: + additionalProperties: + type: string + type: object + serviceType: + enum: + - LoadBalancer + - NodePort + - ClusterIP + type: string + type: object + updateStrategy: + description: StatefulSetUpdateStrategy indicates the strategy + that the StatefulSet controller will use to perform updates. + It includes any additional parameters necessary to perform the + update for the indicated strategy. + properties: + rollingUpdate: + description: RollingUpdate is used to communicate parameters + when Type is RollingUpdateStatefulSetStrategyType. + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + description: 'The maximum number of pods that can be unavailable + during the update. Value can be an absolute number (ex: + 5) or a percentage of desired pods (ex: 10%). Absolute + number is calculated from percentage by rounding up. + This can not be 0. Defaults to 1. This field is alpha-level + and is only honored by servers that enable the MaxUnavailableStatefulSet + feature. The field applies to all pods in the range + 0 to Replicas-1. That means if there is any unavailable + pod in the range 0 to Replicas-1, it will be counted + towards MaxUnavailable.' + x-kubernetes-int-or-string: true + partition: + description: Partition indicates the ordinal at which + the StatefulSet should be partitioned for updates. During + a rolling update, all pods from ordinal Replicas-1 to + Partition are updated. All pods from ordinal Partition-1 + to 0 remain untouched. This is helpful in being able + to do a canary based deployment. The default value is + 0. + format: int32 + type: integer + type: object + type: + description: Type indicates the type of the StatefulSetUpdateStrategy. + Default is RollingUpdate. + type: string + type: object + required: + - image + type: object + livenessProbe: + description: Probe describes a health check to be performed against + a container to determine whether it is alive or ready to receive + traffic. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside + the container, the working directory for the command is + root ('/') in the container's filesystem. The command is + simply exec'd, it is not run inside a shell, so traditional + shell instructions ('|', etc) won't work. To use a shell, + you need to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be + considered failed after having succeeded. Defaults to 3. Minimum + value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. + properties: + port: + description: Port number of the gRPC service. Number must + be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place + in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior is defined + by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod + IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows + repeated headers. + items: + description: HTTPHeader describes a custom header to be + used in HTTP probes + properties: + name: + description: The header field name. This will be canonicalized + upon output, so case-variant names will be understood + as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. + Number must be in the range 1 to 65535. Name must be an + IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults + to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started + before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default + to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be + considered successful after having failed. Defaults to 1. Must + be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults + to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. + Number must be in the range 1 to 65535. Name must be an + IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate + gracefully upon probe failure. The grace period is the duration + in seconds after the processes running in the pod are sent a + termination signal and the time when the processes are forcibly + halted with a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, the pod's + terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. Value must + be non-negative integer. The value zero indicates stop immediately + via the kill signal (no opportunity to shut down). This is a + beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + nodeSelector: + additionalProperties: + type: string + type: object + pdb: + description: RedisPodDisruptionBudget configure a PodDisruptionBudget + on the resource (leader/follower) + properties: + enabled: + type: boolean + maxUnavailable: + format: int32 + type: integer + minAvailable: + format: int32 + type: integer + type: object + priorityClassName: + type: string + readinessProbe: + description: Probe describes a health check to be performed against + a container to determine whether it is alive or ready to receive + traffic. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside + the container, the working directory for the command is + root ('/') in the container's filesystem. The command is + simply exec'd, it is not run inside a shell, so traditional + shell instructions ('|', etc) won't work. To use a shell, + you need to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be + considered failed after having succeeded. Defaults to 3. Minimum + value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. + properties: + port: + description: Port number of the gRPC service. Number must + be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place + in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior is defined + by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod + IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows + repeated headers. + items: + description: HTTPHeader describes a custom header to be + used in HTTP probes + properties: + name: + description: The header field name. This will be canonicalized + upon output, so case-variant names will be understood + as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. + Number must be in the range 1 to 65535. Name must be an + IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults + to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started + before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default + to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be + considered successful after having failed. Defaults to 1. Must + be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults + to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. + Number must be in the range 1 to 65535. Name must be an + IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate + gracefully upon probe failure. The grace period is the duration + in seconds after the processes running in the pod are sent a + termination signal and the time when the processes are forcibly + halted with a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, the pod's + terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. Value must + be non-negative integer. The value zero indicates stop immediately + via the kill signal (no opportunity to shut down). This is a + beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + redisSentinelConfig: + properties: + additionalSentinelConfig: + type: string + downAfterMilliseconds: + default: "30000" + type: string + failoverTimeout: + default: "180000" + type: string + masterGroupName: + default: myMaster + type: string + parallelSyncs: + default: "1" + type: string + quorum: + default: "2" + type: string + redisPort: + default: "6379" + type: string + redisReplicationName: + type: string + redisReplicationPassword: + description: EnvVarSource represents a source for the value of + an EnvVar. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, `metadata.annotations['''']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath is written + in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified + API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only resources + limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, + requests.cpu, requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, optional + for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed + resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + type: object + required: + - redisReplicationName + type: object + securityContext: + description: PodSecurityContext holds pod-level security attributes + and common container settings. Some fields are also present in container.securityContext. Field + values of container.securityContext take precedence over field values + of PodSecurityContext. + properties: + fsGroup: + description: "A special supplemental group that applies to all + containers in a pod. Some volume types allow the Kubelet to + change the ownership of that volume to be owned by the pod: + \n 1. The owning GID will be the FSGroup 2. The setgid bit is + set (new files created in the volume will be owned by FSGroup) + 3. The permission bits are OR'd with rw-rw---- \n If unset, + the Kubelet will not modify the ownership and permissions of + any volume. Note that this field cannot be set when spec.os.name + is windows." + format: int64 + type: integer + fsGroupChangePolicy: + description: 'fsGroupChangePolicy defines behavior of changing + ownership and permission of the volume before being exposed + inside Pod. This field will only apply to volume types which + support fsGroup based ownership(and permissions). It will have + no effect on ephemeral volume types such as: secret, configmaps + and emptydir. Valid values are "OnRootMismatch" and "Always". + If not specified, "Always" is used. Note that this field cannot + be set when spec.os.name is windows.' + type: string + runAsGroup: + description: The GID to run the entrypoint of the container process. + Uses runtime default if unset. May also be set in SecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail to start + the container if it does. If unset or false, no such validation + will be performed. May also be set in SecurityContext. If set + in both SecurityContext and PodSecurityContext, the value specified + in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in SecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. Note that this field cannot + be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in SecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to + the container. + type: string + role: + description: Role is a SELinux role label that applies to + the container. + type: string + type: + description: Type is a SELinux type label that applies to + the container. + type: string + user: + description: User is a SELinux user label that applies to + the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by the containers in this + pod. Note that this field cannot be set when spec.os.name is + windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must be + preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must be set if type is "Localhost". Must NOT be + set for any other type. + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a profile + defined in a file on the node should be used. RuntimeDefault + - the container runtime default profile should be used. + Unconfined - no profile should be applied." + type: string + required: + - type + type: object + supplementalGroups: + description: A list of groups applied to the first process run + in each container, in addition to the container's primary GID, + the fsGroup (if specified), and group memberships defined in + the container image for the uid of the container process. If + unspecified, no additional groups are added to any container. + Note that group memberships defined in the container image for + the uid of the container process are still effective, even if + they are not included in this list. Note that this field cannot + be set when spec.os.name is windows. + items: + format: int64 + type: integer + type: array + sysctls: + description: Sysctls hold a list of namespaced sysctls used for + the pod. Pods with unsupported sysctls (by the container runtime) + might fail to launch. Note that this field cannot be set when + spec.os.name is windows. + items: + description: Sysctl defines a kernel parameter to be set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + description: The Windows specific settings applied to all containers. + If unspecified, the options within a container's SecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named by + the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA + credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. All of a Pod's containers + must have the same effective HostProcess value (it is not + allowed to have a mix of HostProcess containers and non-HostProcess + containers). In addition, if HostProcess is true then HostNetwork + must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in PodSecurityContext. + If set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: string + type: object + type: object + serviceAccountName: + type: string + sidecars: + items: + description: Sidecar for each Redis pods + properties: + env: + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be + a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. + If a variable cannot be resolved, the reference in the + input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) + syntax: i.e. "$$(VAR_NAME)" will produce the string + literal "$(VAR_NAME)". Escaped references will never + be expanded, regardless of whether the variable exists + or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its + key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + image: + type: string + imagePullPolicy: + description: PullPolicy describes a policy for if/when to pull + a container image + type: string + name: + type: string + resources: + description: ResourceRequirements describes the compute resource + requirements. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only + be set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where this + field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests + cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + required: + - image + - name + type: object + type: array + tolerations: + items: + description: The pod this Toleration is attached to tolerates any + taint that matches the triple using the matching + operator . + properties: + effect: + description: Effect indicates the taint effect to match. Empty + means match all taint effects. When specified, allowed values + are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match all + values and all keys. + type: string + operator: + description: Operator represents a key's relationship to the + value. Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod + can tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of time + the toleration (which must be of effect NoExecute, otherwise + this field is ignored) tolerates the taint. By default, it + is not set, which means tolerate the taint forever (do not + evict). Zero and negative values will be treated as 0 (evict + immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + required: + - clusterSize + - kubernetesConfig + type: object + status: + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} + - name: v1beta2 + schema: + openAPIV3Schema: + description: Redis is the Schema for the redis API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + properties: + TLS: + description: TLS Configuration for redis instances + properties: + ca: + type: string + cert: + type: string + key: + type: string + secret: + description: Reference to secret which contains the certificates + properties: + defaultMode: + description: 'defaultMode is Optional: mode bits used to set + permissions on created files by default. Must be an octal + value between 0000 and 0777 or a decimal value between 0 + and 511. YAML accepts both octal and decimal values, JSON + requires decimal values for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect + the file mode, like fsGroup, and the result can be other + mode bits set.' + format: int32 + type: integer + items: + description: items If unspecified, each key-value pair in + the Data field of the referenced Secret will be projected + into the volume as a file whose name is the key and content + is the value. If specified, the listed keys will be projected + into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the + Secret, the volume setup will error unless it is marked + optional. Paths must be relative and may not contain the + '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used to set + permissions on this file. Must be an octal value between + 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires + decimal values for mode bits. If not specified, the + volume defaultMode will be used. This might be in + conflict with other options that affect the file mode, + like fsGroup, and the result can be other mode bits + set.' + format: int32 + type: integer + path: + description: path is the relative path of the file to + map the key to. May not be an absolute path. May not + contain the path element '..'. May not start with + the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the Secret or + its keys must be defined + type: boolean + secretName: + description: 'secretName is the name of the secret in the + pod''s namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + type: string + type: object + required: + - secret + type: object + affinity: + description: Affinity is a group of affinity scheduling rules. + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for the + pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the affinity expressions specified by + this field, but it may choose a node that violates one or + more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node matches + the corresponding matchExpressions; the node(s) with the + highest sum are the most preferred. + items: + description: An empty preferred scheduling term matches + all objects with implicit weight 0 (i.e. it's a no-op). + A null preferred scheduling term matches no objects (i.e. + is also a no-op). + properties: + preference: + description: A node selector term, associated with the + corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + description: Weight associated with matching the corresponding + nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this + field are not met at scheduling time, the pod will not be + scheduled onto the node. If the affinity requirements specified + by this field cease to be met at some point during pod execution + (e.g. due to an update), the system may or may not try to + eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: A null or empty node selector term matches + no objects. The requirements of them are ANDed. The + TopologySelectorTerm type implements a subset of the + NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. co-locate + this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the affinity expressions specified by + this field, but it may choose a node that violates one or + more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node has + pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key in (value)` to select + the group of existing pods which pods will be + taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MatchLabelKeys and LabelSelector. Also, + MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key notin (value)` to + select the group of existing pods which pods will + be taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MismatchLabelKeys and LabelSelector. Also, + MismatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding + podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this + field are not met at scheduling time, the pod will not be + scheduled onto the node. If the affinity requirements specified + by this field cease to be met at some point during pod execution + (e.g. due to a pod label update), the system may or may + not try to eventually evict the pod from its node. When + there are multiple elements, the lists of nodes corresponding + to each podAffinityTerm are intersected, i.e. all terms + must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not co-located + (anti-affinity) with, where co-located is defined as running + on a node whose value of the label with key + matches that of any node on which a pod of the set of + pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod label keys + to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged with + `LabelSelector` as `key in (value)` to select the + group of existing pods which pods will be taken into + consideration for the incoming pod's pod (anti) affinity. + Keys that don't exist in the incoming pod labels will + be ignored. The default value is empty. The same key + is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires enabling + MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged with + `LabelSelector` as `key notin (value)` to select the + group of existing pods which pods will be taken into + consideration for the incoming pod's pod (anti) affinity. + Keys that don't exist in the incoming pod labels will + be ignored. The default value is empty. The same key + is forbidden to exist in both MismatchLabelKeys and + LabelSelector. Also, MismatchLabelKeys cannot be set + when LabelSelector isn't set. This is an alpha field + and requires enabling MatchLabelKeysInPodAffinity + feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied to the + union of the namespaces selected by this field and + the ones listed in the namespaces field. null selector + and null or empty namespaces list means "this pod's + namespace". An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace + names that the term applies to. The term is applied + to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. null or + empty namespaces list and null namespaceSelector means + "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where + co-located is defined as running on a node whose value + of the label with key topologyKey matches that of + any node on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules (e.g. + avoid putting this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the anti-affinity expressions specified + by this field, but it may choose a node that violates one + or more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node has + pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key in (value)` to select + the group of existing pods which pods will be + taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MatchLabelKeys and LabelSelector. Also, + MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key notin (value)` to + select the group of existing pods which pods will + be taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MismatchLabelKeys and LabelSelector. Also, + MismatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding + podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the anti-affinity requirements + specified by this field cease to be met at some point during + pod execution (e.g. due to a pod label update), the system + may or may not try to eventually evict the pod from its + node. When there are multiple elements, the lists of nodes + corresponding to each podAffinityTerm are intersected, i.e. + all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not co-located + (anti-affinity) with, where co-located is defined as running + on a node whose value of the label with key + matches that of any node on which a pod of the set of + pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod label keys + to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged with + `LabelSelector` as `key in (value)` to select the + group of existing pods which pods will be taken into + consideration for the incoming pod's pod (anti) affinity. + Keys that don't exist in the incoming pod labels will + be ignored. The default value is empty. The same key + is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires enabling + MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged with + `LabelSelector` as `key notin (value)` to select the + group of existing pods which pods will be taken into + consideration for the incoming pod's pod (anti) affinity. + Keys that don't exist in the incoming pod labels will + be ignored. The default value is empty. The same key + is forbidden to exist in both MismatchLabelKeys and + LabelSelector. Also, MismatchLabelKeys cannot be set + when LabelSelector isn't set. This is an alpha field + and requires enabling MatchLabelKeysInPodAffinity + feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied to the + union of the namespaces selected by this field and + the ones listed in the namespaces field. null selector + and null or empty namespaces list means "this pod's + namespace". An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace + names that the term applies to. The term is applied + to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. null or + empty namespaces list and null namespaceSelector means + "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where + co-located is defined as running on a node whose value + of the label with key topologyKey matches that of + any node on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + clusterSize: + default: 3 + format: int32 + minimum: 1 + type: integer + env: + items: + description: EnvVar represents an environment variable present in + a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded using + the previously defined environment variables in the container + and any service environment variables. If a variable cannot + be resolved, the reference in the input string will be unchanged. + Double $$ are reduced to a single $, which allows for escaping + the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the + string literal "$(VAR_NAME)". Escaped references will never + be expanded, regardless of whether the variable exists or + not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. Cannot + be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, `metadata.annotations['''']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, + status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath is + written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified + API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed + resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + initContainer: + description: InitContainer for each Redis pods + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + enabled: + type: boolean + env: + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + image: + type: string + imagePullPolicy: + description: PullPolicy describes a policy for if/when to pull + a container image + type: string + resources: + description: ResourceRequirements describes the compute resource + requirements. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: SecurityContext holds security configuration that + will be applied to a container. Some fields are present in both + SecurityContext and PodSecurityContext. When both are set, + the values in SecurityContext take precedence. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a + process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the + container runtime. Note that this field cannot be set when + spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in + privileged containers are essentially equivalent to root + on the host. Defaults to false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use + for the containers. The default is DefaultProcMount which + uses the container runtime defaults for readonly paths and + masked paths. This requires the ProcMountType feature flag + to be enabled. Note that this field cannot be set when spec.os.name + is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when + spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail + to start the container if it does. If unset or false, no + such validation will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata if + unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. Note + that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must + be preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must be set if type is "Localhost". Must NOT + be set for any other type. + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a + profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile + should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also be + set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + required: + - image + type: object + kubernetesConfig: + description: KubernetesConfig will be the JSON struct for Basic Redis + Config + properties: + ignoreAnnotations: + items: + type: string + type: array + image: + type: string + imagePullPolicy: + description: PullPolicy describes a policy for if/when to pull + a container image + type: string + imagePullSecrets: + items: + description: LocalObjectReference contains enough information + to let you locate the referenced object inside the same namespace. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + type: array + redisSecret: + description: ExistingPasswordSecret is the struct to access the + existing secret + properties: + key: + type: string + name: + type: string + type: object + resources: + description: ResourceRequirements describes the compute resource + requirements. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + service: + description: ServiceConfig define the type of service to be created + and its annotations + properties: + annotations: + additionalProperties: + type: string + type: object + serviceType: + enum: + - LoadBalancer + - NodePort + - ClusterIP + type: string + type: object + updateStrategy: + description: StatefulSetUpdateStrategy indicates the strategy + that the StatefulSet controller will use to perform updates. + It includes any additional parameters necessary to perform the + update for the indicated strategy. + properties: + rollingUpdate: + description: RollingUpdate is used to communicate parameters + when Type is RollingUpdateStatefulSetStrategyType. + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + description: 'The maximum number of pods that can be unavailable + during the update. Value can be an absolute number (ex: + 5) or a percentage of desired pods (ex: 10%). Absolute + number is calculated from percentage by rounding up. + This can not be 0. Defaults to 1. This field is alpha-level + and is only honored by servers that enable the MaxUnavailableStatefulSet + feature. The field applies to all pods in the range + 0 to Replicas-1. That means if there is any unavailable + pod in the range 0 to Replicas-1, it will be counted + towards MaxUnavailable.' + x-kubernetes-int-or-string: true + partition: + description: Partition indicates the ordinal at which + the StatefulSet should be partitioned for updates. During + a rolling update, all pods from ordinal Replicas-1 to + Partition are updated. All pods from ordinal Partition-1 + to 0 remain untouched. This is helpful in being able + to do a canary based deployment. The default value is + 0. + format: int32 + type: integer + type: object + type: + description: Type indicates the type of the StatefulSetUpdateStrategy. + Default is RollingUpdate. + type: string + type: object + required: + - image + type: object + livenessProbe: + description: Probe describes a health check to be performed against + a container to determine whether it is alive or ready to receive + traffic. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside + the container, the working directory for the command is + root ('/') in the container's filesystem. The command is + simply exec'd, it is not run inside a shell, so traditional + shell instructions ('|', etc) won't work. To use a shell, + you need to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be + considered failed after having succeeded. Defaults to 3. Minimum + value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. + properties: + port: + description: Port number of the gRPC service. Number must + be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place + in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior is defined + by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod + IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows + repeated headers. + items: + description: HTTPHeader describes a custom header to be + used in HTTP probes + properties: + name: + description: The header field name. This will be canonicalized + upon output, so case-variant names will be understood + as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. + Number must be in the range 1 to 65535. Name must be an + IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults + to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started + before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default + to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be + considered successful after having failed. Defaults to 1. Must + be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults + to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. + Number must be in the range 1 to 65535. Name must be an + IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate + gracefully upon probe failure. The grace period is the duration + in seconds after the processes running in the pod are sent a + termination signal and the time when the processes are forcibly + halted with a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, the pod's + terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. Value must + be non-negative integer. The value zero indicates stop immediately + via the kill signal (no opportunity to shut down). This is a + beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + nodeSelector: + additionalProperties: + type: string + type: object + pdb: + description: RedisPodDisruptionBudget configure a PodDisruptionBudget + on the resource (leader/follower) + properties: + enabled: + type: boolean + maxUnavailable: + format: int32 + type: integer + minAvailable: + format: int32 + type: integer + type: object + podSecurityContext: + description: PodSecurityContext holds pod-level security attributes + and common container settings. Some fields are also present in container.securityContext. Field + values of container.securityContext take precedence over field values + of PodSecurityContext. + properties: + fsGroup: + description: "A special supplemental group that applies to all + containers in a pod. Some volume types allow the Kubelet to + change the ownership of that volume to be owned by the pod: + \n 1. The owning GID will be the FSGroup 2. The setgid bit is + set (new files created in the volume will be owned by FSGroup) + 3. The permission bits are OR'd with rw-rw---- \n If unset, + the Kubelet will not modify the ownership and permissions of + any volume. Note that this field cannot be set when spec.os.name + is windows." + format: int64 + type: integer + fsGroupChangePolicy: + description: 'fsGroupChangePolicy defines behavior of changing + ownership and permission of the volume before being exposed + inside Pod. This field will only apply to volume types which + support fsGroup based ownership(and permissions). It will have + no effect on ephemeral volume types such as: secret, configmaps + and emptydir. Valid values are "OnRootMismatch" and "Always". + If not specified, "Always" is used. Note that this field cannot + be set when spec.os.name is windows.' + type: string + runAsGroup: + description: The GID to run the entrypoint of the container process. + Uses runtime default if unset. May also be set in SecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail to start + the container if it does. If unset or false, no such validation + will be performed. May also be set in SecurityContext. If set + in both SecurityContext and PodSecurityContext, the value specified + in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in SecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. Note that this field cannot + be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in SecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to + the container. + type: string + role: + description: Role is a SELinux role label that applies to + the container. + type: string + type: + description: Type is a SELinux type label that applies to + the container. + type: string + user: + description: User is a SELinux user label that applies to + the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by the containers in this + pod. Note that this field cannot be set when spec.os.name is + windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must be + preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must be set if type is "Localhost". Must NOT be + set for any other type. + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a profile + defined in a file on the node should be used. RuntimeDefault + - the container runtime default profile should be used. + Unconfined - no profile should be applied." + type: string + required: + - type + type: object + supplementalGroups: + description: A list of groups applied to the first process run + in each container, in addition to the container's primary GID, + the fsGroup (if specified), and group memberships defined in + the container image for the uid of the container process. If + unspecified, no additional groups are added to any container. + Note that group memberships defined in the container image for + the uid of the container process are still effective, even if + they are not included in this list. Note that this field cannot + be set when spec.os.name is windows. + items: + format: int64 + type: integer + type: array + sysctls: + description: Sysctls hold a list of namespaced sysctls used for + the pod. Pods with unsupported sysctls (by the container runtime) + might fail to launch. Note that this field cannot be set when + spec.os.name is windows. + items: + description: Sysctl defines a kernel parameter to be set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + description: The Windows specific settings applied to all containers. + If unspecified, the options within a container's SecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named by + the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA + credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. All of a Pod's containers + must have the same effective HostProcess value (it is not + allowed to have a mix of HostProcess containers and non-HostProcess + containers). In addition, if HostProcess is true then HostNetwork + must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in PodSecurityContext. + If set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: string + type: object + type: object + priorityClassName: + type: string + readinessProbe: + description: Probe describes a health check to be performed against + a container to determine whether it is alive or ready to receive + traffic. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside + the container, the working directory for the command is + root ('/') in the container's filesystem. The command is + simply exec'd, it is not run inside a shell, so traditional + shell instructions ('|', etc) won't work. To use a shell, + you need to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be + considered failed after having succeeded. Defaults to 3. Minimum + value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. + properties: + port: + description: Port number of the gRPC service. Number must + be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place + in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior is defined + by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod + IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows + repeated headers. + items: + description: HTTPHeader describes a custom header to be + used in HTTP probes + properties: + name: + description: The header field name. This will be canonicalized + upon output, so case-variant names will be understood + as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. + Number must be in the range 1 to 65535. Name must be an + IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults + to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started + before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default + to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be + considered successful after having failed. Defaults to 1. Must + be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults + to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. + Number must be in the range 1 to 65535. Name must be an + IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate + gracefully upon probe failure. The grace period is the duration + in seconds after the processes running in the pod are sent a + termination signal and the time when the processes are forcibly + halted with a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, the pod's + terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. Value must + be non-negative integer. The value zero indicates stop immediately + via the kill signal (no opportunity to shut down). This is a + beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + redisExporter: + description: RedisExporter interface will have the information for + redis exporter related stuff + properties: + enabled: + type: boolean + env: + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + image: + type: string + imagePullPolicy: + description: PullPolicy describes a policy for if/when to pull + a container image + type: string + port: + default: 9121 + type: integer + resources: + description: ResourceRequirements describes the compute resource + requirements. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: SecurityContext holds security configuration that + will be applied to a container. Some fields are present in both + SecurityContext and PodSecurityContext. When both are set, + the values in SecurityContext take precedence. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a + process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the + container runtime. Note that this field cannot be set when + spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in + privileged containers are essentially equivalent to root + on the host. Defaults to false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use + for the containers. The default is DefaultProcMount which + uses the container runtime defaults for readonly paths and + masked paths. This requires the ProcMountType feature flag + to be enabled. Note that this field cannot be set when spec.os.name + is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when + spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail + to start the container if it does. If unset or false, no + such validation will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata if + unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. Note + that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must + be preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must be set if type is "Localhost". Must NOT + be set for any other type. + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a + profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile + should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also be + set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + required: + - image + type: object + redisSentinelConfig: + properties: + additionalSentinelConfig: + type: string + downAfterMilliseconds: + default: "30000" + type: string + failoverTimeout: + default: "180000" + type: string + masterGroupName: + default: myMaster + type: string + parallelSyncs: + default: "1" + type: string + quorum: + default: "2" + type: string + redisPort: + default: "6379" + type: string + redisReplicationName: + type: string + redisReplicationPassword: + description: EnvVarSource represents a source for the value of + an EnvVar. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, `metadata.annotations['''']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath is written + in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified + API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only resources + limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, + requests.cpu, requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, optional + for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed + resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + type: object + required: + - redisReplicationName + type: object + securityContext: + description: SecurityContext holds security configuration that will + be applied to a container. Some fields are present in both SecurityContext + and PodSecurityContext. When both are set, the values in SecurityContext + take precedence. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a process + can gain more privileges than its parent process. This bool + directly controls if the no_new_privs flag will be set on the + container process. AllowPrivilegeEscalation is true always when + the container is: 1) run as Privileged 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container + runtime. Note that this field cannot be set when spec.os.name + is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in privileged + containers are essentially equivalent to root on the host. Defaults + to false. Note that this field cannot be set when spec.os.name + is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use for + the containers. The default is DefaultProcMount which uses the + container runtime defaults for readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when spec.os.name + is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container process. + Uses runtime default if unset. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence. Note that this + field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail to start + the container if it does. If unset or false, no such validation + will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when spec.os.name + is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence. Note that this + field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to + the container. + type: string + role: + description: Role is a SELinux role label that applies to + the container. + type: string + type: + description: Type is a SELinux type label that applies to + the container. + type: string + user: + description: User is a SELinux user label that applies to + the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. If + seccomp options are provided at both the pod & container level, + the container options override the pod options. Note that this + field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must be + preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must be set if type is "Localhost". Must NOT be + set for any other type. + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a profile + defined in a file on the node should be used. RuntimeDefault + - the container runtime default profile should be used. + Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will + be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named by + the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA + credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. All of a Pod's containers + must have the same effective HostProcess value (it is not + allowed to have a mix of HostProcess containers and non-HostProcess + containers). In addition, if HostProcess is true then HostNetwork + must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in PodSecurityContext. + If set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: string + type: object + type: object + serviceAccountName: + type: string + sidecars: + items: + description: Sidecar for each Redis pods + properties: + command: + items: + type: string + type: array + env: + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be + a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. + If a variable cannot be resolved, the reference in the + input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) + syntax: i.e. "$$(VAR_NAME)" will produce the string + literal "$(VAR_NAME)". Escaped references will never + be expanded, regardless of whether the variable exists + or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its + key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + image: + type: string + imagePullPolicy: + description: PullPolicy describes a policy for if/when to pull + a container image + type: string + mountPath: + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: Path within the container at which the volume + should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are + propagated from the host to container and the other + way around. When not set, MountPropagationNone is used. + This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise + (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's + volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which + the container's volume should be mounted. Behaves similarly + to SubPath but environment variable references $(VAR_NAME) + are expanded using the container's environment. Defaults + to "" (volume's root). SubPathExpr and SubPath are mutually + exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + name: + type: string + ports: + items: + description: ContainerPort represents a network port in a + single container. + properties: + containerPort: + description: Number of port to expose on the pod's IP + address. This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port to. + type: string + hostPort: + description: Number of port to expose on the host. If + specified, this must be a valid port number, 0 < x < + 65536. If HostNetwork is specified, this must match + ContainerPort. Most containers do not need this. + format: int32 + type: integer + name: + description: If specified, this must be an IANA_SVC_NAME + and unique within the pod. Each named port in a pod + must have a unique name. Name for the port that can + be referred to by services. + type: string + protocol: + default: TCP + description: Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + resources: + description: ResourceRequirements describes the compute resource + requirements. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only + be set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where this + field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests + cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: SecurityContext holds security configuration that + will be applied to a container. Some fields are present in + both SecurityContext and PodSecurityContext. When both are + set, the values in SecurityContext take precedence. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether + a process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by + the container runtime. Note that this field cannot be + set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes + in privileged containers are essentially equivalent to + root on the host. Defaults to false. Note that this field + cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to + use for the containers. The default is DefaultProcMount + which uses the container runtime defaults for readonly + paths and masked paths. This requires the ProcMountType + feature flag to be enabled. Note that this field cannot + be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root + filesystem. Default is false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a + non-root user. If true, the Kubelet will validate the + image at runtime to ensure that it does not run as UID + 0 (root) and fail to start the container if it does. If + unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both + SecurityContext and PodSecurityContext, the value specified + in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata + if unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a + random SELinux context for each container. May also be + set in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. + Note that this field cannot be set when spec.os.name is + windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile + must be preconfigured on the node to work. Must be + a descending path, relative to the kubelet's configured + seccomp profile location. Must be set if type is "Localhost". + Must NOT be set for any other type. + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - + a profile defined in a file on the node should be + used. RuntimeDefault - the container runtime default + profile should be used. Unconfined - no profile should + be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also + be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set + in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + required: + - image + - name + type: object + type: array + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + description: The pod this Toleration is attached to tolerates any + taint that matches the triple using the matching + operator . + properties: + effect: + description: Effect indicates the taint effect to match. Empty + means match all taint effects. When specified, allowed values + are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match all + values and all keys. + type: string + operator: + description: Operator represents a key's relationship to the + value. Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod + can tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of time + the toleration (which must be of effect NoExecute, otherwise + this field is ignored) tolerates the taint. By default, it + is not set, which means tolerate the taint forever (do not + evict). Zero and negative values will be treated as 0 (evict + immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + volumeMount: + description: Additional Volume is provided by user that is mounted + on the pods + properties: + mountPath: + items: + description: VolumeMount describes a mounting of a Volume within + a container. + properties: + mountPath: + description: Path within the container at which the volume + should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are + propagated from the host to container and the other way + around. When not set, MountPropagationNone is used. This + field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise + (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's + volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which + the container's volume should be mounted. Behaves similarly + to SubPath but environment variable references $(VAR_NAME) + are expanded using the container's environment. Defaults + to "" (volume's root). SubPathExpr and SubPath are mutually + exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + volume: + items: + description: Volume represents a named volume in a pod that + may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: 'awsElasticBlockStore represents an AWS Disk + resource that is attached to a kubelet''s host machine + and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + properties: + fsType: + description: 'fsType is the filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + partition: + description: 'partition is the partition in the volume + that you want to mount. If omitted, the default is + to mount by volume name. Examples: For volume /dev/sda1, + you specify the partition as "1". Similarly, the volume + partition for /dev/sda is "0" (or you can leave the + property empty).' + format: int32 + type: integer + readOnly: + description: 'readOnly value true will force the readOnly + setting in VolumeMounts. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: boolean + volumeID: + description: 'volumeID is unique ID of the persistent + disk resource in AWS (Amazon EBS volume). More info: + https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data Disk mount + on the host and bind mount to the pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching mode: + None, Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data disk in + the blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in the + blob storage + type: string + fsType: + description: fsType is Filesystem type to mount. Must + be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: multiple + blob disks per storage account Dedicated: single + blob disk per storage account Managed: azure managed + data disk (only in managed availability set). defaults + to shared' + type: string + readOnly: + description: readOnly Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File Service + mount on the host and bind mount to the pod. + properties: + readOnly: + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret that + contains Azure Storage Account Name and Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount on the host + that shares a pod's lifetime + properties: + monitors: + description: 'monitors is Required: Monitors is a collection + of Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + items: + type: string + type: array + path: + description: 'path is Optional: Used as the mounted + root, rather than the full Ceph tree, default is /' + type: string + readOnly: + description: 'readOnly is Optional: Defaults to false + (read/write). ReadOnly here will force the ReadOnly + setting in VolumeMounts. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: boolean + secretFile: + description: 'secretFile is Optional: SecretFile is + the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + secretRef: + description: 'secretRef is Optional: SecretRef is reference + to the authentication secret for User, default is + empty. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + user: + description: 'user is optional: User is the rados user + name, default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + required: + - monitors + type: object + cinder: + description: 'cinder represents a cinder volume attached + and mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + properties: + fsType: + description: 'fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Examples: "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + readOnly: + description: 'readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: boolean + secretRef: + description: 'secretRef is optional: points to a secret + object containing parameters used to connect to OpenStack.' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + volumeID: + description: 'volumeID used to identify the volume in + cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that should + populate this volume + properties: + defaultMode: + description: 'defaultMode is optional: mode bits used + to set permissions on created files by default. Must + be an octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal and + decimal values, JSON requires decimal values for mode + bits. Defaults to 0644. Directories within the path + are not affected by this setting. This might be in + conflict with other options that affect the file mode, + like fsGroup, and the result can be other mode bits + set.' + format: int32 + type: integer + items: + description: items if unspecified, each key-value pair + in the Data field of the referenced ConfigMap will + be projected into the volume as a file whose name + is the key and content is the value. If specified, + the listed keys will be projected into the specified + paths, and unlisted keys will not be present. If a + key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. + Paths must be relative and may not contain the '..' + path or start with '..'. + items: + description: Maps a string key to a path within a + volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used + to set permissions on this file. Must be an + octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal + and decimal values, JSON requires decimal values + for mode bits. If not specified, the volume + defaultMode will be used. This might be in conflict + with other options that affect the file mode, + like fsGroup, and the result can be other mode + bits set.' + format: int32 + type: integer + path: + description: path is the relative path of the + file to map the key to. May not be an absolute + path. May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + csi: + description: csi (Container Storage Interface) represents + ephemeral storage that is handled by certain external + CSI drivers (Beta feature). + properties: + driver: + description: driver is the name of the CSI driver that + handles this volume. Consult with your admin for the + correct name as registered in the cluster. + type: string + fsType: + description: fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the + associated CSI driver which will determine the default + filesystem to apply. + type: string + nodePublishSecretRef: + description: nodePublishSecretRef is a reference to + the secret object containing sensitive information + to pass to the CSI driver to complete the CSI NodePublishVolume + and NodeUnpublishVolume calls. This field is optional, + and may be empty if no secret is required. If the + secret object contains more than one secret, all secret + references are passed. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + readOnly: + description: readOnly specifies a read-only configuration + for the volume. Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: volumeAttributes stores driver-specific + properties that are passed to the CSI driver. Consult + your driver's documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about the + pod that should populate this volume + properties: + defaultMode: + description: 'Optional: mode bits to use on created + files by default. Must be a Optional: mode bits used + to set permissions on created files by default. Must + be an octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal and + decimal values, JSON requires decimal values for mode + bits. Defaults to 0644. Directories within the path + are not affected by this setting. This might be in + conflict with other options that affect the file mode, + like fsGroup, and the result can be other mode bits + set.' + format: int32 + type: integer + items: + description: Items is a list of downward API volume + file + items: + description: DownwardAPIVolumeFile represents information + to create the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects a field of the + pod: only annotations, labels, name and namespace + are supported.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in + the specified API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: mode bits used to set + permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and decimal + values, JSON requires decimal values for mode + bits. If not specified, the volume defaultMode + will be used. This might be in conflict with + other options that affect the file mode, like + fsGroup, and the result can be other mode bits + set.' + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. Must not + be absolute or contain the ''..'' path. Must + be utf-8 encoded. The first item of the relative + path must not start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, requests.cpu and requests.memory) + are currently supported.' + properties: + containerName: + description: 'Container name: required for + volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of + the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + emptyDir: + description: 'emptyDir represents a temporary directory + that shares a pod''s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + properties: + medium: + description: 'medium represents what type of storage + medium should back this directory. The default is + "" which means to use the node''s default medium. + Must be an empty string (default) or Memory. More + info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: 'sizeLimit is the total amount of local + storage required for this EmptyDir volume. The size + limit is also applicable for memory medium. The maximum + usage on memory medium EmptyDir would be the minimum + value between the SizeLimit specified here and the + sum of memory limits of all containers in a pod. The + default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: "ephemeral represents a volume that is handled + by a cluster storage driver. The volume's lifecycle is + tied to the pod that defines it - it will be created before + the pod starts, and deleted when the pod is removed. \n + Use this if: a) the volume is only needed while the pod + runs, b) features of normal volumes like restoring from + snapshot or capacity tracking are needed, c) the storage + driver is specified through a storage class, and d) the + storage driver supports dynamic volume provisioning through + \ a PersistentVolumeClaim (see EphemeralVolumeSource + for more information on the connection between this + volume type and PersistentVolumeClaim). \n Use PersistentVolumeClaim + or one of the vendor-specific APIs for volumes that persist + for longer than the lifecycle of an individual pod. \n + Use CSI for light-weight local ephemeral volumes if the + CSI driver is meant to be used that way - see the documentation + of the driver for more information. \n A pod can use both + types of ephemeral volumes and persistent volumes at the + same time." + properties: + volumeClaimTemplate: + description: "Will be used to create a stand-alone PVC + to provision the volume. The pod in which this EphemeralVolumeSource + is embedded will be the owner of the PVC, i.e. the + PVC will be deleted together with the pod. The name + of the PVC will be `-` where + `` is the name from the `PodSpec.Volumes` + array entry. Pod validation will reject the pod if + the concatenated name is not valid for a PVC (for + example, too long). \n An existing PVC with that name + that is not owned by the pod will *not* be used for + the pod to avoid using an unrelated volume by mistake. + Starting the pod is then blocked until the unrelated + PVC is removed. If such a pre-created PVC is meant + to be used by the pod, the PVC has to updated with + an owner reference to the pod once the pod exists. + Normally this should not be necessary, but it may + be useful when manually reconstructing a broken cluster. + \n This field is read-only and no changes will be + made by Kubernetes to the PVC after it has been created. + \n Required, must not be nil." + properties: + metadata: + description: May contain labels and annotations + that will be copied into the PVC when creating + it. No other fields are allowed and will be rejected + during validation. + type: object + spec: + description: The specification for the PersistentVolumeClaim. + The entire content is copied unchanged into the + PVC that gets created from this template. The + same fields as in a PersistentVolumeClaim are + also valid here. + properties: + accessModes: + description: 'accessModes contains the desired + access modes the volume should have. More + info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'dataSource field can be used to + specify either: * An existing VolumeSnapshot + object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller + can support the specified data source, it + will create a new volume based on the contents + of the specified data source. When the AnyVolumeDataSource + feature gate is enabled, dataSource contents + will be copied to dataSourceRef, and dataSourceRef + contents will be copied to dataSource when + dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef + will not be copied to dataSource.' + properties: + apiGroup: + description: APIGroup is the group for the + resource being referenced. If APIGroup + is not specified, the specified Kind must + be in the core API group. For any other + third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + required: + - kind + - name + type: object + dataSourceRef: + description: 'dataSourceRef specifies the object + from which to populate the volume with data, + if a non-empty volume is desired. This may + be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding + will only succeed if the type of the specified + object matches some installed volume populator + or dynamic provisioner. This field will replace + the functionality of the dataSource field + and as such if both fields are non-empty, + they must have the same value. For backwards + compatibility, when namespace isn''t specified + in dataSourceRef, both fields (dataSource + and dataSourceRef) will be set to the same + value automatically if one of them is empty + and the other is non-empty. When namespace + is specified in dataSourceRef, dataSource + isn''t set to the same value and must be empty. + There are three important differences between + dataSource and dataSourceRef: * While dataSource + only allows two specific types of objects, + dataSourceRef allows any non-core object, + as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values + (dropping them), dataSourceRef preserves + all values, and generates an error if a disallowed + value is specified. * While dataSource only + allows local objects, dataSourceRef allows + objects in any namespaces. (Beta) Using + this field requires the AnyVolumeDataSource + feature gate to be enabled. (Alpha) Using + the namespace field of dataSourceRef requires + the CrossNamespaceVolumeDataSource feature + gate to be enabled.' + properties: + apiGroup: + description: APIGroup is the group for the + resource being referenced. If APIGroup + is not specified, the specified Kind must + be in the core API group. For any other + third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + namespace: + description: Namespace is the namespace + of resource being referenced Note that + when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant + object is required in the referent namespace + to allow that namespace's owner to accept + the reference. See the ReferenceGrant + documentation for details. (Alpha) This + field requires the CrossNamespaceVolumeDataSource + feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: 'resources represents the minimum + resources the volume should have. If RecoverVolumeExpansionFailure + feature is enabled users are allowed to specify + resource requirements that are lower than + previous value but must still be higher than + capacity recorded in the status field of the + claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum + amount of compute resources allowed. More + info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum + amount of compute resources required. + If Requests is omitted for a container, + it defaults to Limits if that is explicitly + specified, otherwise to an implementation-defined + value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + selector: + description: selector is a label query over + volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + storageClassName: + description: 'storageClassName is the name of + the StorageClass required by the claim. More + info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + type: string + volumeAttributesClassName: + description: 'volumeAttributesClassName may + be used to set the VolumeAttributesClass used + by this claim. If specified, the CSI driver + will create or update the volume with the + attributes defined in the corresponding VolumeAttributesClass. + This has a different purpose than storageClassName, + it can be changed after the claim is created. + An empty string value means that no VolumeAttributesClass + will be applied to the claim but it''s not + allowed to reset this field to empty string + once it is set. If unspecified and the PersistentVolumeClaim + is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller + if it exists. If the resource referred to + by volumeAttributesClass does not exist, this + PersistentVolumeClaim will be set to a Pending + state, as reflected by the modifyVolumeStatus + field, until such as a resource exists. More + info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + (Alpha) Using this field requires the VolumeAttributesClass + feature gate to be enabled.' + type: string + volumeMode: + description: volumeMode defines what type of + volume is required by the claim. Value of + Filesystem is implied when not included in + claim spec. + type: string + volumeName: + description: volumeName is the binding reference + to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource that + is attached to a kubelet's host machine and then exposed + to the pod. + properties: + fsType: + description: 'fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. TODO: how do we prevent + errors in the filesystem from compromising the machine' + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: 'readOnly is Optional: Defaults to false + (read/write). ReadOnly here will force the ReadOnly + setting in VolumeMounts.' + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target worldwide + names (WWNs)' + items: + type: string + type: array + wwids: + description: 'wwids Optional: FC volume world wide identifiers + (wwids) Either wwids or combination of targetWWNs + and lun must be set, but not both simultaneously.' + items: + type: string + type: array + type: object + flexVolume: + description: flexVolume represents a generic volume resource + that is provisioned/attached using an exec based plugin. + properties: + driver: + description: driver is the name of the driver to use + for this volume. + type: string + fsType: + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". The default filesystem + depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field holds + extra command options if any.' + type: object + readOnly: + description: 'readOnly is Optional: defaults to false + (read/write). ReadOnly here will force the ReadOnly + setting in VolumeMounts.' + type: boolean + secretRef: + description: 'secretRef is Optional: secretRef is reference + to the secret object containing sensitive information + to pass to the plugin scripts. This may be empty if + no secret object is specified. If the secret object + contains more than one secret, all secrets are passed + to the plugin scripts.' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume attached + to a kubelet's host machine. This depends on the Flocker + control service being running + properties: + datasetName: + description: datasetName is Name of the dataset stored + as metadata -> name on the dataset for Flocker should + be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. + This is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: 'gcePersistentDisk represents a GCE Disk resource + that is attached to a kubelet''s host machine and then + exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + properties: + fsType: + description: 'fsType is filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + partition: + description: 'partition is the partition in the volume + that you want to mount. If omitted, the default is + to mount by volume name. Examples: For volume /dev/sda1, + you specify the partition as "1". Similarly, the volume + partition for /dev/sda is "0" (or you can leave the + property empty). More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + format: int32 + type: integer + pdName: + description: 'pdName is unique name of the PD resource + in GCE. Used to identify the disk in GCE. More info: + https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: string + readOnly: + description: 'readOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. More info: + https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: boolean + required: + - pdName + type: object + gitRepo: + description: 'gitRepo represents a git repository at a particular + revision. DEPRECATED: GitRepo is deprecated. To provision + a container with a git repo, mount an EmptyDir into an + InitContainer that clones the repo using git, then mount + the EmptyDir into the Pod''s container.' + properties: + directory: + description: directory is the target directory name. + Must not contain or start with '..'. If '.' is supplied, + the volume directory will be the git repository. Otherwise, + if specified, the volume will contain the git repository + in the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the specified + revision. + type: string + required: + - repository + type: object + glusterfs: + description: 'glusterfs represents a Glusterfs mount on + the host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/glusterfs/README.md' + properties: + endpoints: + description: 'endpoints is the endpoint name that details + Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + path: + description: 'path is the Glusterfs volume path. More + info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + readOnly: + description: 'readOnly here will force the Glusterfs + volume to be mounted with read-only permissions. Defaults + to false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: 'hostPath represents a pre-existing file or + directory on the host machine that is directly exposed + to the container. This is generally used for system agents + or other privileged things that are allowed to see the + host machine. Most containers will NOT need this. More + info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- TODO(jonesdl) We need to restrict who can use host + directory mounts and who can/can not mount host directories + as read/write.' + properties: + path: + description: 'path of the directory on the host. If + the path is a symlink, it will follow the link to + the real path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + type: + description: 'type for HostPath Volume Defaults to "" + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + required: + - path + type: object + iscsi: + description: 'iscsi represents an ISCSI Disk resource that + is attached to a kubelet''s host machine and then exposed + to the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md' + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether support + iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support + iSCSI Session CHAP authentication + type: boolean + fsType: + description: 'fsType is the filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + initiatorName: + description: initiatorName is the custom iSCSI Initiator + Name. If initiatorName is specified with iscsiInterface + simultaneously, new iSCSI interface : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified Name. + type: string + iscsiInterface: + description: iscsiInterface is the interface Name that + uses an iSCSI transport. Defaults to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: portals is the iSCSI Target Portal List. + The portal is either an IP or ip_addr:port if the + port is other than default (typically TCP ports 860 + and 3260). + items: + type: string + type: array + readOnly: + description: readOnly here will force the ReadOnly setting + in VolumeMounts. Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for iSCSI + target and initiator authentication + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + targetPortal: + description: targetPortal is iSCSI Target Portal. The + Portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and + 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: 'name of the volume. Must be a DNS_LABEL and + unique within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + nfs: + description: 'nfs represents an NFS mount on the host that + shares a pod''s lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + properties: + path: + description: 'path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + readOnly: + description: 'readOnly here will force the NFS export + to be mounted with read-only permissions. Defaults + to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: boolean + server: + description: 'server is the hostname or IP address of + the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: 'persistentVolumeClaimVolumeSource represents + a reference to a PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + claimName: + description: 'claimName is the name of a PersistentVolumeClaim + in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + type: string + readOnly: + description: readOnly Will force the ReadOnly setting + in VolumeMounts. Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents a PhotonController + persistent disk attached and mounted on kubelets host + machine + properties: + fsType: + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon Controller + persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx volume + attached and mounted on kubelets host machine + properties: + fsType: + description: fSType represents the filesystem type to + mount Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs". Implicitly inferred + to be "ext4" if unspecified. + type: string + readOnly: + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx + volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources secrets, + configmaps, and downward API + properties: + defaultMode: + description: defaultMode are the mode bits used to set + permissions on created files by default. Must be an + octal value between 0000 and 0777 or a decimal value + between 0 and 511. YAML accepts both octal and decimal + values, JSON requires decimal values for mode bits. + Directories within the path are not affected by this + setting. This might be in conflict with other options + that affect the file mode, like fsGroup, and the result + can be other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume projections + items: + description: Projection that may be projected along + with other supported volume types + properties: + clusterTrustBundle: + description: "ClusterTrustBundle allows a pod + to access the `.spec.trustBundle` field of ClusterTrustBundle + objects in an auto-updating file. \n Alpha, + gated by the ClusterTrustBundleProjection feature + gate. \n ClusterTrustBundle objects can either + be selected by name, or by the combination of + signer name and a label selector. \n Kubelet + performs aggressive normalization of the PEM + contents written into the pod filesystem. Esoteric + PEM features such as inter-block comments and + block headers are stripped. Certificates are + deduplicated. The ordering of certificates within + the file is arbitrary, and Kubelet may change + the order over time." + properties: + labelSelector: + description: Select all ClusterTrustBundles + that match this label selector. Only has + effect if signerName is set. Mutually-exclusive + with name. If unset, interpreted as "match + nothing". If set but empty, interpreted + as "match everything". + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + name: + description: Select a single ClusterTrustBundle + by object name. Mutually-exclusive with + signerName and labelSelector. + type: string + optional: + description: If true, don't block pod startup + if the referenced ClusterTrustBundle(s) + aren't available. If using name, then the + named ClusterTrustBundle is allowed not + to exist. If using signerName, then the + combination of signerName and labelSelector + is allowed to match zero ClusterTrustBundles. + type: boolean + path: + description: Relative path from the volume + root to write the bundle. + type: string + signerName: + description: Select all ClusterTrustBundles + that match this signer name. Mutually-exclusive + with name. The contents of all selected + ClusterTrustBundles will be unified and + deduplicated. + type: string + required: + - path + type: object + configMap: + description: configMap information about the configMap + data to project + properties: + items: + description: items if unspecified, each key-value + pair in the Data field of the referenced + ConfigMap will be projected into the volume + as a file whose name is the key and content + is the value. If specified, the listed keys + will be projected into the specified paths, + and unlisted keys will not be present. If + a key is specified which is not present + in the ConfigMap, the volume setup will + error unless it is marked optional. Paths + must be relative and may not contain the + '..' path or start with '..'. + items: + description: Maps a string key to a path + within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode + bits used to set permissions on this + file. Must be an octal value between + 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal + and decimal values, JSON requires + decimal values for mode bits. If not + specified, the volume defaultMode + will be used. This might be in conflict + with other options that affect the + file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path + of the file to map the key to. May + not be an absolute path. May not contain + the path element '..'. May not start + with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: optional specify whether the + ConfigMap or its keys must be defined + type: boolean + type: object + downwardAPI: + description: downwardAPI information about the + downwardAPI data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects a field + of the pod: only annotations, labels, + name and namespace are supported.' + properties: + apiVersion: + description: Version of the schema + the FieldPath is written in terms + of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to + select in the specified API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: mode bits used + to set permissions on this file, must + be an octal value between 0000 and + 0777 or a decimal value between 0 + and 511. YAML accepts both octal and + decimal values, JSON requires decimal + values for mode bits. If not specified, + the volume defaultMode will be used. + This might be in conflict with other + options that affect the file mode, + like fsGroup, and the result can be + other mode bits set.' + format: int32 + type: integer + path: + description: 'Required: Path is the + relative path name of the file to + be created. Must not be absolute or + contain the ''..'' path. Must be utf-8 + encoded. The first item of the relative + path must not start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of + the container: only resources limits + and requests (limits.cpu, limits.memory, + requests.cpu and requests.memory) + are currently supported.' + properties: + containerName: + description: 'Container name: required + for volumes, optional for env + vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource + to select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + secret: + description: secret information about the secret + data to project + properties: + items: + description: items if unspecified, each key-value + pair in the Data field of the referenced + Secret will be projected into the volume + as a file whose name is the key and content + is the value. If specified, the listed keys + will be projected into the specified paths, + and unlisted keys will not be present. If + a key is specified which is not present + in the Secret, the volume setup will error + unless it is marked optional. Paths must + be relative and may not contain the '..' + path or start with '..'. + items: + description: Maps a string key to a path + within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode + bits used to set permissions on this + file. Must be an octal value between + 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal + and decimal values, JSON requires + decimal values for mode bits. If not + specified, the volume defaultMode + will be used. This might be in conflict + with other options that affect the + file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path + of the file to map the key to. May + not be an absolute path. May not contain + the path element '..'. May not start + with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: optional field specify whether + the Secret or its key must be defined + type: boolean + type: object + serviceAccountToken: + description: serviceAccountToken is information + about the serviceAccountToken data to project + properties: + audience: + description: audience is the intended audience + of the token. A recipient of a token must + identify itself with an identifier specified + in the audience of the token, and otherwise + should reject the token. The audience defaults + to the identifier of the apiserver. + type: string + expirationSeconds: + description: expirationSeconds is the requested + duration of validity of the service account + token. As the token approaches expiration, + the kubelet volume plugin will proactively + rotate the service account token. The kubelet + will start trying to rotate the token if + the token is older than 80 percent of its + time to live or if the token is older than + 24 hours.Defaults to 1 hour and must be + at least 10 minutes. + format: int64 + type: integer + path: + description: path is the path relative to + the mount point of the file to project the + token into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: quobyte represents a Quobyte mount on the host + that shares a pod's lifetime + properties: + group: + description: group to map volume access to Default is + no group + type: string + readOnly: + description: readOnly here will force the Quobyte volume + to be mounted with read-only permissions. Defaults + to false. + type: boolean + registry: + description: registry represents a single or multiple + Quobyte Registry services specified as a string as + host:port pair (multiple entries are separated with + commas) which acts as the central registry for volumes + type: string + tenant: + description: tenant owning the given Quobyte volume + in the Backend Used with dynamically provisioned Quobyte + volumes, value is set by the plugin + type: string + user: + description: user to map volume access to Defaults to + serivceaccount user + type: string + volume: + description: volume is a string that references an already + created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: 'rbd represents a Rados Block Device mount + on the host that shares a pod''s lifetime. More info: + https://examples.k8s.io/volumes/rbd/README.md' + properties: + fsType: + description: 'fsType is the filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + image: + description: 'image is the rados image name. More info: + https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + keyring: + description: 'keyring is the path to key ring for RBDUser. + Default is /etc/ceph/keyring. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + monitors: + description: 'monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + items: + type: string + type: array + pool: + description: 'pool is the rados pool name. Default is + rbd. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + readOnly: + description: 'readOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. More info: + https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: boolean + secretRef: + description: 'secretRef is name of the authentication + secret for RBDUser. If provided overrides keyring. + Default is nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + user: + description: 'user is the rados user name. Default is + admin. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent volume + attached and mounted on Kubernetes nodes. + properties: + fsType: + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Default is "xfs". + type: string + gateway: + description: gateway is the host address of the ScaleIO + API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the ScaleIO + Protection Domain for the configured storage. + type: string + readOnly: + description: readOnly Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: secretRef references to the secret for + ScaleIO user and other sensitive information. If this + is not provided, Login operation will fail. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + sslEnabled: + description: sslEnabled Flag enable/disable SSL communication + with Gateway, default false + type: boolean + storageMode: + description: storageMode indicates whether the storage + for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage Pool + associated with the protection domain. + type: string + system: + description: system is the name of the storage system + as configured in ScaleIO. + type: string + volumeName: + description: volumeName is the name of a volume already + created in the ScaleIO system that is associated with + this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: 'secret represents a secret that should populate + this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + properties: + defaultMode: + description: 'defaultMode is Optional: mode bits used + to set permissions on created files by default. Must + be an octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal and + decimal values, JSON requires decimal values for mode + bits. Defaults to 0644. Directories within the path + are not affected by this setting. This might be in + conflict with other options that affect the file mode, + like fsGroup, and the result can be other mode bits + set.' + format: int32 + type: integer + items: + description: items If unspecified, each key-value pair + in the Data field of the referenced Secret will be + projected into the volume as a file whose name is + the key and content is the value. If specified, the + listed keys will be projected into the specified paths, + and unlisted keys will not be present. If a key is + specified which is not present in the Secret, the + volume setup will error unless it is marked optional. + Paths must be relative and may not contain the '..' + path or start with '..'. + items: + description: Maps a string key to a path within a + volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used + to set permissions on this file. Must be an + octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both octal + and decimal values, JSON requires decimal values + for mode bits. If not specified, the volume + defaultMode will be used. This might be in conflict + with other options that affect the file mode, + like fsGroup, and the result can be other mode + bits set.' + format: int32 + type: integer + path: + description: path is the relative path of the + file to map the key to. May not be an absolute + path. May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the Secret + or its keys must be defined + type: boolean + secretName: + description: 'secretName is the name of the secret in + the pod''s namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + type: string + type: object + storageos: + description: storageOS represents a StorageOS volume attached + and mounted on Kubernetes nodes. + properties: + fsType: + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. + type: string + readOnly: + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: secretRef specifies the secret to use for + obtaining the StorageOS API credentials. If not specified, + default values will be attempted. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + volumeName: + description: volumeName is the human-readable name of + the StorageOS volume. Volume names are only unique + within a namespace. + type: string + volumeNamespace: + description: volumeNamespace specifies the scope of + the volume within StorageOS. If no namespace is specified + then the Pod's namespace will be used. This allows + the Kubernetes name scoping to be mirrored within + StorageOS for tighter integration. Set VolumeName + to any name to override the default behaviour. Set + to "default" if you are not using namespaces within + StorageOS. Namespaces that do not pre-exist within + StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere volume attached + and mounted on kubelets host machine + properties: + fsType: + description: fsType is filesystem type to mount. Must + be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy Based + Management (SPBM) profile ID associated with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage Policy + Based Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies + vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + type: object + required: + - clusterSize + - kubernetesConfig + type: object + status: + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/crds/redis.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/crds/redis.yaml new file mode 100644 index 000000000..3506cf20d --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/crds/redis.yaml @@ -0,0 +1,9966 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.1 + creationTimestamp: null + name: redis.redis.redis.opstreelabs.in +spec: + group: redis.redis.opstreelabs.in + names: + kind: Redis + listKind: RedisList + plural: redis + singular: redis + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + description: Redis is the Schema for the redis API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: RedisSpec defines the desired state of Redis + properties: + TLS: + description: TLS Configuration for redis instances + properties: + ca: + type: string + cert: + type: string + key: + type: string + secret: + description: Reference to secret which contains the certificates + properties: + defaultMode: + description: 'defaultMode is Optional: mode bits used to set + permissions on created files by default. Must be an octal + value between 0000 and 0777 or a decimal value between 0 + and 511. YAML accepts both octal and decimal values, JSON + requires decimal values for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect + the file mode, like fsGroup, and the result can be other + mode bits set.' + format: int32 + type: integer + items: + description: items If unspecified, each key-value pair in + the Data field of the referenced Secret will be projected + into the volume as a file whose name is the key and content + is the value. If specified, the listed keys will be projected + into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the + Secret, the volume setup will error unless it is marked + optional. Paths must be relative and may not contain the + '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used to set + permissions on this file. Must be an octal value between + 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires + decimal values for mode bits. If not specified, the + volume defaultMode will be used. This might be in + conflict with other options that affect the file mode, + like fsGroup, and the result can be other mode bits + set.' + format: int32 + type: integer + path: + description: path is the relative path of the file to + map the key to. May not be an absolute path. May not + contain the path element '..'. May not start with + the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the Secret or + its keys must be defined + type: boolean + secretName: + description: 'secretName is the name of the secret in the + pod''s namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + type: string + type: object + required: + - secret + type: object + affinity: + description: Affinity is a group of affinity scheduling rules. + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for the + pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the affinity expressions specified by + this field, but it may choose a node that violates one or + more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node matches + the corresponding matchExpressions; the node(s) with the + highest sum are the most preferred. + items: + description: An empty preferred scheduling term matches + all objects with implicit weight 0 (i.e. it's a no-op). + A null preferred scheduling term matches no objects (i.e. + is also a no-op). + properties: + preference: + description: A node selector term, associated with the + corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + description: Weight associated with matching the corresponding + nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this + field are not met at scheduling time, the pod will not be + scheduled onto the node. If the affinity requirements specified + by this field cease to be met at some point during pod execution + (e.g. due to an update), the system may or may not try to + eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: A null or empty node selector term matches + no objects. The requirements of them are ANDed. The + TopologySelectorTerm type implements a subset of the + NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. co-locate + this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the affinity expressions specified by + this field, but it may choose a node that violates one or + more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node has + pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key in (value)` to select + the group of existing pods which pods will be + taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MatchLabelKeys and LabelSelector. Also, + MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key notin (value)` to + select the group of existing pods which pods will + be taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MismatchLabelKeys and LabelSelector. Also, + MismatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding + podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this + field are not met at scheduling time, the pod will not be + scheduled onto the node. If the affinity requirements specified + by this field cease to be met at some point during pod execution + (e.g. due to a pod label update), the system may or may + not try to eventually evict the pod from its node. When + there are multiple elements, the lists of nodes corresponding + to each podAffinityTerm are intersected, i.e. all terms + must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not co-located + (anti-affinity) with, where co-located is defined as running + on a node whose value of the label with key + matches that of any node on which a pod of the set of + pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod label keys + to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged with + `LabelSelector` as `key in (value)` to select the + group of existing pods which pods will be taken into + consideration for the incoming pod's pod (anti) affinity. + Keys that don't exist in the incoming pod labels will + be ignored. The default value is empty. The same key + is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires enabling + MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged with + `LabelSelector` as `key notin (value)` to select the + group of existing pods which pods will be taken into + consideration for the incoming pod's pod (anti) affinity. + Keys that don't exist in the incoming pod labels will + be ignored. The default value is empty. The same key + is forbidden to exist in both MismatchLabelKeys and + LabelSelector. Also, MismatchLabelKeys cannot be set + when LabelSelector isn't set. This is an alpha field + and requires enabling MatchLabelKeysInPodAffinity + feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied to the + union of the namespaces selected by this field and + the ones listed in the namespaces field. null selector + and null or empty namespaces list means "this pod's + namespace". An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace + names that the term applies to. The term is applied + to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. null or + empty namespaces list and null namespaceSelector means + "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where + co-located is defined as running on a node whose value + of the label with key topologyKey matches that of + any node on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules (e.g. + avoid putting this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the anti-affinity expressions specified + by this field, but it may choose a node that violates one + or more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node has + pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key in (value)` to select + the group of existing pods which pods will be + taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MatchLabelKeys and LabelSelector. Also, + MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key notin (value)` to + select the group of existing pods which pods will + be taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MismatchLabelKeys and LabelSelector. Also, + MismatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding + podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the anti-affinity requirements + specified by this field cease to be met at some point during + pod execution (e.g. due to a pod label update), the system + may or may not try to eventually evict the pod from its + node. When there are multiple elements, the lists of nodes + corresponding to each podAffinityTerm are intersected, i.e. + all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not co-located + (anti-affinity) with, where co-located is defined as running + on a node whose value of the label with key + matches that of any node on which a pod of the set of + pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod label keys + to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged with + `LabelSelector` as `key in (value)` to select the + group of existing pods which pods will be taken into + consideration for the incoming pod's pod (anti) affinity. + Keys that don't exist in the incoming pod labels will + be ignored. The default value is empty. The same key + is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires enabling + MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged with + `LabelSelector` as `key notin (value)` to select the + group of existing pods which pods will be taken into + consideration for the incoming pod's pod (anti) affinity. + Keys that don't exist in the incoming pod labels will + be ignored. The default value is empty. The same key + is forbidden to exist in both MismatchLabelKeys and + LabelSelector. Also, MismatchLabelKeys cannot be set + when LabelSelector isn't set. This is an alpha field + and requires enabling MatchLabelKeysInPodAffinity + feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied to the + union of the namespaces selected by this field and + the ones listed in the namespaces field. null selector + and null or empty namespaces list means "this pod's + namespace". An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace + names that the term applies to. The term is applied + to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. null or + empty namespaces list and null namespaceSelector means + "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where + co-located is defined as running on a node whose value + of the label with key topologyKey matches that of + any node on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + kubernetesConfig: + description: KubernetesConfig will be the JSON struct for Basic Redis + Config + properties: + ignoreAnnotations: + items: + type: string + type: array + image: + type: string + imagePullPolicy: + description: PullPolicy describes a policy for if/when to pull + a container image + type: string + imagePullSecrets: + items: + description: LocalObjectReference contains enough information + to let you locate the referenced object inside the same namespace. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + type: array + redisSecret: + description: ExistingPasswordSecret is the struct to access the + existing secret + properties: + key: + type: string + name: + type: string + type: object + resources: + description: ResourceRequirements describes the compute resource + requirements. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + service: + description: ServiceConfig define the type of service to be created + and its annotations + properties: + annotations: + additionalProperties: + type: string + type: object + serviceType: + enum: + - LoadBalancer + - NodePort + - ClusterIP + type: string + type: object + updateStrategy: + description: StatefulSetUpdateStrategy indicates the strategy + that the StatefulSet controller will use to perform updates. + It includes any additional parameters necessary to perform the + update for the indicated strategy. + properties: + rollingUpdate: + description: RollingUpdate is used to communicate parameters + when Type is RollingUpdateStatefulSetStrategyType. + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + description: 'The maximum number of pods that can be unavailable + during the update. Value can be an absolute number (ex: + 5) or a percentage of desired pods (ex: 10%). Absolute + number is calculated from percentage by rounding up. + This can not be 0. Defaults to 1. This field is alpha-level + and is only honored by servers that enable the MaxUnavailableStatefulSet + feature. The field applies to all pods in the range + 0 to Replicas-1. That means if there is any unavailable + pod in the range 0 to Replicas-1, it will be counted + towards MaxUnavailable.' + x-kubernetes-int-or-string: true + partition: + description: Partition indicates the ordinal at which + the StatefulSet should be partitioned for updates. During + a rolling update, all pods from ordinal Replicas-1 to + Partition are updated. All pods from ordinal Partition-1 + to 0 remain untouched. This is helpful in being able + to do a canary based deployment. The default value is + 0. + format: int32 + type: integer + type: object + type: + description: Type indicates the type of the StatefulSetUpdateStrategy. + Default is RollingUpdate. + type: string + type: object + required: + - image + type: object + livenessProbe: + description: Probe describes a health check to be performed against + a container to determine whether it is alive or ready to receive + traffic. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside + the container, the working directory for the command is + root ('/') in the container's filesystem. The command is + simply exec'd, it is not run inside a shell, so traditional + shell instructions ('|', etc) won't work. To use a shell, + you need to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be + considered failed after having succeeded. Defaults to 3. Minimum + value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. + properties: + port: + description: Port number of the gRPC service. Number must + be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place + in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior is defined + by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod + IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows + repeated headers. + items: + description: HTTPHeader describes a custom header to be + used in HTTP probes + properties: + name: + description: The header field name. This will be canonicalized + upon output, so case-variant names will be understood + as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. + Number must be in the range 1 to 65535. Name must be an + IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults + to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started + before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default + to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be + considered successful after having failed. Defaults to 1. Must + be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults + to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. + Number must be in the range 1 to 65535. Name must be an + IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate + gracefully upon probe failure. The grace period is the duration + in seconds after the processes running in the pod are sent a + termination signal and the time when the processes are forcibly + halted with a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, the pod's + terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. Value must + be non-negative integer. The value zero indicates stop immediately + via the kill signal (no opportunity to shut down). This is a + beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + nodeSelector: + additionalProperties: + type: string + type: object + priorityClassName: + type: string + readinessProbe: + description: Probe describes a health check to be performed against + a container to determine whether it is alive or ready to receive + traffic. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside + the container, the working directory for the command is + root ('/') in the container's filesystem. The command is + simply exec'd, it is not run inside a shell, so traditional + shell instructions ('|', etc) won't work. To use a shell, + you need to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be + considered failed after having succeeded. Defaults to 3. Minimum + value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. + properties: + port: + description: Port number of the gRPC service. Number must + be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place + in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior is defined + by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod + IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows + repeated headers. + items: + description: HTTPHeader describes a custom header to be + used in HTTP probes + properties: + name: + description: The header field name. This will be canonicalized + upon output, so case-variant names will be understood + as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. + Number must be in the range 1 to 65535. Name must be an + IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults + to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started + before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default + to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be + considered successful after having failed. Defaults to 1. Must + be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults + to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. + Number must be in the range 1 to 65535. Name must be an + IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate + gracefully upon probe failure. The grace period is the duration + in seconds after the processes running in the pod are sent a + termination signal and the time when the processes are forcibly + halted with a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, the pod's + terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. Value must + be non-negative integer. The value zero indicates stop immediately + via the kill signal (no opportunity to shut down). This is a + beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + redisConfig: + description: RedisConfig defines the external configuration of Redis + properties: + additionalRedisConfig: + type: string + type: object + redisExporter: + description: RedisExporter interface will have the information for + redis exporter related stuff + properties: + enabled: + type: boolean + env: + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + image: + type: string + imagePullPolicy: + description: PullPolicy describes a policy for if/when to pull + a container image + type: string + port: + default: 9121 + type: integer + resources: + description: ResourceRequirements describes the compute resource + requirements. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: SecurityContext holds security configuration that + will be applied to a container. Some fields are present in both + SecurityContext and PodSecurityContext. When both are set, + the values in SecurityContext take precedence. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a + process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the + container runtime. Note that this field cannot be set when + spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in + privileged containers are essentially equivalent to root + on the host. Defaults to false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use + for the containers. The default is DefaultProcMount which + uses the container runtime defaults for readonly paths and + masked paths. This requires the ProcMountType feature flag + to be enabled. Note that this field cannot be set when spec.os.name + is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when + spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail + to start the container if it does. If unset or false, no + such validation will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata if + unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. Note + that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must + be preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must be set if type is "Localhost". Must NOT + be set for any other type. + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a + profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile + should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also be + set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + required: + - image + type: object + securityContext: + description: PodSecurityContext holds pod-level security attributes + and common container settings. Some fields are also present in container.securityContext. Field + values of container.securityContext take precedence over field values + of PodSecurityContext. + properties: + fsGroup: + description: "A special supplemental group that applies to all + containers in a pod. Some volume types allow the Kubelet to + change the ownership of that volume to be owned by the pod: + \n 1. The owning GID will be the FSGroup 2. The setgid bit is + set (new files created in the volume will be owned by FSGroup) + 3. The permission bits are OR'd with rw-rw---- \n If unset, + the Kubelet will not modify the ownership and permissions of + any volume. Note that this field cannot be set when spec.os.name + is windows." + format: int64 + type: integer + fsGroupChangePolicy: + description: 'fsGroupChangePolicy defines behavior of changing + ownership and permission of the volume before being exposed + inside Pod. This field will only apply to volume types which + support fsGroup based ownership(and permissions). It will have + no effect on ephemeral volume types such as: secret, configmaps + and emptydir. Valid values are "OnRootMismatch" and "Always". + If not specified, "Always" is used. Note that this field cannot + be set when spec.os.name is windows.' + type: string + runAsGroup: + description: The GID to run the entrypoint of the container process. + Uses runtime default if unset. May also be set in SecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail to start + the container if it does. If unset or false, no such validation + will be performed. May also be set in SecurityContext. If set + in both SecurityContext and PodSecurityContext, the value specified + in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in SecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. Note that this field cannot + be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in SecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to + the container. + type: string + role: + description: Role is a SELinux role label that applies to + the container. + type: string + type: + description: Type is a SELinux type label that applies to + the container. + type: string + user: + description: User is a SELinux user label that applies to + the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by the containers in this + pod. Note that this field cannot be set when spec.os.name is + windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must be + preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must be set if type is "Localhost". Must NOT be + set for any other type. + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a profile + defined in a file on the node should be used. RuntimeDefault + - the container runtime default profile should be used. + Unconfined - no profile should be applied." + type: string + required: + - type + type: object + supplementalGroups: + description: A list of groups applied to the first process run + in each container, in addition to the container's primary GID, + the fsGroup (if specified), and group memberships defined in + the container image for the uid of the container process. If + unspecified, no additional groups are added to any container. + Note that group memberships defined in the container image for + the uid of the container process are still effective, even if + they are not included in this list. Note that this field cannot + be set when spec.os.name is windows. + items: + format: int64 + type: integer + type: array + sysctls: + description: Sysctls hold a list of namespaced sysctls used for + the pod. Pods with unsupported sysctls (by the container runtime) + might fail to launch. Note that this field cannot be set when + spec.os.name is windows. + items: + description: Sysctl defines a kernel parameter to be set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + description: The Windows specific settings applied to all containers. + If unspecified, the options within a container's SecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named by + the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA + credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. All of a Pod's containers + must have the same effective HostProcess value (it is not + allowed to have a mix of HostProcess containers and non-HostProcess + containers). In addition, if HostProcess is true then HostNetwork + must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in PodSecurityContext. + If set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: string + type: object + type: object + serviceAccountName: + type: string + sidecars: + items: + description: Sidecar for each Redis pods + properties: + env: + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be + a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. + If a variable cannot be resolved, the reference in the + input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) + syntax: i.e. "$$(VAR_NAME)" will produce the string + literal "$(VAR_NAME)". Escaped references will never + be expanded, regardless of whether the variable exists + or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its + key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + image: + type: string + imagePullPolicy: + description: PullPolicy describes a policy for if/when to pull + a container image + type: string + name: + type: string + resources: + description: ResourceRequirements describes the compute resource + requirements. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only + be set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where this + field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests + cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + required: + - image + - name + type: object + type: array + storage: + description: Storage is the inteface to add pvc and pv support in + redis + properties: + keepAfterDelete: + type: boolean + volumeClaimTemplate: + description: PersistentVolumeClaim is a user's request for and + claim to a persistent volume + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this + representation of an object. Servers should convert recognized + schemas to the latest internal value, and may reject unrecognized + values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST + resource this object represents. Servers may infer this + from the endpoint the client submits requests to. Cannot + be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + description: 'Standard object''s metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata' + type: object + spec: + description: 'spec defines the desired characteristics of + a volume requested by a pod author. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + accessModes: + description: 'accessModes contains the desired access + modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'dataSource field can be used to specify + either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) If the provisioner + or an external controller can support the specified + data source, it will create a new volume based on the + contents of the specified data source. When the AnyVolumeDataSource + feature gate is enabled, dataSource contents will be + copied to dataSourceRef, and dataSourceRef contents + will be copied to dataSource when dataSourceRef.namespace + is not specified. If the namespace is specified, then + dataSourceRef will not be copied to dataSource.' + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + dataSourceRef: + description: 'dataSourceRef specifies the object from + which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty + API group (non core object) or a PersistentVolumeClaim + object. When this field is specified, volume binding + will only succeed if the type of the specified object + matches some installed volume populator or dynamic provisioner. + This field will replace the functionality of the dataSource + field and as such if both fields are non-empty, they + must have the same value. For backwards compatibility, + when namespace isn''t specified in dataSourceRef, both + fields (dataSource and dataSourceRef) will be set to + the same value automatically if one of them is empty + and the other is non-empty. When namespace is specified + in dataSourceRef, dataSource isn''t set to the same + value and must be empty. There are three important differences + between dataSource and dataSourceRef: * While dataSource + only allows two specific types of objects, dataSourceRef allows + any non-core object, as well as PersistentVolumeClaim + objects. * While dataSource ignores disallowed values + (dropping them), dataSourceRef preserves all values, + and generates an error if a disallowed value is specified. + * While dataSource only allows local objects, dataSourceRef + allows objects in any namespaces. (Beta) Using this + field requires the AnyVolumeDataSource feature gate + to be enabled. (Alpha) Using the namespace field of + dataSourceRef requires the CrossNamespaceVolumeDataSource + feature gate to be enabled.' + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + namespace: + description: Namespace is the namespace of resource + being referenced Note that when a namespace is specified, + a gateway.networking.k8s.io/ReferenceGrant object + is required in the referent namespace to allow that + namespace's owner to accept the reference. See the + ReferenceGrant documentation for details. (Alpha) + This field requires the CrossNamespaceVolumeDataSource + feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: 'resources represents the minimum resources + the volume should have. If RecoverVolumeExpansionFailure + feature is enabled users are allowed to specify resource + requirements that are lower than previous value but + must still be higher than capacity recorded in the status + field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount + of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount + of compute resources required. If Requests is omitted + for a container, it defaults to Limits if that is + explicitly specified, otherwise to an implementation-defined + value. Requests cannot exceed Limits. More info: + https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + selector: + description: selector is a label query over volumes to + consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, + NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values + array must be non-empty. If the operator is + Exists or DoesNotExist, the values array must + be empty. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field + is "key", the operator is "In", and the values array + contains only "value". The requirements are ANDed. + type: object + type: object + storageClassName: + description: 'storageClassName is the name of the StorageClass + required by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + type: string + volumeAttributesClassName: + description: 'volumeAttributesClassName may be used to + set the VolumeAttributesClass used by this claim. If + specified, the CSI driver will create or update the + volume with the attributes defined in the corresponding + VolumeAttributesClass. This has a different purpose + than storageClassName, it can be changed after the claim + is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it''s not allowed to + reset this field to empty string once it is set. If + unspecified and the PersistentVolumeClaim is unbound, + the default VolumeAttributesClass will be set by the + persistentvolume controller if it exists. If the resource + referred to by volumeAttributesClass does not exist, + this PersistentVolumeClaim will be set to a Pending + state, as reflected by the modifyVolumeStatus field, + until such as a resource exists. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + (Alpha) Using this field requires the VolumeAttributesClass + feature gate to be enabled.' + type: string + volumeMode: + description: volumeMode defines what type of volume is + required by the claim. Value of Filesystem is implied + when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to the + PersistentVolume backing this claim. + type: string + type: object + status: + description: 'status represents the current information/status + of a persistent volume claim. Read-only. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + accessModes: + description: 'accessModes contains the actual access modes + the volume backing the PVC has. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + allocatedResourceStatuses: + additionalProperties: + description: When a controller receives persistentvolume + claim update with ClaimResourceStatus for a resource + that it does not recognizes, then it should ignore + that update and let other controllers handle it. + type: string + description: "allocatedResourceStatuses stores status + of resource being resized for the given PVC. Key names + follow standard Kubernetes label syntax. Valid values + are either: \t* Un-prefixed keys: \t\t- storage - the + capacity of the volume. \t* Custom resources must use + implementation-defined prefixed names such as \"example.com/my-custom-resource\" + Apart from above values - keys that are unprefixed or + have kubernetes.io prefix are considered reserved and + hence may not be used. \n ClaimResourceStatus can be + in any of following states: \t- ControllerResizeInProgress: + \t\tState set when resize controller starts resizing + the volume in control-plane. \t- ControllerResizeFailed: + \t\tState set when resize has failed in resize controller + with a terminal error. \t- NodeResizePending: \t\tState + set when resize controller has finished resizing the + volume but further resizing of \t\tvolume is needed + on the node. \t- NodeResizeInProgress: \t\tState set + when kubelet starts resizing the volume. \t- NodeResizeFailed: + \t\tState set when resizing has failed in kubelet with + a terminal error. Transient errors don't set \t\tNodeResizeFailed. + For example: if expanding a PVC for more capacity - + this field can be one of the following states: \t- pvc.status.allocatedResourceStatus['storage'] + = \"ControllerResizeInProgress\" - pvc.status.allocatedResourceStatus['storage'] + = \"ControllerResizeFailed\" - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizePending\" - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizeInProgress\" - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizeFailed\" When this field is not set, it + means that no resize operation is in progress for the + given PVC. \n A controller that receives PVC update + with previously unknown resourceName or ClaimResourceStatus + should ignore the update for the purpose it was designed. + For example - a controller that only is responsible + for resizing capacity of the volume, should ignore PVC + updates that change other valid resources associated + with PVC. \n This is an alpha field and requires enabling + RecoverVolumeExpansionFailure feature." + type: object + x-kubernetes-map-type: granular + allocatedResources: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: "allocatedResources tracks the resources + allocated to a PVC including its capacity. Key names + follow standard Kubernetes label syntax. Valid values + are either: \t* Un-prefixed keys: \t\t- storage - the + capacity of the volume. \t* Custom resources must use + implementation-defined prefixed names such as \"example.com/my-custom-resource\" + Apart from above values - keys that are unprefixed or + have kubernetes.io prefix are considered reserved and + hence may not be used. \n Capacity reported here may + be larger than the actual capacity when a volume expansion + operation is requested. For storage quota, the larger + value from allocatedResources and PVC.spec.resources + is used. If allocatedResources is not set, PVC.spec.resources + alone is used for quota calculation. If a volume expansion + capacity request is lowered, allocatedResources is only + lowered if there are no expansion operations in progress + and if the actual volume capacity is equal or lower + than the requested capacity. \n A controller that receives + PVC update with previously unknown resourceName should + ignore the update for the purpose it was designed. For + example - a controller that only is responsible for + resizing capacity of the volume, should ignore PVC updates + that change other valid resources associated with PVC. + \n This is an alpha field and requires enabling RecoverVolumeExpansionFailure + feature." + type: object + capacity: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: capacity represents the actual resources + of the underlying volume. + type: object + conditions: + description: conditions is the current Condition of persistent + volume claim. If underlying persistent volume is being + resized then the Condition will be set to 'ResizeStarted'. + items: + description: PersistentVolumeClaimCondition contains + details about state of pvc + properties: + lastProbeTime: + description: lastProbeTime is the time we probed + the condition. + format: date-time + type: string + lastTransitionTime: + description: lastTransitionTime is the time the + condition transitioned from one status to another. + format: date-time + type: string + message: + description: message is the human-readable message + indicating details about last transition. + type: string + reason: + description: reason is a unique, this should be + a short, machine understandable string that gives + the reason for condition's last transition. If + it reports "ResizeStarted" that means the underlying + persistent volume is being resized. + type: string + status: + type: string + type: + description: PersistentVolumeClaimConditionType + is a valid value of PersistentVolumeClaimCondition.Type + type: string + required: + - status + - type + type: object + type: array + currentVolumeAttributesClassName: + description: currentVolumeAttributesClassName is the current + name of the VolumeAttributesClass the PVC is using. + When unset, there is no VolumeAttributeClass applied + to this PersistentVolumeClaim This is an alpha field + and requires enabling VolumeAttributesClass feature. + type: string + modifyVolumeStatus: + description: ModifyVolumeStatus represents the status + object of ControllerModifyVolume operation. When this + is unset, there is no ModifyVolume operation being attempted. + This is an alpha field and requires enabling VolumeAttributesClass + feature. + properties: + status: + description: "status is the status of the ControllerModifyVolume + operation. It can be in any of following states: + \ - Pending Pending indicates that the PersistentVolumeClaim + cannot be modified due to unmet requirements, such + as the specified VolumeAttributesClass not existing. + \ - InProgress InProgress indicates that the + volume is being modified. - Infeasible Infeasible + indicates that the request has been rejected as + invalid by the CSI driver. To \t resolve the error, + a valid VolumeAttributesClass needs to be specified. + Note: New statuses can be added in the future. Consumers + should check for unknown statuses and fail appropriately." + type: string + targetVolumeAttributesClassName: + description: targetVolumeAttributesClassName is the + name of the VolumeAttributesClass the PVC currently + being reconciled + type: string + required: + - status + type: object + phase: + description: phase represents the current phase of PersistentVolumeClaim. + type: string + type: object + type: object + volumeMount: + description: Additional Volume is provided by user that is mounted + on the pods + properties: + mountPath: + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: Path within the container at which the + volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts + are propagated from the host to container and the + other way around. When not set, MountPropagationNone + is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise + (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's + volume should be mounted. Defaults to "" (volume's + root). + type: string + subPathExpr: + description: Expanded path within the volume from which + the container's volume should be mounted. Behaves + similarly to SubPath but environment variable references + $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). SubPathExpr and SubPath + are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + volume: + items: + description: Volume represents a named volume in a pod that + may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: 'awsElasticBlockStore represents an AWS + Disk resource that is attached to a kubelet''s host + machine and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + properties: + fsType: + description: 'fsType is the filesystem type of the + volume that you want to mount. Tip: Ensure that + the filesystem type is supported by the host operating + system. Examples: "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. More info: + https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem + from compromising the machine' + type: string + partition: + description: 'partition is the partition in the + volume that you want to mount. If omitted, the + default is to mount by volume name. Examples: + For volume /dev/sda1, you specify the partition + as "1". Similarly, the volume partition for /dev/sda + is "0" (or you can leave the property empty).' + format: int32 + type: integer + readOnly: + description: 'readOnly value true will force the + readOnly setting in VolumeMounts. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: boolean + volumeID: + description: 'volumeID is unique ID of the persistent + disk resource in AWS (Amazon EBS volume). More + info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data Disk + mount on the host and bind mount to the pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching mode: + None, Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data disk + in the blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in + the blob storage + type: string + fsType: + description: fsType is Filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: multiple + blob disks per storage account Dedicated: single + blob disk per storage account Managed: azure + managed data disk (only in managed availability + set). defaults to shared' + type: string + readOnly: + description: readOnly Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File Service + mount on the host and bind mount to the pod. + properties: + readOnly: + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret that + contains Azure Storage Account Name and Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount on the + host that shares a pod's lifetime + properties: + monitors: + description: 'monitors is Required: Monitors is + a collection of Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + items: + type: string + type: array + path: + description: 'path is Optional: Used as the mounted + root, rather than the full Ceph tree, default + is /' + type: string + readOnly: + description: 'readOnly is Optional: Defaults to + false (read/write). ReadOnly here will force the + ReadOnly setting in VolumeMounts. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: boolean + secretFile: + description: 'secretFile is Optional: SecretFile + is the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + secretRef: + description: 'secretRef is Optional: SecretRef is + reference to the authentication secret for User, + default is empty. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + user: + description: 'user is optional: User is the rados + user name, default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + required: + - monitors + type: object + cinder: + description: 'cinder represents a cinder volume attached + and mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + properties: + fsType: + description: 'fsType is the filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Examples: "ext4", "xfs", "ntfs". + Implicitly inferred to be "ext4" if unspecified. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + readOnly: + description: 'readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: boolean + secretRef: + description: 'secretRef is optional: points to a + secret object containing parameters used to connect + to OpenStack.' + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + volumeID: + description: 'volumeID used to identify the volume + in cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that should + populate this volume + properties: + defaultMode: + description: 'defaultMode is optional: mode bits + used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or + a decimal value between 0 and 511. YAML accepts + both octal and decimal values, JSON requires decimal + values for mode bits. Defaults to 0644. Directories + within the path are not affected by this setting. + This might be in conflict with other options that + affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + items: + description: items if unspecified, each key-value + pair in the Data field of the referenced ConfigMap + will be projected into the volume as a file whose + name is the key and content is the value. If specified, + the listed keys will be projected into the specified + paths, and unlisted keys will not be present. + If a key is specified which is not present in + the ConfigMap, the volume setup will error unless + it is marked optional. Paths must be relative + and may not contain the '..' path or start with + '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits + used to set permissions on this file. Must + be an octal value between 0000 and 0777 + or a decimal value between 0 and 511. YAML + accepts both octal and decimal values, JSON + requires decimal values for mode bits. If + not specified, the volume defaultMode will + be used. This might be in conflict with + other options that affect the file mode, + like fsGroup, and the result can be other + mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of + the file to map the key to. May not be an + absolute path. May not contain the path + element '..'. May not start with the string + '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + csi: + description: csi (Container Storage Interface) represents + ephemeral storage that is handled by certain external + CSI drivers (Beta feature). + properties: + driver: + description: driver is the name of the CSI driver + that handles this volume. Consult with your admin + for the correct name as registered in the cluster. + type: string + fsType: + description: fsType to mount. Ex. "ext4", "xfs", + "ntfs". If not provided, the empty value is passed + to the associated CSI driver which will determine + the default filesystem to apply. + type: string + nodePublishSecretRef: + description: nodePublishSecretRef is a reference + to the secret object containing sensitive information + to pass to the CSI driver to complete the CSI + NodePublishVolume and NodeUnpublishVolume calls. + This field is optional, and may be empty if no + secret is required. If the secret object contains + more than one secret, all secret references are + passed. + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + readOnly: + description: readOnly specifies a read-only configuration + for the volume. Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: volumeAttributes stores driver-specific + properties that are passed to the CSI driver. + Consult your driver's documentation for supported + values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about + the pod that should populate this volume + properties: + defaultMode: + description: 'Optional: mode bits to use on created + files by default. Must be a Optional: mode bits + used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or + a decimal value between 0 and 511. YAML accepts + both octal and decimal values, JSON requires decimal + values for mode bits. Defaults to 0644. Directories + within the path are not affected by this setting. + This might be in conflict with other options that + affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + items: + description: Items is a list of downward API volume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing the + pod field + properties: + fieldRef: + description: 'Required: Selects a field of + the pod: only annotations, labels, name + and namespace are supported.' + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: mode bits used to + set permissions on this file, must be an + octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both + octal and decimal values, JSON requires + decimal values for mode bits. If not specified, + the volume defaultMode will be used. This + might be in conflict with other options + that affect the file mode, like fsGroup, + and the result can be other mode bits set.' + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. Must + not be absolute or contain the ''..'' path. + Must be utf-8 encoded. The first item of + the relative path must not start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, requests.cpu and requests.memory) + are currently supported.' + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + emptyDir: + description: 'emptyDir represents a temporary directory + that shares a pod''s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + properties: + medium: + description: 'medium represents what type of storage + medium should back this directory. The default + is "" which means to use the node''s default medium. + Must be an empty string (default) or Memory. More + info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: 'sizeLimit is the total amount of local + storage required for this EmptyDir volume. The + size limit is also applicable for memory medium. + The maximum usage on memory medium EmptyDir would + be the minimum value between the SizeLimit specified + here and the sum of memory limits of all containers + in a pod. The default is nil which means that + the limit is undefined. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: "ephemeral represents a volume that is + handled by a cluster storage driver. The volume's + lifecycle is tied to the pod that defines it - it + will be created before the pod starts, and deleted + when the pod is removed. \n Use this if: a) the volume + is only needed while the pod runs, b) features of + normal volumes like restoring from snapshot or capacity + \ tracking are needed, c) the storage driver is + specified through a storage class, and d) the storage + driver supports dynamic volume provisioning through + \ a PersistentVolumeClaim (see EphemeralVolumeSource + for more information on the connection between + this volume type and PersistentVolumeClaim). \n + Use PersistentVolumeClaim or one of the vendor-specific + APIs for volumes that persist for longer than the + lifecycle of an individual pod. \n Use CSI for light-weight + local ephemeral volumes if the CSI driver is meant + to be used that way - see the documentation of the + driver for more information. \n A pod can use both + types of ephemeral volumes and persistent volumes + at the same time." + properties: + volumeClaimTemplate: + description: "Will be used to create a stand-alone + PVC to provision the volume. The pod in which + this EphemeralVolumeSource is embedded will be + the owner of the PVC, i.e. the PVC will be deleted + together with the pod. The name of the PVC will + be `-` where `` + is the name from the `PodSpec.Volumes` array entry. + Pod validation will reject the pod if the concatenated + name is not valid for a PVC (for example, too + long). \n An existing PVC with that name that + is not owned by the pod will *not* be used for + the pod to avoid using an unrelated volume by + mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created + PVC is meant to be used by the pod, the PVC has + to updated with an owner reference to the pod + once the pod exists. Normally this should not + be necessary, but it may be useful when manually + reconstructing a broken cluster. \n This field + is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. \n Required, + must not be nil." + properties: + metadata: + description: May contain labels and annotations + that will be copied into the PVC when creating + it. No other fields are allowed and will be + rejected during validation. + type: object + spec: + description: The specification for the PersistentVolumeClaim. + The entire content is copied unchanged into + the PVC that gets created from this template. + The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: 'accessModes contains the desired + access modes the volume should have. More + info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'dataSource field can be used + to specify either: * An existing VolumeSnapshot + object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller + can support the specified data source, + it will create a new volume based on the + contents of the specified data source. + When the AnyVolumeDataSource feature gate + is enabled, dataSource contents will be + copied to dataSourceRef, and dataSourceRef + contents will be copied to dataSource + when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef + will not be copied to dataSource.' + properties: + apiGroup: + description: APIGroup is the group for + the resource being referenced. If + APIGroup is not specified, the specified + Kind must be in the core API group. + For any other third-party types, APIGroup + is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + required: + - kind + - name + type: object + dataSourceRef: + description: 'dataSourceRef specifies the + object from which to populate the volume + with data, if a non-empty volume is desired. + This may be any object from a non-empty + API group (non core object) or a PersistentVolumeClaim + object. When this field is specified, + volume binding will only succeed if the + type of the specified object matches some + installed volume populator or dynamic + provisioner. This field will replace the + functionality of the dataSource field + and as such if both fields are non-empty, + they must have the same value. For backwards + compatibility, when namespace isn''t specified + in dataSourceRef, both fields (dataSource + and dataSourceRef) will be set to the + same value automatically if one of them + is empty and the other is non-empty. When + namespace is specified in dataSourceRef, + dataSource isn''t set to the same value + and must be empty. There are three important + differences between dataSource and dataSourceRef: + * While dataSource only allows two specific + types of objects, dataSourceRef allows + any non-core object, as well as PersistentVolumeClaim + objects. * While dataSource ignores disallowed + values (dropping them), dataSourceRef preserves + all values, and generates an error if + a disallowed value is specified. * While + dataSource only allows local objects, + dataSourceRef allows objects in any + namespaces. (Beta) Using this field requires + the AnyVolumeDataSource feature gate to + be enabled. (Alpha) Using the namespace + field of dataSourceRef requires the CrossNamespaceVolumeDataSource + feature gate to be enabled.' + properties: + apiGroup: + description: APIGroup is the group for + the resource being referenced. If + APIGroup is not specified, the specified + Kind must be in the core API group. + For any other third-party types, APIGroup + is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + namespace: + description: Namespace is the namespace + of resource being referenced Note + that when a namespace is specified, + a gateway.networking.k8s.io/ReferenceGrant + object is required in the referent + namespace to allow that namespace's + owner to accept the reference. See + the ReferenceGrant documentation for + details. (Alpha) This field requires + the CrossNamespaceVolumeDataSource + feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: 'resources represents the minimum + resources the volume should have. If RecoverVolumeExpansionFailure + feature is enabled users are allowed to + specify resource requirements that are + lower than previous value but must still + be higher than capacity recorded in the + status field of the claim. More info: + https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum + amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the + minimum amount of compute resources + required. If Requests is omitted for + a container, it defaults to Limits + if that is explicitly specified, otherwise + to an implementation-defined value. + Requests cannot exceed Limits. More + info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + selector: + description: selector is a label query over + volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. + This array is replaced during + a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of + {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + storageClassName: + description: 'storageClassName is the name + of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + type: string + volumeAttributesClassName: + description: 'volumeAttributesClassName + may be used to set the VolumeAttributesClass + used by this claim. If specified, the + CSI driver will create or update the volume + with the attributes defined in the corresponding + VolumeAttributesClass. This has a different + purpose than storageClassName, it can + be changed after the claim is created. + An empty string value means that no VolumeAttributesClass + will be applied to the claim but it''s + not allowed to reset this field to empty + string once it is set. If unspecified + and the PersistentVolumeClaim is unbound, + the default VolumeAttributesClass will + be set by the persistentvolume controller + if it exists. If the resource referred + to by volumeAttributesClass does not exist, + this PersistentVolumeClaim will be set + to a Pending state, as reflected by the + modifyVolumeStatus field, until such as + a resource exists. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + (Alpha) Using this field requires the + VolumeAttributesClass feature gate to + be enabled.' + type: string + volumeMode: + description: volumeMode defines what type + of volume is required by the claim. Value + of Filesystem is implied when not included + in claim spec. + type: string + volumeName: + description: volumeName is the binding reference + to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource + that is attached to a kubelet's host machine and then + exposed to the pod. + properties: + fsType: + description: 'fsType is the filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. TODO: how + do we prevent errors in the filesystem from compromising + the machine' + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: 'readOnly is Optional: Defaults to + false (read/write). ReadOnly here will force the + ReadOnly setting in VolumeMounts.' + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target + worldwide names (WWNs)' + items: + type: string + type: array + wwids: + description: 'wwids Optional: FC volume world wide + identifiers (wwids) Either wwids or combination + of targetWWNs and lun must be set, but not both + simultaneously.' + items: + type: string + type: array + type: object + flexVolume: + description: flexVolume represents a generic volume + resource that is provisioned/attached using an exec + based plugin. + properties: + driver: + description: driver is the name of the driver to + use for this volume. + type: string + fsType: + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". The + default filesystem depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field holds + extra command options if any.' + type: object + readOnly: + description: 'readOnly is Optional: defaults to + false (read/write). ReadOnly here will force the + ReadOnly setting in VolumeMounts.' + type: boolean + secretRef: + description: 'secretRef is Optional: secretRef is + reference to the secret object containing sensitive + information to pass to the plugin scripts. This + may be empty if no secret object is specified. + If the secret object contains more than one secret, + all secrets are passed to the plugin scripts.' + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume attached + to a kubelet's host machine. This depends on the Flocker + control service being running + properties: + datasetName: + description: datasetName is Name of the dataset + stored as metadata -> name on the dataset for + Flocker should be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. + This is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: 'gcePersistentDisk represents a GCE Disk + resource that is attached to a kubelet''s host machine + and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + properties: + fsType: + description: 'fsType is filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem + from compromising the machine' + type: string + partition: + description: 'partition is the partition in the + volume that you want to mount. If omitted, the + default is to mount by volume name. Examples: + For volume /dev/sda1, you specify the partition + as "1". Similarly, the volume partition for /dev/sda + is "0" (or you can leave the property empty). + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + format: int32 + type: integer + pdName: + description: 'pdName is unique name of the PD resource + in GCE. Used to identify the disk in GCE. More + info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: string + readOnly: + description: 'readOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. More + info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: boolean + required: + - pdName + type: object + gitRepo: + description: 'gitRepo represents a git repository at + a particular revision. DEPRECATED: GitRepo is deprecated. + To provision a container with a git repo, mount an + EmptyDir into an InitContainer that clones the repo + using git, then mount the EmptyDir into the Pod''s + container.' + properties: + directory: + description: directory is the target directory name. + Must not contain or start with '..'. If '.' is + supplied, the volume directory will be the git + repository. Otherwise, if specified, the volume + will contain the git repository in the subdirectory + with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the + specified revision. + type: string + required: + - repository + type: object + glusterfs: + description: 'glusterfs represents a Glusterfs mount + on the host that shares a pod''s lifetime. More info: + https://examples.k8s.io/volumes/glusterfs/README.md' + properties: + endpoints: + description: 'endpoints is the endpoint name that + details Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + path: + description: 'path is the Glusterfs volume path. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + readOnly: + description: 'readOnly here will force the Glusterfs + volume to be mounted with read-only permissions. + Defaults to false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: 'hostPath represents a pre-existing file + or directory on the host machine that is directly + exposed to the container. This is generally used for + system agents or other privileged things that are + allowed to see the host machine. Most containers will + NOT need this. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- TODO(jonesdl) We need to restrict who can use + host directory mounts and who can/can not mount host + directories as read/write.' + properties: + path: + description: 'path of the directory on the host. + If the path is a symlink, it will follow the link + to the real path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + type: + description: 'type for HostPath Volume Defaults + to "" More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + required: + - path + type: object + iscsi: + description: 'iscsi represents an ISCSI Disk resource + that is attached to a kubelet''s host machine and + then exposed to the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md' + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether support + iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support + iSCSI Session CHAP authentication + type: boolean + fsType: + description: 'fsType is the filesystem type of the + volume that you want to mount. Tip: Ensure that + the filesystem type is supported by the host operating + system. Examples: "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. More info: + https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem + from compromising the machine' + type: string + initiatorName: + description: initiatorName is the custom iSCSI Initiator + Name. If initiatorName is specified with iscsiInterface + simultaneously, new iSCSI interface : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified Name. + type: string + iscsiInterface: + description: iscsiInterface is the interface Name + that uses an iSCSI transport. Defaults to 'default' + (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: portals is the iSCSI Target Portal + List. The portal is either an IP or ip_addr:port + if the port is other than default (typically TCP + ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: readOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for iSCSI + target and initiator authentication + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + targetPortal: + description: targetPortal is iSCSI Target Portal. + The Portal is either an IP or ip_addr:port if + the port is other than default (typically TCP + ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: 'name of the volume. Must be a DNS_LABEL + and unique within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + nfs: + description: 'nfs represents an NFS mount on the host + that shares a pod''s lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + properties: + path: + description: 'path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + readOnly: + description: 'readOnly here will force the NFS export + to be mounted with read-only permissions. Defaults + to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: boolean + server: + description: 'server is the hostname or IP address + of the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: 'persistentVolumeClaimVolumeSource represents + a reference to a PersistentVolumeClaim in the same + namespace. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + claimName: + description: 'claimName is the name of a PersistentVolumeClaim + in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + type: string + readOnly: + description: readOnly Will force the ReadOnly setting + in VolumeMounts. Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents a PhotonController + persistent disk attached and mounted on kubelets host + machine + properties: + fsType: + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon + Controller persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx volume + attached and mounted on kubelets host machine + properties: + fsType: + description: fSType represents the filesystem type + to mount Must be a filesystem type supported by + the host operating system. Ex. "ext4", "xfs". + Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx + volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources + secrets, configmaps, and downward API + properties: + defaultMode: + description: defaultMode are the mode bits used + to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or + a decimal value between 0 and 511. YAML accepts + both octal and decimal values, JSON requires decimal + values for mode bits. Directories within the path + are not affected by this setting. This might be + in conflict with other options that affect the + file mode, like fsGroup, and the result can be + other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume projections + items: + description: Projection that may be projected + along with other supported volume types + properties: + clusterTrustBundle: + description: "ClusterTrustBundle allows a + pod to access the `.spec.trustBundle` field + of ClusterTrustBundle objects in an auto-updating + file. \n Alpha, gated by the ClusterTrustBundleProjection + feature gate. \n ClusterTrustBundle objects + can either be selected by name, or by the + combination of signer name and a label selector. + \n Kubelet performs aggressive normalization + of the PEM contents written into the pod + filesystem. Esoteric PEM features such + as inter-block comments and block headers + are stripped. Certificates are deduplicated. + The ordering of certificates within the + file is arbitrary, and Kubelet may change + the order over time." + properties: + labelSelector: + description: Select all ClusterTrustBundles + that match this label selector. Only + has effect if signerName is set. Mutually-exclusive + with name. If unset, interpreted as + "match nothing". If set but empty, + interpreted as "match everything". + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a + set of values. Valid operators + are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values + array must be non-empty. If + the operator is Exists or + DoesNotExist, the values array + must be empty. This array + is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map + of {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + name: + description: Select a single ClusterTrustBundle + by object name. Mutually-exclusive + with signerName and labelSelector. + type: string + optional: + description: If true, don't block pod + startup if the referenced ClusterTrustBundle(s) + aren't available. If using name, then + the named ClusterTrustBundle is allowed + not to exist. If using signerName, + then the combination of signerName and + labelSelector is allowed to match zero + ClusterTrustBundles. + type: boolean + path: + description: Relative path from the volume + root to write the bundle. + type: string + signerName: + description: Select all ClusterTrustBundles + that match this signer name. Mutually-exclusive + with name. The contents of all selected + ClusterTrustBundles will be unified + and deduplicated. + type: string + required: + - path + type: object + configMap: + description: configMap information about the + configMap data to project + properties: + items: + description: items if unspecified, each + key-value pair in the Data field of + the referenced ConfigMap will be projected + into the volume as a file whose name + is the key and content is the value. + If specified, the listed keys will be + projected into the specified paths, + and unlisted keys will not be present. + If a key is specified which is not present + in the ConfigMap, the volume setup will + error unless it is marked optional. + Paths must be relative and may not contain + the '..' path or start with '..'. + items: + description: Maps a string key to a + path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: + mode bits used to set permissions + on this file. Must be an octal + value between 0000 and 0777 or + a decimal value between 0 and + 511. YAML accepts both octal and + decimal values, JSON requires + decimal values for mode bits. + If not specified, the volume defaultMode + will be used. This might be in + conflict with other options that + affect the file mode, like fsGroup, + and the result can be other mode + bits set.' + format: int32 + type: integer + path: + description: path is the relative + path of the file to map the key + to. May not be an absolute path. + May not contain the path element + '..'. May not start with the string + '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: optional specify whether + the ConfigMap or its keys must be defined + type: boolean + type: object + downwardAPI: + description: downwardAPI information about + the downwardAPI data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects + a field of the pod: only annotations, + labels, name and namespace are + supported.' + properties: + apiVersion: + description: Version of the + schema the FieldPath is written + in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field + to select in the specified + API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: mode bits + used to set permissions on this + file, must be an octal value between + 0000 and 0777 or a decimal value + between 0 and 511. YAML accepts + both octal and decimal values, + JSON requires decimal values for + mode bits. If not specified, the + volume defaultMode will be used. + This might be in conflict with + other options that affect the + file mode, like fsGroup, and the + result can be other mode bits + set.' + format: int32 + type: integer + path: + description: 'Required: Path is the + relative path name of the file + to be created. Must not be absolute + or contain the ''..'' path. Must + be utf-8 encoded. The first item + of the relative path must not + start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource + of the container: only resources + limits and requests (limits.cpu, + limits.memory, requests.cpu and + requests.memory) are currently + supported.' + properties: + containerName: + description: 'Container name: + required for volumes, optional + for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource + to select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + secret: + description: secret information about the + secret data to project + properties: + items: + description: items if unspecified, each + key-value pair in the Data field of + the referenced Secret will be projected + into the volume as a file whose name + is the key and content is the value. + If specified, the listed keys will be + projected into the specified paths, + and unlisted keys will not be present. + If a key is specified which is not present + in the Secret, the volume setup will + error unless it is marked optional. + Paths must be relative and may not contain + the '..' path or start with '..'. + items: + description: Maps a string key to a + path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: + mode bits used to set permissions + on this file. Must be an octal + value between 0000 and 0777 or + a decimal value between 0 and + 511. YAML accepts both octal and + decimal values, JSON requires + decimal values for mode bits. + If not specified, the volume defaultMode + will be used. This might be in + conflict with other options that + affect the file mode, like fsGroup, + and the result can be other mode + bits set.' + format: int32 + type: integer + path: + description: path is the relative + path of the file to map the key + to. May not be an absolute path. + May not contain the path element + '..'. May not start with the string + '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: optional field specify whether + the Secret or its key must be defined + type: boolean + type: object + serviceAccountToken: + description: serviceAccountToken is information + about the serviceAccountToken data to project + properties: + audience: + description: audience is the intended + audience of the token. A recipient of + a token must identify itself with an + identifier specified in the audience + of the token, and otherwise should reject + the token. The audience defaults to + the identifier of the apiserver. + type: string + expirationSeconds: + description: expirationSeconds is the + requested duration of validity of the + service account token. As the token + approaches expiration, the kubelet volume + plugin will proactively rotate the service + account token. The kubelet will start + trying to rotate the token if the token + is older than 80 percent of its time + to live or if the token is older than + 24 hours.Defaults to 1 hour and must + be at least 10 minutes. + format: int64 + type: integer + path: + description: path is the path relative + to the mount point of the file to project + the token into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: quobyte represents a Quobyte mount on the + host that shares a pod's lifetime + properties: + group: + description: group to map volume access to Default + is no group + type: string + readOnly: + description: readOnly here will force the Quobyte + volume to be mounted with read-only permissions. + Defaults to false. + type: boolean + registry: + description: registry represents a single or multiple + Quobyte Registry services specified as a string + as host:port pair (multiple entries are separated + with commas) which acts as the central registry + for volumes + type: string + tenant: + description: tenant owning the given Quobyte volume + in the Backend Used with dynamically provisioned + Quobyte volumes, value is set by the plugin + type: string + user: + description: user to map volume access to Defaults + to serivceaccount user + type: string + volume: + description: volume is a string that references + an already created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: 'rbd represents a Rados Block Device mount + on the host that shares a pod''s lifetime. More info: + https://examples.k8s.io/volumes/rbd/README.md' + properties: + fsType: + description: 'fsType is the filesystem type of the + volume that you want to mount. Tip: Ensure that + the filesystem type is supported by the host operating + system. Examples: "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. More info: + https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem + from compromising the machine' + type: string + image: + description: 'image is the rados image name. More + info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + keyring: + description: 'keyring is the path to key ring for + RBDUser. Default is /etc/ceph/keyring. More info: + https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + monitors: + description: 'monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + items: + type: string + type: array + pool: + description: 'pool is the rados pool name. Default + is rbd. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + readOnly: + description: 'readOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. More + info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: boolean + secretRef: + description: 'secretRef is name of the authentication + secret for RBDUser. If provided overrides keyring. + Default is nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + user: + description: 'user is the rados user name. Default + is admin. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent + volume attached and mounted on Kubernetes nodes. + properties: + fsType: + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". Default + is "xfs". + type: string + gateway: + description: gateway is the host address of the + ScaleIO API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the + ScaleIO Protection Domain for the configured storage. + type: string + readOnly: + description: readOnly Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. + type: boolean + secretRef: + description: secretRef references to the secret + for ScaleIO user and other sensitive information. + If this is not provided, Login operation will + fail. + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + sslEnabled: + description: sslEnabled Flag enable/disable SSL + communication with Gateway, default false + type: boolean + storageMode: + description: storageMode indicates whether the storage + for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage + Pool associated with the protection domain. + type: string + system: + description: system is the name of the storage system + as configured in ScaleIO. + type: string + volumeName: + description: volumeName is the name of a volume + already created in the ScaleIO system that is + associated with this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: 'secret represents a secret that should + populate this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + properties: + defaultMode: + description: 'defaultMode is Optional: mode bits + used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or + a decimal value between 0 and 511. YAML accepts + both octal and decimal values, JSON requires decimal + values for mode bits. Defaults to 0644. Directories + within the path are not affected by this setting. + This might be in conflict with other options that + affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + items: + description: items If unspecified, each key-value + pair in the Data field of the referenced Secret + will be projected into the volume as a file whose + name is the key and content is the value. If specified, + the listed keys will be projected into the specified + paths, and unlisted keys will not be present. + If a key is specified which is not present in + the Secret, the volume setup will error unless + it is marked optional. Paths must be relative + and may not contain the '..' path or start with + '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits + used to set permissions on this file. Must + be an octal value between 0000 and 0777 + or a decimal value between 0 and 511. YAML + accepts both octal and decimal values, JSON + requires decimal values for mode bits. If + not specified, the volume defaultMode will + be used. This might be in conflict with + other options that affect the file mode, + like fsGroup, and the result can be other + mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of + the file to map the key to. May not be an + absolute path. May not contain the path + element '..'. May not start with the string + '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the + Secret or its keys must be defined + type: boolean + secretName: + description: 'secretName is the name of the secret + in the pod''s namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + type: string + type: object + storageos: + description: storageOS represents a StorageOS volume + attached and mounted on Kubernetes nodes. + properties: + fsType: + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + readOnly: + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. + type: boolean + secretRef: + description: secretRef specifies the secret to use + for obtaining the StorageOS API credentials. If + not specified, default values will be attempted. + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + volumeName: + description: volumeName is the human-readable name + of the StorageOS volume. Volume names are only + unique within a namespace. + type: string + volumeNamespace: + description: volumeNamespace specifies the scope + of the volume within StorageOS. If no namespace + is specified then the Pod's namespace will be + used. This allows the Kubernetes name scoping + to be mirrored within StorageOS for tighter integration. + Set VolumeName to any name to override the default + behaviour. Set to "default" if you are not using + namespaces within StorageOS. Namespaces that do + not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere volume + attached and mounted on kubelets host machine + properties: + fsType: + description: fsType is filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy + Based Management (SPBM) profile ID associated + with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage Policy + Based Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies + vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + type: object + type: object + tolerations: + items: + description: The pod this Toleration is attached to tolerates any + taint that matches the triple using the matching + operator . + properties: + effect: + description: Effect indicates the taint effect to match. Empty + means match all taint effects. When specified, allowed values + are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match all + values and all keys. + type: string + operator: + description: Operator represents a key's relationship to the + value. Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod + can tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of time + the toleration (which must be of effect NoExecute, otherwise + this field is ignored) tolerates the taint. By default, it + is not set, which means tolerate the taint forever (do not + evict). Zero and negative values will be treated as 0 (evict + immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + required: + - kubernetesConfig + type: object + status: + description: RedisStatus defines the observed state of Redis + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} + - name: v1beta2 + schema: + openAPIV3Schema: + description: Redis is the Schema for the redis API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: RedisSpec defines the desired state of Redis + properties: + TLS: + description: TLS Configuration for redis instances + properties: + ca: + type: string + cert: + type: string + key: + type: string + secret: + description: Reference to secret which contains the certificates + properties: + defaultMode: + description: 'defaultMode is Optional: mode bits used to set + permissions on created files by default. Must be an octal + value between 0000 and 0777 or a decimal value between 0 + and 511. YAML accepts both octal and decimal values, JSON + requires decimal values for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect + the file mode, like fsGroup, and the result can be other + mode bits set.' + format: int32 + type: integer + items: + description: items If unspecified, each key-value pair in + the Data field of the referenced Secret will be projected + into the volume as a file whose name is the key and content + is the value. If specified, the listed keys will be projected + into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the + Secret, the volume setup will error unless it is marked + optional. Paths must be relative and may not contain the + '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used to set + permissions on this file. Must be an octal value between + 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires + decimal values for mode bits. If not specified, the + volume defaultMode will be used. This might be in + conflict with other options that affect the file mode, + like fsGroup, and the result can be other mode bits + set.' + format: int32 + type: integer + path: + description: path is the relative path of the file to + map the key to. May not be an absolute path. May not + contain the path element '..'. May not start with + the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the Secret or + its keys must be defined + type: boolean + secretName: + description: 'secretName is the name of the secret in the + pod''s namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + type: string + type: object + required: + - secret + type: object + acl: + properties: + secret: + description: "Adapts a Secret into a volume. \n The contents of + the target Secret's Data field will be presented in a volume + as files using the keys in the Data field as the file names. + Secret volumes support ownership management and SELinux relabeling." + properties: + defaultMode: + description: 'defaultMode is Optional: mode bits used to set + permissions on created files by default. Must be an octal + value between 0000 and 0777 or a decimal value between 0 + and 511. YAML accepts both octal and decimal values, JSON + requires decimal values for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect + the file mode, like fsGroup, and the result can be other + mode bits set.' + format: int32 + type: integer + items: + description: items If unspecified, each key-value pair in + the Data field of the referenced Secret will be projected + into the volume as a file whose name is the key and content + is the value. If specified, the listed keys will be projected + into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the + Secret, the volume setup will error unless it is marked + optional. Paths must be relative and may not contain the + '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used to set + permissions on this file. Must be an octal value between + 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires + decimal values for mode bits. If not specified, the + volume defaultMode will be used. This might be in + conflict with other options that affect the file mode, + like fsGroup, and the result can be other mode bits + set.' + format: int32 + type: integer + path: + description: path is the relative path of the file to + map the key to. May not be an absolute path. May not + contain the path element '..'. May not start with + the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the Secret or + its keys must be defined + type: boolean + secretName: + description: 'secretName is the name of the secret in the + pod''s namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + type: string + type: object + type: object + affinity: + description: Affinity is a group of affinity scheduling rules. + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for the + pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the affinity expressions specified by + this field, but it may choose a node that violates one or + more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node matches + the corresponding matchExpressions; the node(s) with the + highest sum are the most preferred. + items: + description: An empty preferred scheduling term matches + all objects with implicit weight 0 (i.e. it's a no-op). + A null preferred scheduling term matches no objects (i.e. + is also a no-op). + properties: + preference: + description: A node selector term, associated with the + corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + description: Weight associated with matching the corresponding + nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this + field are not met at scheduling time, the pod will not be + scheduled onto the node. If the affinity requirements specified + by this field cease to be met at some point during pod execution + (e.g. due to an update), the system may or may not try to + eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: A null or empty node selector term matches + no objects. The requirements of them are ANDed. The + TopologySelectorTerm type implements a subset of the + NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. co-locate + this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the affinity expressions specified by + this field, but it may choose a node that violates one or + more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node has + pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key in (value)` to select + the group of existing pods which pods will be + taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MatchLabelKeys and LabelSelector. Also, + MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key notin (value)` to + select the group of existing pods which pods will + be taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MismatchLabelKeys and LabelSelector. Also, + MismatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding + podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this + field are not met at scheduling time, the pod will not be + scheduled onto the node. If the affinity requirements specified + by this field cease to be met at some point during pod execution + (e.g. due to a pod label update), the system may or may + not try to eventually evict the pod from its node. When + there are multiple elements, the lists of nodes corresponding + to each podAffinityTerm are intersected, i.e. all terms + must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not co-located + (anti-affinity) with, where co-located is defined as running + on a node whose value of the label with key + matches that of any node on which a pod of the set of + pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod label keys + to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged with + `LabelSelector` as `key in (value)` to select the + group of existing pods which pods will be taken into + consideration for the incoming pod's pod (anti) affinity. + Keys that don't exist in the incoming pod labels will + be ignored. The default value is empty. The same key + is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires enabling + MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged with + `LabelSelector` as `key notin (value)` to select the + group of existing pods which pods will be taken into + consideration for the incoming pod's pod (anti) affinity. + Keys that don't exist in the incoming pod labels will + be ignored. The default value is empty. The same key + is forbidden to exist in both MismatchLabelKeys and + LabelSelector. Also, MismatchLabelKeys cannot be set + when LabelSelector isn't set. This is an alpha field + and requires enabling MatchLabelKeysInPodAffinity + feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied to the + union of the namespaces selected by this field and + the ones listed in the namespaces field. null selector + and null or empty namespaces list means "this pod's + namespace". An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace + names that the term applies to. The term is applied + to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. null or + empty namespaces list and null namespaceSelector means + "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where + co-located is defined as running on a node whose value + of the label with key topologyKey matches that of + any node on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules (e.g. + avoid putting this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the anti-affinity expressions specified + by this field, but it may choose a node that violates one + or more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node has + pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key in (value)` to select + the group of existing pods which pods will be + taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MatchLabelKeys and LabelSelector. Also, + MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key notin (value)` to + select the group of existing pods which pods will + be taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MismatchLabelKeys and LabelSelector. Also, + MismatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding + podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the anti-affinity requirements + specified by this field cease to be met at some point during + pod execution (e.g. due to a pod label update), the system + may or may not try to eventually evict the pod from its + node. When there are multiple elements, the lists of nodes + corresponding to each podAffinityTerm are intersected, i.e. + all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not co-located + (anti-affinity) with, where co-located is defined as running + on a node whose value of the label with key + matches that of any node on which a pod of the set of + pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod label keys + to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged with + `LabelSelector` as `key in (value)` to select the + group of existing pods which pods will be taken into + consideration for the incoming pod's pod (anti) affinity. + Keys that don't exist in the incoming pod labels will + be ignored. The default value is empty. The same key + is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires enabling + MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged with + `LabelSelector` as `key notin (value)` to select the + group of existing pods which pods will be taken into + consideration for the incoming pod's pod (anti) affinity. + Keys that don't exist in the incoming pod labels will + be ignored. The default value is empty. The same key + is forbidden to exist in both MismatchLabelKeys and + LabelSelector. Also, MismatchLabelKeys cannot be set + when LabelSelector isn't set. This is an alpha field + and requires enabling MatchLabelKeysInPodAffinity + feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied to the + union of the namespaces selected by this field and + the ones listed in the namespaces field. null selector + and null or empty namespaces list means "this pod's + namespace". An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace + names that the term applies to. The term is applied + to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. null or + empty namespaces list and null namespaceSelector means + "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where + co-located is defined as running on a node whose value + of the label with key topologyKey matches that of + any node on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + env: + items: + description: EnvVar represents an environment variable present in + a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded using + the previously defined environment variables in the container + and any service environment variables. If a variable cannot + be resolved, the reference in the input string will be unchanged. + Double $$ are reduced to a single $, which allows for escaping + the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the + string literal "$(VAR_NAME)". Escaped references will never + be expanded, regardless of whether the variable exists or + not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. Cannot + be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, `metadata.annotations['''']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, + status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath is + written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified + API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed + resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + initContainer: + description: InitContainer for each Redis pods + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + enabled: + type: boolean + env: + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + image: + type: string + imagePullPolicy: + description: PullPolicy describes a policy for if/when to pull + a container image + type: string + resources: + description: ResourceRequirements describes the compute resource + requirements. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: SecurityContext holds security configuration that + will be applied to a container. Some fields are present in both + SecurityContext and PodSecurityContext. When both are set, + the values in SecurityContext take precedence. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a + process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the + container runtime. Note that this field cannot be set when + spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in + privileged containers are essentially equivalent to root + on the host. Defaults to false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use + for the containers. The default is DefaultProcMount which + uses the container runtime defaults for readonly paths and + masked paths. This requires the ProcMountType feature flag + to be enabled. Note that this field cannot be set when spec.os.name + is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when + spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail + to start the container if it does. If unset or false, no + such validation will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata if + unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. Note + that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must + be preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must be set if type is "Localhost". Must NOT + be set for any other type. + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a + profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile + should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also be + set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + required: + - image + type: object + kubernetesConfig: + description: KubernetesConfig will be the JSON struct for Basic Redis + Config + properties: + ignoreAnnotations: + items: + type: string + type: array + image: + type: string + imagePullPolicy: + description: PullPolicy describes a policy for if/when to pull + a container image + type: string + imagePullSecrets: + items: + description: LocalObjectReference contains enough information + to let you locate the referenced object inside the same namespace. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + type: array + redisSecret: + description: ExistingPasswordSecret is the struct to access the + existing secret + properties: + key: + type: string + name: + type: string + type: object + resources: + description: ResourceRequirements describes the compute resource + requirements. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + service: + description: ServiceConfig define the type of service to be created + and its annotations + properties: + annotations: + additionalProperties: + type: string + type: object + serviceType: + enum: + - LoadBalancer + - NodePort + - ClusterIP + type: string + type: object + updateStrategy: + description: StatefulSetUpdateStrategy indicates the strategy + that the StatefulSet controller will use to perform updates. + It includes any additional parameters necessary to perform the + update for the indicated strategy. + properties: + rollingUpdate: + description: RollingUpdate is used to communicate parameters + when Type is RollingUpdateStatefulSetStrategyType. + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + description: 'The maximum number of pods that can be unavailable + during the update. Value can be an absolute number (ex: + 5) or a percentage of desired pods (ex: 10%). Absolute + number is calculated from percentage by rounding up. + This can not be 0. Defaults to 1. This field is alpha-level + and is only honored by servers that enable the MaxUnavailableStatefulSet + feature. The field applies to all pods in the range + 0 to Replicas-1. That means if there is any unavailable + pod in the range 0 to Replicas-1, it will be counted + towards MaxUnavailable.' + x-kubernetes-int-or-string: true + partition: + description: Partition indicates the ordinal at which + the StatefulSet should be partitioned for updates. During + a rolling update, all pods from ordinal Replicas-1 to + Partition are updated. All pods from ordinal Partition-1 + to 0 remain untouched. This is helpful in being able + to do a canary based deployment. The default value is + 0. + format: int32 + type: integer + type: object + type: + description: Type indicates the type of the StatefulSetUpdateStrategy. + Default is RollingUpdate. + type: string + type: object + required: + - image + type: object + livenessProbe: + description: Probe describes a health check to be performed against + a container to determine whether it is alive or ready to receive + traffic. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside + the container, the working directory for the command is + root ('/') in the container's filesystem. The command is + simply exec'd, it is not run inside a shell, so traditional + shell instructions ('|', etc) won't work. To use a shell, + you need to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be + considered failed after having succeeded. Defaults to 3. Minimum + value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. + properties: + port: + description: Port number of the gRPC service. Number must + be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place + in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior is defined + by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod + IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows + repeated headers. + items: + description: HTTPHeader describes a custom header to be + used in HTTP probes + properties: + name: + description: The header field name. This will be canonicalized + upon output, so case-variant names will be understood + as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. + Number must be in the range 1 to 65535. Name must be an + IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults + to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started + before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default + to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be + considered successful after having failed. Defaults to 1. Must + be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults + to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. + Number must be in the range 1 to 65535. Name must be an + IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate + gracefully upon probe failure. The grace period is the duration + in seconds after the processes running in the pod are sent a + termination signal and the time when the processes are forcibly + halted with a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, the pod's + terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. Value must + be non-negative integer. The value zero indicates stop immediately + via the kill signal (no opportunity to shut down). This is a + beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + nodeSelector: + additionalProperties: + type: string + type: object + podSecurityContext: + description: PodSecurityContext holds pod-level security attributes + and common container settings. Some fields are also present in container.securityContext. Field + values of container.securityContext take precedence over field values + of PodSecurityContext. + properties: + fsGroup: + description: "A special supplemental group that applies to all + containers in a pod. Some volume types allow the Kubelet to + change the ownership of that volume to be owned by the pod: + \n 1. The owning GID will be the FSGroup 2. The setgid bit is + set (new files created in the volume will be owned by FSGroup) + 3. The permission bits are OR'd with rw-rw---- \n If unset, + the Kubelet will not modify the ownership and permissions of + any volume. Note that this field cannot be set when spec.os.name + is windows." + format: int64 + type: integer + fsGroupChangePolicy: + description: 'fsGroupChangePolicy defines behavior of changing + ownership and permission of the volume before being exposed + inside Pod. This field will only apply to volume types which + support fsGroup based ownership(and permissions). It will have + no effect on ephemeral volume types such as: secret, configmaps + and emptydir. Valid values are "OnRootMismatch" and "Always". + If not specified, "Always" is used. Note that this field cannot + be set when spec.os.name is windows.' + type: string + runAsGroup: + description: The GID to run the entrypoint of the container process. + Uses runtime default if unset. May also be set in SecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail to start + the container if it does. If unset or false, no such validation + will be performed. May also be set in SecurityContext. If set + in both SecurityContext and PodSecurityContext, the value specified + in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in SecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. Note that this field cannot + be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in SecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to + the container. + type: string + role: + description: Role is a SELinux role label that applies to + the container. + type: string + type: + description: Type is a SELinux type label that applies to + the container. + type: string + user: + description: User is a SELinux user label that applies to + the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by the containers in this + pod. Note that this field cannot be set when spec.os.name is + windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must be + preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must be set if type is "Localhost". Must NOT be + set for any other type. + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a profile + defined in a file on the node should be used. RuntimeDefault + - the container runtime default profile should be used. + Unconfined - no profile should be applied." + type: string + required: + - type + type: object + supplementalGroups: + description: A list of groups applied to the first process run + in each container, in addition to the container's primary GID, + the fsGroup (if specified), and group memberships defined in + the container image for the uid of the container process. If + unspecified, no additional groups are added to any container. + Note that group memberships defined in the container image for + the uid of the container process are still effective, even if + they are not included in this list. Note that this field cannot + be set when spec.os.name is windows. + items: + format: int64 + type: integer + type: array + sysctls: + description: Sysctls hold a list of namespaced sysctls used for + the pod. Pods with unsupported sysctls (by the container runtime) + might fail to launch. Note that this field cannot be set when + spec.os.name is windows. + items: + description: Sysctl defines a kernel parameter to be set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + description: The Windows specific settings applied to all containers. + If unspecified, the options within a container's SecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named by + the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA + credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. All of a Pod's containers + must have the same effective HostProcess value (it is not + allowed to have a mix of HostProcess containers and non-HostProcess + containers). In addition, if HostProcess is true then HostNetwork + must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in PodSecurityContext. + If set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: string + type: object + type: object + priorityClassName: + type: string + readinessProbe: + description: Probe describes a health check to be performed against + a container to determine whether it is alive or ready to receive + traffic. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside + the container, the working directory for the command is + root ('/') in the container's filesystem. The command is + simply exec'd, it is not run inside a shell, so traditional + shell instructions ('|', etc) won't work. To use a shell, + you need to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be + considered failed after having succeeded. Defaults to 3. Minimum + value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. + properties: + port: + description: Port number of the gRPC service. Number must + be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place + in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior is defined + by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod + IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows + repeated headers. + items: + description: HTTPHeader describes a custom header to be + used in HTTP probes + properties: + name: + description: The header field name. This will be canonicalized + upon output, so case-variant names will be understood + as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. + Number must be in the range 1 to 65535. Name must be an + IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults + to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started + before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default + to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be + considered successful after having failed. Defaults to 1. Must + be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults + to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. + Number must be in the range 1 to 65535. Name must be an + IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate + gracefully upon probe failure. The grace period is the duration + in seconds after the processes running in the pod are sent a + termination signal and the time when the processes are forcibly + halted with a kill signal. Set this value longer than the expected + cleanup time for your process. If this value is nil, the pod's + terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. Value must + be non-negative integer. The value zero indicates stop immediately + via the kill signal (no opportunity to shut down). This is a + beta field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + redisConfig: + description: RedisConfig defines the external configuration of Redis + properties: + additionalRedisConfig: + type: string + type: object + redisExporter: + description: RedisExporter interface will have the information for + redis exporter related stuff + properties: + enabled: + type: boolean + env: + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + image: + type: string + imagePullPolicy: + description: PullPolicy describes a policy for if/when to pull + a container image + type: string + port: + default: 9121 + type: integer + resources: + description: ResourceRequirements describes the compute resource + requirements. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: SecurityContext holds security configuration that + will be applied to a container. Some fields are present in both + SecurityContext and PodSecurityContext. When both are set, + the values in SecurityContext take precedence. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a + process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the + container runtime. Note that this field cannot be set when + spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in + privileged containers are essentially equivalent to root + on the host. Defaults to false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use + for the containers. The default is DefaultProcMount which + uses the container runtime defaults for readonly paths and + masked paths. This requires the ProcMountType feature flag + to be enabled. Note that this field cannot be set when spec.os.name + is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when + spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail + to start the container if it does. If unset or false, no + such validation will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata if + unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. Note + that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must + be preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must be set if type is "Localhost". Must NOT + be set for any other type. + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a + profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile + should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also be + set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in + PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + required: + - image + type: object + securityContext: + description: SecurityContext holds security configuration that will + be applied to a container. Some fields are present in both SecurityContext + and PodSecurityContext. When both are set, the values in SecurityContext + take precedence. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a process + can gain more privileges than its parent process. This bool + directly controls if the no_new_privs flag will be set on the + container process. AllowPrivilegeEscalation is true always when + the container is: 1) run as Privileged 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container + runtime. Note that this field cannot be set when spec.os.name + is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in privileged + containers are essentially equivalent to root on the host. Defaults + to false. Note that this field cannot be set when spec.os.name + is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use for + the containers. The default is DefaultProcMount which uses the + container runtime defaults for readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when spec.os.name + is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container process. + Uses runtime default if unset. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence. Note that this + field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail to start + the container if it does. If unset or false, no such validation + will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when spec.os.name + is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence. Note that this + field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to + the container. + type: string + role: + description: Role is a SELinux role label that applies to + the container. + type: string + type: + description: Type is a SELinux type label that applies to + the container. + type: string + user: + description: User is a SELinux user label that applies to + the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. If + seccomp options are provided at both the pod & container level, + the container options override the pod options. Note that this + field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must be + preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must be set if type is "Localhost". Must NOT be + set for any other type. + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a profile + defined in a file on the node should be used. RuntimeDefault + - the container runtime default profile should be used. + Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will + be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named by + the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA + credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. All of a Pod's containers + must have the same effective HostProcess value (it is not + allowed to have a mix of HostProcess containers and non-HostProcess + containers). In addition, if HostProcess is true then HostNetwork + must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in PodSecurityContext. + If set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: string + type: object + type: object + serviceAccountName: + type: string + sidecars: + items: + description: Sidecar for each Redis pods + properties: + command: + items: + type: string + type: array + env: + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be + a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. + If a variable cannot be resolved, the reference in the + input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) + syntax: i.e. "$$(VAR_NAME)" will produce the string + literal "$(VAR_NAME)". Escaped references will never + be expanded, regardless of whether the variable exists + or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its + key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + image: + type: string + imagePullPolicy: + description: PullPolicy describes a policy for if/when to pull + a container image + type: string + mountPath: + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: Path within the container at which the volume + should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are + propagated from the host to container and the other + way around. When not set, MountPropagationNone is used. + This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise + (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's + volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which + the container's volume should be mounted. Behaves similarly + to SubPath but environment variable references $(VAR_NAME) + are expanded using the container's environment. Defaults + to "" (volume's root). SubPathExpr and SubPath are mutually + exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + name: + type: string + ports: + items: + description: ContainerPort represents a network port in a + single container. + properties: + containerPort: + description: Number of port to expose on the pod's IP + address. This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port to. + type: string + hostPort: + description: Number of port to expose on the host. If + specified, this must be a valid port number, 0 < x < + 65536. If HostNetwork is specified, this must match + ContainerPort. Most containers do not need this. + format: int32 + type: integer + name: + description: If specified, this must be an IANA_SVC_NAME + and unique within the pod. Each named port in a pod + must have a unique name. Name for the port that can + be referred to by services. + type: string + protocol: + default: TCP + description: Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + resources: + description: ResourceRequirements describes the compute resource + requirements. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only + be set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where this + field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests + cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: SecurityContext holds security configuration that + will be applied to a container. Some fields are present in + both SecurityContext and PodSecurityContext. When both are + set, the values in SecurityContext take precedence. + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether + a process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by + the container runtime. Note that this field cannot be + set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes + in privileged containers are essentially equivalent to + root on the host. Defaults to false. Note that this field + cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to + use for the containers. The default is DefaultProcMount + which uses the container runtime defaults for readonly + paths and masked paths. This requires the ProcMountType + feature flag to be enabled. Note that this field cannot + be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root + filesystem. Default is false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a + non-root user. If true, the Kubelet will validate the + image at runtime to ensure that it does not run as UID + 0 (root) and fail to start the container if it does. If + unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both + SecurityContext and PodSecurityContext, the value specified + in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata + if unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a + random SELinux context for each container. May also be + set in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. + Note that this field cannot be set when spec.os.name is + windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile + must be preconfigured on the node to work. Must be + a descending path, relative to the kubelet's configured + seccomp profile location. Must be set if type is "Localhost". + Must NOT be set for any other type. + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - + a profile defined in a file on the node should be + used. RuntimeDefault - the container runtime default + profile should be used. Unconfined - no profile should + be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also + be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set + in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + required: + - image + - name + type: object + type: array + storage: + description: Storage is the inteface to add pvc and pv support in + redis + properties: + keepAfterDelete: + type: boolean + volumeClaimTemplate: + description: PersistentVolumeClaim is a user's request for and + claim to a persistent volume + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this + representation of an object. Servers should convert recognized + schemas to the latest internal value, and may reject unrecognized + values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST + resource this object represents. Servers may infer this + from the endpoint the client submits requests to. Cannot + be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + description: 'Standard object''s metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata' + type: object + spec: + description: 'spec defines the desired characteristics of + a volume requested by a pod author. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + accessModes: + description: 'accessModes contains the desired access + modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'dataSource field can be used to specify + either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) If the provisioner + or an external controller can support the specified + data source, it will create a new volume based on the + contents of the specified data source. When the AnyVolumeDataSource + feature gate is enabled, dataSource contents will be + copied to dataSourceRef, and dataSourceRef contents + will be copied to dataSource when dataSourceRef.namespace + is not specified. If the namespace is specified, then + dataSourceRef will not be copied to dataSource.' + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + dataSourceRef: + description: 'dataSourceRef specifies the object from + which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty + API group (non core object) or a PersistentVolumeClaim + object. When this field is specified, volume binding + will only succeed if the type of the specified object + matches some installed volume populator or dynamic provisioner. + This field will replace the functionality of the dataSource + field and as such if both fields are non-empty, they + must have the same value. For backwards compatibility, + when namespace isn''t specified in dataSourceRef, both + fields (dataSource and dataSourceRef) will be set to + the same value automatically if one of them is empty + and the other is non-empty. When namespace is specified + in dataSourceRef, dataSource isn''t set to the same + value and must be empty. There are three important differences + between dataSource and dataSourceRef: * While dataSource + only allows two specific types of objects, dataSourceRef allows + any non-core object, as well as PersistentVolumeClaim + objects. * While dataSource ignores disallowed values + (dropping them), dataSourceRef preserves all values, + and generates an error if a disallowed value is specified. + * While dataSource only allows local objects, dataSourceRef + allows objects in any namespaces. (Beta) Using this + field requires the AnyVolumeDataSource feature gate + to be enabled. (Alpha) Using the namespace field of + dataSourceRef requires the CrossNamespaceVolumeDataSource + feature gate to be enabled.' + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + namespace: + description: Namespace is the namespace of resource + being referenced Note that when a namespace is specified, + a gateway.networking.k8s.io/ReferenceGrant object + is required in the referent namespace to allow that + namespace's owner to accept the reference. See the + ReferenceGrant documentation for details. (Alpha) + This field requires the CrossNamespaceVolumeDataSource + feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: 'resources represents the minimum resources + the volume should have. If RecoverVolumeExpansionFailure + feature is enabled users are allowed to specify resource + requirements that are lower than previous value but + must still be higher than capacity recorded in the status + field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount + of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount + of compute resources required. If Requests is omitted + for a container, it defaults to Limits if that is + explicitly specified, otherwise to an implementation-defined + value. Requests cannot exceed Limits. More info: + https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + selector: + description: selector is a label query over volumes to + consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, + NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values + array must be non-empty. If the operator is + Exists or DoesNotExist, the values array must + be empty. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field + is "key", the operator is "In", and the values array + contains only "value". The requirements are ANDed. + type: object + type: object + storageClassName: + description: 'storageClassName is the name of the StorageClass + required by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + type: string + volumeAttributesClassName: + description: 'volumeAttributesClassName may be used to + set the VolumeAttributesClass used by this claim. If + specified, the CSI driver will create or update the + volume with the attributes defined in the corresponding + VolumeAttributesClass. This has a different purpose + than storageClassName, it can be changed after the claim + is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it''s not allowed to + reset this field to empty string once it is set. If + unspecified and the PersistentVolumeClaim is unbound, + the default VolumeAttributesClass will be set by the + persistentvolume controller if it exists. If the resource + referred to by volumeAttributesClass does not exist, + this PersistentVolumeClaim will be set to a Pending + state, as reflected by the modifyVolumeStatus field, + until such as a resource exists. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + (Alpha) Using this field requires the VolumeAttributesClass + feature gate to be enabled.' + type: string + volumeMode: + description: volumeMode defines what type of volume is + required by the claim. Value of Filesystem is implied + when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to the + PersistentVolume backing this claim. + type: string + type: object + status: + description: 'status represents the current information/status + of a persistent volume claim. Read-only. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + accessModes: + description: 'accessModes contains the actual access modes + the volume backing the PVC has. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + allocatedResourceStatuses: + additionalProperties: + description: When a controller receives persistentvolume + claim update with ClaimResourceStatus for a resource + that it does not recognizes, then it should ignore + that update and let other controllers handle it. + type: string + description: "allocatedResourceStatuses stores status + of resource being resized for the given PVC. Key names + follow standard Kubernetes label syntax. Valid values + are either: \t* Un-prefixed keys: \t\t- storage - the + capacity of the volume. \t* Custom resources must use + implementation-defined prefixed names such as \"example.com/my-custom-resource\" + Apart from above values - keys that are unprefixed or + have kubernetes.io prefix are considered reserved and + hence may not be used. \n ClaimResourceStatus can be + in any of following states: \t- ControllerResizeInProgress: + \t\tState set when resize controller starts resizing + the volume in control-plane. \t- ControllerResizeFailed: + \t\tState set when resize has failed in resize controller + with a terminal error. \t- NodeResizePending: \t\tState + set when resize controller has finished resizing the + volume but further resizing of \t\tvolume is needed + on the node. \t- NodeResizeInProgress: \t\tState set + when kubelet starts resizing the volume. \t- NodeResizeFailed: + \t\tState set when resizing has failed in kubelet with + a terminal error. Transient errors don't set \t\tNodeResizeFailed. + For example: if expanding a PVC for more capacity - + this field can be one of the following states: \t- pvc.status.allocatedResourceStatus['storage'] + = \"ControllerResizeInProgress\" - pvc.status.allocatedResourceStatus['storage'] + = \"ControllerResizeFailed\" - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizePending\" - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizeInProgress\" - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizeFailed\" When this field is not set, it + means that no resize operation is in progress for the + given PVC. \n A controller that receives PVC update + with previously unknown resourceName or ClaimResourceStatus + should ignore the update for the purpose it was designed. + For example - a controller that only is responsible + for resizing capacity of the volume, should ignore PVC + updates that change other valid resources associated + with PVC. \n This is an alpha field and requires enabling + RecoverVolumeExpansionFailure feature." + type: object + x-kubernetes-map-type: granular + allocatedResources: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: "allocatedResources tracks the resources + allocated to a PVC including its capacity. Key names + follow standard Kubernetes label syntax. Valid values + are either: \t* Un-prefixed keys: \t\t- storage - the + capacity of the volume. \t* Custom resources must use + implementation-defined prefixed names such as \"example.com/my-custom-resource\" + Apart from above values - keys that are unprefixed or + have kubernetes.io prefix are considered reserved and + hence may not be used. \n Capacity reported here may + be larger than the actual capacity when a volume expansion + operation is requested. For storage quota, the larger + value from allocatedResources and PVC.spec.resources + is used. If allocatedResources is not set, PVC.spec.resources + alone is used for quota calculation. If a volume expansion + capacity request is lowered, allocatedResources is only + lowered if there are no expansion operations in progress + and if the actual volume capacity is equal or lower + than the requested capacity. \n A controller that receives + PVC update with previously unknown resourceName should + ignore the update for the purpose it was designed. For + example - a controller that only is responsible for + resizing capacity of the volume, should ignore PVC updates + that change other valid resources associated with PVC. + \n This is an alpha field and requires enabling RecoverVolumeExpansionFailure + feature." + type: object + capacity: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: capacity represents the actual resources + of the underlying volume. + type: object + conditions: + description: conditions is the current Condition of persistent + volume claim. If underlying persistent volume is being + resized then the Condition will be set to 'ResizeStarted'. + items: + description: PersistentVolumeClaimCondition contains + details about state of pvc + properties: + lastProbeTime: + description: lastProbeTime is the time we probed + the condition. + format: date-time + type: string + lastTransitionTime: + description: lastTransitionTime is the time the + condition transitioned from one status to another. + format: date-time + type: string + message: + description: message is the human-readable message + indicating details about last transition. + type: string + reason: + description: reason is a unique, this should be + a short, machine understandable string that gives + the reason for condition's last transition. If + it reports "ResizeStarted" that means the underlying + persistent volume is being resized. + type: string + status: + type: string + type: + description: PersistentVolumeClaimConditionType + is a valid value of PersistentVolumeClaimCondition.Type + type: string + required: + - status + - type + type: object + type: array + currentVolumeAttributesClassName: + description: currentVolumeAttributesClassName is the current + name of the VolumeAttributesClass the PVC is using. + When unset, there is no VolumeAttributeClass applied + to this PersistentVolumeClaim This is an alpha field + and requires enabling VolumeAttributesClass feature. + type: string + modifyVolumeStatus: + description: ModifyVolumeStatus represents the status + object of ControllerModifyVolume operation. When this + is unset, there is no ModifyVolume operation being attempted. + This is an alpha field and requires enabling VolumeAttributesClass + feature. + properties: + status: + description: "status is the status of the ControllerModifyVolume + operation. It can be in any of following states: + \ - Pending Pending indicates that the PersistentVolumeClaim + cannot be modified due to unmet requirements, such + as the specified VolumeAttributesClass not existing. + \ - InProgress InProgress indicates that the + volume is being modified. - Infeasible Infeasible + indicates that the request has been rejected as + invalid by the CSI driver. To \t resolve the error, + a valid VolumeAttributesClass needs to be specified. + Note: New statuses can be added in the future. Consumers + should check for unknown statuses and fail appropriately." + type: string + targetVolumeAttributesClassName: + description: targetVolumeAttributesClassName is the + name of the VolumeAttributesClass the PVC currently + being reconciled + type: string + required: + - status + type: object + phase: + description: phase represents the current phase of PersistentVolumeClaim. + type: string + type: object + type: object + volumeMount: + description: Additional Volume is provided by user that is mounted + on the pods + properties: + mountPath: + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: Path within the container at which the + volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts + are propagated from the host to container and the + other way around. When not set, MountPropagationNone + is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise + (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's + volume should be mounted. Defaults to "" (volume's + root). + type: string + subPathExpr: + description: Expanded path within the volume from which + the container's volume should be mounted. Behaves + similarly to SubPath but environment variable references + $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). SubPathExpr and SubPath + are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + volume: + items: + description: Volume represents a named volume in a pod that + may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: 'awsElasticBlockStore represents an AWS + Disk resource that is attached to a kubelet''s host + machine and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + properties: + fsType: + description: 'fsType is the filesystem type of the + volume that you want to mount. Tip: Ensure that + the filesystem type is supported by the host operating + system. Examples: "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. More info: + https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem + from compromising the machine' + type: string + partition: + description: 'partition is the partition in the + volume that you want to mount. If omitted, the + default is to mount by volume name. Examples: + For volume /dev/sda1, you specify the partition + as "1". Similarly, the volume partition for /dev/sda + is "0" (or you can leave the property empty).' + format: int32 + type: integer + readOnly: + description: 'readOnly value true will force the + readOnly setting in VolumeMounts. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: boolean + volumeID: + description: 'volumeID is unique ID of the persistent + disk resource in AWS (Amazon EBS volume). More + info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data Disk + mount on the host and bind mount to the pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching mode: + None, Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data disk + in the blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in + the blob storage + type: string + fsType: + description: fsType is Filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: multiple + blob disks per storage account Dedicated: single + blob disk per storage account Managed: azure + managed data disk (only in managed availability + set). defaults to shared' + type: string + readOnly: + description: readOnly Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File Service + mount on the host and bind mount to the pod. + properties: + readOnly: + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret that + contains Azure Storage Account Name and Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount on the + host that shares a pod's lifetime + properties: + monitors: + description: 'monitors is Required: Monitors is + a collection of Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + items: + type: string + type: array + path: + description: 'path is Optional: Used as the mounted + root, rather than the full Ceph tree, default + is /' + type: string + readOnly: + description: 'readOnly is Optional: Defaults to + false (read/write). ReadOnly here will force the + ReadOnly setting in VolumeMounts. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: boolean + secretFile: + description: 'secretFile is Optional: SecretFile + is the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + secretRef: + description: 'secretRef is Optional: SecretRef is + reference to the authentication secret for User, + default is empty. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + user: + description: 'user is optional: User is the rados + user name, default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + required: + - monitors + type: object + cinder: + description: 'cinder represents a cinder volume attached + and mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + properties: + fsType: + description: 'fsType is the filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Examples: "ext4", "xfs", "ntfs". + Implicitly inferred to be "ext4" if unspecified. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + readOnly: + description: 'readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: boolean + secretRef: + description: 'secretRef is optional: points to a + secret object containing parameters used to connect + to OpenStack.' + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + volumeID: + description: 'volumeID used to identify the volume + in cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that should + populate this volume + properties: + defaultMode: + description: 'defaultMode is optional: mode bits + used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or + a decimal value between 0 and 511. YAML accepts + both octal and decimal values, JSON requires decimal + values for mode bits. Defaults to 0644. Directories + within the path are not affected by this setting. + This might be in conflict with other options that + affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + items: + description: items if unspecified, each key-value + pair in the Data field of the referenced ConfigMap + will be projected into the volume as a file whose + name is the key and content is the value. If specified, + the listed keys will be projected into the specified + paths, and unlisted keys will not be present. + If a key is specified which is not present in + the ConfigMap, the volume setup will error unless + it is marked optional. Paths must be relative + and may not contain the '..' path or start with + '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits + used to set permissions on this file. Must + be an octal value between 0000 and 0777 + or a decimal value between 0 and 511. YAML + accepts both octal and decimal values, JSON + requires decimal values for mode bits. If + not specified, the volume defaultMode will + be used. This might be in conflict with + other options that affect the file mode, + like fsGroup, and the result can be other + mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of + the file to map the key to. May not be an + absolute path. May not contain the path + element '..'. May not start with the string + '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + csi: + description: csi (Container Storage Interface) represents + ephemeral storage that is handled by certain external + CSI drivers (Beta feature). + properties: + driver: + description: driver is the name of the CSI driver + that handles this volume. Consult with your admin + for the correct name as registered in the cluster. + type: string + fsType: + description: fsType to mount. Ex. "ext4", "xfs", + "ntfs". If not provided, the empty value is passed + to the associated CSI driver which will determine + the default filesystem to apply. + type: string + nodePublishSecretRef: + description: nodePublishSecretRef is a reference + to the secret object containing sensitive information + to pass to the CSI driver to complete the CSI + NodePublishVolume and NodeUnpublishVolume calls. + This field is optional, and may be empty if no + secret is required. If the secret object contains + more than one secret, all secret references are + passed. + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + readOnly: + description: readOnly specifies a read-only configuration + for the volume. Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: volumeAttributes stores driver-specific + properties that are passed to the CSI driver. + Consult your driver's documentation for supported + values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about + the pod that should populate this volume + properties: + defaultMode: + description: 'Optional: mode bits to use on created + files by default. Must be a Optional: mode bits + used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or + a decimal value between 0 and 511. YAML accepts + both octal and decimal values, JSON requires decimal + values for mode bits. Defaults to 0644. Directories + within the path are not affected by this setting. + This might be in conflict with other options that + affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + items: + description: Items is a list of downward API volume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing the + pod field + properties: + fieldRef: + description: 'Required: Selects a field of + the pod: only annotations, labels, name + and namespace are supported.' + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, defaults + to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: mode bits used to + set permissions on this file, must be an + octal value between 0000 and 0777 or a decimal + value between 0 and 511. YAML accepts both + octal and decimal values, JSON requires + decimal values for mode bits. If not specified, + the volume defaultMode will be used. This + might be in conflict with other options + that affect the file mode, like fsGroup, + and the result can be other mode bits set.' + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. Must + not be absolute or contain the ''..'' path. + Must be utf-8 encoded. The first item of + the relative path must not start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, requests.cpu and requests.memory) + are currently supported.' + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + emptyDir: + description: 'emptyDir represents a temporary directory + that shares a pod''s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + properties: + medium: + description: 'medium represents what type of storage + medium should back this directory. The default + is "" which means to use the node''s default medium. + Must be an empty string (default) or Memory. More + info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: 'sizeLimit is the total amount of local + storage required for this EmptyDir volume. The + size limit is also applicable for memory medium. + The maximum usage on memory medium EmptyDir would + be the minimum value between the SizeLimit specified + here and the sum of memory limits of all containers + in a pod. The default is nil which means that + the limit is undefined. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: "ephemeral represents a volume that is + handled by a cluster storage driver. The volume's + lifecycle is tied to the pod that defines it - it + will be created before the pod starts, and deleted + when the pod is removed. \n Use this if: a) the volume + is only needed while the pod runs, b) features of + normal volumes like restoring from snapshot or capacity + \ tracking are needed, c) the storage driver is + specified through a storage class, and d) the storage + driver supports dynamic volume provisioning through + \ a PersistentVolumeClaim (see EphemeralVolumeSource + for more information on the connection between + this volume type and PersistentVolumeClaim). \n + Use PersistentVolumeClaim or one of the vendor-specific + APIs for volumes that persist for longer than the + lifecycle of an individual pod. \n Use CSI for light-weight + local ephemeral volumes if the CSI driver is meant + to be used that way - see the documentation of the + driver for more information. \n A pod can use both + types of ephemeral volumes and persistent volumes + at the same time." + properties: + volumeClaimTemplate: + description: "Will be used to create a stand-alone + PVC to provision the volume. The pod in which + this EphemeralVolumeSource is embedded will be + the owner of the PVC, i.e. the PVC will be deleted + together with the pod. The name of the PVC will + be `-` where `` + is the name from the `PodSpec.Volumes` array entry. + Pod validation will reject the pod if the concatenated + name is not valid for a PVC (for example, too + long). \n An existing PVC with that name that + is not owned by the pod will *not* be used for + the pod to avoid using an unrelated volume by + mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created + PVC is meant to be used by the pod, the PVC has + to updated with an owner reference to the pod + once the pod exists. Normally this should not + be necessary, but it may be useful when manually + reconstructing a broken cluster. \n This field + is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. \n Required, + must not be nil." + properties: + metadata: + description: May contain labels and annotations + that will be copied into the PVC when creating + it. No other fields are allowed and will be + rejected during validation. + type: object + spec: + description: The specification for the PersistentVolumeClaim. + The entire content is copied unchanged into + the PVC that gets created from this template. + The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: 'accessModes contains the desired + access modes the volume should have. More + info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'dataSource field can be used + to specify either: * An existing VolumeSnapshot + object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller + can support the specified data source, + it will create a new volume based on the + contents of the specified data source. + When the AnyVolumeDataSource feature gate + is enabled, dataSource contents will be + copied to dataSourceRef, and dataSourceRef + contents will be copied to dataSource + when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef + will not be copied to dataSource.' + properties: + apiGroup: + description: APIGroup is the group for + the resource being referenced. If + APIGroup is not specified, the specified + Kind must be in the core API group. + For any other third-party types, APIGroup + is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + required: + - kind + - name + type: object + dataSourceRef: + description: 'dataSourceRef specifies the + object from which to populate the volume + with data, if a non-empty volume is desired. + This may be any object from a non-empty + API group (non core object) or a PersistentVolumeClaim + object. When this field is specified, + volume binding will only succeed if the + type of the specified object matches some + installed volume populator or dynamic + provisioner. This field will replace the + functionality of the dataSource field + and as such if both fields are non-empty, + they must have the same value. For backwards + compatibility, when namespace isn''t specified + in dataSourceRef, both fields (dataSource + and dataSourceRef) will be set to the + same value automatically if one of them + is empty and the other is non-empty. When + namespace is specified in dataSourceRef, + dataSource isn''t set to the same value + and must be empty. There are three important + differences between dataSource and dataSourceRef: + * While dataSource only allows two specific + types of objects, dataSourceRef allows + any non-core object, as well as PersistentVolumeClaim + objects. * While dataSource ignores disallowed + values (dropping them), dataSourceRef preserves + all values, and generates an error if + a disallowed value is specified. * While + dataSource only allows local objects, + dataSourceRef allows objects in any + namespaces. (Beta) Using this field requires + the AnyVolumeDataSource feature gate to + be enabled. (Alpha) Using the namespace + field of dataSourceRef requires the CrossNamespaceVolumeDataSource + feature gate to be enabled.' + properties: + apiGroup: + description: APIGroup is the group for + the resource being referenced. If + APIGroup is not specified, the specified + Kind must be in the core API group. + For any other third-party types, APIGroup + is required. + type: string + kind: + description: Kind is the type of resource + being referenced + type: string + name: + description: Name is the name of resource + being referenced + type: string + namespace: + description: Namespace is the namespace + of resource being referenced Note + that when a namespace is specified, + a gateway.networking.k8s.io/ReferenceGrant + object is required in the referent + namespace to allow that namespace's + owner to accept the reference. See + the ReferenceGrant documentation for + details. (Alpha) This field requires + the CrossNamespaceVolumeDataSource + feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: 'resources represents the minimum + resources the volume should have. If RecoverVolumeExpansionFailure + feature is enabled users are allowed to + specify resource requirements that are + lower than previous value but must still + be higher than capacity recorded in the + status field of the claim. More info: + https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum + amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the + minimum amount of compute resources + required. If Requests is omitted for + a container, it defaults to Limits + if that is explicitly specified, otherwise + to an implementation-defined value. + Requests cannot exceed Limits. More + info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + selector: + description: selector is a label query over + volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. + This array is replaced during + a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of + {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + storageClassName: + description: 'storageClassName is the name + of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + type: string + volumeAttributesClassName: + description: 'volumeAttributesClassName + may be used to set the VolumeAttributesClass + used by this claim. If specified, the + CSI driver will create or update the volume + with the attributes defined in the corresponding + VolumeAttributesClass. This has a different + purpose than storageClassName, it can + be changed after the claim is created. + An empty string value means that no VolumeAttributesClass + will be applied to the claim but it''s + not allowed to reset this field to empty + string once it is set. If unspecified + and the PersistentVolumeClaim is unbound, + the default VolumeAttributesClass will + be set by the persistentvolume controller + if it exists. If the resource referred + to by volumeAttributesClass does not exist, + this PersistentVolumeClaim will be set + to a Pending state, as reflected by the + modifyVolumeStatus field, until such as + a resource exists. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + (Alpha) Using this field requires the + VolumeAttributesClass feature gate to + be enabled.' + type: string + volumeMode: + description: volumeMode defines what type + of volume is required by the claim. Value + of Filesystem is implied when not included + in claim spec. + type: string + volumeName: + description: volumeName is the binding reference + to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource + that is attached to a kubelet's host machine and then + exposed to the pod. + properties: + fsType: + description: 'fsType is the filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. TODO: how + do we prevent errors in the filesystem from compromising + the machine' + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: 'readOnly is Optional: Defaults to + false (read/write). ReadOnly here will force the + ReadOnly setting in VolumeMounts.' + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target + worldwide names (WWNs)' + items: + type: string + type: array + wwids: + description: 'wwids Optional: FC volume world wide + identifiers (wwids) Either wwids or combination + of targetWWNs and lun must be set, but not both + simultaneously.' + items: + type: string + type: array + type: object + flexVolume: + description: flexVolume represents a generic volume + resource that is provisioned/attached using an exec + based plugin. + properties: + driver: + description: driver is the name of the driver to + use for this volume. + type: string + fsType: + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". The + default filesystem depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field holds + extra command options if any.' + type: object + readOnly: + description: 'readOnly is Optional: defaults to + false (read/write). ReadOnly here will force the + ReadOnly setting in VolumeMounts.' + type: boolean + secretRef: + description: 'secretRef is Optional: secretRef is + reference to the secret object containing sensitive + information to pass to the plugin scripts. This + may be empty if no secret object is specified. + If the secret object contains more than one secret, + all secrets are passed to the plugin scripts.' + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume attached + to a kubelet's host machine. This depends on the Flocker + control service being running + properties: + datasetName: + description: datasetName is Name of the dataset + stored as metadata -> name on the dataset for + Flocker should be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. + This is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: 'gcePersistentDisk represents a GCE Disk + resource that is attached to a kubelet''s host machine + and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + properties: + fsType: + description: 'fsType is filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred + to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem + from compromising the machine' + type: string + partition: + description: 'partition is the partition in the + volume that you want to mount. If omitted, the + default is to mount by volume name. Examples: + For volume /dev/sda1, you specify the partition + as "1". Similarly, the volume partition for /dev/sda + is "0" (or you can leave the property empty). + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + format: int32 + type: integer + pdName: + description: 'pdName is unique name of the PD resource + in GCE. Used to identify the disk in GCE. More + info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: string + readOnly: + description: 'readOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. More + info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: boolean + required: + - pdName + type: object + gitRepo: + description: 'gitRepo represents a git repository at + a particular revision. DEPRECATED: GitRepo is deprecated. + To provision a container with a git repo, mount an + EmptyDir into an InitContainer that clones the repo + using git, then mount the EmptyDir into the Pod''s + container.' + properties: + directory: + description: directory is the target directory name. + Must not contain or start with '..'. If '.' is + supplied, the volume directory will be the git + repository. Otherwise, if specified, the volume + will contain the git repository in the subdirectory + with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the + specified revision. + type: string + required: + - repository + type: object + glusterfs: + description: 'glusterfs represents a Glusterfs mount + on the host that shares a pod''s lifetime. More info: + https://examples.k8s.io/volumes/glusterfs/README.md' + properties: + endpoints: + description: 'endpoints is the endpoint name that + details Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + path: + description: 'path is the Glusterfs volume path. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + readOnly: + description: 'readOnly here will force the Glusterfs + volume to be mounted with read-only permissions. + Defaults to false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: 'hostPath represents a pre-existing file + or directory on the host machine that is directly + exposed to the container. This is generally used for + system agents or other privileged things that are + allowed to see the host machine. Most containers will + NOT need this. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- TODO(jonesdl) We need to restrict who can use + host directory mounts and who can/can not mount host + directories as read/write.' + properties: + path: + description: 'path of the directory on the host. + If the path is a symlink, it will follow the link + to the real path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + type: + description: 'type for HostPath Volume Defaults + to "" More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + required: + - path + type: object + iscsi: + description: 'iscsi represents an ISCSI Disk resource + that is attached to a kubelet''s host machine and + then exposed to the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md' + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether support + iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support + iSCSI Session CHAP authentication + type: boolean + fsType: + description: 'fsType is the filesystem type of the + volume that you want to mount. Tip: Ensure that + the filesystem type is supported by the host operating + system. Examples: "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. More info: + https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem + from compromising the machine' + type: string + initiatorName: + description: initiatorName is the custom iSCSI Initiator + Name. If initiatorName is specified with iscsiInterface + simultaneously, new iSCSI interface : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified Name. + type: string + iscsiInterface: + description: iscsiInterface is the interface Name + that uses an iSCSI transport. Defaults to 'default' + (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: portals is the iSCSI Target Portal + List. The portal is either an IP or ip_addr:port + if the port is other than default (typically TCP + ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: readOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for iSCSI + target and initiator authentication + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + targetPortal: + description: targetPortal is iSCSI Target Portal. + The Portal is either an IP or ip_addr:port if + the port is other than default (typically TCP + ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: 'name of the volume. Must be a DNS_LABEL + and unique within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + nfs: + description: 'nfs represents an NFS mount on the host + that shares a pod''s lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + properties: + path: + description: 'path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + readOnly: + description: 'readOnly here will force the NFS export + to be mounted with read-only permissions. Defaults + to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: boolean + server: + description: 'server is the hostname or IP address + of the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: 'persistentVolumeClaimVolumeSource represents + a reference to a PersistentVolumeClaim in the same + namespace. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + claimName: + description: 'claimName is the name of a PersistentVolumeClaim + in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + type: string + readOnly: + description: readOnly Will force the ReadOnly setting + in VolumeMounts. Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents a PhotonController + persistent disk attached and mounted on kubelets host + machine + properties: + fsType: + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon + Controller persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx volume + attached and mounted on kubelets host machine + properties: + fsType: + description: fSType represents the filesystem type + to mount Must be a filesystem type supported by + the host operating system. Ex. "ext4", "xfs". + Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx + volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources + secrets, configmaps, and downward API + properties: + defaultMode: + description: defaultMode are the mode bits used + to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or + a decimal value between 0 and 511. YAML accepts + both octal and decimal values, JSON requires decimal + values for mode bits. Directories within the path + are not affected by this setting. This might be + in conflict with other options that affect the + file mode, like fsGroup, and the result can be + other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume projections + items: + description: Projection that may be projected + along with other supported volume types + properties: + clusterTrustBundle: + description: "ClusterTrustBundle allows a + pod to access the `.spec.trustBundle` field + of ClusterTrustBundle objects in an auto-updating + file. \n Alpha, gated by the ClusterTrustBundleProjection + feature gate. \n ClusterTrustBundle objects + can either be selected by name, or by the + combination of signer name and a label selector. + \n Kubelet performs aggressive normalization + of the PEM contents written into the pod + filesystem. Esoteric PEM features such + as inter-block comments and block headers + are stripped. Certificates are deduplicated. + The ordering of certificates within the + file is arbitrary, and Kubelet may change + the order over time." + properties: + labelSelector: + description: Select all ClusterTrustBundles + that match this label selector. Only + has effect if signerName is set. Mutually-exclusive + with name. If unset, interpreted as + "match nothing". If set but empty, + interpreted as "match everything". + properties: + matchExpressions: + description: matchExpressions is a + list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a + set of values. Valid operators + are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values + array must be non-empty. If + the operator is Exists or + DoesNotExist, the values array + must be empty. This array + is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map + of {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + name: + description: Select a single ClusterTrustBundle + by object name. Mutually-exclusive + with signerName and labelSelector. + type: string + optional: + description: If true, don't block pod + startup if the referenced ClusterTrustBundle(s) + aren't available. If using name, then + the named ClusterTrustBundle is allowed + not to exist. If using signerName, + then the combination of signerName and + labelSelector is allowed to match zero + ClusterTrustBundles. + type: boolean + path: + description: Relative path from the volume + root to write the bundle. + type: string + signerName: + description: Select all ClusterTrustBundles + that match this signer name. Mutually-exclusive + with name. The contents of all selected + ClusterTrustBundles will be unified + and deduplicated. + type: string + required: + - path + type: object + configMap: + description: configMap information about the + configMap data to project + properties: + items: + description: items if unspecified, each + key-value pair in the Data field of + the referenced ConfigMap will be projected + into the volume as a file whose name + is the key and content is the value. + If specified, the listed keys will be + projected into the specified paths, + and unlisted keys will not be present. + If a key is specified which is not present + in the ConfigMap, the volume setup will + error unless it is marked optional. + Paths must be relative and may not contain + the '..' path or start with '..'. + items: + description: Maps a string key to a + path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: + mode bits used to set permissions + on this file. Must be an octal + value between 0000 and 0777 or + a decimal value between 0 and + 511. YAML accepts both octal and + decimal values, JSON requires + decimal values for mode bits. + If not specified, the volume defaultMode + will be used. This might be in + conflict with other options that + affect the file mode, like fsGroup, + and the result can be other mode + bits set.' + format: int32 + type: integer + path: + description: path is the relative + path of the file to map the key + to. May not be an absolute path. + May not contain the path element + '..'. May not start with the string + '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: optional specify whether + the ConfigMap or its keys must be defined + type: boolean + type: object + downwardAPI: + description: downwardAPI information about + the downwardAPI data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects + a field of the pod: only annotations, + labels, name and namespace are + supported.' + properties: + apiVersion: + description: Version of the + schema the FieldPath is written + in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field + to select in the specified + API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: mode bits + used to set permissions on this + file, must be an octal value between + 0000 and 0777 or a decimal value + between 0 and 511. YAML accepts + both octal and decimal values, + JSON requires decimal values for + mode bits. If not specified, the + volume defaultMode will be used. + This might be in conflict with + other options that affect the + file mode, like fsGroup, and the + result can be other mode bits + set.' + format: int32 + type: integer + path: + description: 'Required: Path is the + relative path name of the file + to be created. Must not be absolute + or contain the ''..'' path. Must + be utf-8 encoded. The first item + of the relative path must not + start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource + of the container: only resources + limits and requests (limits.cpu, + limits.memory, requests.cpu and + requests.memory) are currently + supported.' + properties: + containerName: + description: 'Container name: + required for volumes, optional + for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource + to select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + secret: + description: secret information about the + secret data to project + properties: + items: + description: items if unspecified, each + key-value pair in the Data field of + the referenced Secret will be projected + into the volume as a file whose name + is the key and content is the value. + If specified, the listed keys will be + projected into the specified paths, + and unlisted keys will not be present. + If a key is specified which is not present + in the Secret, the volume setup will + error unless it is marked optional. + Paths must be relative and may not contain + the '..' path or start with '..'. + items: + description: Maps a string key to a + path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: + mode bits used to set permissions + on this file. Must be an octal + value between 0000 and 0777 or + a decimal value between 0 and + 511. YAML accepts both octal and + decimal values, JSON requires + decimal values for mode bits. + If not specified, the volume defaultMode + will be used. This might be in + conflict with other options that + affect the file mode, like fsGroup, + and the result can be other mode + bits set.' + format: int32 + type: integer + path: + description: path is the relative + path of the file to map the key + to. May not be an absolute path. + May not contain the path element + '..'. May not start with the string + '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: optional field specify whether + the Secret or its key must be defined + type: boolean + type: object + serviceAccountToken: + description: serviceAccountToken is information + about the serviceAccountToken data to project + properties: + audience: + description: audience is the intended + audience of the token. A recipient of + a token must identify itself with an + identifier specified in the audience + of the token, and otherwise should reject + the token. The audience defaults to + the identifier of the apiserver. + type: string + expirationSeconds: + description: expirationSeconds is the + requested duration of validity of the + service account token. As the token + approaches expiration, the kubelet volume + plugin will proactively rotate the service + account token. The kubelet will start + trying to rotate the token if the token + is older than 80 percent of its time + to live or if the token is older than + 24 hours.Defaults to 1 hour and must + be at least 10 minutes. + format: int64 + type: integer + path: + description: path is the path relative + to the mount point of the file to project + the token into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: quobyte represents a Quobyte mount on the + host that shares a pod's lifetime + properties: + group: + description: group to map volume access to Default + is no group + type: string + readOnly: + description: readOnly here will force the Quobyte + volume to be mounted with read-only permissions. + Defaults to false. + type: boolean + registry: + description: registry represents a single or multiple + Quobyte Registry services specified as a string + as host:port pair (multiple entries are separated + with commas) which acts as the central registry + for volumes + type: string + tenant: + description: tenant owning the given Quobyte volume + in the Backend Used with dynamically provisioned + Quobyte volumes, value is set by the plugin + type: string + user: + description: user to map volume access to Defaults + to serivceaccount user + type: string + volume: + description: volume is a string that references + an already created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: 'rbd represents a Rados Block Device mount + on the host that shares a pod''s lifetime. More info: + https://examples.k8s.io/volumes/rbd/README.md' + properties: + fsType: + description: 'fsType is the filesystem type of the + volume that you want to mount. Tip: Ensure that + the filesystem type is supported by the host operating + system. Examples: "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. More info: + https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem + from compromising the machine' + type: string + image: + description: 'image is the rados image name. More + info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + keyring: + description: 'keyring is the path to key ring for + RBDUser. Default is /etc/ceph/keyring. More info: + https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + monitors: + description: 'monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + items: + type: string + type: array + pool: + description: 'pool is the rados pool name. Default + is rbd. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + readOnly: + description: 'readOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. More + info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: boolean + secretRef: + description: 'secretRef is name of the authentication + secret for RBDUser. If provided overrides keyring. + Default is nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + user: + description: 'user is the rados user name. Default + is admin. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent + volume attached and mounted on Kubernetes nodes. + properties: + fsType: + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". Default + is "xfs". + type: string + gateway: + description: gateway is the host address of the + ScaleIO API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the + ScaleIO Protection Domain for the configured storage. + type: string + readOnly: + description: readOnly Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. + type: boolean + secretRef: + description: secretRef references to the secret + for ScaleIO user and other sensitive information. + If this is not provided, Login operation will + fail. + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + sslEnabled: + description: sslEnabled Flag enable/disable SSL + communication with Gateway, default false + type: boolean + storageMode: + description: storageMode indicates whether the storage + for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage + Pool associated with the protection domain. + type: string + system: + description: system is the name of the storage system + as configured in ScaleIO. + type: string + volumeName: + description: volumeName is the name of a volume + already created in the ScaleIO system that is + associated with this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: 'secret represents a secret that should + populate this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + properties: + defaultMode: + description: 'defaultMode is Optional: mode bits + used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or + a decimal value between 0 and 511. YAML accepts + both octal and decimal values, JSON requires decimal + values for mode bits. Defaults to 0644. Directories + within the path are not affected by this setting. + This might be in conflict with other options that + affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + items: + description: items If unspecified, each key-value + pair in the Data field of the referenced Secret + will be projected into the volume as a file whose + name is the key and content is the value. If specified, + the listed keys will be projected into the specified + paths, and unlisted keys will not be present. + If a key is specified which is not present in + the Secret, the volume setup will error unless + it is marked optional. Paths must be relative + and may not contain the '..' path or start with + '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits + used to set permissions on this file. Must + be an octal value between 0000 and 0777 + or a decimal value between 0 and 511. YAML + accepts both octal and decimal values, JSON + requires decimal values for mode bits. If + not specified, the volume defaultMode will + be used. This might be in conflict with + other options that affect the file mode, + like fsGroup, and the result can be other + mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of + the file to map the key to. May not be an + absolute path. May not contain the path + element '..'. May not start with the string + '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the + Secret or its keys must be defined + type: boolean + secretName: + description: 'secretName is the name of the secret + in the pod''s namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + type: string + type: object + storageos: + description: storageOS represents a StorageOS volume + attached and mounted on Kubernetes nodes. + properties: + fsType: + description: fsType is the filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + readOnly: + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. + type: boolean + secretRef: + description: secretRef specifies the secret to use + for obtaining the StorageOS API credentials. If + not specified, default values will be attempted. + properties: + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + volumeName: + description: volumeName is the human-readable name + of the StorageOS volume. Volume names are only + unique within a namespace. + type: string + volumeNamespace: + description: volumeNamespace specifies the scope + of the volume within StorageOS. If no namespace + is specified then the Pod's namespace will be + used. This allows the Kubernetes name scoping + to be mirrored within StorageOS for tighter integration. + Set VolumeName to any name to override the default + behaviour. Set to "default" if you are not using + namespaces within StorageOS. Namespaces that do + not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere volume + attached and mounted on kubelets host machine + properties: + fsType: + description: fsType is filesystem type to mount. + Must be a filesystem type supported by the host + operating system. Ex. "ext4", "xfs", "ntfs". Implicitly + inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy + Based Management (SPBM) profile ID associated + with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage Policy + Based Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies + vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + type: object + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + description: The pod this Toleration is attached to tolerates any + taint that matches the triple using the matching + operator . + properties: + effect: + description: Effect indicates the taint effect to match. Empty + means match all taint effects. When specified, allowed values + are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match all + values and all keys. + type: string + operator: + description: Operator represents a key's relationship to the + value. Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod + can tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of time + the toleration (which must be of effect NoExecute, otherwise + this field is ignored) tolerates the taint. By default, it + is not set, which means tolerate the taint forever (do not + evict). Zero and negative values will be treated as 0 (evict + immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + required: + - kubernetesConfig + type: object + status: + description: RedisStatus defines the observed state of Redis + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/readme.md b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/readme.md new file mode 100644 index 000000000..63c12c6ca --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/readme.md @@ -0,0 +1,115 @@ +# Redis Operator Helm Chart + +## Introduction + +This Helm chart deploys the redis-operator into your Kubernetes cluster. The operator facilitates the deployment, scaling, and management of Redis clusters and other Redis resources provided by the OpsTree Solutions team. + +## Pre-requisites + +- Helm v3+ +- Kubernetes v1.16+ +- If you intend to use the cert-manager, ensure that the cert-manager CRDs are installed before deploying the redis-operator. + +## Installation Steps + +### 1. Add Helm Repository + +```bash +helm repo add ot-helm https://ot-container-kit.github.io/helm-charts +``` + +### 2. Install Cert-Manager CRDs (if using cert-manager) + +If you plan to use cert-manager with the redis-operator, you need to install the cert-manager CRDs before deploying the operator. + +```bash +kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.12.4/cert-manager.crds.yaml +``` + +### 3. Install Redis Operator + +Replace `` and `` with your specific values. + +```bash +helm install ot-helm/redis-operator --version=0.15.5 --appVersion=0.15.1 --set certificate.secretName= --set certmanager.enabled=true --set redisOperator.webhook=true --namespace --create-namespace +``` + +> Note: If `certificate.secretName` is not provided, the operator will generate a self-signed certificate and use it for webhook server. +--- +> Note : If you want to disable the webhook you have to pass the `--set webhook=false` and `--set certmanager.enabled=false` while installing the redis-operator. + +### 4. Patch the CA Bundle (if using cert-manager) + +Cert-manager injects the CA bundle into the webhook configuration. + +```bash +kubectl patch crd redis.redis.redis.opstreelabs.in -p '{"metadata":{"annotations":{"cert-manager.io/inject-ca-from":"/"}}}' + +kubectl patch crd redisclusters.redis.redis.opstreelabs.in -p '{"metadata":{"annotations":{"cert-manager.io/inject-ca-from":"/"}}}' + +kubectl patch crd redisreplications.redis.redis.opstreelabs.in -p '{"metadata":{"annotations":{"cert-manager.io/inject-ca-from":"/"}}}' + +kubectl patch crd redissentinels.redis.redis.opstreelabs.in -p '{"metadata":{"annotations":{"cert-manager.io/inject-ca-from":"/"}}}' +``` + +> Note: Replace `` and `` with your specific values i.e. release name and certificate name. + +#### You can verify the patch by running the following commands + +```bash +kubectl get crd redis.redis.redis.opstreelabs.in -o=jsonpath='{.metadata.annotations}' +kubectl get crd redisclusters.redis.redis.opstreelabs.in -o=jsonpath='{.metadata.annotations}' +kubectl get crd redisreplications.redis.redis.opstreelabs.in -o=jsonpath='{.metadata.annotations}' +kubectl get crd redissentinels.redis.redis.opstreelabs.in -o=jsonpath='{.metadata.annotations}' +``` + +### How to generate private key( Optional ) + +```bash +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt +kubectl create secret tls --key tls.key --cert tls.crt -n +``` + +> Note: This secret will be used for webhook server certificate so generate it before installing the redis-operator. + +## Default Values + +| Parameter | Description | Default | +|-----------------------------------------------|----------------------------------------|--------------------------------------------------| +| `redisOperator.name` | Operator name | `redis-operator` | +| `redisOperator.imageName` | Image repository | `quay.io/opstree/redis-operator` | +| `redisOperator.imageTag` | Image tag | `{{appVersion}}` | +| `redisOperator.imagePullPolicy` | Image pull policy | `Always` | +| `redisOperator.podAnnotations` | Additional pod annotations | `{}` | +| `redisOperator.podLabels` | Additional Pod labels | `{}` | +| `redisOperator.extraArgs` | Additional arguments for the operator | `{}` | +| `redisOperator.watchNamespace` | Namespace for the operator to watch | `""` | +| `redisOperator.env` | Environment variables for the operator | `{}` | +| `redisOperator.webhook` | Enable webhook | `false` | +| `redisOperator.automountServiceAccountToken` | Automount service account token | `true` | +| `resources.limits.cpu` | CPU limit | `500m` | +| `resources.limits.memory` | Memory limit | `500Mi` | +| `resources.requests.cpu` | CPU request | `500m` | +| `resources.requests.memory` | Memory request | `500Mi` | +| `replicas` | Number of replicas | `1` | +| `rbac.enabled` | Feature flag for rbac resources | `true` | +| `serviceAccountName` | Service account name | `redis-operator` | +| `serviceAccount.automountServiceAccountToken` | Automount service account token | `true` | +| `certificate.name` | Certificate name | `serving-cert` | +| `certificate.secretName` | Certificate secret name | `webhook-server-cert` | +| `issuer.type` | Issuer type | `selfSigned` | +| `issuer.name` | Issuer name | `redis-operator-issuer` | +| `issuer.email` | Issuer email | `shubham.gupta@opstree.com` | +| `issuer.server` | Issuer server URL | `https://acme-v02.api.letsencrypt.org/directory` | +| `issuer.privateKeySecretName` | Private key secret name | `letsencrypt-prod` | +| `certManager.enabled` | Enable cert-manager | `false` | + +## Scheduling Parameters + +| Parameter | Description | Default | +|---------------------|-------------------------------------|---------| +| `priorityClassName` | Priority class name for the pods | `""` | +| `nodeSelector` | Labels for pod assignment | `{}` | +| `tolerateAllTaints` | Whether to tolerate all node taints | `false` | +| `tolerations` | Taints to tolerate | `[]` | +| `affinity` | Affinity rules for pod assignment | `{}` | diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/templates/_helpers.tpl b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/templates/_helpers.tpl new file mode 100644 index 000000000..5a70733b0 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/templates/_helpers.tpl @@ -0,0 +1,34 @@ +{{/* vim: set filetype=mustache: */}} + +{{/* Define issuer spec based on the type */}} +{{- define "redis-operator.issuerSpec" -}} +{{- if eq .Values.issuer.type "acme" }} +acme: + email: {{ .Values.issuer.email }} + server: {{ .Values.issuer.server }} + privateKeySecretRef: + name: {{ .Values.issuer.privateKeySecretName }} + solvers: + - http01: + ingress: + class: {{ .Values.issuer.solver.ingressClass }} +{{- else }} +selfSigned: {} +{{- end }} +{{- end -}} + +{{/* Common labels */}} +{{- define "redisOperator.labels" -}} +app.kubernetes.io/name: {{ .Values.redisOperator.name }} +helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +app.kubernetes.io/instance: {{ .Release.Name }} +app.kubernetes.io/version: {{ .Chart.AppVersion }} +app.kubernetes.io/component: operator +app.kubernetes.io/part-of: {{ .Release.Name }} +{{- end }} + +{{/* Selector labels */}} +{{- define "redisOperator.selectorLabels" -}} +name: {{ .Values.redisOperator.name }} +{{- end }} \ No newline at end of file diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/templates/cert-manager.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/templates/cert-manager.yaml new file mode 100644 index 000000000..fa09325fe --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/templates/cert-manager.yaml @@ -0,0 +1,43 @@ +{{ if .Values.certmanager.enabled }} + +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: {{ .Values.issuer.name }} + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Values.redisOperator.name }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: issuer + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + {{- include "redis-operator.issuerSpec" . | nindent 2 }} + +--- + +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: {{ .Values.certificate.name }} + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Values.redisOperator.name }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: certificate + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + dnsNames: + - {{ .Values.service.name }}.{{ .Values.service.namespace }}.svc + - {{ .Values.service.name }}.{{ .Values.service.namespace }}.svc.cluster.local + issuerRef: + kind: Issuer + name: {{ .Values.issuer.name }} + secretName: {{ .Values.certificate.secretName }} + +{{ end }} \ No newline at end of file diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/templates/operator-deployment.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/templates/operator-deployment.yaml new file mode 100644 index 000000000..eb05d945d --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/templates/operator-deployment.yaml @@ -0,0 +1,81 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Values.redisOperator.name }} + namespace: {{ .Release.Namespace }} + labels: {{- include "redisOperator.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.replicas }} + selector: + matchLabels: {{- include "redisOperator.selectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/{{ .Values.certificate.name }} + {{- with .Values.redisOperator.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: {{- include "redisOperator.selectorLabels" . | nindent 8 }} + {{- with .Values.redisOperator.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + automountServiceAccountToken: {{ .Values.redisOperator.automountServiceAccountToken }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: "{{ .Values.redisOperator.name }}" + securityContext: + {{- toYaml .Values.securityContext | nindent 10 }} + image: "{{ .Values.redisOperator.imageName }}:{{ .Values.redisOperator.imageTag | default (printf "v%s" .Chart.AppVersion) }}" + imagePullPolicy: {{ .Values.redisOperator.imagePullPolicy }} + command: + - /manager + args: + - --leader-elect + {{- range $arg := .Values.redisOperator.extraArgs }} + - {{ $arg }} + {{- end }} + {{- if .Values.redisOperator.webhook }} + ports: + - containerPort: 9443 + name: webhook-server + protocol: TCP + volumeMounts: + - mountPath: /tmp/k8s-webhook-server/serving-certs + name: cert + readOnly: true + {{- end }} + env: + - name: ENABLE_WEBHOOKS + value: {{ .Values.redisOperator.webhook | quote }} + {{- if .Values.redisOperator.watchNamespace }} + - name: WATCH_NAMESPACE + value: {{ .Values.redisOperator.watchNamespace | quote }} + {{- end }} + {{- range $env := .Values.redisOperator.env }} + - name: {{ $env.name }} + value: {{ $env.value | quote }} + {{- end }} + {{- if .Values.resources }} + resources: {{ toYaml .Values.resources | nindent 10 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: {{ toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.priorityClassName}} + priorityClassName: {{ .Values.priorityClassName }} + {{- end }} + {{- with .Values.affinity }} + affinity: {{ toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: "{{ .Values.serviceAccountName }}" + serviceAccount: "{{ .Values.serviceAccountName }}" + {{- if .Values.redisOperator.webhook }} + volumes: + - name: cert + secret: + defaultMode: 420 + secretName: {{ .Values.certificate.secretName }} + {{- end }} \ No newline at end of file diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/templates/role-binding.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/templates/role-binding.yaml new file mode 100644 index 000000000..1ea08b001 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/templates/role-binding.yaml @@ -0,0 +1,23 @@ +{{- if .Values.rbac.enabled }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ .Values.redisOperator.name }} + labels: + app.kubernetes.io/name : {{ .Values.redisOperator.name }} + helm.sh/chart : {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by : {{ .Release.Service }} + app.kubernetes.io/instance : {{ .Release.Name }} + app.kubernetes.io/version : {{ .Chart.AppVersion }} + app.kubernetes.io/component: role-binding + app.kubernetes.io/part-of : {{ .Release.Name }} +subjects: +- kind: ServiceAccount + name: {{ .Values.serviceAccountName }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: {{ .Values.redisOperator.name }} + apiGroup: rbac.authorization.k8s.io +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/templates/role.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/templates/role.yaml new file mode 100644 index 000000000..61b89710b --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/templates/role.yaml @@ -0,0 +1,128 @@ +{{- if .Values.rbac.enabled }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ .Values.redisOperator.name }} + labels: + app.kubernetes.io/name : {{ .Values.redisOperator.name }} + helm.sh/chart : {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by : {{ .Release.Service }} + app.kubernetes.io/instance : {{ .Release.Name }} + app.kubernetes.io/version : {{ .Chart.AppVersion }} + app.kubernetes.io/component: role + app.kubernetes.io/part-of : {{ .Release.Name }} +rules: +- apiGroups: + - redis.redis.opstreelabs.in + resources: + - rediss + - redisclusters + - redisreplications + - redis + - rediscluster + - redissentinel + - redissentinels + - redisreplication + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- nonResourceURLs: + - '*' + verbs: + - get +- apiGroups: + - "apiextensions.k8s.io" + resources: + - "customresourcedefinitions" + verbs: + - "get" + - "list" + - "watch" +- apiGroups: + - redis.redis.opstreelabs.in + resources: + - redis/finalizers + - rediscluster/finalizers + - redisclusters/finalizers + - redissentinel/finalizers + - redissentinels/finalizers + - redisreplication/finalizers + - redisreplications/finalizers + verbs: + - update +- apiGroups: + - redis.redis.opstreelabs.in + resources: + - redis/status + - rediscluster/status + - redisclusters/status + - redissentinel/status + - redissentinels/status + - redisreplication/status + - redisreplications/status + verbs: + - get + - patch + - update +- apiGroups: + - "" + resources: + - secrets + - pods/exec + - pods + - services + - configmaps + - events + - persistentvolumeclaims + - namespace + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - apps + resources: + - statefulsets + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - "coordination.k8s.io" + resources: + - leases + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - "policy" + resources: + - poddisruptionbudgets + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/templates/service-account.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/templates/service-account.yaml new file mode 100644 index 000000000..024f7ec2d --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/templates/service-account.yaml @@ -0,0 +1,17 @@ +{{- if .Values.rbac.enabled }} +--- +apiVersion: v1 +kind: ServiceAccount +automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} +metadata: + name: {{ .Values.redisOperator.name }} + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name : {{ .Values.redisOperator.name }} + helm.sh/chart : {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by : {{ .Release.Service }} + app.kubernetes.io/instance : {{ .Release.Name }} + app.kubernetes.io/version : {{ .Chart.AppVersion }} + app.kubernetes.io/component: service-account + app.kubernetes.io/part-of : {{ .Release.Name }} +{{- end }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/templates/service.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/templates/service.yaml new file mode 100644 index 000000000..9a6bcbf68 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/templates/service.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/name : {{ .Values.redisOperator.name }} + helm.sh/chart : {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by : {{ .Release.Service }} + app.kubernetes.io/instance : {{ .Release.Name }} + app.kubernetes.io/version : {{ .Chart.AppVersion }} + app.kubernetes.io/component: webhook + app.kubernetes.io/part-of : {{ .Release.Name }} + name: {{ .Values.service.name }} + namespace: {{ .Release.Namespace }} +spec: + ports: + - port: 443 + protocol: TCP + targetPort: 9443 + selector: + name: {{ .Values.redisOperator.name }} diff --git a/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/values.yaml b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/values.yaml new file mode 100644 index 000000000..47ef96d48 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/charts/redis-operator/values.yaml @@ -0,0 +1,76 @@ +--- +redisOperator: + name: redis-operator + imageName: ghcr.io/ot-container-kit/redis-operator/redis-operator + # Overrides the image tag whose default is the chart appVersion. + imageTag: "" + imagePullPolicy: Always + + # Additional pod annotations + podAnnotations: {} + # Additional Pod labels (e.g. for filtering Pod by custom labels) + podLabels: {} + + # Additional arguments for redis-operator container + extraArgs: [] + # When not specified, the operator will watch all namespaces. It can be set to a specific namespace or multiple namespaces separated by commas. + watchNamespace: "" + env: [] + webhook: false + automountServiceAccountToken: true + + +resources: + limits: + cpu: 500m + memory: 500Mi + requests: + cpu: 500m + memory: 500Mi + +replicas: 1 + +rbac: + enabled: true +serviceAccountName: redis-operator + +serviceAccount: + automountServiceAccountToken: true + +service: + name: webhook-service + namespace: redis-operator + +certificate: + name: serving-cert + secretName: webhook-server-cert + +issuer: + type: selfSigned + name: redis-operator-issuer + email: shubham.gupta@opstree.com + server: https://acme-v02.api.letsencrypt.org/directory + privateKeySecretName: letsencrypt-prod + solver: + enabled: true + ingressClass: nginx + +certmanager: + enabled: false + +priorityClassName: "" +nodeSelector: {} +tolerateAllTaints: false +tolerations: [] +affinity: {} + +podSecurityContext: {} +# fsGroup: 2000 + +securityContext: {} +# capabilities: +# drop: +# - ALL +# readOnlyRootFilesystem: true +# runAsNonRoot: true +# runAsUser: 1000 diff --git a/charts/linux-polska/ezd-crd/1.5.1/questions.yaml b/charts/linux-polska/ezd-crd/1.5.1/questions.yaml new file mode 100644 index 000000000..155cfaa49 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/questions.yaml @@ -0,0 +1,97 @@ +categories: +- database +namespace: default +questions: +- variable: global.postgresql.deploy + default: "true" + label: Deploy Postgresql + type: boolean + group: "Components" +- variable: global.rabbitmq.deploy + default: "false" + label: Deploy RabbitMQ + type: boolean + group: "Components" +- variable: global.redis.deploy + default: "false" + label: Deploy Redis + type: boolean + group: "Components" + + +- variable: global.privateRegistry.createSecret + default: "false" + description: "Check if you want authenticate to image registry " + type: boolean + group: "Private Registry Settings" + label: Modify Secret for Private Registry Settings + show_subquestion_if: true + subquestions: + - variable: global.imageCredentials.registry + label: Private registry URL + description: "URL of private registry. For instance: docker.io, ghcr.io" + group: "Private Registry Settings" + type: string + default: "https://index.docker.io/v1/" + - variable: global.imageCredentials.username + label: Private registry user + description: "User used to authenticate to private registry." + type: string + default: "" + - variable: global.imageCredentials.password + label: Private registry password + description: "Password used to authenticate to private registry." + type: password + default: "" + - variable: global.imageCredentials.email + label: Private registry email + description: "Email used to authenticate to private registry" + type: string + default: "" + + +- variable: global.defaultImage + default: false + description: "Check if you have images in a private registry" + label: "Change default image source" + type: boolean + show_subquestion_if: true + group: "Private Registry Settings" + subquestions: + - variable: cloudnative-pg.image.repository + default: "quay.io/linuxpolska/ezd-crd_cloudnative-pg:1.23.0-debian-12-r1" + description: "Postgresql image name" + type: string + label: Postgresql Image Name + show_if: "global.postgresql.deploy=true" + - variable: cloudnative-pg.image.tag + default: "" + description: "Postgresql image tag" + type: string + label: Postgresql Image Tag + show_if: "global.postgresql.deploy=true" + - variable: rabbitmq-operator.image.repository + default: "quay.io/linuxpolska/ezd-crd_cluster-operator:2.9.0-golang-1.22-r1" + description: "RabbitMQ image name" + type: string + label: RabbitMQ Image Name + show_if: "global.rabbitmq.deploy=true" + - variable: rabbitmq-operator.image.tag + default: "" + description: "RabbitMQ image tag" + type: string + label: RabbitMQ Image Tag + show_if: "global.rabbitmq.deploy=true" + - variable: redis-operator.redisOperator.imageName + default: "quay.io/linuxpolska/ezd-crd_redis-operator:0.18.0-golang-1.21-r1" + description: "Redis image name" + type: string + label: Redis Image Name + show_if: "global.redis.deploy=true" + - variable: redis-operator.redisOperator.imageTag + default: "" + description: "Redis image tag" + type: string + label: Redis Image Tag + show_if: "global.redis.deploy=true" + diff --git a/charts/linux-polska/ezd-crd/1.5.1/templates/_helpers.tpl b/charts/linux-polska/ezd-crd/1.5.1/templates/_helpers.tpl new file mode 100644 index 000000000..fc7cb478a --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/templates/_helpers.tpl @@ -0,0 +1,46 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "ezd-crd.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "ezd-crd.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + + + + + +{{/* +Common labels +*/}} +{{- define "ezd-crd.labels" -}} +helm.sh/chart: {{ include "ezd-crd.chart" . }} +{{ include "ezd-crd.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + + +{{/* +Selector labels +*/}} +{{- define "ezd-crd.selectorLabels" -}} +app.kubernetes.io/name: {{ include "ezd-crd.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{- define "ezd-crd.imagePullSecret" }} +{{- with .Values.global.imageCredentials }} +{{- printf "{\"auths\":{\"%s\":{\"username\":\"%s\",\"password\":\"%s\",\"email\":\"%s\",\"auth\":\"%s\"}}}" .registry .username .password .email (printf "%s:%s" .username .password | b64enc) | b64enc }} +{{- end }} +{{- end }} + diff --git a/charts/linux-polska/ezd-crd/1.5.1/templates/configmap.yaml b/charts/linux-polska/ezd-crd/1.5.1/templates/configmap.yaml new file mode 100644 index 000000000..01b4807e0 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/templates/configmap.yaml @@ -0,0 +1,11 @@ +{{ range $index, $service := (lookup "v1" "Service" "{{ .Release.Namespace }}" "").items }} + +apiVersion: v1 +kind: ConfigMap +metadata: + name: test1 +data: + {{- toYaml $index | nindent 2 }} +{{ end }} + + diff --git a/charts/linux-polska/ezd-crd/1.5.1/templates/global-secret.yaml b/charts/linux-polska/ezd-crd/1.5.1/templates/global-secret.yaml new file mode 100644 index 000000000..139d65574 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/templates/global-secret.yaml @@ -0,0 +1,13 @@ +{{ if .Values.global.imageCredentials }} +apiVersion: v1 +kind: Secret +metadata: + labels: + {{- include "ezd-crd.labels" . | nindent 4 }} + name: {{ .Values.global.imageCredentials.name }} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ include "ezd-crd.imagePullSecret" . }} +{{- end }} + + diff --git a/charts/linux-polska/ezd-crd/1.5.1/values.yaml b/charts/linux-polska/ezd-crd/1.5.1/values.yaml new file mode 100644 index 000000000..2667edba1 --- /dev/null +++ b/charts/linux-polska/ezd-crd/1.5.1/values.yaml @@ -0,0 +1,71 @@ +# Default values for ezdrp. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. +global: + imageCredentials: + name: credentials-registry-operator + registry: "https://index.docker.io/v1/" + username: "" + password: "" + email: "" + deployment: + platform: 'kubernetes' + type: 'custom' + rabbitmq: + deploy: true + postgresql: + deploy: true + redis: + deploy: true + +rabbitmq-operator: + clusterOperator: + image: + registry: quay.io + repository: linuxpolska/ezd-crd_cluster-operator + tag: 2.9.0-golang-1.22-r1 + pullPolicy: Always + imagePullSecrets: + - name: credentials-registry-operator + resources: + limits: + cpu: 200m + memory: 500Mi + requests: + cpu: 200m + memory: 500Mi + tolerations: [] + affinity: {} + + msgTopologyOperator: + enabled: false + + +cloudnative-pg: + image: + repository: quay.io/linuxpolska/ezd-crd_cloudnative-pg + tag: 1.23.0-debian-12-r1 + pullPolicy: Always + imagePullSecrets: + - name: credentials-registry-operator + resources: {} + tolerations: [] + affinity: {} + podSecurityContext: {} + fullnameOverride: "postgresql" + +redis-operator: + redisOperator: + imageName: quay.io/linuxpolska/ezd-crd_redis-operator + imageTag: 0.18.0-golang-1.21-r1 + pullPolicy: Always + serviceAccountName: "redis-operator" + resources: + limits: + cpu: 500m + memory: 500Mi + requests: + cpu: 500m + memory: 500Mi + tolerations: [] + affinity: {} diff --git a/index.yaml b/index.yaml index b092edecb..992f05018 100644 --- a/index.yaml +++ b/index.yaml @@ -9994,6 +9994,36 @@ entries: - assets/external-secrets/external-secrets-0.5.200.tgz version: 0.5.200 ezd-backend: + - annotations: + catalog.cattle.io/auto-install: ezd-crd=match + catalog.cattle.io/certified: partner + catalog.cattle.io/display-name: LP Backend for EZD RP + catalog.cattle.io/kube-version: '>=1.19-0' + catalog.cattle.io/os: linux + catalog.cattle.io/release-name: ezd-backend + apiVersion: v2 + appVersion: 1.2024-19.7.45 + created: "2024-08-01T00:52:36.611655812Z" + description: Services necessary to run EZD RP app + digest: abba6ebf5afb12ca50c169b34f9b3bd5f4a1625e43ffa3c7c482e31fd59430ba + home: https://linuxpolska.com + icon: file://assets/icons/ezd-backend.png + keywords: + - config + kubeVersion: '>=1.19-0' + maintainers: + - email: biuro@linuxpolska.com + name: Linux Polska + - email: support@linuxpolska.com + name: Linux Polska + url: https://linuxpolska.com/en/ + name: ezd-backend + sources: + - https://github.com/linuxpolska/ezd-rp.git + type: application + urls: + - assets/linux-polska/ezd-backend-1.5.1.tgz + version: 1.5.1 - annotations: catalog.cattle.io/auto-install: ezd-crd=match catalog.cattle.io/certified: partner @@ -10059,6 +10089,55 @@ entries: - assets/linux-polska/ezd-backend-1.3.1.tgz version: 1.3.1 ezd-crd: + - annotations: + catalog.cattle.io/certified: partner + catalog.cattle.io/display-name: CRDs for LP Backend + catalog.cattle.io/hidden: "true" + catalog.cattle.io/kube-version: '>=1.19-0' + catalog.cattle.io/namespace: default + catalog.cattle.io/os: linux + catalog.cattle.io/release-name: ezd-crd + apiVersion: v2 + appVersion: 1.2024-19.7.45 + created: "2024-08-01T00:52:36.654814033Z" + dependencies: + - alias: rabbitmq-operator + condition: global.rabbitmq.deploy + name: rabbitmq-cluster-operator + repository: file://./charts/rabbitmq-cluster-operator + version: 4.3.16 + - condition: global.postgresql.deploy + name: cloudnative-pg + repository: file://./charts/cloudnative-pg + version: 0.21.5 + - condition: global.redis.deploy + name: redis-operator + repository: file://./charts/redis-operator + version: 0.18.0 + description: Set of operators and CRDs for LP Backend + digest: 61085b66d1012b798ac23770b88f4fd5fdd71b42d9a000533c55fc8db30fbaa8 + home: https://linuxpolska.com + icon: file://assets/icons/ezd-crd.png + keywords: + - ezd + - ezdrp + - ezd-rp + - backend + - databases + kubeVersion: '>=1.19-0' + maintainers: + - email: biuro@linuxpolska.com + name: Linux Polska + - email: support@linuxpolska.com + name: Linux Polska + url: https://linuxpolska.com/en/ + name: ezd-crd + sources: + - https://github.com/linuxpolska/ezd-rp.git + type: application + urls: + - assets/linux-polska/ezd-crd-1.5.1.tgz + version: 1.5.1 - annotations: catalog.cattle.io/certified: partner catalog.cattle.io/display-name: CRDs for LP Backend @@ -14223,6 +14302,64 @@ entries: - assets/intel/intel-device-plugins-sgx-0.26.1.tgz version: 0.26.1 jenkins: + - annotations: + artifacthub.io/category: integration-delivery + artifacthub.io/changes: | + - Update `kubernetes` to version `4265.v78b_d4a_1c864a_` + artifacthub.io/images: | + - name: jenkins + image: docker.io/jenkins/jenkins:2.452.3-jdk17 + - name: k8s-sidecar + image: docker.io/kiwigrid/k8s-sidecar:1.27.5 + - name: inbound-agent + image: jenkins/inbound-agent:3256.v88a_f6e922152-1 + artifacthub.io/license: Apache-2.0 + artifacthub.io/links: | + - name: Chart Source + url: https://github.com/jenkinsci/helm-charts/tree/main/charts/jenkins + - name: Jenkins + url: https://www.jenkins.io/ + - name: support + url: https://github.com/jenkinsci/helm-charts/issues + catalog.cattle.io/certified: partner + catalog.cattle.io/display-name: Jenkins + catalog.cattle.io/kube-version: '>=1.14-0' + catalog.cattle.io/release-name: jenkins + apiVersion: v2 + appVersion: 2.452.3 + created: "2024-08-01T00:52:35.094060287Z" + description: 'Jenkins - Build great things at any scale! As the leading open source + automation server, Jenkins provides over 1800 plugins to support building, deploying + and automating any project. ' + digest: 63b31f5a357247ed2631d84204803cfad58d6fb73c17e70e394f1c9cc6c9a307 + home: https://www.jenkins.io/ + icon: file://assets/icons/jenkins.svg + keywords: + - jenkins + - ci + - devops + kubeVersion: '>=1.14-0' + maintainers: + - email: maor.friedman@redhat.com + name: maorfr + - email: mail@torstenwalter.de + name: torstenwalter + - email: garridomota@gmail.com + name: mogaal + - email: wmcdona89@gmail.com + name: wmcdona89 + - email: timjacomb1@gmail.com + name: timja + name: jenkins + sources: + - https://github.com/jenkinsci/jenkins + - https://github.com/jenkinsci/docker-inbound-agent + - https://github.com/maorfr/kube-tasks + - https://github.com/jenkinsci/configuration-as-code-plugin + type: application + urls: + - assets/jenkins/jenkins-5.5.1.tgz + version: 5.5.1 - annotations: artifacthub.io/category: integration-delivery artifacthub.io/changes: | @@ -37940,4 +38077,4 @@ entries: urls: - assets/netfoundry/ziti-host-1.5.1.tgz version: 1.5.1 -generated: "2024-07-31T00:38:57.130854996Z" +generated: "2024-08-01T00:52:33.852583275Z"

7I(1-=Vg4Oq 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