From 0fa2e16d579faecc201e8d9b4510f1b2efc1d6f5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 27 Aug 2024 00:52:55 +0000 Subject: [PATCH] Added chart versions: cockroach-labs/cockroachdb: - 14.0.0 confluent/confluent-for-kubernetes: - 0.1033.22 crate/crate-operator: - 2.41.0 speedscale/speedscale-operator: - 2.2.303 stackstate/stackstate-k8s-agent: - 1.0.95 --- assets/cockroach-labs/cockroachdb-14.0.0.tgz | Bin 0 -> 31742 bytes .../confluent-for-kubernetes-0.1033.22.tgz | Bin 0 -> 369958 bytes assets/crate/crate-operator-2.41.0.tgz | Bin 0 -> 7816 bytes .../speedscale-operator-2.2.303.tgz | Bin 0 -> 16694 bytes .../stackstate-k8s-agent-1.0.95.tgz | Bin 0 -> 34922 bytes .../cockroachdb/14.0.0/CONTRIBUTING.md | 14 + .../cockroachdb/14.0.0/Chart.yaml | 18 + .../cockroachdb/14.0.0/README.md | 586 + .../cockroachdb/14.0.0/app-readme.md | 9 + .../cockroachdb/14.0.0/templates/NOTES.txt | 50 + .../cockroachdb/14.0.0/templates/_helpers.tpl | 291 + .../14.0.0/templates/backendconfig.yaml | 21 + .../14.0.0/templates/certificate.ca.yaml | 33 + .../14.0.0/templates/certificate.client.yaml | 40 + .../14.0.0/templates/certificate.issuer.yaml | 20 + .../14.0.0/templates/certificate.node.yaml | 50 + .../14.0.0/templates/clusterrole.yaml | 19 + .../14.0.0/templates/clusterrolebinding.yaml | 23 + .../templates/cronjob-ca-certSelfSigner.yaml | 46 + .../cronjob-client-node-certSelfSigner.yaml | 53 + .../cockroachdb/14.0.0/templates/ingress.yaml | 90 + .../14.0.0/templates/job-certSelfSigner.yaml | 83 + .../14.0.0/templates/job-cleaner.yaml | 55 + .../14.0.0/templates/job.init.yaml | 296 + .../14.0.0/templates/networkpolicy.yaml | 59 + .../14.0.0/templates/poddisruptionbudget.yaml | 26 + .../templates/role-certRotateSelfSigner.yaml | 27 + .../14.0.0/templates/role-certSelfSigner.yaml | 33 + .../cockroachdb/14.0.0/templates/role.yaml | 23 + .../rolebinding-certRotateSelfSigner.yaml | 23 + .../templates/rolebinding-certSelfSigner.yaml | 29 + .../14.0.0/templates/rolebinding.yaml | 23 + .../templates/secret.backendconfig.yaml | 25 + .../14.0.0/templates/secret.logconfig.yaml | 19 + .../14.0.0/templates/secret.registry.yaml | 23 + .../14.0.0/templates/secrets.init.yaml | 20 + .../14.0.0/templates/service.discovery.yaml | 64 + .../14.0.0/templates/service.public.yaml | 55 + .../14.0.0/templates/serviceMonitor.yaml | 54 + .../serviceaccount-certRotateSelfSigner.yaml | 22 + .../serviceaccount-certSelfSigner.yaml | 25 + .../14.0.0/templates/serviceaccount.yaml | 21 + .../14.0.0/templates/statefulset.yaml | 402 + .../14.0.0/templates/tests/client.yaml | 65 + .../cockroachdb/14.0.0/values.schema.json | 97 + .../cockroachdb/14.0.0/values.yaml | 590 + .../0.1033.22/Chart.yaml | 23 + .../0.1033.22/README.md | 72 + .../0.1033.22/app-readme.md | 3 + .../platform.confluent.io_clusterlinks.yaml | 883 ++ ...rm.confluent.io_confluentrolebindings.yaml | 296 + .../platform.confluent.io_connectors.yaml | 496 + .../crds/platform.confluent.io_connects.yaml | 6941 ++++++++++ .../platform.confluent.io_controlcenters.yaml | 6394 +++++++++ ...latform.confluent.io_kafkarestclasses.yaml | 557 + ...latform.confluent.io_kafkarestproxies.yaml | 5834 ++++++++ .../crds/platform.confluent.io_kafkas.yaml | 10948 ++++++++++++++++ .../platform.confluent.io_kafkatopics.yaml | 410 + ...latform.confluent.io_kraftcontrollers.yaml | 5752 ++++++++ ...tform.confluent.io_kraftmigrationjobs.yaml | 194 + .../crds/platform.confluent.io_ksqldbs.yaml | 6646 ++++++++++ ...platform.confluent.io_schemaexporters.yaml | 688 + ...latform.confluent.io_schemaregistries.yaml | 5801 ++++++++ .../crds/platform.confluent.io_schemas.yaml | 590 + .../platform.confluent.io_zookeepers.yaml | 4713 +++++++ .../0.1033.22/templates/NOTES.txt | 4 + .../0.1033.22/templates/_helpers.tpl | 42 + .../0.1033.22/templates/clusterrole.yaml | 172 + .../templates/clusterrolebinding.yaml | 56 + .../0.1033.22/templates/deployment.yaml | 238 + .../0.1033.22/templates/licensing.yaml | 19 + .../0.1033.22/templates/service.yaml | 28 + .../0.1033.22/templates/serviceaccount.yaml | 18 + .../validatingwebhookconfiguration.yaml | 184 + .../0.1033.22/values.yaml | 269 + .../crate/crate-operator/2.41.0/.helmignore | 23 + charts/crate/crate-operator/2.41.0/Chart.lock | 6 + charts/crate/crate-operator/2.41.0/Chart.yaml | 18 + charts/crate/crate-operator/2.41.0/README.md | 61 + .../charts/crate-operator-crds/.helmignore | 23 + .../charts/crate-operator-crds/Chart.yaml | 9 + .../charts/crate-operator-crds/README.md | 30 + .../crate-operator-crds/templates/NOTES.txt | 1 + .../templates/cratedbs-cloud-crate-io.yaml | 691 + .../charts/crate-operator-crds/values.yaml | 3 + .../crate-operator/2.41.0/templates/NOTES.txt | 1 + .../2.41.0/templates/_helpers.tpl | 63 + .../2.41.0/templates/deployment.yaml | 59 + .../crate-operator/2.41.0/templates/rbac.yaml | 87 + .../2.41.0/templates/serviceaccount.yaml | 18 + .../crate/crate-operator/2.41.0/values.yaml | 65 + .../speedscale-operator/2.2.303/.helmignore | 23 + .../speedscale-operator/2.2.303/Chart.yaml | 27 + .../speedscale-operator/2.2.303/LICENSE | 201 + .../speedscale-operator/2.2.303/README.md | 108 + .../speedscale-operator/2.2.303/app-readme.md | 108 + .../2.2.303/questions.yaml | 9 + .../2.2.303/templates/NOTES.txt | 12 + .../2.2.303/templates/admission.yaml | 199 + .../2.2.303/templates/configmap.yaml | 41 + .../templates/crds/trafficreplays.yaml | 515 + .../2.2.303/templates/deployments.yaml | 132 + .../2.2.303/templates/hooks.yaml | 73 + .../2.2.303/templates/rbac.yaml | 244 + .../2.2.303/templates/secrets.yaml | 18 + .../2.2.303/templates/services.yaml | 22 + .../2.2.303/templates/tls.yaml | 183 + .../speedscale-operator/2.2.303/values.yaml | 133 + .../stackstate-k8s-agent/1.0.95/.helmignore | 26 + .../stackstate-k8s-agent/1.0.95/Chart.lock | 6 + .../stackstate-k8s-agent/1.0.95/Chart.yaml | 25 + .../stackstate-k8s-agent/1.0.95/README.md | 263 + .../1.0.95/README.md.gotmpl | 45 + .../stackstate-k8s-agent/1.0.95/Releasing.md | 15 + .../stackstate-k8s-agent/1.0.95/app-readme.md | 5 + .../charts/http-header-injector/.helmignore | 25 + .../charts/http-header-injector/Chart.yaml | 15 + .../charts/http-header-injector/README.md | 56 + .../http-header-injector/Readme.md.gotpl | 26 + .../templates/_defines.tpl | 131 + .../cert-hook-clusterrolbinding.yaml | 24 + .../templates/cert-hook-clusterrole.yaml | 26 + .../templates/cert-hook-config.yaml | 158 + .../templates/cert-hook-job-delete.yaml | 39 + .../templates/cert-hook-job-setup.yaml | 39 + .../templates/cert-hook-serviceaccount.yaml | 18 + .../templates/pull-secret.yaml | 32 + .../templates/webhook-cert-secret.yaml | 18 + .../templates/webhook-certificate.yaml | 23 + .../templates/webhook-config.yaml | 128 + .../templates/webhook-deployment.yaml | 61 + .../webhook-mutatingwebhookconfiguration.yaml | 54 + .../templates/webhook-service.yaml | 20 + .../charts/http-header-injector/values.yaml | 110 + .../stackstate-k8s-agent/1.0.95/questions.yml | 184 + .../_cluster-agent-kube-state-metrics.yaml | 62 + .../1.0.95/templates/_container-agent.yaml | 191 + .../templates/_container-process-agent.yaml | 160 + .../1.0.95/templates/_helpers.tpl | 219 + .../checks-agent-clusterrolebinding.yaml | 21 + .../templates/checks-agent-configmap.yaml | 17 + .../templates/checks-agent-deployment.yaml | 185 + .../checks-agent-poddisruptionbudget.yaml | 23 + .../checks-agent-serviceaccount.yaml | 16 + .../templates/cluster-agent-clusterrole.yaml | 152 + .../cluster-agent-clusterrolebinding.yaml | 19 + .../templates/cluster-agent-configmap.yaml | 31 + .../templates/cluster-agent-deployment.yaml | 169 + .../cluster-agent-poddisruptionbudget.yaml | 21 + .../1.0.95/templates/cluster-agent-role.yaml | 21 + .../templates/cluster-agent-rolebinding.yaml | 18 + .../templates/cluster-agent-service.yaml | 21 + .../cluster-agent-serviceaccount.yaml | 14 + .../templates/logs-agent-clusterrole.yaml | 23 + .../logs-agent-clusterrolebinding.yaml | 21 + .../templates/logs-agent-configmap.yaml | 63 + .../templates/logs-agent-daemonset.yaml | 91 + .../templates/logs-agent-serviceaccount.yaml | 16 + .../templates/node-agent-clusterrole.yaml | 21 + .../node-agent-clusterrolebinding.yaml | 19 + .../templates/node-agent-configmap.yaml | 17 + .../templates/node-agent-daemonset.yaml | 110 + .../templates/node-agent-podautoscaler.yaml | 39 + .../1.0.95/templates/node-agent-scc.yaml | 60 + .../1.0.95/templates/node-agent-service.yaml | 28 + .../templates/node-agent-serviceaccount.yaml | 14 + .../templates/openshift-logging-secret.yaml | 22 + .../1.0.95/templates/pull-secret.yaml | 39 + .../1.0.95/templates/secret.yaml | 27 + .../test/clusteragent_resources_test.go | 145 + .../1.0.95/test/clustername_test.go | 54 + .../values/clustercheck_ksm_custom_url.yaml | 7 + .../values/clustercheck_ksm_no_override.yaml | 5 + .../values/clustercheck_ksm_override.yaml | 26 + .../clustercheck_no_ksm_custom_url.yaml | 7 + .../clustercheck_service_port_override.yaml | 4 + .../test/values/disable-all-resource.yaml | 17 + .../test/values/http-header-injector.yaml | 8 + .../1.0.95/test/values/minimal.yaml | 7 + .../1.0.95/values.schema.json | 78 + .../stackstate-k8s-agent/1.0.95/values.yaml | 616 + index.yaml | 133 +- 182 files changed, 69647 insertions(+), 1 deletion(-) create mode 100644 assets/cockroach-labs/cockroachdb-14.0.0.tgz create mode 100644 assets/confluent/confluent-for-kubernetes-0.1033.22.tgz create mode 100644 assets/crate/crate-operator-2.41.0.tgz create mode 100644 assets/speedscale/speedscale-operator-2.2.303.tgz create mode 100644 assets/stackstate/stackstate-k8s-agent-1.0.95.tgz create mode 100644 charts/cockroach-labs/cockroachdb/14.0.0/CONTRIBUTING.md create mode 100644 charts/cockroach-labs/cockroachdb/14.0.0/Chart.yaml create mode 100644 charts/cockroach-labs/cockroachdb/14.0.0/README.md create mode 100644 charts/cockroach-labs/cockroachdb/14.0.0/app-readme.md create mode 100644 charts/cockroach-labs/cockroachdb/14.0.0/templates/NOTES.txt create mode 100644 charts/cockroach-labs/cockroachdb/14.0.0/templates/_helpers.tpl create mode 100644 charts/cockroach-labs/cockroachdb/14.0.0/templates/backendconfig.yaml create mode 100644 charts/cockroach-labs/cockroachdb/14.0.0/templates/certificate.ca.yaml create mode 100644 charts/cockroach-labs/cockroachdb/14.0.0/templates/certificate.client.yaml create mode 100644 charts/cockroach-labs/cockroachdb/14.0.0/templates/certificate.issuer.yaml create mode 100644 charts/cockroach-labs/cockroachdb/14.0.0/templates/certificate.node.yaml create mode 100644 charts/cockroach-labs/cockroachdb/14.0.0/templates/clusterrole.yaml create mode 100644 charts/cockroach-labs/cockroachdb/14.0.0/templates/clusterrolebinding.yaml create mode 100644 charts/cockroach-labs/cockroachdb/14.0.0/templates/cronjob-ca-certSelfSigner.yaml create mode 100644 charts/cockroach-labs/cockroachdb/14.0.0/templates/cronjob-client-node-certSelfSigner.yaml create mode 100644 charts/cockroach-labs/cockroachdb/14.0.0/templates/ingress.yaml create mode 100644 charts/cockroach-labs/cockroachdb/14.0.0/templates/job-certSelfSigner.yaml create mode 100644 charts/cockroach-labs/cockroachdb/14.0.0/templates/job-cleaner.yaml create mode 100644 charts/cockroach-labs/cockroachdb/14.0.0/templates/job.init.yaml create mode 100644 charts/cockroach-labs/cockroachdb/14.0.0/templates/networkpolicy.yaml create mode 100644 charts/cockroach-labs/cockroachdb/14.0.0/templates/poddisruptionbudget.yaml create mode 100644 charts/cockroach-labs/cockroachdb/14.0.0/templates/role-certRotateSelfSigner.yaml create mode 100644 charts/cockroach-labs/cockroachdb/14.0.0/templates/role-certSelfSigner.yaml create mode 100644 charts/cockroach-labs/cockroachdb/14.0.0/templates/role.yaml create mode 100644 charts/cockroach-labs/cockroachdb/14.0.0/templates/rolebinding-certRotateSelfSigner.yaml create mode 100644 charts/cockroach-labs/cockroachdb/14.0.0/templates/rolebinding-certSelfSigner.yaml create mode 100644 charts/cockroach-labs/cockroachdb/14.0.0/templates/rolebinding.yaml create mode 100644 charts/cockroach-labs/cockroachdb/14.0.0/templates/secret.backendconfig.yaml create mode 100644 charts/cockroach-labs/cockroachdb/14.0.0/templates/secret.logconfig.yaml create mode 100644 charts/cockroach-labs/cockroachdb/14.0.0/templates/secret.registry.yaml create mode 100644 charts/cockroach-labs/cockroachdb/14.0.0/templates/secrets.init.yaml create mode 100644 charts/cockroach-labs/cockroachdb/14.0.0/templates/service.discovery.yaml create mode 100644 charts/cockroach-labs/cockroachdb/14.0.0/templates/service.public.yaml create mode 100644 charts/cockroach-labs/cockroachdb/14.0.0/templates/serviceMonitor.yaml create mode 100644 charts/cockroach-labs/cockroachdb/14.0.0/templates/serviceaccount-certRotateSelfSigner.yaml create mode 100644 charts/cockroach-labs/cockroachdb/14.0.0/templates/serviceaccount-certSelfSigner.yaml create mode 100644 charts/cockroach-labs/cockroachdb/14.0.0/templates/serviceaccount.yaml create mode 100644 charts/cockroach-labs/cockroachdb/14.0.0/templates/statefulset.yaml create mode 100644 charts/cockroach-labs/cockroachdb/14.0.0/templates/tests/client.yaml create mode 100644 charts/cockroach-labs/cockroachdb/14.0.0/values.schema.json create mode 100644 charts/cockroach-labs/cockroachdb/14.0.0/values.yaml create mode 100644 charts/confluent/confluent-for-kubernetes/0.1033.22/Chart.yaml create mode 100644 charts/confluent/confluent-for-kubernetes/0.1033.22/README.md create mode 100644 charts/confluent/confluent-for-kubernetes/0.1033.22/app-readme.md create mode 100644 charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_clusterlinks.yaml create mode 100644 charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_confluentrolebindings.yaml create mode 100644 charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_connectors.yaml create mode 100644 charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_connects.yaml create mode 100644 charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_controlcenters.yaml create mode 100644 charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_kafkarestclasses.yaml create mode 100644 charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_kafkarestproxies.yaml create mode 100644 charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_kafkas.yaml create mode 100644 charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_kafkatopics.yaml create mode 100644 charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_kraftcontrollers.yaml create mode 100644 charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_kraftmigrationjobs.yaml create mode 100644 charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_ksqldbs.yaml create mode 100644 charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_schemaexporters.yaml create mode 100644 charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_schemaregistries.yaml create mode 100644 charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_schemas.yaml create mode 100644 charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_zookeepers.yaml create mode 100644 charts/confluent/confluent-for-kubernetes/0.1033.22/templates/NOTES.txt create mode 100644 charts/confluent/confluent-for-kubernetes/0.1033.22/templates/_helpers.tpl create mode 100644 charts/confluent/confluent-for-kubernetes/0.1033.22/templates/clusterrole.yaml create mode 100644 charts/confluent/confluent-for-kubernetes/0.1033.22/templates/clusterrolebinding.yaml create mode 100644 charts/confluent/confluent-for-kubernetes/0.1033.22/templates/deployment.yaml create mode 100644 charts/confluent/confluent-for-kubernetes/0.1033.22/templates/licensing.yaml create mode 100644 charts/confluent/confluent-for-kubernetes/0.1033.22/templates/service.yaml create mode 100644 charts/confluent/confluent-for-kubernetes/0.1033.22/templates/serviceaccount.yaml create mode 100644 charts/confluent/confluent-for-kubernetes/0.1033.22/templates/validatingwebhookconfiguration.yaml create mode 100644 charts/confluent/confluent-for-kubernetes/0.1033.22/values.yaml create mode 100644 charts/crate/crate-operator/2.41.0/.helmignore create mode 100644 charts/crate/crate-operator/2.41.0/Chart.lock create mode 100644 charts/crate/crate-operator/2.41.0/Chart.yaml create mode 100644 charts/crate/crate-operator/2.41.0/README.md create mode 100644 charts/crate/crate-operator/2.41.0/charts/crate-operator-crds/.helmignore create mode 100644 charts/crate/crate-operator/2.41.0/charts/crate-operator-crds/Chart.yaml create mode 100644 charts/crate/crate-operator/2.41.0/charts/crate-operator-crds/README.md create mode 100644 charts/crate/crate-operator/2.41.0/charts/crate-operator-crds/templates/NOTES.txt create mode 100644 charts/crate/crate-operator/2.41.0/charts/crate-operator-crds/templates/cratedbs-cloud-crate-io.yaml create mode 100644 charts/crate/crate-operator/2.41.0/charts/crate-operator-crds/values.yaml create mode 100644 charts/crate/crate-operator/2.41.0/templates/NOTES.txt create mode 100644 charts/crate/crate-operator/2.41.0/templates/_helpers.tpl create mode 100644 charts/crate/crate-operator/2.41.0/templates/deployment.yaml create mode 100644 charts/crate/crate-operator/2.41.0/templates/rbac.yaml create mode 100644 charts/crate/crate-operator/2.41.0/templates/serviceaccount.yaml create mode 100644 charts/crate/crate-operator/2.41.0/values.yaml create mode 100644 charts/speedscale/speedscale-operator/2.2.303/.helmignore create mode 100644 charts/speedscale/speedscale-operator/2.2.303/Chart.yaml create mode 100644 charts/speedscale/speedscale-operator/2.2.303/LICENSE create mode 100644 charts/speedscale/speedscale-operator/2.2.303/README.md create mode 100644 charts/speedscale/speedscale-operator/2.2.303/app-readme.md create mode 100644 charts/speedscale/speedscale-operator/2.2.303/questions.yaml create mode 100644 charts/speedscale/speedscale-operator/2.2.303/templates/NOTES.txt create mode 100644 charts/speedscale/speedscale-operator/2.2.303/templates/admission.yaml create mode 100644 charts/speedscale/speedscale-operator/2.2.303/templates/configmap.yaml create mode 100644 charts/speedscale/speedscale-operator/2.2.303/templates/crds/trafficreplays.yaml create mode 100644 charts/speedscale/speedscale-operator/2.2.303/templates/deployments.yaml create mode 100644 charts/speedscale/speedscale-operator/2.2.303/templates/hooks.yaml create mode 100644 charts/speedscale/speedscale-operator/2.2.303/templates/rbac.yaml create mode 100644 charts/speedscale/speedscale-operator/2.2.303/templates/secrets.yaml create mode 100644 charts/speedscale/speedscale-operator/2.2.303/templates/services.yaml create mode 100644 charts/speedscale/speedscale-operator/2.2.303/templates/tls.yaml create mode 100644 charts/speedscale/speedscale-operator/2.2.303/values.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/.helmignore create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/Chart.lock create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/Chart.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/README.md create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/README.md.gotmpl create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/Releasing.md create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/app-readme.md create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/.helmignore create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/Chart.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/README.md create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/Readme.md.gotpl create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/_defines.tpl create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/cert-hook-clusterrolbinding.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/cert-hook-clusterrole.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/cert-hook-config.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/cert-hook-job-delete.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/cert-hook-job-setup.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/cert-hook-serviceaccount.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/pull-secret.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/webhook-cert-secret.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/webhook-certificate.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/webhook-config.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/webhook-deployment.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/webhook-mutatingwebhookconfiguration.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/webhook-service.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/values.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/questions.yml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/templates/_cluster-agent-kube-state-metrics.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/templates/_container-agent.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/templates/_container-process-agent.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/templates/_helpers.tpl create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/templates/checks-agent-clusterrolebinding.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/templates/checks-agent-configmap.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/templates/checks-agent-deployment.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/templates/checks-agent-poddisruptionbudget.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/templates/checks-agent-serviceaccount.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/templates/cluster-agent-clusterrole.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/templates/cluster-agent-clusterrolebinding.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/templates/cluster-agent-configmap.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/templates/cluster-agent-deployment.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/templates/cluster-agent-poddisruptionbudget.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/templates/cluster-agent-role.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/templates/cluster-agent-rolebinding.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/templates/cluster-agent-service.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/templates/cluster-agent-serviceaccount.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/templates/logs-agent-clusterrole.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/templates/logs-agent-clusterrolebinding.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/templates/logs-agent-configmap.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/templates/logs-agent-daemonset.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/templates/logs-agent-serviceaccount.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/templates/node-agent-clusterrole.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/templates/node-agent-clusterrolebinding.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/templates/node-agent-configmap.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/templates/node-agent-daemonset.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/templates/node-agent-podautoscaler.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/templates/node-agent-scc.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/templates/node-agent-service.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/templates/node-agent-serviceaccount.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/templates/openshift-logging-secret.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/templates/pull-secret.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/templates/secret.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/test/clusteragent_resources_test.go create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/test/clustername_test.go create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/test/values/clustercheck_ksm_custom_url.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/test/values/clustercheck_ksm_no_override.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/test/values/clustercheck_ksm_override.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/test/values/clustercheck_no_ksm_custom_url.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/test/values/clustercheck_service_port_override.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/test/values/disable-all-resource.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/test/values/http-header-injector.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/test/values/minimal.yaml create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/values.schema.json create mode 100644 charts/stackstate/stackstate-k8s-agent/1.0.95/values.yaml diff --git a/assets/cockroach-labs/cockroachdb-14.0.0.tgz b/assets/cockroach-labs/cockroachdb-14.0.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..59598c6de096cedc236cc808730ee92aa3fac816 GIT binary patch literal 31742 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�s2a+UYLy3 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

IIn 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 z

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


XJlTWBg8iJ)}zM#*8!q7UepD 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 efVOK{UaxORtWru0pI2a8a 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 Q0RRC1|37XONdPuC03q3F3IG5A literal 0 HcmV?d00001 diff --git a/assets/crate/crate-operator-2.41.0.tgz b/assets/crate/crate-operator-2.41.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..d0321adcbb8a9e0838b3a113f6d9ca9e8d234872 GIT binary patch literal 7816 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 a24AIBTBTL0N&gc70RR6LjsP+M+5iAB=x=xc literal 0 HcmV?d00001 diff --git a/assets/speedscale/speedscale-operator-2.2.303.tgz b/assets/speedscale/speedscale-operator-2.2.303.tgz new file mode 100644 index 0000000000000000000000000000000000000000..555783a5e9602f50c0bbba4430e1a42060716ca0 GIT binary patch literal 16694 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 JWbk2R006zV$8rDw literal 0 HcmV?d00001 diff --git a/assets/stackstate/stackstate-k8s-agent-1.0.95.tgz b/assets/stackstate/stackstate-k8s-agent-1.0.95.tgz new file mode 100644 index 0000000000000000000000000000000000000000..622e5941b169d717b3b99720df241a8857edebf6 GIT binary patch literal 34922 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 literal 0 HcmV?d00001 diff --git a/charts/cockroach-labs/cockroachdb/14.0.0/CONTRIBUTING.md b/charts/cockroach-labs/cockroachdb/14.0.0/CONTRIBUTING.md new file mode 100644 index 0000000000..e248d72e11 --- /dev/null +++ b/charts/cockroach-labs/cockroachdb/14.0.0/CONTRIBUTING.md @@ -0,0 +1,14 @@ +# Contributing + +Contributions are welcome! + +For every change, please increment the `version` contained in +[Chart.yaml](https://github.com/cockroachdb/helm-charts/blob/master/cockroachdb/Chart.yaml). +The `version` roughly follows the [SEMVER](https://semver.org/) versioning +pattern. For changes which do not affect backwards compatibility, the PATCH or +MINOR version must be incremented, e.g. `4.1.3` -> `4.1.4`. For changes which +affect the backwards compatibility of the chart, the major version must be +incremented, e.g. `4.1.3` -> `5.0.0`. Examples of changes which affect backwards +compatibility include any major version releases of CockroachDB, as well as any +breaking changes to the CockroachDB chart templates. + diff --git a/charts/cockroach-labs/cockroachdb/14.0.0/Chart.yaml b/charts/cockroach-labs/cockroachdb/14.0.0/Chart.yaml new file mode 100644 index 0000000000..ccbe616fe2 --- /dev/null +++ b/charts/cockroach-labs/cockroachdb/14.0.0/Chart.yaml @@ -0,0 +1,18 @@ +annotations: + catalog.cattle.io/certified: partner + catalog.cattle.io/display-name: CockroachDB + catalog.cattle.io/kube-version: '>=1.8-0' + catalog.cattle.io/release-name: cockroachdb +apiVersion: v1 +appVersion: 24.2.0 +description: CockroachDB is a scalable, survivable, strongly-consistent SQL database. +home: https://www.cockroachlabs.com +icon: file://assets/icons/cockroachdb.png +kubeVersion: '>=1.8-0' +maintainers: +- email: helm-charts@cockroachlabs.com + name: cockroachlabs +name: cockroachdb +sources: +- https://github.com/cockroachdb/cockroach +version: 14.0.0 diff --git a/charts/cockroach-labs/cockroachdb/14.0.0/README.md b/charts/cockroach-labs/cockroachdb/14.0.0/README.md new file mode 100644 index 0000000000..4a16e47c3d --- /dev/null +++ b/charts/cockroach-labs/cockroachdb/14.0.0/README.md @@ -0,0 +1,586 @@ + +# CockroachDB Helm Chart + +[CockroachDB](https://github.com/cockroachdb/cockroach) - the open source, cloud-native distributed SQL database. + +## Documentation + +Below is a brief overview of operating the CockroachDB Helm Chart and some specific implementation details. For additional information on deploying CockroachDB, please see: +> + +Note that the documentation requires Helm 3.0 or higher. + +## Prerequisites Details + +* Kubernetes 1.8 +* PV support on the underlying infrastructure (only if using `storage.persistentVolume`). [Docker for windows hostpath provisioner is not supported](https://github.com/cockroachdb/docs/issues/3184). +* If you want to secure your cluster to use TLS certificates for all network communication, [Helm must be installed with RBAC privileges](https://helm.sh/docs/topics/rbac/) or else you will get an "attempt to grant extra privileges" error. + +## StatefulSet Details + +* + +## StatefulSet Caveats + +* + +## Chart Details + +This chart will do the following: + +* Set up a dynamically scalable CockroachDB cluster using a Kubernetes StatefulSet. + +## Add the CockroachDB Repository + +```shell +helm repo add cockroachdb https://charts.cockroachdb.com/ +``` + +## Installing the Chart + +To install the chart with the release name `my-release`: + +```shell +helm install my-release cockroachdb/cockroachdb +``` + +Note that for a production cluster, you will likely want to override the following parameters in [`values.yaml`](values.yaml) with your own values. + +- `statefulset.resources.requests.memory` and `statefulset.resources.limits.memory` allocate memory resources to CockroachDB pods in your cluster. +- `conf.cache` and `conf.max-sql-memory` are memory limits that we recommend setting to 1/4 of the above resource allocation. When running CockroachDB, you must set these limits explicitly to avoid running out of memory. +- `storage.persistentVolume.size` defaults to `100Gi` of disk space per pod, which you may increase or decrease for your use case. +- `storage.persistentVolume.storageClass` uses the default storage class for your environment. We strongly recommend that you specify a storage class which uses an SSD. +- `tls.enabled` must be set to `yes`/`true` to deploy in secure mode. + +For more information on overriding the `values.yaml` parameters, please see: +> + +Confirm that all pods are `Running` successfully and init has been completed: + +```shell +kubectl get pods +``` + +``` +NAME READY STATUS RESTARTS AGE +my-release-cockroachdb-0 1/1 Running 0 1m +my-release-cockroachdb-1 1/1 Running 0 1m +my-release-cockroachdb-2 1/1 Running 0 1m +my-release-cockroachdb-init-k6jcr 0/1 Completed 0 1m +``` + +Confirm that persistent volumes are created and claimed for each pod: + +```shell +kubectl get pv +``` + +``` +NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE +pvc-64878ebf-f3f0-11e8-ab5b-42010a8e0035 100Gi RWO Delete Bound default/datadir-my-release-cockroachdb-0 standard 51s +pvc-64945b4f-f3f0-11e8-ab5b-42010a8e0035 100Gi RWO Delete Bound default/datadir-my-release-cockroachdb-1 standard 51s +pvc-649d920d-f3f0-11e8-ab5b-42010a8e0035 100Gi RWO Delete Bound default/datadir-my-release-cockroachdb-2 standard 51s +``` + +### Running in secure mode + +In order to set up a secure cockroachdb cluster set `tls.enabled` to `yes`/`true` + +There are 3 ways to configure a secure cluster, with this chart. This all relates to how the certificates are issued: + +* Self-signer (default) +* Cert-manager +* Manual + +#### Self-signer + +This is the default behaviour, and requires no configuration beyond setting certificate durations if user wants to set custom duration. + +If you are running in this mode, self-signed certificates are created by self-signed utility for the nodes and root client and are stored in a secret. +You can look for the certificates created: +```shell +kubectl get secrets +``` + +```shell +crdb-cockroachdb-ca-secret Opaque 2 23s +crdb-cockroachdb-client-secret kubernetes.io/tls 3 22s +crdb-cockroachdb-node-secret kubernetes.io/tls 3 23s +``` + + +#### Manual + +If you wish to supply the certificates to the nodes yourself set `tls.certs.provided` to `yes`/`true`. You may want to use this if you want to use a different certificate authority from the one being used by Kubernetes or if your Kubernetes cluster doesn't fully support certificate-signing requests. To use this, first set up your certificates and load them into your Kubernetes cluster as Secrets using the commands below: + +```shell +$ mkdir certs +$ mkdir my-safe-directory +$ cockroach cert create-ca --certs-dir=certs --ca-key=my-safe-directory/ca.key +$ cockroach cert create-client root --certs-dir=certs --ca-key=my-safe-directory/ca.key +$ kubectl create secret generic cockroachdb-root --from-file=certs +secret/cockroachdb-root created +$ cockroach cert create-node --certs-dir=certs --ca-key=my-safe-directory/ca.key localhost 127.0.0.1 my-release-cockroachdb-public my-release-cockroachdb-public.my-namespace my-release-cockroachdb-public.my-namespace.svc.cluster.local *.my-release-cockroachdb *.my-release-cockroachdb.my-namespace *.my-release-cockroachdb.my-namespace.svc.cluster.local +$ kubectl create secret generic cockroachdb-node --from-file=certs +secret/cockroachdb-node created +``` + +> Note: The subject alternative names are based on a release called `my-release` in the `my-namespace` namespace. Make sure they match the services created with the release during `helm install` + +If your certificates are stored in tls secrets such as secrets generated by cert-manager, the secret will contain files named: + +* `ca.crt` +* `tls.crt` +* `tls.key` + +Cockroachdb, however, expects the files to be named like this: + +* `ca.crt` +* `node.crt` +* `node.key` +* `client.root.crt` +* `client.root.key` + +By enabling `tls.certs.tlsSecret` the tls secrets are projected on to the correct filenames, when they are mounted to the cockroachdb pods. + +#### Cert-manager + +If you wish to supply certificates with [cert-manager][3], set + +* `tls.certs.certManager` to `yes`/`true` +* `tls.certs.certManagerIssuer` to an IssuerRef (as they appear in certificate resources) pointing to a clusterIssuer or issuer, you have set up in the cluster + +Example issuer: + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: cockroachdb-ca + namespace: cockroachdb +data: + tls.crt: [BASE64 Encoded ca.crt] + tls.key: [BASE64 Encoded ca.key] +type: kubernetes.io/tls +--- +apiVersion: cert-manager.io/v1alpha3 +kind: Issuer +metadata: + name: cockroachdb-cert-issuer + namespace: cockroachdb +spec: + ca: + secretName: cockroachdb-ca +``` + +## Upgrading the cluster + +### Chart version 3.0.0 and after + +Launch a temporary interactive pod and start the built-in SQL client: + +```shell +kubectl run cockroachdb --rm -it \ +--image=cockroachdb/cockroach \ +--restart=Never \ +-- sql --insecure --host=my-release-cockroachdb-public +``` + +> If you are running in secure mode, you will have to provide a client certificate to the cluster in order to authenticate, so the above command will not work. See [here](https://github.com/cockroachdb/cockroach/blob/master/cloud/kubernetes/client-secure.yaml) for an example of how to set up an interactive SQL shell against a secure cluster or [here](https://github.com/cockroachdb/cockroach/blob/master/cloud/kubernetes/example-app-secure.yaml) for an example application connecting to a secure cluster. + +Set `cluster.preserve_downgrade_option`, where `$current_version` is the CockroachDB version currently running (e.g., `19.2`): + +```sql +> SET CLUSTER SETTING cluster.preserve_downgrade_option = '$current_version'; +``` + +Exit the shell and delete the temporary pod: + +```sql +> \q +``` + +Kick off the upgrade process by changing the new Docker image, where `$new_version` is the CockroachDB version to which you are upgrading: + +```shell +helm upgrade my-release cockroachdb/cockroachdb \ +--set image.tag=$new_version \ +--reuse-values +``` + +Kubernetes will carry out a safe [rolling upgrade](https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/#updating-statefulsets) of your CockroachDB nodes one-by-one. Monitor the cluster's pods until all have been successfully restarted: + +```shell +kubectl get pods +``` + +``` +NAME READY STATUS RESTARTS AGE +my-release-cockroachdb-0 1/1 Running 0 2m +my-release-cockroachdb-1 1/1 Running 0 3m +my-release-cockroachdb-2 1/1 Running 0 3m +my-release-cockroachdb-3 0/1 ContainerCreating 0 25s +my-release-cockroachdb-init-nwjkh 0/1 ContainerCreating 0 6s +``` + +```shell +kubectl get pods \ +-o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[0].image}{"\n"}' +``` + +``` +my-release-cockroachdb-0 cockroachdb/cockroach:v24.2.0 +my-release-cockroachdb-1 cockroachdb/cockroach:v24.2.0 +my-release-cockroachdb-2 cockroachdb/cockroach:v24.2.0 +my-release-cockroachdb-3 cockroachdb/cockroach:v24.2.0 +``` + +Resume normal operations. Once you are comfortable that the stability and performance of the cluster is what you'd expect post-upgrade, finalize the upgrade: + +```shell +kubectl run cockroachdb --rm -it \ +--image=cockroachdb/cockroach \ +--restart=Never \ +-- sql --insecure --host=my-release-cockroachdb-public +``` + +```sql +> RESET CLUSTER SETTING cluster.preserve_downgrade_option; +> \q +``` + +### Chart versions prior to 3.0.0 + +Due to a change in the label format in version 3.0.0 of this chart, upgrading requires that you delete the StatefulSet. Luckily there is a way to do it without actually deleting all the resources managed by the StatefulSet. Use the workaround below to upgrade from charts versions previous to 3.0.0: + +Get the new labels from the specs rendered by Helm: + +```shell +helm template -f deploy.vals.yml cockroachdb/cockroachdb -x templates/statefulset.yaml \ +| yq r - spec.template.metadata.labels +``` + +``` +app.kubernetes.io/name: cockroachdb +app.kubernetes.io/instance: my-release +app.kubernetes.io/component: cockroachdb +``` + +Place the new labels on all pods of the StatefulSet (change `my-release-cockroachdb-0` to the name of each pod): + +```shell +kubectl label pods my-release-cockroachdb-0 \ +app.kubernetes.io/name=cockroachdb \ +app.kubernetes.io/instance=my-release \ +app.kubernetes.io/component=cockroachdb +``` + +Delete the StatefulSet without deleting pods: + +```shell +kubectl delete statefulset my-release-cockroachdb --cascade=false +``` + +Verify that no pod is deleted and then upgrade as normal. A new StatefulSet will be created, taking over the management of the existing pods and upgrading them if needed. + +### See also + +For more information about upgrading a cluster to the latest major release of CockroachDB, see [Upgrade to CockroachDB](https://www.cockroachlabs.com/docs/stable/upgrade-cockroach-version.html). + +Note that there are sometimes backward-incompatible changes to SQL features between major CockroachDB releases. For details, see the [Upgrade Policy](https://www.cockroachlabs.com/docs/cockroachcloud/upgrade-policy). + +## Configuration + +The following table lists the configurable parameters of the CockroachDB chart and their default values. +For details see the [`values.yaml`](values.yaml) file. + +| Parameter | Description | Default | +| --------- | ----------- | ------- | +| `clusterDomain` | Cluster's default DNS domain | `cluster.local` | +| `conf.attrs` | CockroachDB node attributes | `[]` | +| `conf.cache` | Size of CockroachDB's in-memory cache | `25%` | +| `conf.cluster-name` | Name of CockroachDB cluster | `""` | +| `conf.disable-cluster-name-verification` | Disable CockroachDB cluster name verification | `no` | +| `conf.join` | List of already-existing CockroachDB instances | `[]` | +| `conf.max-disk-temp-storage` | Max storage capacity for temp data | `0` | +| `conf.max-offset` | Max allowed clock offset for CockroachDB cluster | `500ms` | +| `conf.max-sql-memory` | Max memory to use processing SQL querie | `25%` | +| `conf.locality` | Locality attribute for this deployment | `""` | +| `conf.single-node` | Disable CockroachDB clustering (standalone mode) | `no` | +| `conf.sql-audit-dir` | Directory for SQL audit log | `""` | +| `conf.port` | CockroachDB primary serving port in Pods | `26257` | +| `conf.http-port` | CockroachDB HTTP port in Pods | `8080` | +| `conf.path` | CockroachDB data directory mount path | `cockroach-data` | +| `conf.store.enabled` | Enable store configuration for CockroachDB | `false` | +| `conf.store.type` | CockroachDB storage type | `""` | +| `conf.store.size` | CockroachDB storage size | `""` | +| `conf.store.attrs` | CockroachDB storage attributes | `""` | +| `image.repository` | Container image name | `cockroachdb/cockroach` | +| `image.tag` | Container image tag | `v24.2.0` | +| `image.pullPolicy` | Container pull policy | `IfNotPresent` | +| `image.credentials` | `registry`, `user` and `pass` credentials to pull private image | `{}` | +| `statefulset.replicas` | StatefulSet replicas number | `3` | +| `statefulset.updateStrategy` | Update strategy for StatefulSet Pods | `{"type": "RollingUpdate"}` | +| `statefulset.podManagementPolicy` | `OrderedReady`/`Parallel` Pods creation/deletion order | `Parallel` | +| `statefulset.budget.maxUnavailable` | k8s PodDisruptionBudget parameter | `1` | +| `statefulset.args` | Extra command-line arguments | `[]` | +| `statefulset.env` | Extra env vars | `[]` | +| `statefulset.secretMounts` | Additional Secrets to mount at cluster members | `[]` | +| `statefulset.labels` | Additional labels of StatefulSet and its Pods | `{"app.kubernetes.io/component": "cockroachdb"}` | +| `statefulset.annotations` | Additional annotations of StatefulSet Pods | `{}` | +| `statefulset.nodeAffinity` | [Node affinity rules][2] of StatefulSet Pods | `{}` | +| `statefulset.podAffinity` | [Inter-Pod affinity rules][1] of StatefulSet Pods | `{}` | +| `statefulset.podAntiAffinity` | [Anti-affinity rules][1] of StatefulSet Pods | auto | +| `statefulset.podAntiAffinity.topologyKey` | The topologyKey for auto [anti-affinity rules][1] | `kubernetes.io/hostname` | +| `statefulset.podAntiAffinity.type` | Type of auto [anti-affinity rules][1] | `soft` | +| `statefulset.podAntiAffinity.weight` | Weight for `soft` auto [anti-affinity rules][1] | `100` | +| `statefulset.nodeSelector` | Node labels for StatefulSet Pods assignment | `{}` | +| `statefulset.priorityClassName` | [PriorityClassName][4] for StatefulSet Pods | `""` | +| `statefulset.tolerations` | Node taints to tolerate by StatefulSet Pods | `[]` | +| `statefulset.topologySpreadConstraints` | [Topology Spread Constraints rules][5] of StatefulSet Pods | auto | +| `statefulset.topologySpreadConstraints.maxSkew` | Degree to which Pods may be unevenly distributed | `1` | +| `statefulset.topologySpreadConstraints.topologyKey` | The key of node labels | `topology.kubernetes.io/zone` | +| `statefulset.topologySpreadConstraints.whenUnsatisfiable` | `ScheduleAnyway`/`DoNotSchedule` for unsatisfiable constraints | `ScheduleAnyway` | +| `statefulset.resources` | Resource requests and limits for StatefulSet Pods | `{}` | +| `statefulset.customLivenessProbe` | Custom Liveness probe | `{}` | +| `statefulset.customReadinessProbe` | Custom Rediness probe | `{}` | +| `service.ports.grpc.external.port` | CockroachDB primary serving port in Services | `26257` | +| `service.ports.grpc.external.name` | CockroachDB primary serving port name in Services | `grpc` | +| `service.ports.grpc.internal.port` | CockroachDB inter-communication port in Services | `26257` | +| `service.ports.grpc.internal.name` | CockroachDB inter-communication port name in Services | `grpc-internal` | +| `service.ports.http.port` | CockroachDB HTTP port in Services | `8080` | +| `service.ports.http.name` | CockroachDB HTTP port name in Services | `http` | +| `service.public.type` | Public Service type | `ClusterIP` | +| `service.public.labels` | Additional labels of public Service | `{"app.kubernetes.io/component": "cockroachdb"}` | +| `service.public.annotations` | Additional annotations of public Service | `{}` | +| `service.discovery.labels` | Additional labels of discovery Service | `{"app.kubernetes.io/component": "cockroachdb"}` | +| `service.discovery.annotations` | Additional annotations of discovery Service | `{}` | +| `ingress.enabled` | Enable ingress resource for CockroachDB | `false` | +| `ingress.labels` | Additional labels of Ingress | `{}` | +| `ingress.annotations` | Additional annotations of Ingress | `{}` | +| `ingress.paths` | Paths for the default host | `[/]` | +| `ingress.hosts` | CockroachDB Ingress hostnames | `[]` | +| `ingress.tls[0].hosts` | CockroachDB Ingress tls hostnames | `nil` | +| `ingress.tls[0].secretName` | CockroachDB Ingress tls secret name | `nil` | +| `prometheus.enabled` | Enable automatic monitoring of all instances when Prometheus is running | `true` | +| `serviceMonitor.enabled` | Create [ServiceMonitor](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/design.md#servicemonitor) Resource for scraping metrics using [PrometheusOperator](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/user-guides/getting-started.md#prometheus-operator) | `false` | +| `serviceMonitor.labels` | Additional labels of ServiceMonitor | `{}` | +| `serviceMonitor.annotations` | Additional annotations of ServiceMonitor | `{}` | +| `serviceMonitor.interval` | ServiceMonitor scrape metrics interval | `10s` | +| `serviceMonitor.scrapeTimeout` | ServiceMonitor scrape timeout | `nil` | +| `serviceMonitor.tlsConfig` | Additional TLS configuration of ServiceMonitor | `{}` | +| `serviceMonitor.namespaced` | Limit ServiceMonitor to current namespace | `false` | +| `storage.hostPath` | Absolute path on host to store data | `""` | +| `storage.persistentVolume.enabled` | Whether to use PersistentVolume to store data | `yes` | +| `storage.persistentVolume.size` | PersistentVolume size | `100Gi` | +| `storage.persistentVolume.storageClass` | PersistentVolume class | `""` | +| `storage.persistentVolume.labels` | Additional labels of PersistentVolumeClaim | `{}` | +| `storage.persistentVolume.annotations` | Additional annotations of PersistentVolumeClaim | `{}` | +| `init.labels` | Additional labels of init Job and its Pod | `{"app.kubernetes.io/component": "init"}` | +| `init.jobAnnotations` | Additional annotations of the init Job itself | `{}` | +| `init.annotations` | Additional annotations of the Pod of init Job | `{}` | +| `init.affinity` | [Affinity rules][2] of init Job Pod | `{}` | +| `init.nodeSelector` | Node labels for init Job Pod assignment | `{}` | +| `init.tolerations` | Node taints to tolerate by init Job Pod | `[]` | +| `init.resources` | Resource requests and limits for the `cluster-init` container | `{}` | +| `tls.enabled` | Whether to run securely using TLS certificates | `no` | +| `tls.serviceAccount.create` | Whether to create a new RBAC service account | `yes` | +| `tls.serviceAccount.name` | Name of RBAC service account to use | `""` | +| `tls.copyCerts.image` | Image used in copy certs init container | `busybox` | +| `tls.copyCerts.resources` | Resource requests and limits for the `copy-certs` container | `{}` | +| `tls.certs.provided` | Bring your own certs scenario, i.e certificates are provided | `no` | +| `tls.certs.clientRootSecret` | If certs are provided, secret name for client root cert | `cockroachdb-root` | +| `tls.certs.nodeSecret` | If certs are provided, secret name for node cert | `cockroachdb-node` | +| `tls.certs.tlsSecret` | Own certs are stored in TLS secret | `no` | +| `tls.certs.selfSigner.enabled` | Whether cockroachdb should generate its own self-signed certs | `true` | +| `tls.certs.selfSigner.caProvided` | Bring your own CA scenario. This CA will be used to generate node and client cert | `false` | +| `tls.certs.selfSigner.caSecret` | If CA is provided, secret name for CA cert | `""` | +| `tls.certs.selfSigner.minimumCertDuration` | Minimum cert duration for all the certs, all certs duration will be validated against this duration | `624h` | +| `tls.certs.selfSigner.caCertDuration` | Duration of CA cert in hour | `43824h` | +| `tls.certs.selfSigner.caCertExpiryWindow` | Expiry window of CA cert means a window before actual expiry in which CA cert should be rotated | `648h` | +| `tls.certs.selfSigner.clientCertDuration` | Duration of client cert in hour | `672h | +| `tls.certs.selfSigner.clientCertExpiryWindow` | Expiry window of client cert means a window before actual expiry in which client cert should be rotated | `48h` | +| `tls.certs.selfSigner.nodeCertDuration` | Duration of node cert in hour | `8760h` | +| `tls.certs.selfSigner.nodeCertExpiryWindow` | Expiry window of node cert means a window before actual expiry in which node certs should be rotated | `168h` | +| `tls.certs.selfSigner.rotateCerts` | Whether to rotate the certs generate by cockroachdb | `true` | +| `tls.certs.selfSigner.readinessWait` | Wait time for each cockroachdb replica to become ready once it comes in running state. Only considered when rotateCerts is set to true | `30s` | +| `tls.certs.selfSigner.podUpdateTimeout` | Wait time for each cockroachdb replica to get to running state. Only considered when rotateCerts is set to true | `2m` | +| `tls.certs.certManager` | Provision certificates with cert-manager | `false` | +| `tls.certs.certManagerIssuer.group` | IssuerRef group to use when generating certificates | `cert-manager.io` | +| `tls.certs.certManagerIssuer.kind` | IssuerRef kind to use when generating certificates | `Issuer` | +| `tls.certs.certManagerIssuer.name` | IssuerRef name to use when generating certificates | `cockroachdb` | +| `tls.certs.certManagerIssuer.caCertDuration` | Duration of CA cert in hour | `43824h` | +| `tls.certs.certManagerIssuer.caCertExpiryWindow` | Expiry window of CA cert means a window before actual expiry in which CA cert should be rotated | `648h` | +| `tls.certs.certManagerIssuer.clientCertDuration` | Duration of client cert in hours | `672h` | +| `tls.certs.certManagerIssuer.clientCertExpiryWindow` | Expiry window of client cert means a window before actual expiry in which client cert should be rotated | `48h` | +| `tls.certs.certManagerIssuer.nodeCertDuration` | Duration of node cert in hours | `8760h` | +| `tls.certs.certManagerIssuer.nodeCertExpiryWindow` | Expiry window of node certificates means a window before actual expiry in which node certs should be rotated. | `168h` | +| `tls.selfSigner.image.repository` | Image to use for self signing TLS certificates | `cockroachlabs-helm-charts/cockroach-self-signer-cert`| +| `tls.selfSigner.image.tag` | Image tag to use for self signing TLS certificates | `0.1` | +| `tls.selfSigner.image.pullPolicy` | Self signing TLS certificates container pull policy | `IfNotPresent` | +| `tls.selfSigner.image.credentials` | `registry`, `user` and `pass` credentials to pull private image | `{}` | +| `networkPolicy.enabled` | Enable NetworkPolicy for CockroachDB's Pods | `no` | +| `networkPolicy.ingress.grpc` | Whitelist resources to access gRPC port of CockroachDB's Pods | `[]` | +| `networkPolicy.ingress.http` | Whitelist resources to access gRPC port of CockroachDB's Pods | `[]` | + + +Override the default parameters using the `--set key=value[,key=value]` argument to `helm install`. + +Alternatively, a YAML file that specifies custom values for the parameters can be provided while installing the chart. For example: + +```shell +helm install my-release -f my-values.yaml cockroachdb/cockroachdb +``` + +> **Tip**: You can use the default [values.yaml](values.yaml) + +## Deep dive + +### Connecting to the CockroachDB cluster + +Once you've created the cluster, you can start talking to it by connecting to its `-public` Service. CockroachDB is PostgreSQL wire protocol compatible, so there's a [wide variety of supported clients](https://www.cockroachlabs.com/docs/install-client-drivers.html). As an example, we'll open up a SQL shell using CockroachDB's built-in shell and play around with it a bit, like this (likely needing to replace `my-release-cockroachdb-public` with the name of the `-public` Service that was created with your installed chart): + +```shell +kubectl run cockroach-client --rm -it \ +--image=cockroachdb/cockroach \ +--restart=Never \ +-- sql --insecure --host my-release-cockroachdb-public +``` + +``` +Waiting for pod default/cockroach-client to be running, status is Pending, +pod ready: false +If you don't see a command prompt, try pressing enter. +root@my-release-cockroachdb-public:26257> SHOW DATABASES; ++--------------------+ +| Database | ++--------------------+ +| information_schema | +| pg_catalog | +| system | ++--------------------+ +(3 rows) +root@my-release-cockroachdb-public:26257> CREATE DATABASE bank; +CREATE DATABASE +root@my-release-cockroachdb-public:26257> CREATE TABLE bank.accounts (id INT +PRIMARY KEY, balance DECIMAL); +CREATE TABLE +root@my-release-cockroachdb-public:26257> INSERT INTO bank.accounts VALUES +(1234, 10000.50); +INSERT 1 +root@my-release-cockroachdb-public:26257> SELECT * FROM bank.accounts; ++------+---------+ +| id | balance | ++------+---------+ +| 1234 | 10000.5 | ++------+---------+ +(1 row) +root@my-release-cockroachdb-public:26257> \q +Waiting for pod default/cockroach-client to terminate, status is Running +pod "cockroach-client" deleted +``` + +> If you are running in secure mode, you will have to provide a client certificate to the cluster in order to authenticate, so the above command will not work. See [here](https://github.com/cockroachdb/cockroach/blob/master/cloud/kubernetes/client-secure.yaml) for an example of how to set up an interactive SQL shell against a secure cluster or [here](https://github.com/cockroachdb/cockroach/blob/master/cloud/kubernetes/example-app-secure.yaml) for an example application connecting to a secure cluster. + +### Cluster health + +Because our pod spec includes regular health checks of the CockroachDB processes, simply running `kubectl get pods` and looking at the `STATUS` column is sufficient to determine the health of each instance in the cluster. + +If you want more detailed information about the cluster, the best place to look is the Admin UI. + +### Accessing the Admin UI + +If you want to see information about how the cluster is doing, you can try pulling up the CockroachDB Admin UI by port-forwarding from your local machine to one of the pods (replacing `my-release-cockroachdb-0` with the name of one of your pods: + +```shell +kubectl port-forward my-release-cockroachdb-0 8080 +``` + +You should then be able to access the Admin UI by visiting in your web browser. + +### Failover + +If any CockroachDB member fails, it is restarted or recreated automatically by the Kubernetes infrastructure, and will re-join the cluster automatically when it comes back up. You can test this scenario by killing any of the CockroachDB pods: + +```shell +kubectl delete pod my-release-cockroachdb-1 +``` + +```shell +kubectl get pods -l "app.kubernetes.io/instance=my-release,app.kubernetes.io/component=cockroachdb" +``` + +``` +NAME READY STATUS RESTARTS AGE +my-release-cockroachdb-0 1/1 Running 0 5m +my-release-cockroachdb-2 1/1 Running 0 5m +``` + +After a while: + +```shell +kubectl get pods -l "app.kubernetes.io/instance=my-release,app.kubernetes.io/component=cockroachdb" +``` + +``` +NAME READY STATUS RESTARTS AGE +my-release-cockroachdb-0 1/1 Running 0 5m +my-release-cockroachdb-1 1/1 Running 0 20s +my-release-cockroachdb-2 1/1 Running 0 5m +``` + +You can check the state of re-joining from the new pod's logs: + +```shell +kubectl logs my-release-cockroachdb-1 +``` + +``` +[...] +I161028 19:32:09.754026 1 server/node.go:586 [n1] node connected via gossip and +verified as part of cluster {"35ecbc27-3f67-4e7d-9b8f-27c31aae17d6"} +[...] +cockroachdb-0.my-release-cockroachdb.default.svc.cluster.local:26257 +build: beta-20161027-55-gd2d3c7f @ 2016/10/28 19:27:25 (go1.7.3) +admin: http://0.0.0.0:8080 +sql: +postgresql://root@my-release-cockroachdb-1.my-release-cockroachdb.default.svc.cluster.local:26257?sslmode=disable +logs: cockroach-data/logs +store[0]: path=cockroach-data +status: restarted pre-existing node +clusterID: {35ecbc27-3f67-4e7d-9b8f-27c31aae17d6} +nodeID: 2 +[...] +``` + +### NetworkPolicy + +To enable NetworkPolicy for CockroachDB, install [a networking plugin that implements the Kubernetes NetworkPolicy spec](https://kubernetes.io/docs/tasks/administer-cluster/declare-network-policy#before-you-begin), and set `networkPolicy.enabled` to `yes`/`true`. + +For Kubernetes v1.5 & v1.6, you must also turn on NetworkPolicy by setting the `DefaultDeny` Namespace annotation. Note: this will enforce policy for _all_ pods in the Namespace: + +```shell +kubectl annotate namespace default "net.beta.kubernetes.io/network-policy={\"ingress\":{\"isolation\":\"DefaultDeny\"}}" +``` + +For more precise policy, set `networkPolicy.ingress.grpc` and `networkPolicy.ingress.http` rules. This will only allow pods that match the provided rules to connect to CockroachDB. + +### Scaling + +Scaling should be managed via the `helm upgrade` command. After resizing your cluster on your cloud environment (e.g., GKE or EKS), run the following command to add a pod. This assumes you scaled from 3 to 4 nodes: + +```shell +helm upgrade \ +my-release \ +cockroachdb/cockroachdb \ +--set statefulset.replicas=4 \ +--reuse-values +``` + +Note, that if you are running in secure mode (`tls.enabled` is `yes`/`true`) and increase the size of your cluster, you will also have to approve the CSR (certificate-signing request) of each new node (using `kubectl get csr` and `kubectl certificate approve`). + +[1]: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#inter-pod-affinity-and-anti-affinity +[2]: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#node-affinity +[3]: https://cert-manager.io/ +[4]: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#priorityclass +[5]: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ diff --git a/charts/cockroach-labs/cockroachdb/14.0.0/app-readme.md b/charts/cockroach-labs/cockroachdb/14.0.0/app-readme.md new file mode 100644 index 0000000000..8fcc1fd6fb --- /dev/null +++ b/charts/cockroach-labs/cockroachdb/14.0.0/app-readme.md @@ -0,0 +1,9 @@ +# CockroachDB Chart + +CockroachDB is a Distributed SQL database that runs natively in Kubernetes. It gives you resilient, horizontal scale across multiple clouds with always-on availability and data partitioned by location. + +CockroachDB scales horizontally without reconfiguration or need for a massive architectural overhaul. Simply add a new node to the cluster and CockroachDB takes care of the underlying complexity. + + - Scale by simply adding new nodes to a CockroachDB cluster + - Automate balancing and distribution of ranges, not shards + - Optimize server utilization evenly across all nodes diff --git a/charts/cockroach-labs/cockroachdb/14.0.0/templates/NOTES.txt b/charts/cockroach-labs/cockroachdb/14.0.0/templates/NOTES.txt new file mode 100644 index 0000000000..13b421f624 --- /dev/null +++ b/charts/cockroach-labs/cockroachdb/14.0.0/templates/NOTES.txt @@ -0,0 +1,50 @@ +CockroachDB can be accessed via port {{ .Values.service.ports.grpc.external.port }} at the +following DNS name from within your cluster: + +{{ template "cockroachdb.fullname" . }}-public.{{ .Release.Namespace }}.svc.cluster.local + +Because CockroachDB supports the PostgreSQL wire protocol, you can connect to +the cluster using any available PostgreSQL client. + +{{- if not .Values.tls.enabled }} + +For example, you can open up a SQL shell to the cluster by running: + + kubectl run -it --rm cockroach-client \ + --image=cockroachdb/cockroach \ + --restart=Never \ + {{- if .Values.networkPolicy.enabled }} + --labels="{{ template "cockroachdb.fullname" . }}-client=true" \ + {{- end }} + --command -- \ + ./cockroach sql --insecure --host={{ template "cockroachdb.fullname" . }}-public.{{ .Release.Namespace }} + +From there, you can interact with the SQL shell as you would any other SQL +shell, confident that any data you write will be safe and available even if +parts of your cluster fail. +{{- else }} + +Note that because the cluster is running in secure mode, any client application +that you attempt to connect will either need to have a valid client certificate +or a valid username and password. +{{- end }} + +{{- if and (.Values.networkPolicy.enabled) (not (empty .Values.networkPolicy.ingress.grpc)) }} + +Note: Since NetworkPolicy is enabled, the only Pods allowed to connect to this +CockroachDB cluster are: + +1. Having the label: "{{ template "cockroachdb.fullname" . }}-client=true" + +2. Matching the following rules: {{- toYaml .Values.networkPolicy.ingress.grpc | nindent 0 }} +{{- end }} + +Finally, to open up the CockroachDB admin UI, you can port-forward from your +local machine into one of the instances in the cluster: + + kubectl port-forward -n {{ .Release.Namespace }} {{ template "cockroachdb.fullname" . }}-0 {{ index .Values.conf `http-port` | int64 }} + +Then you can access the admin UI at http{{ if .Values.tls.enabled }}s{{ end }}://localhost:{{ index .Values.conf `http-port` | int64 }}/ in your web browser. + +For more information on using CockroachDB, please see the project's docs at: +https://www.cockroachlabs.com/docs/ diff --git a/charts/cockroach-labs/cockroachdb/14.0.0/templates/_helpers.tpl b/charts/cockroach-labs/cockroachdb/14.0.0/templates/_helpers.tpl new file mode 100644 index 0000000000..9ef769a70a --- /dev/null +++ b/charts/cockroach-labs/cockroachdb/14.0.0/templates/_helpers.tpl @@ -0,0 +1,291 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "cockroachdb.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 56 | 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 "cockroachdb.fullname" -}} +{{- if .Values.fullnameOverride -}} + {{- .Values.fullnameOverride | trunc 56 | trimSuffix "-" -}} +{{- else -}} + {{- $name := default .Chart.Name .Values.nameOverride -}} + {{- if contains $name .Release.Name -}} + {{- .Release.Name | trunc 56 | trimSuffix "-" -}} + {{- else -}} + {{- printf "%s-%s" .Release.Name $name | trunc 56 | trimSuffix "-" -}} + {{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create a default fully qualified app name for cluster scope resource. +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 with release namespace appended at the end. +*/}} +{{- define "cockroachdb.clusterfullname" -}} +{{- if .Values.fullnameOverride -}} + {{- printf "%s-%s" .Values.fullnameOverride .Release.Namespace | trunc 56 | trimSuffix "-" -}} +{{- else -}} + {{- $name := default .Chart.Name .Values.nameOverride -}} + {{- if contains $name .Release.Name -}} + {{- printf "%s-%s" .Release.Name .Release.Namespace | trunc 56 | trimSuffix "-" -}} + {{- else -}} + {{- printf "%s-%s-%s" .Release.Name $name .Release.Namespace | trunc 56 | trimSuffix "-" -}} + {{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "cockroachdb.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 56 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create the name of the ServiceAccount to use. +*/}} +{{- define "cockroachdb.serviceAccount.name" -}} +{{- if .Values.statefulset.serviceAccount.create -}} + {{- default (include "cockroachdb.fullname" .) .Values.statefulset.serviceAccount.name -}} +{{- else -}} + {{- default "default" .Values.statefulset.serviceAccount.name -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for NetworkPolicy. +*/}} +{{- define "cockroachdb.networkPolicy.apiVersion" -}} +{{- if semverCompare ">=1.4-0, <=1.7-0" .Capabilities.KubeVersion.Version -}} + {{- print "extensions/v1beta1" -}} +{{- else if semverCompare "^1.7-0" .Capabilities.KubeVersion.Version -}} + {{- print "networking.k8s.io/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for StatefulSets +*/}} +{{- define "cockroachdb.statefulset.apiVersion" -}} +{{- if semverCompare "<1.12-0" .Capabilities.KubeVersion.Version -}} + {{- print "apps/v1beta1" -}} +{{- else -}} + {{- print "apps/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return CockroachDB store expression +*/}} +{{- define "cockroachdb.conf.store" -}} +{{- $isInMemory := eq (.Values.conf.store.type | toString) "mem" -}} +{{- $persistentSize := empty .Values.conf.store.size | ternary .Values.storage.persistentVolume.size .Values.conf.store.size -}} + +{{- $store := dict -}} +{{- $_ := set $store "type" ($isInMemory | ternary "type=mem" "") -}} +{{- $_ := set $store "path" ($isInMemory | ternary "" (print "path=" .Values.conf.path)) -}} +{{- $_ := set $store "size" (print "size=" ($isInMemory | ternary .Values.conf.store.size $persistentSize)) -}} +{{- $_ := set $store "attrs" (empty .Values.conf.store.attrs | ternary "" (print "attrs=" .Values.conf.store.attrs)) -}} + +{{ compact (values $store) | join "," }} +{{- end -}} + +{{/* +Define the default values for the certificate selfSigner inputs +*/}} +{{- define "selfcerts.fullname" -}} + {{- printf "%s-%s" (include "cockroachdb.fullname" .) "self-signer" | trunc 56 | trimSuffix "-" -}} +{{- end -}} + +{{- define "rotatecerts.fullname" -}} + {{- printf "%s-%s" (include "cockroachdb.fullname" .) "rotate-self-signer" | trunc 56 | trimSuffix "-" -}} +{{- end -}} + +{{- define "selfcerts.minimumCertDuration" -}} + {{- if .Values.tls.certs.selfSigner.minimumCertDuration -}} + {{- print (.Values.tls.certs.selfSigner.minimumCertDuration | trimSuffix "h") -}} + {{- else }} + {{- $minCertDuration := min (sub (.Values.tls.certs.selfSigner.clientCertDuration | trimSuffix "h" ) (.Values.tls.certs.selfSigner.clientCertExpiryWindow | trimSuffix "h")) (sub (.Values.tls.certs.selfSigner.nodeCertDuration | trimSuffix "h") (.Values.tls.certs.selfSigner.nodeCertExpiryWindow | trimSuffix "h")) -}} + {{- print $minCertDuration -}} + {{- end }} +{{- end -}} + +{{/* +Define the cron schedules for certificate rotate jobs and converting from hours to valid cron string. +We assume that each month has 31 days, hence the cron job may run few days earlier in a year. In a cron schedule, +we can not set a cron of more than a year, hence we try to run the cron in such a way that the cron run comes to +as close possible to the expiry window. However, it is possible that cron may run earlier than the expiry window. +*/}} +{{- define "selfcerts.caRotateSchedule" -}} +{{- $tempHours := sub (.Values.tls.certs.selfSigner.caCertDuration | trimSuffix "h") (.Values.tls.certs.selfSigner.caCertExpiryWindow | trimSuffix "h") -}} +{{- $days := "*" -}} +{{- $months := "*" -}} +{{- $hours := mod $tempHours 24 -}} +{{- if not (eq $hours $tempHours) -}} +{{- $tempDays := div $tempHours 24 -}} +{{- $days = mod $tempDays 31 -}} +{{- if not (eq $days $tempDays) -}} +{{- $days = add $days 1 -}} +{{- $tempMonths := div $tempDays 31 -}} +{{- $months = mod $tempMonths 12 -}} +{{- if not (eq $months $tempMonths) -}} +{{- $months = add $months 1 -}} +{{- end -}} +{{- end -}} +{{- end -}} +{{- if ne (toString $months) "*" -}} +{{- $months = printf "*/%s" (toString $months) -}} +{{- else -}} +{{- if ne (toString $days) "*" -}} +{{- $days = printf "*/%s" (toString $days) -}} +{{- else -}} +{{- if ne $hours 0 -}} +{{- $hours = printf "*/%s" (toString $hours) -}} +{{- end -}} +{{- end -}} +{{- end -}} +{{- printf "0 %s %s %s *" (toString $hours) (toString $days) (toString $months) -}} +{{- end -}} + +{{- define "selfcerts.clientRotateSchedule" -}} +{{- $tempHours := int64 (include "selfcerts.minimumCertDuration" .) -}} +{{- $days := "*" -}} +{{- $months := "*" -}} +{{- $hours := mod $tempHours 24 -}} +{{- if not (eq $hours $tempHours) -}} +{{- $tempDays := div $tempHours 24 -}} +{{- $days = mod $tempDays 31 -}} +{{- if not (eq $days $tempDays) -}} +{{- $days = add $days 1 -}} +{{- $tempMonths := div $tempDays 31 -}} +{{- $months = mod $tempMonths 12 -}} +{{- if not (eq $months $tempMonths) -}} +{{- $months = add $months 1 -}} +{{- end -}} +{{- end -}} +{{- end -}} +{{- if ne (toString $months) "*" -}} +{{- $months = printf "*/%s" (toString $months) -}} +{{- else -}} +{{- if ne (toString $days) "*" -}} +{{- $days = printf "*/%s" (toString $days) -}} +{{- else -}} +{{- if ne $hours 0 -}} +{{- $hours = printf "*/%s" (toString $hours) -}} +{{- end -}} +{{- end -}} +{{- end -}} +{{- printf "0 %s %s %s *" (toString $hours) (toString $days) (toString $months) -}} +{{- end -}} + +{{/* +Define the appropriate validations for the certificate selfSigner inputs +*/}} + +{{/* +Validate that if caProvided is true, then the caSecret must not be empty and secret must be present in the namespace. +*/}} +{{- define "cockroachdb.tls.certs.selfSigner.caProvidedValidation" -}} +{{- if .Values.tls.certs.selfSigner.caProvided -}} +{{- if eq "" .Values.tls.certs.selfSigner.caSecret -}} + {{ fail "CA secret can't be empty if caProvided is set to true" }} +{{- else -}} + {{- if not (lookup "v1" "Secret" .Release.Namespace .Values.tls.certs.selfSigner.caSecret) }} + {{ fail "CA secret is not present in the release namespace" }} + {{- end }} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Validate that if caCertDuration or caCertExpiryWindow must not be empty and caCertExpiryWindow must be greater than +minimumCertDuration. +*/}} +{{- define "cockroachdb.tls.certs.selfSigner.caCertValidation" -}} +{{- if not .Values.tls.certs.selfSigner.caProvided -}} +{{- if or (not .Values.tls.certs.selfSigner.caCertDuration) (not .Values.tls.certs.selfSigner.caCertExpiryWindow) }} + {{ fail "CA cert duration or CA cert expiry window can not be empty" }} +{{- else }} +{{- if gt (int64 (include "selfcerts.minimumCertDuration" .)) (int64 (.Values.tls.certs.selfSigner.caCertExpiryWindow | trimSuffix "h")) -}} + {{ fail "CA cert expiration window should not be less than minimum Cert duration" }} +{{- end -}} +{{- if gt (int64 (include "selfcerts.minimumCertDuration" .)) (sub (.Values.tls.certs.selfSigner.caCertDuration | trimSuffix "h") (.Values.tls.certs.selfSigner.caCertExpiryWindow | trimSuffix "h")) -}} + {{ fail "CA cert Duration minus CA cert expiration window should not be less than minimum Cert duration" }} +{{- end -}} +{{- end -}} +{{- end }} +{{- end -}} + +{{/* +Validate that if clientCertDuration must not be empty and it must be greater than minimumCertDuration. +*/}} +{{- define "cockroachdb.tls.certs.selfSigner.clientCertValidation" -}} +{{- if or (not .Values.tls.certs.selfSigner.clientCertDuration) (not .Values.tls.certs.selfSigner.clientCertExpiryWindow) }} + {{ fail "Client cert duration can not be empty" }} +{{- else }} +{{- if lt (sub (.Values.tls.certs.selfSigner.clientCertDuration | trimSuffix "h") (.Values.tls.certs.selfSigner.clientCertExpiryWindow | trimSuffix "h")) (int64 (include "selfcerts.minimumCertDuration" .)) }} + {{ fail "Client cert duration minus client cert expiry window should not be less than minimum Cert duration" }} +{{- end }} +{{- end }} +{{- end -}} + +{{/* +Validate that nodeCertDuration must not be empty and nodeCertDuration minus nodeCertExpiryWindow must be greater than minimumCertDuration. +*/}} +{{- define "cockroachdb.tls.certs.selfSigner.nodeCertValidation" -}} +{{- if or (not .Values.tls.certs.selfSigner.nodeCertDuration) (not .Values.tls.certs.selfSigner.nodeCertExpiryWindow) }} + {{ fail "Node cert duration can not be empty" }} +{{- else }} +{{- if lt (sub (.Values.tls.certs.selfSigner.nodeCertDuration | trimSuffix "h") (.Values.tls.certs.selfSigner.nodeCertExpiryWindow | trimSuffix "h")) (int64 (include "selfcerts.minimumCertDuration" .))}} + {{ fail "Node cert duration minus node cert expiry window should not be less than minimum Cert duration" }} +{{- end }} +{{- end }} +{{- end -}} + +{{/* +Validate that if user enabled tls, then either self-signed certificates or certificate manager is enabled +*/}} +{{- define "cockroachdb.tlsValidation" -}} +{{- if .Values.tls.enabled -}} +{{- if and .Values.tls.certs.selfSigner.enabled .Values.tls.certs.certManager -}} + {{ fail "Can not enable the self signed certificates and certificate manager at the same time" }} +{{- end -}} +{{- if and (not .Values.tls.certs.selfSigner.enabled) (not .Values.tls.certs.certManager) -}} + {{- if not .Values.tls.certs.provided -}} + {{ fail "You have to enable either self signed certificates or certificate manager, if you have enabled tls" }} + {{- end -}} +{{- end -}} +{{- end -}} +{{- end -}} + + +{{- define "cockroachdb.tls.certs.selfSigner.validation" -}} +{{ include "cockroachdb.tls.certs.selfSigner.caProvidedValidation" . }} +{{ include "cockroachdb.tls.certs.selfSigner.caCertValidation" . }} +{{ include "cockroachdb.tls.certs.selfSigner.clientCertValidation" . }} +{{ include "cockroachdb.tls.certs.selfSigner.nodeCertValidation" . }} +{{- end -}} + +{{- define "cockroachdb.securityContext.versionValidation" }} +{{- /* Allow using `securityContext` for custom images. */}} +{{- if ne "cockroachdb/cockroach" .Values.image.repository -}} + {{ print true }} +{{- else -}} +{{- if semverCompare ">=22.1.2" .Values.image.tag -}} + {{ print true }} +{{- else -}} +{{- if semverCompare ">=21.2.13, <22.1.0" .Values.image.tag -}} + {{ print true }} +{{- else -}} + {{ print false }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/cockroach-labs/cockroachdb/14.0.0/templates/backendconfig.yaml b/charts/cockroach-labs/cockroachdb/14.0.0/templates/backendconfig.yaml new file mode 100644 index 0000000000..2edc88619a --- /dev/null +++ b/charts/cockroach-labs/cockroachdb/14.0.0/templates/backendconfig.yaml @@ -0,0 +1,21 @@ +{{- if .Values.iap.enabled }} +apiVersion: cloud.google.com/v1beta1 +kind: BackendConfig +metadata: + name: {{ template "cockroachdb.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: + helm.sh/chart: {{ template "cockroachdb.chart" . }} + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + iap: + enabled: true + oauthclientCredentials: + secretName: {{ template "cockroachdb.fullname" . }}.iap + timeoutSec: 120 +{{- end }} \ No newline at end of file diff --git a/charts/cockroach-labs/cockroachdb/14.0.0/templates/certificate.ca.yaml b/charts/cockroach-labs/cockroachdb/14.0.0/templates/certificate.ca.yaml new file mode 100644 index 0000000000..4043fafb0f --- /dev/null +++ b/charts/cockroach-labs/cockroachdb/14.0.0/templates/certificate.ca.yaml @@ -0,0 +1,33 @@ +{{- if and .Values.tls.enabled .Values.tls.certs.certManager }} + {{- if .Values.tls.certs.certManagerIssuer.isSelfSignedIssuer }} +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: {{ template "cockroachdb.fullname" . }}-ca-cert + namespace: {{ .Release.Namespace | quote }} + labels: + helm.sh/chart: {{ template "cockroachdb.chart" . }} + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + duration: {{ .Values.tls.certs.certManagerIssuer.caCertDuration }} + renewBefore: {{ .Values.tls.certs.certManagerIssuer.caCertExpiryWindow }} + isCA: true + secretName: {{ .Values.tls.certs.caSecret }} + privateKey: + algorithm: ECDSA + size: 256 + commonName: root + subject: + organizations: + - Cockroach + issuerRef: + name: {{ .Values.tls.certs.certManagerIssuer.name }} + kind: {{ .Values.tls.certs.certManagerIssuer.kind }} + group: {{ .Values.tls.certs.certManagerIssuer.group }} + {{- end }} +{{- end }} diff --git a/charts/cockroach-labs/cockroachdb/14.0.0/templates/certificate.client.yaml b/charts/cockroach-labs/cockroachdb/14.0.0/templates/certificate.client.yaml new file mode 100644 index 0000000000..dd0272f3e2 --- /dev/null +++ b/charts/cockroach-labs/cockroachdb/14.0.0/templates/certificate.client.yaml @@ -0,0 +1,40 @@ +{{- if and .Values.tls.enabled .Values.tls.certs.certManager }} +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: {{ template "cockroachdb.fullname" . }}-root-client + namespace: {{ .Release.Namespace | quote }} + labels: + helm.sh/chart: {{ template "cockroachdb.chart" . }} + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + duration: {{ .Values.tls.certs.certManagerIssuer.clientCertDuration }} + renewBefore: {{ .Values.tls.certs.certManagerIssuer.clientCertExpiryWindow }} + usages: + - digital signature + - key encipherment + - client auth + privateKey: + algorithm: RSA + size: 2048 + commonName: root + subject: + organizations: + - Cockroach + secretName: {{ .Values.tls.certs.clientRootSecret }} + issuerRef: + {{- if .Values.tls.certs.certManagerIssuer.isSelfSignedIssuer }} + name: {{ template "cockroachdb.fullname" . }}-ca-issuer + kind: Issuer + group: cert-manager.io + {{- else }} + name: {{ .Values.tls.certs.certManagerIssuer.name }} + kind: {{ .Values.tls.certs.certManagerIssuer.kind }} + group: {{ .Values.tls.certs.certManagerIssuer.group }} + {{- end }} +{{- end }} diff --git a/charts/cockroach-labs/cockroachdb/14.0.0/templates/certificate.issuer.yaml b/charts/cockroach-labs/cockroachdb/14.0.0/templates/certificate.issuer.yaml new file mode 100644 index 0000000000..5cf579ff9d --- /dev/null +++ b/charts/cockroach-labs/cockroachdb/14.0.0/templates/certificate.issuer.yaml @@ -0,0 +1,20 @@ +{{- if and .Values.tls.enabled .Values.tls.certs.certManager }} + {{- if .Values.tls.certs.certManagerIssuer.isSelfSignedIssuer }} +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: {{ template "cockroachdb.fullname" . }}-ca-issuer + namespace: {{ .Release.Namespace | quote }} + labels: + helm.sh/chart: {{ template "cockroachdb.chart" . }} + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + ca: + secretName: {{ .Values.tls.certs.caSecret }} + {{- end }} +{{- end }} diff --git a/charts/cockroach-labs/cockroachdb/14.0.0/templates/certificate.node.yaml b/charts/cockroach-labs/cockroachdb/14.0.0/templates/certificate.node.yaml new file mode 100644 index 0000000000..05e909d0b0 --- /dev/null +++ b/charts/cockroach-labs/cockroachdb/14.0.0/templates/certificate.node.yaml @@ -0,0 +1,50 @@ +{{- if and .Values.tls.enabled .Values.tls.certs.certManager }} +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: {{ template "cockroachdb.fullname" . }}-node + namespace: {{ .Release.Namespace | quote }} + labels: + helm.sh/chart: {{ template "cockroachdb.chart" . }} + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + duration: {{ .Values.tls.certs.certManagerIssuer.nodeCertDuration }} + renewBefore: {{ .Values.tls.certs.certManagerIssuer.nodeCertExpiryWindow }} + usages: + - digital signature + - key encipherment + - server auth + - client auth + privateKey: + algorithm: RSA + size: 2048 + commonName: node + subject: + organizations: + - Cockroach + dnsNames: + - "localhost" + - "127.0.0.1" + - {{ printf "%s-public" (include "cockroachdb.fullname" .) | quote }} + - {{ printf "%s-public.%s" (include "cockroachdb.fullname" .) .Release.Namespace | quote }} + - {{ printf "%s-public.%s.svc.%s" (include "cockroachdb.fullname" .) .Release.Namespace .Values.clusterDomain | quote }} + - {{ printf "*.%s" (include "cockroachdb.fullname" .) | quote }} + - {{ printf "*.%s.%s" (include "cockroachdb.fullname" .) .Release.Namespace | quote }} + - {{ printf "*.%s.%s.svc.%s" (include "cockroachdb.fullname" .) .Release.Namespace .Values.clusterDomain | quote }} + secretName: {{ .Values.tls.certs.nodeSecret }} + issuerRef: + {{- if .Values.tls.certs.certManagerIssuer.isSelfSignedIssuer }} + name: {{ template "cockroachdb.fullname" . }}-ca-issuer + kind: Issuer + group: cert-manager.io + {{- else }} + name: {{ .Values.tls.certs.certManagerIssuer.name }} + kind: {{ .Values.tls.certs.certManagerIssuer.kind }} + group: {{ .Values.tls.certs.certManagerIssuer.group }} + {{- end }} +{{- end }} diff --git a/charts/cockroach-labs/cockroachdb/14.0.0/templates/clusterrole.yaml b/charts/cockroach-labs/cockroachdb/14.0.0/templates/clusterrole.yaml new file mode 100644 index 0000000000..6b8a3dc5f7 --- /dev/null +++ b/charts/cockroach-labs/cockroachdb/14.0.0/templates/clusterrole.yaml @@ -0,0 +1,19 @@ +{{- if and .Values.tls.enabled (not .Values.tls.certs.provided) (not .Values.tls.certs.certManager) }} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "cockroachdb.clusterfullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: + helm.sh/chart: {{ template "cockroachdb.chart" . }} + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +rules: + - apiGroups: ["certificates.k8s.io"] + resources: ["certificatesigningrequests"] + verbs: ["create", "get", "watch"] +{{- end }} \ No newline at end of file diff --git a/charts/cockroach-labs/cockroachdb/14.0.0/templates/clusterrolebinding.yaml b/charts/cockroach-labs/cockroachdb/14.0.0/templates/clusterrolebinding.yaml new file mode 100644 index 0000000000..3c18694efd --- /dev/null +++ b/charts/cockroach-labs/cockroachdb/14.0.0/templates/clusterrolebinding.yaml @@ -0,0 +1,23 @@ +{{- if and .Values.tls.enabled (not .Values.tls.certs.provided) (not .Values.tls.certs.certManager) }} +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "cockroachdb.clusterfullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: + helm.sh/chart: {{ template "cockroachdb.chart" . }} + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "cockroachdb.clusterfullname" . }} +subjects: + - kind: ServiceAccount + name: {{ template "cockroachdb.serviceAccount.name" . }} + namespace: {{ .Release.Namespace | quote }} +{{- end }} \ No newline at end of file diff --git a/charts/cockroach-labs/cockroachdb/14.0.0/templates/cronjob-ca-certSelfSigner.yaml b/charts/cockroach-labs/cockroachdb/14.0.0/templates/cronjob-ca-certSelfSigner.yaml new file mode 100644 index 0000000000..903c42f767 --- /dev/null +++ b/charts/cockroach-labs/cockroachdb/14.0.0/templates/cronjob-ca-certSelfSigner.yaml @@ -0,0 +1,46 @@ +{{- if and .Values.tls.enabled (and .Values.tls.certs.selfSigner.enabled (not .Values.tls.certs.selfSigner.caProvided)) }} + {{- if .Values.tls.certs.selfSigner.rotateCerts }} + {{- if .Capabilities.APIVersions.Has "batch/v1/CronJob" }} +apiVersion: batch/v1 + {{- else }} +apiVersion: batch/v1beta1 + {{- end }} +kind: CronJob +metadata: + name: {{ template "rotatecerts.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: + helm.sh/chart: {{ template "cockroachdb.chart" . }} + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} +spec: + schedule: {{ template "selfcerts.caRotateSchedule" . }} + jobTemplate: + spec: + backoffLimit: 1 + template: + spec: + restartPolicy: Never + containers: + - name: cert-rotate-job + image: "{{ .Values.tls.selfSigner.image.registry }}/{{ .Values.tls.selfSigner.image.repository }}:{{ .Values.tls.selfSigner.image.tag }}" + imagePullPolicy: "{{ .Values.tls.selfSigner.image.pullPolicy }}" + args: + - rotate + - --ca + - --ca-duration={{ .Values.tls.certs.selfSigner.caCertDuration }} + - --ca-expiry={{ .Values.tls.certs.selfSigner.caCertExpiryWindow }} + - --ca-cron={{ template "selfcerts.caRotateSchedule" . }} + - --readiness-wait={{ .Values.tls.certs.selfSigner.readinessWait }} + - --pod-update-timeout={{ .Values.tls.certs.selfSigner.podUpdateTimeout }} + env: + - name: STATEFULSET_NAME + value: {{ template "cockroachdb.fullname" . }} + - name: NAMESPACE + value: {{ .Release.Namespace }} + - name: CLUSTER_DOMAIN + value: {{ .Values.clusterDomain}} + serviceAccountName: {{ template "rotatecerts.fullname" . }} + {{- end }} +{{- end }} diff --git a/charts/cockroach-labs/cockroachdb/14.0.0/templates/cronjob-client-node-certSelfSigner.yaml b/charts/cockroach-labs/cockroachdb/14.0.0/templates/cronjob-client-node-certSelfSigner.yaml new file mode 100644 index 0000000000..5c9f6d9925 --- /dev/null +++ b/charts/cockroach-labs/cockroachdb/14.0.0/templates/cronjob-client-node-certSelfSigner.yaml @@ -0,0 +1,53 @@ +{{- if and .Values.tls.certs.selfSigner.enabled .Values.tls.certs.selfSigner.rotateCerts }} + {{- if .Capabilities.APIVersions.Has "batch/v1/CronJob" }} +apiVersion: batch/v1 + {{- else }} +apiVersion: batch/v1beta1 + {{- end }} +kind: CronJob +metadata: + name: {{ template "rotatecerts.fullname" . }}-client + namespace: {{ .Release.Namespace | quote }} + labels: + helm.sh/chart: {{ template "cockroachdb.chart" . }} + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} +spec: + schedule: {{ template "selfcerts.clientRotateSchedule" . }} + jobTemplate: + spec: + backoffLimit: 1 + template: + spec: + restartPolicy: Never + containers: + - name: cert-rotate-job + image: "{{ .Values.tls.selfSigner.image.registry }}/{{ .Values.tls.selfSigner.image.repository }}:{{ .Values.tls.selfSigner.image.tag }}" + imagePullPolicy: "{{ .Values.tls.selfSigner.image.pullPolicy }}" + args: + - rotate + {{- if .Values.tls.certs.selfSigner.caProvided }} + - --ca-secret={{ .Values.tls.certs.selfSigner.caSecret }} + {{- else }} + - --ca-duration={{ .Values.tls.certs.selfSigner.caCertDuration }} + - --ca-expiry={{ .Values.tls.certs.selfSigner.caCertExpiryWindow }} + {{- end }} + - --client + - --client-duration={{ .Values.tls.certs.selfSigner.clientCertDuration }} + - --client-expiry={{ .Values.tls.certs.selfSigner.clientCertExpiryWindow }} + - --node + - --node-duration={{ .Values.tls.certs.selfSigner.nodeCertDuration }} + - --node-expiry={{ .Values.tls.certs.selfSigner.nodeCertExpiryWindow }} + - --node-client-cron={{ template "selfcerts.clientRotateSchedule" . }} + - --readiness-wait={{ .Values.tls.certs.selfSigner.readinessWait }} + - --pod-update-timeout={{ .Values.tls.certs.selfSigner.podUpdateTimeout }} + env: + - name: STATEFULSET_NAME + value: {{ template "cockroachdb.fullname" . }} + - name: NAMESPACE + value: {{ .Release.Namespace }} + - name: CLUSTER_DOMAIN + value: {{ .Values.clusterDomain}} + serviceAccountName: {{ template "rotatecerts.fullname" . }} + {{- end}} diff --git a/charts/cockroach-labs/cockroachdb/14.0.0/templates/ingress.yaml b/charts/cockroach-labs/cockroachdb/14.0.0/templates/ingress.yaml new file mode 100644 index 0000000000..2fa6373c87 --- /dev/null +++ b/charts/cockroach-labs/cockroachdb/14.0.0/templates/ingress.yaml @@ -0,0 +1,90 @@ +{{- if .Values.ingress.enabled -}} +{{- $paths := .Values.ingress.paths -}} +{{- $ports := .Values.service.ports -}} +{{- $fullName := include "cockroachdb.fullname" . -}} +{{- if $.Capabilities.APIVersions.Has "networking.k8s.io/v1/Ingress" }} +apiVersion: networking.k8s.io/v1 +{{- else if $.Capabilities.APIVersions.Has "networking.k8s.io/v1beta1/Ingress" }} +apiVersion: networking.k8s.io/v1beta1 +{{- else -}} +apiVersion: extensions/v1beta1 +{{- end }} +kind: Ingress +metadata: +{{- if or .Values.ingress.annotations .Values.iap.enabled }} + annotations: + {{- range $key, $value := .Values.ingress.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- if .Values.iap.enabled }} + kubernetes.io/ingress.class: "gce" + kubernetes.io/ingress.allow-http: "false" + {{- end }} +{{- end }} + name: {{ $fullName }}-ingress + namespace: {{ .Release.Namespace }} + labels: + helm.sh/chart: {{ template "cockroachdb.chart" . }} + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ $.Release.Name | quote }} + app.kubernetes.io/managed-by: {{ $.Release.Service | quote }} +{{- if .Values.ingress.labels }} +{{- toYaml .Values.ingress.labels | nindent 4 }} +{{- end }} +spec: + rules: + {{- if .Values.ingress.hosts }} + {{- range $host := .Values.ingress.hosts }} + - host: {{ $host }} + http: + paths: + {{- range $path := $paths }} + - path: {{ $path | quote }} + {{- if $.Capabilities.APIVersions.Has "networking.k8s.io/v1/Ingress" }} + {{- if $.Values.iap.enabled }} + pathType: ImplementationSpecific + {{- else }} + pathType: Prefix + {{- end }} + {{- end }} + backend: + {{- if $.Capabilities.APIVersions.Has "networking.k8s.io/v1/Ingress" }} + service: + name: {{ $fullName }}-public + port: + name: {{ $ports.http.name | quote }} + {{- else }} + serviceName: {{ $fullName }}-public + servicePort: {{ $ports.http.name | quote }} + {{- end }} + {{- end }} + {{- end }} + {{- else }} + - http: + paths: + {{- range $path := $paths }} + - path: {{ $path | quote }} + {{- if $.Capabilities.APIVersions.Has "networking.k8s.io/v1/Ingress" }} + {{- if $.Values.iap.enabled }} + pathType: ImplementationSpecific + {{- else }} + pathType: Prefix + {{- end }} + {{- end }} + backend: + {{- if $.Capabilities.APIVersions.Has "networking.k8s.io/v1/Ingress" }} + service: + name: {{ $fullName }}-public + port: + name: {{ $ports.http.name | quote }} + {{- else }} + serviceName: {{ $fullName }}-public + servicePort: {{ $ports.http.name | quote }} + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.ingress.tls }} + tls: +{{- toYaml .Values.ingress.tls | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/cockroach-labs/cockroachdb/14.0.0/templates/job-certSelfSigner.yaml b/charts/cockroach-labs/cockroachdb/14.0.0/templates/job-certSelfSigner.yaml new file mode 100644 index 0000000000..7242a68b39 --- /dev/null +++ b/charts/cockroach-labs/cockroachdb/14.0.0/templates/job-certSelfSigner.yaml @@ -0,0 +1,83 @@ +{{- if and .Values.tls.enabled .Values.tls.certs.selfSigner.enabled }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ template "selfcerts.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + annotations: + # This is what defines this resource as a hook. Without this line, the + # job is considered part of the release. + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-weight": "4" + "helm.sh/hook-delete-policy": hook-succeeded,hook-failed + labels: + helm.sh/chart: {{ template "cockroachdb.chart" . }} + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} +spec: + template: + metadata: + name: {{ template "selfcerts.fullname" . }} + labels: + helm.sh/chart: {{ template "cockroachdb.chart" . }} + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + {{- with .Values.tls.selfSigner.annotations }} + annotations: {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- if and .Values.tls.certs.selfSigner.securityContext.enabled }} + securityContext: + seccompProfile: + type: "RuntimeDefault" + runAsGroup: 1000 + runAsUser: 1000 + fsGroup: 1000 + runAsNonRoot: true + {{- end }} + restartPolicy: Never + {{- if or .Values.tls.selfSigner.nodeAffinity }} + affinity: + {{- with .Values.tls.selfSigner.nodeAffinity }} + nodeAffinity: {{- toYaml . | nindent 10 }} + {{- end }} + {{- end }} + {{- with .Values.tls.selfSigner.nodeSelector }} + nodeSelector: {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tls.selfSigner.tolerations }} + tolerations: {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: cert-generate-job + image: "{{ .Values.tls.selfSigner.image.registry }}/{{ .Values.tls.selfSigner.image.repository }}:{{ .Values.tls.selfSigner.image.tag }}" + imagePullPolicy: "{{ .Values.tls.selfSigner.image.pullPolicy }}" + args: + - generate + {{- if .Values.tls.certs.selfSigner.caProvided }} + - --ca-secret={{ .Values.tls.certs.selfSigner.caSecret }} + {{- else }} + - --ca-duration={{ .Values.tls.certs.selfSigner.caCertDuration }} + - --ca-expiry={{ .Values.tls.certs.selfSigner.caCertExpiryWindow }} + {{- end }} + - --client-duration={{ .Values.tls.certs.selfSigner.clientCertDuration }} + - --client-expiry={{ .Values.tls.certs.selfSigner.clientCertExpiryWindow }} + - --node-duration={{ .Values.tls.certs.selfSigner.nodeCertDuration }} + - --node-expiry={{ .Values.tls.certs.selfSigner.nodeCertExpiryWindow }} + env: + - name: STATEFULSET_NAME + value: {{ template "cockroachdb.fullname" . }} + - name: NAMESPACE + value: {{ .Release.Namespace | quote }} + - name: CLUSTER_DOMAIN + value: {{ .Values.clusterDomain}} + {{- if and .Values.tls.certs.selfSigner.securityContext.enabled }} + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: ["ALL"] + {{- end }} + serviceAccountName: {{ template "selfcerts.fullname" . }} +{{- end}} diff --git a/charts/cockroach-labs/cockroachdb/14.0.0/templates/job-cleaner.yaml b/charts/cockroach-labs/cockroachdb/14.0.0/templates/job-cleaner.yaml new file mode 100644 index 0000000000..5b6dc52f7e --- /dev/null +++ b/charts/cockroach-labs/cockroachdb/14.0.0/templates/job-cleaner.yaml @@ -0,0 +1,55 @@ +{{- if and .Values.tls.enabled .Values.tls.certs.selfSigner.enabled }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ template "selfcerts.fullname" . }}-cleaner + namespace: {{ .Release.Namespace | quote }} + annotations: + # This is what defines this resource as a hook. Without this line, the + # job is considered part of the release. + "helm.sh/hook": pre-delete + "helm.sh/hook-delete-policy": hook-succeeded,hook-failed + labels: + helm.sh/chart: {{ template "cockroachdb.chart" . }} + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} +spec: + backoffLimit: 1 + template: + metadata: + name: {{ template "selfcerts.fullname" . }}-cleaner + labels: + helm.sh/chart: {{ template "cockroachdb.chart" . }} + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + spec: + {{- if and .Values.tls.certs.selfSigner.securityContext.enabled }} + securityContext: + seccompProfile: + type: "RuntimeDefault" + runAsGroup: 1000 + runAsUser: 1000 + fsGroup: 1000 + runAsNonRoot: true + {{- end }} + restartPolicy: Never + containers: + - name: cleaner + image: "{{ .Values.tls.selfSigner.image.registry }}/{{ .Values.tls.selfSigner.image.repository }}:{{ .Values.tls.selfSigner.image.tag }}" + imagePullPolicy: "{{ .Values.tls.selfSigner.image.pullPolicy }}" + args: + - cleanup + - --namespace={{ .Release.Namespace }} + env: + - name: STATEFULSET_NAME + value: {{ template "cockroachdb.fullname" . }} + {{- if and .Values.tls.certs.selfSigner.securityContext.enabled }} + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: ["ALL"] + {{- end }} + serviceAccountName: {{ template "rotatecerts.fullname" . }} +{{- end}} diff --git a/charts/cockroach-labs/cockroachdb/14.0.0/templates/job.init.yaml b/charts/cockroach-labs/cockroachdb/14.0.0/templates/job.init.yaml new file mode 100644 index 0000000000..a4f498a158 --- /dev/null +++ b/charts/cockroach-labs/cockroachdb/14.0.0/templates/job.init.yaml @@ -0,0 +1,296 @@ +{{ $isClusterInitEnabled := and (eq (len .Values.conf.join) 0) (not (index .Values.conf `single-node`)) }} +{{ $isDatabaseProvisioningEnabled := .Values.init.provisioning.enabled }} +{{- if or $isClusterInitEnabled $isDatabaseProvisioningEnabled }} + {{ template "cockroachdb.tlsValidation" . }} +kind: Job +apiVersion: batch/v1 +metadata: + name: {{ template "cockroachdb.fullname" . }}-init + namespace: {{ .Release.Namespace | quote }} + labels: + helm.sh/chart: {{ template "cockroachdb.chart" . }} + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + {{- with .Values.init.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + helm.sh/hook: post-install,post-upgrade + helm.sh/hook-delete-policy: before-hook-creation + {{- with .Values.init.jobAnnotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + template: + metadata: + labels: + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + {{- with .Values.init.labels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.init.annotations }} + annotations: {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- if eq (include "cockroachdb.securityContext.versionValidation" .) "true" }} + {{- if and .Values.init.securityContext.enabled }} + securityContext: + seccompProfile: + type: "RuntimeDefault" + runAsGroup: 1000 + runAsUser: 1000 + fsGroup: 1000 + runAsNonRoot: true + {{- end }} + {{- end }} + restartPolicy: OnFailure + terminationGracePeriodSeconds: 300 + {{- if or .Values.image.credentials (and .Values.tls.enabled .Values.tls.selfSigner.image.credentials (not .Values.tls.certs.provided) (not .Values.tls.certs.certManager)) }} + imagePullSecrets: + {{- if .Values.image.credentials }} + - name: {{ template "cockroachdb.fullname" . }}.db.registry + {{- end }} + {{- if and .Values.tls.enabled .Values.tls.selfSigner.image.credentials (not .Values.tls.certs.provided) (not .Values.tls.certs.certManager) }} + - name: {{ template "cockroachdb.fullname" . }}.self-signed-certs.registry + {{- end }} + {{- end }} + serviceAccountName: {{ template "cockroachdb.serviceAccount.name" . }} + {{- if .Values.tls.enabled }} + initContainers: + - name: copy-certs + image: {{ .Values.tls.copyCerts.image | quote }} + imagePullPolicy: {{ .Values.tls.selfSigner.image.pullPolicy | quote }} + command: + - /bin/sh + - -c + - "cp -f /certs/* /cockroach-certs/; chmod 0400 /cockroach-certs/*.key" + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- if and .Values.init.securityContext.enabled }} + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: ["ALL"] + {{- end }} + volumeMounts: + - name: client-certs + mountPath: /cockroach-certs/ + - name: certs-secret + mountPath: /certs/ + {{- with .Values.tls.copyCerts.resources }} + resources: {{- toYaml . | nindent 12 }} + {{- end }} + {{- end }} + {{- with .Values.init.affinity }} + affinity: {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.init.nodeSelector }} + nodeSelector: {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.init.tolerations }} + tolerations: {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: cluster-init + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy | quote }} + # Run the command in an `while true` loop because this Job is bound + # to come up before the CockroachDB Pods (due to the time needed to + # get PersistentVolumes attached to Nodes), and sleeping 5 seconds + # between attempts is much better than letting the Pod fail when + # the init command does and waiting out Kubernetes' non-configurable + # exponential back-off for Pod restarts. + # Command completes either when cluster initialization succeeds, + # or when cluster has been initialized already. + command: + - /bin/bash + - -c + - >- + {{- if $isClusterInitEnabled }} + initCluster() { + while true; do + local output=$( + set -x; + + /cockroach/cockroach init \ + {{- if .Values.tls.enabled }} + --certs-dir=/cockroach-certs/ \ + {{- else }} + --insecure \ + {{- end }} + {{- with index .Values.conf "cluster-name" }} + --cluster-name={{.}} \ + {{- end }} + --host={{ template "cockroachdb.fullname" . }}-0.{{ template "cockroachdb.fullname" . -}} + :{{ .Values.service.ports.grpc.internal.port | int64 }} \ + 2>&1); + + local exitCode="$?"; + echo $output; + + if [[ "$output" =~ .*"Cluster successfully initialized".* || "$output" =~ .*"cluster has already been initialized".* ]]; then + break; + fi + + echo "Cluster is not ready to be initialized, retrying in 5 seconds" + sleep 5; + done + } + + initCluster; + {{- end }} + + {{- if $isDatabaseProvisioningEnabled }} + provisionCluster() { + while true; do + /cockroach/cockroach sql \ + {{- if .Values.tls.enabled }} + --certs-dir=/cockroach-certs/ \ + {{- else }} + --insecure \ + {{- end }} + --host={{ template "cockroachdb.fullname" . }}-0.{{ template "cockroachdb.fullname" . -}} + :{{ .Values.service.ports.grpc.internal.port | int64 }} \ + --execute=" + {{- range $clusterSetting, $clusterSettingValue := .Values.init.provisioning.clusterSettings }} + SET CLUSTER SETTING {{ $clusterSetting }} = '${{ $clusterSetting | replace "." "_" }}_CLUSTER_SETTING'; + {{- end }} + + {{- range $user := .Values.init.provisioning.users }} + CREATE USER IF NOT EXISTS {{ $user.name }} WITH + {{- if $user.password }} + PASSWORD '${{ $user.name }}_PASSWORD' + {{- else }} + PASSWORD null + {{- end }} + {{ join " " $user.options }} + ; + {{- end }} + + {{- range $database := .Values.init.provisioning.databases }} + CREATE DATABASE IF NOT EXISTS {{ $database.name }} + {{- if $database.options }} + {{ join " " $database.options }} + {{- end }} + ; + + {{- range $owner := $database.owners }} + GRANT ALL ON DATABASE {{ $database.name }} TO {{ $owner }}; + {{- end }} + + {{- range $owner := $database.owners_with_grant_option }} + GRANT ALL ON DATABASE {{ $database.name }} TO {{ $owner }} WITH GRANT OPTION; + {{- end }} + + {{- if $database.backup }} + CREATE SCHEDULE IF NOT EXISTS {{ $database.name }}_scheduled_backup + FOR BACKUP DATABASE {{ $database.name }} INTO '{{ $database.backup.into }}' + + {{- if $database.backup.options }} + WITH {{ join "," $database.backup.options }} + {{- end }} + RECURRING '{{ $database.backup.recurring }}' + {{- if $database.backup.fullBackup }} + FULL BACKUP '{{ $database.backup.fullBackup }}' + {{- else }} + FULL BACKUP ALWAYS + {{- end }} + + {{- if and $database.backup.schedule $database.backup.schedule.options }} + WITH SCHEDULE OPTIONS {{ join "," $database.backup.schedule.options }} + {{- end }} + ; + {{- end }} + {{- end }} + " + &>/dev/null; + + local exitCode="$?"; + + if [[ "$exitCode" -eq "0" ]] + then break; + fi + + sleep 5; + done + + echo "Provisioning completed successfully"; + } + + provisionCluster; + {{- end }} + env: + {{- $secretName := printf "%s-init" (include "cockroachdb.fullname" .) }} + {{- range $user := .Values.init.provisioning.users }} + {{- if $user.password }} + - name: {{ $user.name }}_PASSWORD + valueFrom: + secretKeyRef: + name: {{ $secretName }} + key: {{ $user.name }}-password + {{- end }} + {{- end }} + {{- range $clusterSetting, $clusterSettingValue := .Values.init.provisioning.clusterSettings }} + {{- if $clusterSettingValue }} + - name: {{ $clusterSetting | replace "." "_" }}_CLUSTER_SETTING + valueFrom: + secretKeyRef: + name: {{ $secretName }} + key: {{ $clusterSetting | replace "." "-" }}-cluster-setting + {{- end }} + {{- end }} + {{- if .Values.tls.enabled }} + volumeMounts: + - name: client-certs + mountPath: /cockroach-certs/ + {{- end }} + {{- with .Values.init.resources }} + resources: {{- toYaml . | nindent 12 }} + {{- end }} + {{- if and .Values.init.securityContext.enabled }} + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: ["ALL"] + {{- end }} + {{- if .Values.tls.enabled }} + volumes: + - name: client-certs + emptyDir: {} + {{- if or .Values.tls.certs.provided .Values.tls.certs.certManager .Values.tls.certs.selfSigner.enabled }} + - name: certs-secret + {{- if or .Values.tls.certs.tlsSecret .Values.tls.certs.certManager .Values.tls.certs.selfSigner.enabled }} + projected: + sources: + - secret: + {{- if .Values.tls.certs.selfSigner.enabled }} + name: {{ template "cockroachdb.fullname" . }}-client-secret + {{ else }} + name: {{ .Values.tls.certs.clientRootSecret }} + {{ end -}} + items: + - key: ca.crt + path: ca.crt + mode: 0400 + - key: tls.crt + path: client.root.crt + mode: 0400 + - key: tls.key + path: client.root.key + mode: 0400 + {{- else }} + secret: + secretName: {{ .Values.tls.certs.clientRootSecret }} + defaultMode: 0400 + {{- end }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/cockroach-labs/cockroachdb/14.0.0/templates/networkpolicy.yaml b/charts/cockroach-labs/cockroachdb/14.0.0/templates/networkpolicy.yaml new file mode 100644 index 0000000000..d41afa32ba --- /dev/null +++ b/charts/cockroach-labs/cockroachdb/14.0.0/templates/networkpolicy.yaml @@ -0,0 +1,59 @@ +{{- if .Values.networkPolicy.enabled }} +kind: NetworkPolicy +apiVersion: {{ template "cockroachdb.networkPolicy.apiVersion" . }} +metadata: + name: {{ template "cockroachdb.serviceAccount.name" . }} + namespace: {{ .Release.Namespace | quote }} + labels: + helm.sh/chart: {{ template "cockroachdb.chart" . }} + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + podSelector: + matchLabels: + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + {{- with .Values.statefulset.labels }} + {{- toYaml . | nindent 6 }} + {{- end }} + ingress: + - ports: + - port: grpc + {{- with .Values.networkPolicy.ingress.grpc }} + from: + # Allow connections via custom rules. + {{- toYaml . | nindent 8 }} + # Allow client connection via pre-considered label. + - podSelector: + matchLabels: + {{ template "cockroachdb.fullname" . }}-client: "true" + # Allow other CockroachDBs to connect to form a cluster. + - podSelector: + matchLabels: + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + {{- with .Values.statefulset.labels }} + {{- toYaml . | nindent 14 }} + {{- end }} + {{- if gt (.Values.statefulset.replicas | int64) 1 }} + # Allow init Job to connect to bootstrap a cluster. + - podSelector: + matchLabels: + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + {{- with .Values.init.labels }} + {{- toYaml . | nindent 14 }} + {{- end }} + {{- end }} + {{- end }} + # Allow connections to admin UI and for Prometheus. + - ports: + - port: http + {{- with .Values.networkPolicy.ingress.http }} + from: {{- toYaml . | nindent 8 }} + {{- end }} +{{- end }} diff --git a/charts/cockroach-labs/cockroachdb/14.0.0/templates/poddisruptionbudget.yaml b/charts/cockroach-labs/cockroachdb/14.0.0/templates/poddisruptionbudget.yaml new file mode 100644 index 0000000000..f707e40541 --- /dev/null +++ b/charts/cockroach-labs/cockroachdb/14.0.0/templates/poddisruptionbudget.yaml @@ -0,0 +1,26 @@ +kind: PodDisruptionBudget +{{- if or (.Capabilities.APIVersions.Has "policy/v1") (semverCompare ">=1.21-0" .Capabilities.KubeVersion.Version) }} +apiVersion: policy/v1 +{{- else }} +apiVersion: policy/v1beta1 +{{- end }} +metadata: + name: {{ template "cockroachdb.fullname" . }}-budget + namespace: {{ .Release.Namespace | quote }} + labels: + helm.sh/chart: {{ template "cockroachdb.chart" . }} + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + selector: + matchLabels: + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + {{- with .Values.statefulset.labels }} + {{- toYaml . | nindent 6 }} + {{- end }} + maxUnavailable: {{ .Values.statefulset.budget.maxUnavailable | int64 }} diff --git a/charts/cockroach-labs/cockroachdb/14.0.0/templates/role-certRotateSelfSigner.yaml b/charts/cockroach-labs/cockroachdb/14.0.0/templates/role-certRotateSelfSigner.yaml new file mode 100644 index 0000000000..f0e2b90cea --- /dev/null +++ b/charts/cockroach-labs/cockroachdb/14.0.0/templates/role-certRotateSelfSigner.yaml @@ -0,0 +1,27 @@ +{{- if and .Values.tls.enabled .Values.tls.certs.selfSigner.enabled }} +kind: Role +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "rotatecerts.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: + helm.sh/chart: {{ template "cockroachdb.chart" . }} + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +rules: + - apiGroups: [""] + resources: ["secrets"] + verbs: ["create", "get", "update", "delete"] + - apiGroups: ["apps"] + resources: ["statefulsets"] + verbs: ["get"] + resourceNames: + - {{ template "cockroachdb.fullname" . }} + - apiGroups: [""] + resources: ["pods"] + verbs: ["delete", "get"] +{{- end }} diff --git a/charts/cockroach-labs/cockroachdb/14.0.0/templates/role-certSelfSigner.yaml b/charts/cockroach-labs/cockroachdb/14.0.0/templates/role-certSelfSigner.yaml new file mode 100644 index 0000000000..1cbaab3dd3 --- /dev/null +++ b/charts/cockroach-labs/cockroachdb/14.0.0/templates/role-certSelfSigner.yaml @@ -0,0 +1,33 @@ +{{- if and .Values.tls.enabled .Values.tls.certs.selfSigner.enabled }} +kind: Role +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "selfcerts.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + annotations: + # This is what defines this resource as a hook. Without this line, the + # job is considered part of the release. + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-weight": "2" + "helm.sh/hook-delete-policy": hook-succeeded,hook-failed + labels: + helm.sh/chart: {{ template "cockroachdb.chart" . }} + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +rules: + - apiGroups: [""] + resources: ["secrets"] + verbs: ["create", "get", "update", "delete"] + - apiGroups: ["apps"] + resources: ["statefulsets"] + verbs: ["get"] + resourceNames: + - {{ template "cockroachdb.fullname" . }} + - apiGroups: [""] + resources: ["pods"] + verbs: ["delete", "get"] +{{- end }} diff --git a/charts/cockroach-labs/cockroachdb/14.0.0/templates/role.yaml b/charts/cockroach-labs/cockroachdb/14.0.0/templates/role.yaml new file mode 100644 index 0000000000..ebe5ce8ae7 --- /dev/null +++ b/charts/cockroach-labs/cockroachdb/14.0.0/templates/role.yaml @@ -0,0 +1,23 @@ +{{- if .Values.tls.enabled }} +kind: Role +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "cockroachdb.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: + helm.sh/chart: {{ template "cockroachdb.chart" . }} + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +rules: + - apiGroups: [""] + resources: ["secrets"] + {{- if or .Values.tls.certs.provided .Values.tls.certs.certManager }} + verbs: ["get"] + {{- else }} + verbs: ["create", "get"] + {{- end }} +{{- end }} diff --git a/charts/cockroach-labs/cockroachdb/14.0.0/templates/rolebinding-certRotateSelfSigner.yaml b/charts/cockroach-labs/cockroachdb/14.0.0/templates/rolebinding-certRotateSelfSigner.yaml new file mode 100644 index 0000000000..c1a45f7977 --- /dev/null +++ b/charts/cockroach-labs/cockroachdb/14.0.0/templates/rolebinding-certRotateSelfSigner.yaml @@ -0,0 +1,23 @@ +{{- if and .Values.tls.enabled .Values.tls.certs.selfSigner.enabled }} +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "rotatecerts.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: + helm.sh/chart: {{ template "cockroachdb.chart" . }} + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "rotatecerts.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ template "rotatecerts.fullname" . }} + namespace: {{ .Release.Namespace | quote }} +{{- end }} diff --git a/charts/cockroach-labs/cockroachdb/14.0.0/templates/rolebinding-certSelfSigner.yaml b/charts/cockroach-labs/cockroachdb/14.0.0/templates/rolebinding-certSelfSigner.yaml new file mode 100644 index 0000000000..5725d02a41 --- /dev/null +++ b/charts/cockroach-labs/cockroachdb/14.0.0/templates/rolebinding-certSelfSigner.yaml @@ -0,0 +1,29 @@ +{{- if and .Values.tls.enabled .Values.tls.certs.selfSigner.enabled }} +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "selfcerts.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + annotations: + # This is what defines this resource as a hook. Without this line, the + # job is considered part of the release. + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-weight": "3" + "helm.sh/hook-delete-policy": hook-succeeded,hook-failed + labels: + helm.sh/chart: {{ template "cockroachdb.chart" . }} + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "selfcerts.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ template "selfcerts.fullname" . }} + namespace: {{ .Release.Namespace | quote }} +{{- end }} diff --git a/charts/cockroach-labs/cockroachdb/14.0.0/templates/rolebinding.yaml b/charts/cockroach-labs/cockroachdb/14.0.0/templates/rolebinding.yaml new file mode 100644 index 0000000000..00d9f9a551 --- /dev/null +++ b/charts/cockroach-labs/cockroachdb/14.0.0/templates/rolebinding.yaml @@ -0,0 +1,23 @@ +{{- if .Values.tls.enabled }} +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "cockroachdb.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: + helm.sh/chart: {{ template "cockroachdb.chart" . }} + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "cockroachdb.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ template "cockroachdb.serviceAccount.name" . }} + namespace: {{ .Release.Namespace | quote }} +{{- end }} diff --git a/charts/cockroach-labs/cockroachdb/14.0.0/templates/secret.backendconfig.yaml b/charts/cockroach-labs/cockroachdb/14.0.0/templates/secret.backendconfig.yaml new file mode 100644 index 0000000000..61103060a6 --- /dev/null +++ b/charts/cockroach-labs/cockroachdb/14.0.0/templates/secret.backendconfig.yaml @@ -0,0 +1,25 @@ +{{- if .Values.iap.enabled }} +kind: Secret +apiVersion: v1 +metadata: + name: {{ template "cockroachdb.fullname" . }}.iap + namespace: {{ .Release.Namespace | quote }} + labels: + helm.sh/chart: {{ template "cockroachdb.chart" . }} + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +type: Opaque +data: + {{- if eq "" .Values.iap.clientId }} + {{ fail "iap.clientID can't be empty if iap.enabled is set to true" }} + {{- end }} + client_id: {{ .Values.iap.clientId | b64enc }} + {{- if eq "" .Values.iap.clientSecret }} + {{ fail "iap.clientSecret can't be empty if iap.enabled is set to true" }} + {{- end }} + client_secret: {{ .Values.iap.clientSecret | b64enc }} +{{- end }} \ No newline at end of file diff --git a/charts/cockroach-labs/cockroachdb/14.0.0/templates/secret.logconfig.yaml b/charts/cockroach-labs/cockroachdb/14.0.0/templates/secret.logconfig.yaml new file mode 100644 index 0000000000..40b929ae75 --- /dev/null +++ b/charts/cockroach-labs/cockroachdb/14.0.0/templates/secret.logconfig.yaml @@ -0,0 +1,19 @@ +{{- if .Values.conf.log.enabled }} +kind: Secret +apiVersion: v1 +metadata: + name: {{ template "cockroachdb.fullname" . }}-log-config + namespace: {{ .Release.Namespace | quote }} + labels: + helm.sh/chart: {{ template "cockroachdb.chart" . }} + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +type: Opaque +stringData: + log-config.yaml: | + {{- toYaml .Values.conf.log.config | nindent 4 }} +{{- end }} diff --git a/charts/cockroach-labs/cockroachdb/14.0.0/templates/secret.registry.yaml b/charts/cockroach-labs/cockroachdb/14.0.0/templates/secret.registry.yaml new file mode 100644 index 0000000000..a054069fbc --- /dev/null +++ b/charts/cockroach-labs/cockroachdb/14.0.0/templates/secret.registry.yaml @@ -0,0 +1,23 @@ +{{- range $name, $cred := dict "db" (.Values.image.credentials) "init-certs" (.Values.tls.selfSigner.image.credentials) }} +{{- if not (empty $cred) }} +{{- if or (and (eq $name "init-certs") $.Values.tls.enabled) (ne $name "init-certs") }} +--- +kind: Secret +apiVersion: v1 +metadata: + name: {{ template "cockroachdb.fullname" $ }}.{{ $name }}.registry + namespace: {{ $.Release.Namespace | quote }} + labels: + helm.sh/chart: {{ template "cockroachdb.chart" $ }} + app.kubernetes.io/name: {{ template "cockroachdb.name" $ }} + app.kubernetes.io/instance: {{ $.Release.Name | quote }} + app.kubernetes.io/managed-by: {{ $.Release.Service | quote }} + {{- with $.Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ printf `{"auths":{%s:{"auth":"%s"}}}` ($cred.registry | quote) (printf "%s:%s" $cred.username $cred.password | b64enc) | b64enc | quote }} +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/cockroach-labs/cockroachdb/14.0.0/templates/secrets.init.yaml b/charts/cockroach-labs/cockroachdb/14.0.0/templates/secrets.init.yaml new file mode 100644 index 0000000000..4d13a35ffa --- /dev/null +++ b/charts/cockroach-labs/cockroachdb/14.0.0/templates/secrets.init.yaml @@ -0,0 +1,20 @@ +{{- if .Values.init.provisioning.enabled }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "cockroachdb.fullname" . }}-init + namespace: {{ .Release.Namespace | quote }} +type: Opaque +stringData: + +{{- range $user := .Values.init.provisioning.users }} +{{- if $user.password }} + {{ $user.name }}-password: {{ $user.password | quote }} +{{- end }} +{{- end }} + +{{- range $clusterSetting, $clusterSettingValue := .Values.init.provisioning.clusterSettings }} + {{ $clusterSetting | replace "." "-" }}-cluster-setting: {{ $clusterSettingValue | quote }} +{{- end }} + +{{- end }} diff --git a/charts/cockroach-labs/cockroachdb/14.0.0/templates/service.discovery.yaml b/charts/cockroach-labs/cockroachdb/14.0.0/templates/service.discovery.yaml new file mode 100644 index 0000000000..8fe2a427ad --- /dev/null +++ b/charts/cockroach-labs/cockroachdb/14.0.0/templates/service.discovery.yaml @@ -0,0 +1,64 @@ +# This service only exists to create DNS entries for each pod in +# the StatefulSet such that they can resolve each other's IP addresses. +# It does not create a load-balanced ClusterIP and should not be used directly +# by clients in most circumstances. +kind: Service +apiVersion: v1 +metadata: + name: {{ template "cockroachdb.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: + helm.sh/chart: {{ template "cockroachdb.chart" . }} + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + {{- with .Values.service.discovery.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + # Use this annotation in addition to the actual field below because the + # annotation will stop being respected soon, but the field is broken in + # some versions of Kubernetes: + # https://github.com/kubernetes/kubernetes/issues/58662 + service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" + # Enable automatic monitoring of all instances when Prometheus is running + # in the cluster. + {{- if .Values.prometheus.enabled }} + prometheus.io/scrape: "true" + prometheus.io/path: _status/vars + prometheus.io/port: {{ .Values.service.ports.http.port | quote }} + {{- end }} + {{- with .Values.service.discovery.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + clusterIP: None + # We want all Pods in the StatefulSet to have their addresses published for + # the sake of the other CockroachDB Pods even before they're ready, since they + # have to be able to talk to each other in order to become ready. + publishNotReadyAddresses: true + ports: + {{- $ports := .Values.service.ports }} + # The main port, served by gRPC, serves Postgres-flavor SQL, inter-node + # traffic and the CLI. + - name: {{ $ports.grpc.external.name | quote }} + port: {{ $ports.grpc.external.port | int64 }} + targetPort: grpc + {{- if ne ($ports.grpc.internal.port | int64) ($ports.grpc.external.port | int64) }} + - name: {{ $ports.grpc.internal.name | quote }} + port: {{ $ports.grpc.internal.port | int64 }} + targetPort: grpc + {{- end }} + # The secondary port serves the UI as well as health and debug endpoints. + - name: {{ $ports.http.name | quote }} + port: {{ $ports.http.port | int64 }} + targetPort: http + selector: + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + {{- with .Values.statefulset.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} diff --git a/charts/cockroach-labs/cockroachdb/14.0.0/templates/service.public.yaml b/charts/cockroach-labs/cockroachdb/14.0.0/templates/service.public.yaml new file mode 100644 index 0000000000..251e9ab084 --- /dev/null +++ b/charts/cockroach-labs/cockroachdb/14.0.0/templates/service.public.yaml @@ -0,0 +1,55 @@ +# This Service is meant to be used by clients of the database. +# It exposes a ClusterIP that will automatically load balance connections +# to the different database Pods. +kind: Service +apiVersion: v1 +metadata: + name: {{ template "cockroachdb.fullname" . }}-public + namespace: {{ .Release.Namespace | quote }} + labels: + helm.sh/chart: {{ template "cockroachdb.chart" . }} + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + {{- with .Values.service.public.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if or .Values.service.public.annotations .Values.tls.enabled .Values.iap.enabled }} + annotations: + {{- with .Values.service.public.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.tls.enabled }} + service.alpha.kubernetes.io/app-protocols: '{"http":"HTTPS"}' + {{- end }} + {{- if .Values.iap.enabled }} + beta.cloud.google.com/backend-config: '{"default": "{{ template "cockroachdb.fullname" . }}"}' + {{- end }} + {{- end }} +spec: + type: {{ .Values.service.public.type | quote }} + ports: + {{- $ports := .Values.service.ports }} + # The main port, served by gRPC, serves Postgres-flavor SQL, inter-node + # traffic and the CLI. + - name: {{ $ports.grpc.external.name | quote }} + port: {{ $ports.grpc.external.port | int64 }} + targetPort: grpc + {{- if ne ($ports.grpc.internal.port | int64) ($ports.grpc.external.port | int64) }} + - name: {{ $ports.grpc.internal.name | quote }} + port: {{ $ports.grpc.internal.port | int64 }} + targetPort: grpc + {{- end }} + # The secondary port serves the UI as well as health and debug endpoints. + - name: {{ $ports.http.name | quote }} + port: {{ $ports.http.port | int64 }} + targetPort: http + selector: + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + {{- with .Values.statefulset.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} diff --git a/charts/cockroach-labs/cockroachdb/14.0.0/templates/serviceMonitor.yaml b/charts/cockroach-labs/cockroachdb/14.0.0/templates/serviceMonitor.yaml new file mode 100644 index 0000000000..42f2390b4c --- /dev/null +++ b/charts/cockroach-labs/cockroachdb/14.0.0/templates/serviceMonitor.yaml @@ -0,0 +1,54 @@ +{{- $serviceMonitor := .Values.serviceMonitor -}} +{{- $ports := .Values.service.ports -}} +{{- if $serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "cockroachdb.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: + helm.sh/chart: {{ template "cockroachdb.chart" . }} + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + {{- if $serviceMonitor.labels }} + {{- toYaml $serviceMonitor.labels | nindent 4 }} + {{- end }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if $serviceMonitor.annotations }} + annotations: + {{- toYaml $serviceMonitor.annotations | nindent 4 }} + {{- end }} +spec: + selector: + matchLabels: + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + {{- with .Values.service.discovery.labels }} + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.labels }} + {{- toYaml . | nindent 6 }} + {{- end }} + namespaceSelector: + {{- if $serviceMonitor.namespaced }} + matchNames: + - {{ .Release.Namespace }} + {{- else }} + any: true + {{- end }} + endpoints: + - port: {{ $ports.http.name | quote }} + path: /_status/vars + {{- if $serviceMonitor.interval }} + interval: {{ $serviceMonitor.interval }} + {{- end }} + {{- if $serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ $serviceMonitor.scrapeTimeout }} + {{- end }} + {{- if .Values.serviceMonitor.tlsConfig }} + tlsConfig: {{ toYaml .Values.serviceMonitor.tlsConfig | nindent 6 }} + {{- end }} +{{- end }} diff --git a/charts/cockroach-labs/cockroachdb/14.0.0/templates/serviceaccount-certRotateSelfSigner.yaml b/charts/cockroach-labs/cockroachdb/14.0.0/templates/serviceaccount-certRotateSelfSigner.yaml new file mode 100644 index 0000000000..a27cba9219 --- /dev/null +++ b/charts/cockroach-labs/cockroachdb/14.0.0/templates/serviceaccount-certRotateSelfSigner.yaml @@ -0,0 +1,22 @@ +{{- if and .Values.tls.enabled .Values.tls.certs.selfSigner.enabled }} + {{ template "cockroachdb.tls.certs.selfSigner.validation" . }} +kind: ServiceAccount +apiVersion: v1 +metadata: + name: {{ template "rotatecerts.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: + helm.sh/chart: {{ template "cockroachdb.chart" . }} + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.tls.certs.selfSigner.svcAccountAnnotations }} + annotations: + {{- with .Values.tls.certs.selfSigner.svcAccountAnnotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/cockroach-labs/cockroachdb/14.0.0/templates/serviceaccount-certSelfSigner.yaml b/charts/cockroach-labs/cockroachdb/14.0.0/templates/serviceaccount-certSelfSigner.yaml new file mode 100644 index 0000000000..3ce2d63e9e --- /dev/null +++ b/charts/cockroach-labs/cockroachdb/14.0.0/templates/serviceaccount-certSelfSigner.yaml @@ -0,0 +1,25 @@ +{{- if and .Values.tls.enabled .Values.tls.certs.selfSigner.enabled }} + {{ template "cockroachdb.tls.certs.selfSigner.validation" . }} +kind: ServiceAccount +apiVersion: v1 +metadata: + name: {{ template "selfcerts.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + annotations: + # This is what defines this resource as a hook. Without this line, the + # job is considered part of the release. + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-weight": "1" + "helm.sh/hook-delete-policy": hook-succeeded,hook-failed + {{- with .Values.tls.certs.selfSigner.svcAccountAnnotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + helm.sh/chart: {{ template "cockroachdb.chart" . }} + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/cockroach-labs/cockroachdb/14.0.0/templates/serviceaccount.yaml b/charts/cockroach-labs/cockroachdb/14.0.0/templates/serviceaccount.yaml new file mode 100644 index 0000000000..3af9be9aa9 --- /dev/null +++ b/charts/cockroach-labs/cockroachdb/14.0.0/templates/serviceaccount.yaml @@ -0,0 +1,21 @@ +{{- if .Values.statefulset.serviceAccount.create }} +kind: ServiceAccount +apiVersion: v1 +metadata: + name: {{ template "cockroachdb.serviceAccount.name" . }} + namespace: {{ .Release.Namespace | quote }} + labels: + helm.sh/chart: {{ template "cockroachdb.chart" . }} + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.statefulset.serviceAccount.annotations }} + annotations: + {{- with .Values.statefulset.serviceAccount.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/cockroach-labs/cockroachdb/14.0.0/templates/statefulset.yaml b/charts/cockroach-labs/cockroachdb/14.0.0/templates/statefulset.yaml new file mode 100644 index 0000000000..a627c35161 --- /dev/null +++ b/charts/cockroach-labs/cockroachdb/14.0.0/templates/statefulset.yaml @@ -0,0 +1,402 @@ +kind: StatefulSet +apiVersion: {{ template "cockroachdb.statefulset.apiVersion" . }} +metadata: + name: {{ template "cockroachdb.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: + helm.sh/chart: {{ template "cockroachdb.chart" . }} + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + {{- with .Values.statefulset.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + serviceName: {{ template "cockroachdb.fullname" . }} + replicas: {{ .Values.statefulset.replicas | int64 }} + updateStrategy: {{- toYaml .Values.statefulset.updateStrategy | nindent 4 }} + podManagementPolicy: {{ .Values.statefulset.podManagementPolicy | quote }} + selector: + matchLabels: + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + {{- with .Values.statefulset.labels }} + {{- toYaml . | nindent 6 }} + {{- end }} + template: + metadata: + labels: + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + {{- with .Values.statefulset.labels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.labels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.statefulset.annotations }} + annotations: {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- if or .Values.image.credentials (and .Values.tls.enabled .Values.tls.selfSigner.image.credentials (not .Values.tls.certs.provided) (not .Values.tls.certs.certManager)) }} + imagePullSecrets: + {{- if .Values.image.credentials }} + - name: {{ template "cockroachdb.fullname" . }}.db.registry + {{- end }} + {{- if and .Values.tls.enabled .Values.tls.selfSigner.image.credentials (not .Values.tls.certs.provided) (not .Values.tls.certs.certManager) }} + - name: {{ template "cockroachdb.fullname" . }}.self-signed-certs.registry + {{- end }} + {{- end }} + serviceAccountName: {{ template "cockroachdb.serviceAccount.name" . }} + {{- if .Values.tls.enabled }} + initContainers: + - name: copy-certs + image: {{ .Values.tls.copyCerts.image | quote }} + imagePullPolicy: {{ .Values.tls.selfSigner.image.pullPolicy | quote }} + command: + - /bin/sh + - -c + - "cp -f /certs/* /cockroach-certs/; chmod 0400 /cockroach-certs/*.key" + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- if .Values.statefulset.securityContext.enabled }} + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + privileged: false + readOnlyRootFilesystem: true + {{- end }} + volumeMounts: + - name: certs + mountPath: /cockroach-certs/ + - name: certs-secret + mountPath: /certs/ + {{- with .Values.tls.copyCerts.resources }} + resources: {{- toYaml . | nindent 12 }} + {{- end }} + {{- end }} + {{- if or .Values.statefulset.nodeAffinity .Values.statefulset.podAffinity .Values.statefulset.podAntiAffinity }} + affinity: + {{- with .Values.statefulset.nodeAffinity }} + nodeAffinity: {{- toYaml . | nindent 10 }} + {{- end }} + {{- with .Values.statefulset.podAffinity }} + podAffinity: {{- toYaml . | nindent 10 }} + {{- end }} + {{- if .Values.statefulset.podAntiAffinity }} + podAntiAffinity: + {{- if .Values.statefulset.podAntiAffinity.type }} + {{- if eq .Values.statefulset.podAntiAffinity.type "hard" }} + requiredDuringSchedulingIgnoredDuringExecution: + - topologyKey: {{ .Values.statefulset.podAntiAffinity.topologyKey }} + labelSelector: + matchLabels: + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + {{- with .Values.statefulset.labels }} + {{- toYaml . | nindent 18 }} + {{- end }} + {{- else if eq .Values.statefulset.podAntiAffinity.type "soft" }} + preferredDuringSchedulingIgnoredDuringExecution: + - weight: {{ .Values.statefulset.podAntiAffinity.weight | int64 }} + podAffinityTerm: + topologyKey: {{ .Values.statefulset.podAntiAffinity.topologyKey }} + labelSelector: + matchLabels: + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + {{- with .Values.statefulset.labels }} + {{- toYaml . | nindent 20 }} + {{- end }} + {{- end }} + {{- else }} + {{- toYaml .Values.statefulset.podAntiAffinity | nindent 10 }} + {{- end }} + {{- end }} + {{- end }} + {{- if semverCompare ">=1.16-0" .Capabilities.KubeVersion.Version }} + topologySpreadConstraints: + - labelSelector: + matchLabels: + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + {{- with .Values.statefulset.labels }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.statefulset.topologySpreadConstraints }} + maxSkew: {{ .maxSkew }} + topologyKey: {{ .topologyKey }} + whenUnsatisfiable: {{ .whenUnsatisfiable }} + {{- end }} + {{- end }} + {{- with .Values.statefulset.nodeSelector }} + nodeSelector: {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.statefulset.priorityClassName }} + priorityClassName: {{ .Values.statefulset.priorityClassName }} + {{- end }} + {{- with .Values.statefulset.tolerations }} + tolerations: {{- toYaml . | nindent 8 }} + {{- end }} + # No pre-stop hook is required, a SIGTERM plus some time is all that's + # needed for graceful shutdown of a node. + terminationGracePeriodSeconds: 300 + containers: + - name: db + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy | quote }} + args: + - shell + - -ecx + # The use of qualified `hostname -f` is crucial: + # Other nodes aren't able to look up the unqualified hostname. + # + # `--join` CLI flag is hardcoded to exactly 3 Pods, because: + # 1. Having `--join` value depending on `statefulset.replicas` + # will trigger undesired restart of existing Pods when + # StatefulSet is scaled up/down. We want to scale without + # restarting existing Pods. + # 2. At least one Pod in `--join` is enough to successfully + # join CockroachDB cluster and gossip with all other existing + # Pods, even if there are 3 or more Pods. + # 3. It's harmless for `--join` to have 3 Pods even for 1-Pod + # clusters, while it gives us opportunity to scale up even if + # some Pods of existing cluster are down (for whatever reason). + # See details explained here: + # https://github.com/helm/charts/pull/18993#issuecomment-558795102 + - >- + exec /cockroach/cockroach + {{- if index .Values.conf `single-node` }} + start-single-node + {{- else }} + start --join= + {{- if .Values.conf.join }} + {{- join `,` .Values.conf.join -}} + {{- else }} + {{- range $i, $_ := until 3 -}} + {{- if gt $i 0 -}},{{- end -}} + ${STATEFULSET_NAME}-{{ $i }}.${STATEFULSET_FQDN}:{{ $.Values.service.ports.grpc.internal.port | int64 -}} + {{- end -}} + {{- end }} + {{- with index .Values.conf `cluster-name` }} + --cluster-name={{ . }} + {{- if index $.Values.conf `disable-cluster-name-verification` }} + --disable-cluster-name-verification + {{- end }} + {{- end }} + {{- end }} + --advertise-host=$(hostname).${STATEFULSET_FQDN} + {{- if .Values.tls.enabled }} + --certs-dir=/cockroach/cockroach-certs/ + {{- else }} + --insecure + {{- end }} + {{- with .Values.conf.attrs }} + --attrs={{ join `:` . }} + {{- end }} + --http-port={{ index .Values.conf `http-port` | int64 }} + --port={{ .Values.conf.port | int64 }} + --cache={{ .Values.conf.cache }} + {{- with index .Values.conf `max-disk-temp-storage` }} + --max-disk-temp-storage={{ . }} + {{- end }} + {{- with index .Values.conf `max-offset` }} + --max-offset={{ . }} + {{- end }} + --max-sql-memory={{ index .Values.conf `max-sql-memory` }} + {{- with .Values.conf.locality }} + --locality={{ . }} + {{- end }} + {{- with index .Values.conf `sql-audit-dir` }} + --sql-audit-dir={{ . }} + {{- end }} + {{- if .Values.conf.store.enabled }} + --store={{ template "cockroachdb.conf.store" . }} + {{- end }} + {{- if .Values.conf.log.enabled }} + --log-config-file=/cockroach/log-config/log-config.yaml + {{- else }} + --logtostderr={{ .Values.conf.logtostderr }} + {{- end }} + {{- range .Values.statefulset.args }} + {{ . }} + {{- end }} + env: + - name: STATEFULSET_NAME + value: {{ template "cockroachdb.fullname" . }} + - name: STATEFULSET_FQDN + value: {{ template "cockroachdb.fullname" . }}.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }} + - name: COCKROACH_CHANNEL + value: kubernetes-helm + {{- with .Values.statefulset.env }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: grpc + containerPort: {{ .Values.conf.port | int64 }} + protocol: TCP + - name: http + containerPort: {{ index .Values.conf `http-port` | int64 }} + protocol: TCP + volumeMounts: + - name: datadir + mountPath: /cockroach/{{ .Values.conf.path }}/ + {{- if .Values.tls.enabled }} + - name: certs + mountPath: /cockroach/cockroach-certs/ + {{- if .Values.tls.certs.provided }} + - name: certs-secret + mountPath: /cockroach/certs/ + {{- end }} + {{- end }} + {{- range .Values.statefulset.secretMounts }} + - name: {{ printf "secret-%s" . | quote }} + mountPath: {{ printf "/etc/cockroach/secrets/%s" . | quote }} + readOnly: true + {{- end }} + {{- if .Values.conf.log.enabled }} + - name: log-config + mountPath: /cockroach/log-config + readOnly: true + {{- end }} + livenessProbe: + {{- if .Values.statefulset.customLivenessProbe }} + {{ toYaml .Values.statefulset.customLivenessProbe | nindent 12 }} + {{- else }} + httpGet: + path: /health + port: http + {{- if .Values.tls.enabled }} + scheme: HTTPS + {{- end }} + initialDelaySeconds: 30 + periodSeconds: 5 + {{- end }} + readinessProbe: + {{- if .Values.statefulset.customReadinessProbe }} + {{ toYaml .Values.statefulset.customReadinessProbe | nindent 12 }} + {{- else }} + httpGet: + path: /health?ready=1 + port: http + {{- if .Values.tls.enabled }} + scheme: HTTPS + {{- end }} + initialDelaySeconds: 10 + periodSeconds: 5 + failureThreshold: 2 + {{- end }} + {{- if eq (include "cockroachdb.securityContext.versionValidation" .) "true" }} + {{- if .Values.statefulset.securityContext.enabled }} + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + privileged: false + readOnlyRootFilesystem: true + {{- end }} + {{- end }} + {{- with .Values.statefulset.resources }} + resources: {{- toYaml . | nindent 12 }} + {{- end }} + volumes: + - name: datadir + {{- if .Values.storage.persistentVolume.enabled }} + persistentVolumeClaim: + claimName: datadir + {{- else if .Values.storage.hostPath }} + hostPath: + path: {{ .Values.storage.hostPath | quote }} + {{- else }} + emptyDir: {} + {{- end }} + {{- if .Values.tls.enabled }} + - name: certs + emptyDir: {} + {{- if or .Values.tls.certs.provided .Values.tls.certs.certManager .Values.tls.certs.selfSigner.enabled }} + - name: certs-secret + {{- if or .Values.tls.certs.tlsSecret .Values.tls.certs.certManager .Values.tls.certs.selfSigner.enabled }} + projected: + sources: + - secret: + {{- if .Values.tls.certs.selfSigner.enabled }} + name: {{ template "cockroachdb.fullname" . }}-node-secret + {{ else }} + name: {{ .Values.tls.certs.nodeSecret }} + {{ end -}} + items: + - key: ca.crt + path: ca.crt + mode: 256 + - key: tls.crt + path: node.crt + mode: 256 + - key: tls.key + path: node.key + mode: 256 + {{- else }} + secret: + secretName: {{ .Values.tls.certs.nodeSecret }} + defaultMode: 256 + {{- end }} + {{- end }} + {{- end }} + {{- range .Values.statefulset.secretMounts }} + - name: {{ printf "secret-%s" . | quote }} + secret: + secretName: {{ . | quote }} + {{- end }} + {{- if .Values.conf.log.enabled }} + - name: log-config + secret: + secretName: {{ template "cockroachdb.fullname" . }}-log-config + {{- end }} + {{- if eq (include "cockroachdb.securityContext.versionValidation" .) "true" }} + {{- if and .Values.securityContext.enabled }} + securityContext: + seccompProfile: + type: "RuntimeDefault" + fsGroup: 1000 + runAsGroup: 1000 + runAsUser: 1000 + runAsNonRoot: true + {{- end }} + {{- end }} +{{- if .Values.storage.persistentVolume.enabled }} + volumeClaimTemplates: + - metadata: + name: datadir + labels: + app.kubernetes.io/name: {{ template "cockroachdb.name" . }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + {{- with .Values.storage.persistentVolume.labels }} + {{- toYaml . | nindent 10 }} + {{- end }} + {{- with .Values.labels }} + {{- toYaml . | nindent 10 }} + {{- end }} + {{- with .Values.storage.persistentVolume.annotations }} + annotations: {{- toYaml . | nindent 10 }} + {{- end }} + spec: + accessModes: ["ReadWriteOnce"] + {{- if .Values.storage.persistentVolume.storageClass }} + {{- if (eq "-" .Values.storage.persistentVolume.storageClass) }} + storageClassName: "" + {{- else }} + storageClassName: {{ .Values.storage.persistentVolume.storageClass | quote}} + {{- end }} + {{- end }} + resources: + requests: + storage: {{ .Values.storage.persistentVolume.size | quote }} +{{- end }} diff --git a/charts/cockroach-labs/cockroachdb/14.0.0/templates/tests/client.yaml b/charts/cockroach-labs/cockroachdb/14.0.0/templates/tests/client.yaml new file mode 100644 index 0000000000..8656b8ed68 --- /dev/null +++ b/charts/cockroach-labs/cockroachdb/14.0.0/templates/tests/client.yaml @@ -0,0 +1,65 @@ +kind: Pod +apiVersion: v1 +metadata: + name: {{ template "cockroachdb.fullname" . }}-test + namespace: {{ .Release.Namespace | quote }} +{{- if .Values.networkPolicy.enabled }} + labels: + {{ template "cockroachdb.fullname" . }}-client: "true" +{{- end }} + annotations: + helm.sh/hook: test-success +spec: + restartPolicy: Never +{{- if .Values.image.credentials }} + imagePullSecrets: + - name: {{ template "cockroachdb.fullname" . }}.db.registry +{{- end }} + {{- if or .Values.tls.certs.provided .Values.tls.certs.certManager }} + volumes: + - name: client-certs + {{- if or .Values.tls.certs.tlsSecret .Values.tls.certs.certManager }} + projected: + sources: + - secret: + name: {{ .Values.tls.certs.clientRootSecret }} + items: + - key: ca.crt + path: ca.crt + mode: 0400 + - key: tls.crt + path: client.root.crt + mode: 0400 + - key: tls.key + path: client.root.key + mode: 0400 + {{- else }} + secret: + secretName: {{ .Values.tls.certs.clientRootSecret }} + defaultMode: 0400 + {{- end }} + {{- end }} + containers: + - name: client-test + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy | quote }} + {{- if or .Values.tls.certs.provided .Values.tls.certs.certManager }} + volumeMounts: + - name: client-certs + mountPath: /cockroach-certs + {{- end }} + command: + - /cockroach/cockroach + - sql + {{- if or .Values.tls.certs.provided .Values.tls.certs.certManager }} + - --certs-dir + - /cockroach-certs + {{- else }} + - --insecure + {{- end}} + - --host + - {{ template "cockroachdb.fullname" . }}-public.{{ .Release.Namespace }} + - --port + - {{ .Values.service.ports.grpc.external.port | quote }} + - -e + - SHOW DATABASES; diff --git a/charts/cockroach-labs/cockroachdb/14.0.0/values.schema.json b/charts/cockroach-labs/cockroachdb/14.0.0/values.schema.json new file mode 100644 index 0000000000..b23c479741 --- /dev/null +++ b/charts/cockroach-labs/cockroachdb/14.0.0/values.schema.json @@ -0,0 +1,97 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "tls": { + "type": "object", + "properties": { + "certs": { + "type": "object", + "properties": { + "selfSigner": { + "type": "object", + "required": ["enabled", "caProvided"], + "properties": { + "enabled": { + "type": "boolean" + }, + "caProvided": { + "type": "boolean" + } + }, + "if": { + "properties": { + "enabled": { + "const": true + } + } + }, + "then": { + "if": { + "properties": { + "caProvided": { + "const": false + } + } + }, + "then": { + "properties": { + "caCertDuration" : { + "type": "string", + "pattern": "^[0-9]*h$" + }, + "caCertExpiryWindow": { + "type": "string", + "pattern": "^[0-9]*h$" + } + } + }, + "properties": { + "clientCertDuration": { + "type": "string", + "pattern": "^[0-9]*h$" + }, + "clientCertExpiryWindow": { + "type": "string", + "pattern": "^[0-9]*h$" + }, + "nodeCertDuration": { + "type": "string", + "pattern": "^[0-9]*h$" + }, + "nodeCertExpiryWindow": { + "type": "string", + "pattern": "^[0-9]*h$" + }, + "rotateCerts": { + "type": "boolean" + } + } + } + } + } + }, + "selfSigner": { + "type": "object", + "properties": { + "image": { + "type": "object", + "required": ["repository", "tag", "pullPolicy"], + "properties": { + "repository": { + "type": "string" + }, + "tag": { + "type": "string" + }, + "pullPolicy": { + "type": "string", + "pattern": "^(Always|Never|IfNotPresent)$" + } + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/charts/cockroach-labs/cockroachdb/14.0.0/values.yaml b/charts/cockroach-labs/cockroachdb/14.0.0/values.yaml new file mode 100644 index 0000000000..07c66f1a7d --- /dev/null +++ b/charts/cockroach-labs/cockroachdb/14.0.0/values.yaml @@ -0,0 +1,590 @@ +# Generated file, DO NOT EDIT. Source: build/templates/values.yaml +# Overrides the chart name against the label "app.kubernetes.io/name: " placed on every resource this chart creates. +nameOverride: "" + +# Override the resource names created by this chart which originally is generated using release and chart name. +fullnameOverride: "" + +image: + repository: cockroachdb/cockroach + tag: v24.2.0 + pullPolicy: IfNotPresent + credentials: {} + # registry: docker.io + # username: john_doe + # password: changeme + + +# Additional labels to apply to all Kubernetes resources created by this chart. +labels: {} + # app.kubernetes.io/part-of: my-app + + +# Cluster's default DNS domain. +# You should overwrite it if you're using a different one, +# otherwise CockroachDB nodes discovery won't work. +clusterDomain: cluster.local + + +conf: + # An ordered list of CockroachDB node attributes. + # Attributes are arbitrary strings specifying machine capabilities. + # Machine capabilities might include specialized hardware or number of cores + # (e.g. "gpu", "x16c"). + attrs: [] + # - x16c + # - gpu + + # Total size in bytes for caches, shared evenly if there are multiple + # storage devices. Size suffixes are supported (e.g. `1GB` and `1GiB`). + # A percentage of physical memory can also be specified (e.g. `.25`). + cache: 25% + + # Sets a name to verify the identity of a cluster. + # The value must match between all nodes specified via `conf.join`. + # This can be used as an additional verification when either the node or + # cluster, or both, have not yet been initialized and do not yet know their + # cluster ID. + # To introduce a cluster name into an already-initialized cluster, pair this + # option with `conf.disable-cluster-name-verification: yes`. + cluster-name: "" + + # Tell the server to ignore `conf.cluster-name` mismatches. + # This is meant for use when opting an existing cluster into starting to use + # cluster name verification, or when changing the cluster name. + # The cluster should be restarted once with `conf.cluster-name` and + # `conf.disable-cluster-name-verification: yes` combined, and once all nodes + # have been updated to know the new cluster name, the cluster can be restarted + # again with `conf.disable-cluster-name-verification: no`. + # This option has no effect if `conf.cluster-name` is not specified. + disable-cluster-name-verification: false + + # The addresses for connecting a CockroachDB nodes to an existing cluster. + # If you are deploying a second CockroachDB instance that should join a first + # one, use the below list to join to the existing instance. + # Each item in the array should be a FQDN (and port if needed) resolvable by + # new Pods. + join: [] + + # New logging configuration. + log: + enabled: false + # https://www.cockroachlabs.com/docs/v21.1/configure-logs + config: {} + # file-defaults: + # dir: /custom/dir/path/ + # fluent-defaults: + # format: json-fluent + # sinks: + # stderr: + # channels: [DEV] + + # Logs at or above this threshold to STDERR. Ignored when "log" is enabled + logtostderr: INFO + + # Maximum storage capacity available to store temporary disk-based data for + # SQL queries that exceed the memory budget (e.g. join, sorts, etc are + # sometimes able to spill intermediate results to disk). + # Accepts numbers interpreted as bytes, size suffixes (e.g. `32GB` and + # `32GiB`) or a percentage of disk size (e.g. `10%`). + # The location of the temporary files is within the first store dir. + # If expressed as a percentage, `max-disk-temp-storage` is interpreted + # relative to the size of the storage device on which the first store is + # placed. The temp space usage is never counted towards any store usage + # (although it does share the device with the first store) so, when + # configuring this, make sure that the size of this temp storage plus the size + # of the first store don't exceed the capacity of the storage device. + # If the first store is an in-memory one (i.e. `type=mem`), then this + # temporary "disk" data is also kept in-memory. + # A percentage value is interpreted as a percentage of the available internal + # memory. + # max-disk-temp-storage: 0GB + + # Maximum allowed clock offset for the cluster. If observed clock offsets + # exceed this limit, servers will crash to minimize the likelihood of + # reading inconsistent data. Increasing this value will increase the time + # to recovery of failures as well as the frequency of uncertainty-based + # read restarts. + # Note, that this value must be the same on all nodes in the cluster. + # In order to change it, all nodes in the cluster must be stopped + # simultaneously and restarted with the new value. + # max-offset: 500ms + + # Maximum memory capacity available to store temporary data for SQL clients, + # including prepared queries and intermediate data rows during query + # execution. Accepts numbers interpreted as bytes, size suffixes + # (e.g. `1GB` and `1GiB`) or a percentage of physical memory (e.g. `.25`). + max-sql-memory: 25% + + # An ordered, comma-separated list of key-value pairs that describe the + # topography of the machine. Topography might include country, datacenter + # or rack designations. Data is automatically replicated to maximize + # diversities of each tier. The order of tiers is used to determine + # the priority of the diversity, so the more inclusive localities like + # country should come before less inclusive localities like datacenter. + # The tiers and order must be the same on all nodes. Including more tiers + # is better than including fewer. For example: + # locality: country=us,region=us-west,datacenter=us-west-1b,rack=12 + # locality: country=ca,region=ca-east,datacenter=ca-east-2,rack=4 + # locality: planet=earth,province=manitoba,colo=secondary,power=3 + locality: "" + + # Run CockroachDB instances in standalone mode with replication disabled + # (replication factor = 1). + # Enabling this option makes the following values to be ignored: + # - `conf.cluster-name` + # - `conf.disable-cluster-name-verification` + # - `conf.join` + # + # WARNING: Enabling this option makes each deployed Pod as a STANDALONE + # CockroachDB instance, so the StatefulSet does NOT FORM A CLUSTER. + # Don't use this option for production deployments unless you clearly + # understand what you're doing. + # Usually, this option is intended to be used in conjunction with + # `statefulset.replicas: 1` for temporary one-time deployments (like + # running E2E tests, for example). + single-node: false + + # If non-empty, create a SQL audit log in the specified directory. + sql-audit-dir: "" + + # CockroachDB's port to listen to inter-communications and client connections. + port: 26257 + + # CockroachDB's port to listen to HTTP requests. + http-port: 8080 + + # CockroachDB's data mount path. + path: cockroach-data + + # CockroachDB's storage configuration https://www.cockroachlabs.com/docs/v21.1/cockroach-start.html#storage + # Uses --store flag + store: + enabled: false + # Should be empty or 'mem' + type: + # Required for type=mem. If type and size is empty - storage.persistentVolume.size is used + size: + # Arbitrary strings, separated by colons, specifying disk type or capability + attrs: + +statefulset: + replicas: 3 + updateStrategy: + type: RollingUpdate + podManagementPolicy: Parallel + budget: + maxUnavailable: 1 + + # List of additional command-line arguments you want to pass to the + # `cockroach start` command. + args: [] + # - --disable-cluster-name-verification + + # List of extra environment variables to pass into container + env: [] + # - name: COCKROACH_ENGINE_MAX_SYNC_DURATION + # value: "24h" + + # List of Secrets names in the same Namespace as the CockroachDB cluster, + # which shall be mounted into `/etc/cockroach/secrets/` for every cluster + # member. + secretMounts: [] + + # Additional labels to apply to this StatefulSet and all its Pods. + labels: + app.kubernetes.io/component: cockroachdb + + # Additional annotations to apply to the Pods of this StatefulSet. + annotations: {} + + # Affinity rules for scheduling Pods of this StatefulSet on Nodes. + # https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#node-affinity + nodeAffinity: {} + # Inter-Pod Affinity rules for scheduling Pods of this StatefulSet. + # https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#inter-pod-affinity-and-anti-affinity + podAffinity: {} + # Anti-affinity rules for scheduling Pods of this StatefulSet. + # https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#inter-pod-affinity-and-anti-affinity + # You may either toggle options below for default anti-affinity rules, + # or specify the whole set of anti-affinity rules instead of them. + podAntiAffinity: + # The topologyKey to be used. + # Can be used to spread across different nodes, AZs, regions etc. + topologyKey: kubernetes.io/hostname + # Type of anti-affinity rules: either `soft`, `hard` or empty value (which + # disables anti-affinity rules). + type: soft + # Weight for `soft` anti-affinity rules. + # Does not apply for other anti-affinity types. + weight: 100 + + # Node selection constraints for scheduling Pods of this StatefulSet. + # https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector + nodeSelector: {} + + # PriorityClassName given to Pods of this StatefulSet + # https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#priorityclass + priorityClassName: "" + + # Taints to be tolerated by Pods of this StatefulSet. + # https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ + tolerations: [] + + # https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ + topologySpreadConstraints: + maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: ScheduleAnyway + + # Uncomment the following resources definitions or pass them from + # command line to control the CPU and memory resources allocated + # by Pods of this StatefulSet. + resources: {} + # limits: + # cpu: 100m + # memory: 512Mi + # requests: + # cpu: 100m + # memory: 512Mi + + # Custom Liveness probe + # https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#define-a-liveness-http-request + customLivenessProbe: {} + # httpGet: + # path: /health + # port: http + # scheme: HTTPS + # initialDelaySeconds: 30 + # periodSeconds: 5 + + # Custom Rediness probe + # https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#define-readiness-probes + customReadinessProbe: {} + # httpGet: + # path: /health + # port: http + # scheme: HTTPS + # initialDelaySeconds: 30 + # periodSeconds: 5 + + securityContext: + enabled: true + + serviceAccount: + # Specifies whether this ServiceAccount should be created. + create: true + # The name of this ServiceAccount to use. + # If not set and `create` is `true`, then service account is auto-generated. + # If not set and `create` is `false`, then it uses default service account. + name: "" + # Additional serviceAccount annotations (e.g. for attaching AWS IAM roles to pods) + annotations: {} + +service: + ports: + # You can set a different external and internal gRPC ports and their name. + grpc: + external: + port: 26257 + name: grpc + # If the port number is different than `external.port`, then it will be + # named as `internal.name` in Service. + internal: + port: 26257 + # If using Istio set it to `cockroach`. + name: grpc-internal + http: + port: 8080 + name: http + + # This Service is meant to be used by clients of the database. + # It exposes a ClusterIP that will automatically load balance connections + # to the different database Pods. + public: + type: ClusterIP + # Additional labels to apply to this Service. + labels: + app.kubernetes.io/component: cockroachdb + # Additional annotations to apply to this Service. + annotations: {} + + # This service only exists to create DNS entries for each pod in + # the StatefulSet such that they can resolve each other's IP addresses. + # It does not create a load-balanced ClusterIP and should not be used directly + # by clients in most circumstances. + discovery: + # Additional labels to apply to this Service. + labels: + app.kubernetes.io/component: cockroachdb + # Additional annotations to apply to this Service. + annotations: {} + +# CockroachDB's ingress for web ui. +ingress: + enabled: false + labels: {} + annotations: {} + # kubernetes.io/ingress.class: nginx + # cert-manager.io/cluster-issuer: letsencrypt + paths: [/] + hosts: [] + # - cockroachlabs.com + tls: [] + # - hosts: [cockroachlabs.com] + # secretName: cockroachlabs-tls + +prometheus: + enabled: true + +securityContext: + enabled: true + +# CockroachDB's Prometheus operator ServiceMonitor support +serviceMonitor: + enabled: false + labels: {} + annotations: {} + interval: 10s + # scrapeTimeout: 10s + # Limits the ServiceMonitor to the current namespace if set to `true`. + namespaced: false + + # tlsConfig: TLS configuration to use when scraping the endpoint. + # Of type: https://github.com/coreos/prometheus-operator/blob/main/Documentation/api.md#tlsconfig + tlsConfig: {} + +# CockroachDB's data persistence. +# If neither `persistentVolume` nor `hostPath` is used, then data will be +# persisted in ad-hoc `emptyDir`. +storage: + # Absolute path on host to store CockroachDB's data. + # If not specified, then `emptyDir` will be used instead. + # If specified, but `persistentVolume.enabled` is `true`, then has no effect. + hostPath: "" + + # If `enabled` is `true` then a PersistentVolumeClaim will be created and + # used to store CockroachDB's data, otherwise `hostPath` is used. + persistentVolume: + enabled: true + + size: 100Gi + + # If defined, then `storageClassName: `. + # If set to "-", then `storageClassName: ""`, which disables dynamic + # provisioning. + # If undefined or empty (default), then no `storageClassName` spec is set, + # so the default provisioner will be chosen (gp2 on AWS, standard on + # GKE, AWS & OpenStack). + storageClass: "" + + # Additional labels to apply to the created PersistentVolumeClaims. + labels: {} + # Additional annotations to apply to the created PersistentVolumeClaims. + annotations: {} + + +# Kubernetes Job which initializes multi-node CockroachDB cluster. +# It's not created if `statefulset.replicas` is `1`. +init: + # Additional labels to apply to this Job and its Pod. + labels: + app.kubernetes.io/component: init + + # Additional annotations to apply to this Job. + jobAnnotations: {} + + # Additional annotations to apply to the Pod of this Job. + annotations: {} + + # Affinity rules for scheduling the Pod of this Job. + # https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#node-affinity + affinity: {} + + # Node selection constraints for scheduling the Pod of this Job. + # https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector + nodeSelector: {} + + # Taints to be tolerated by the Pod of this Job. + # https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ + tolerations: [] + + # The init Pod runs at cluster creation to initialize CockroachDB. It finishes + # quickly and doesn't continue to consume resources in the Kubernetes + # cluster. Normally, you should leave this section commented out, but if your + # Kubernetes cluster uses Resource Quotas and requires all pods to specify + # resource requests or limits, you can set those here. + resources: {} + # requests: + # cpu: "10m" + # memory: "128Mi" + # limits: + # cpu: "10m" + # memory: "128Mi" + + securityContext: + enabled: true + + provisioning: + enabled: false + # https://www.cockroachlabs.com/docs/stable/cluster-settings.html + clusterSettings: + # cluster.organization: "'FooCorp - Local Testing'" + # enterprise.license: "'xxxxx'" + users: [] + # - name: + # password: + # # https://www.cockroachlabs.com/docs/stable/create-user.html#parameters + # options: [LOGIN] + databases: [] + # - name: + # # https://www.cockroachlabs.com/docs/stable/create-database.html#parameters + # options: [encoding='utf-8'] + # owners: [] + # # https://www.cockroachlabs.com/docs/stable/grant.html#parameters + # owners_with_grant_option: [] + # # Backup schedules are not idemponent for now and will fail on next run + # # https://github.com/cockroachdb/cockroach/issues/57892 + # backup: + # into: s3:// + # # Enterprise-only option (revision_history) + # # https://www.cockroachlabs.com/docs/stable/create-schedule-for-backup.html#backup-options + # options: [revision_history] + # recurring: '@always' + # # Enterprise-only feature. Remove this value to use `FULL BACKUP ALWAYS` + # fullBackup: '@daily' + # schedule: + # # https://www.cockroachlabs.com/docs/stable/create-schedule-for-backup.html#schedule-options + # options: [first_run = 'now'] + + +# Whether to run securely using TLS certificates. +tls: + enabled: true + copyCerts: + image: busybox + certs: + # Bring your own certs scenario. If provided, tls.init section will be ignored. + provided: false + # Secret name for the client root cert. + clientRootSecret: cockroachdb-root + # Secret name for node cert. + nodeSecret: cockroachdb-node + # Secret name for CA cert + caSecret: cockroach-ca + # Enable if the secret is a dedicated TLS. + # TLS secrets are created by cert-mananger, for example. + tlsSecret: false + # Enable if the you want cockroach db to create its own certificates + selfSigner: + # If set, the cockroach db will generate its own certificates + enabled: true + # Run selfSigner as non-root + securityContext: + enabled: true + # If set, the user should provide the CA certificate to sign other certificates. + caProvided: false + # It holds the name of the secret with caCerts. If caProvided is set, this can not be empty. + caSecret: "" + # Minimum Certificate duration for all the certificates, all certs duration will be validated against this. + minimumCertDuration: 624h + # Duration of CA certificates in hour + caCertDuration: 43800h + # Expiry window of CA certificates means a window before actual expiry in which CA certs should be rotated. + caCertExpiryWindow: 648h + # Duration of Client certificates in hour + clientCertDuration: 672h + # Expiry window of client certificates means a window before actual expiry in which client certs should be rotated. + clientCertExpiryWindow: 48h + # Duration of node certificates in hour + nodeCertDuration: 8760h + # Expiry window of node certificates means a window before actual expiry in which node certs should be rotated. + nodeCertExpiryWindow: 168h + # If set, the cockroachdb cert selfSigner will rotate the certificates before expiry. + rotateCerts: true + # Wait time for each cockroachdb replica to become ready once it comes in running state. Only considered when rotateCerts is set to true + readinessWait: 30s + # Wait time for each cockroachdb replica to get to running state. Only considered when rotateCerts is set to true + podUpdateTimeout: 2m + # ServiceAccount annotations for selfSigner jobs (e.g. for attaching AWS IAM roles to pods) + svcAccountAnnotations: {} + + # Use cert-manager to issue certificates for mTLS. + certManager: false + # Specify an Issuer or a ClusterIssuer to use, when issuing + # node and client certificates. The values correspond to the + # issuerRef specified in the certificate. + certManagerIssuer: + group: cert-manager.io + kind: Issuer + name: cockroachdb + # Make it false when you are providing your own CA issuer + isSelfSignedIssuer: true + # Duration of CA certificates in hour + caCertDuration: 43800h + # Expiry window of CA certificates means a window before actual expiry in which CA certs should be rotated. + caCertExpiryWindow: 648h + # Duration of Client certificates in hours + clientCertDuration: 672h + # Expiry window of client certificates means a window before actual expiry in which client certs should be rotated. + clientCertExpiryWindow: 48h + # Duration of node certificates in hours + nodeCertDuration: 8760h + # Expiry window of node certificates means a window before actual expiry in which node certs should be rotated. + nodeCertExpiryWindow: 168h + + selfSigner: + # Additional annotations to apply to the Pod of this Job. + annotations: {} + + # Affinity rules for scheduling the Pod of this Job. + # https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#node-affinity + affinity: {} + + # Node selection constraints for scheduling the Pod of this Job. + # https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector + nodeSelector: {} + + # Taints to be tolerated by the Pod of this Job. + # https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ + tolerations: [] + + # Image Placeholder for the selfSigner utility. This will be changed once the CI workflows for the image is in place. + image: + repository: cockroachlabs-helm-charts/cockroach-self-signer-cert + tag: "1.5" + pullPolicy: IfNotPresent + credentials: {} + registry: gcr.io + # username: john_doe + # password: changeme + +networkPolicy: + enabled: false + + ingress: + # List of sources which should be able to access the CockroachDB Pods via + # gRPC port. Items in this list are combined using a logical OR operation. + # Rules for allowing inter-communication are applied automatically. + # If empty, then connections from any Pod is allowed. + grpc: [] + # - podSelector: + # matchLabels: + # app.kubernetes.io/name: my-app-django + # app.kubernetes.io/instance: my-app + + # List of sources which should be able to access the CockroachDB Pods via + # HTTP port. Items in this list are combined using a logical OR operation. + # If empty, then connections from any Pod is allowed. + http: [] + # - namespaceSelector: + # matchLabels: + # project: my-project + +# To put the admin interface behind Identity Aware Proxy (IAP) on Google Cloud Platform +# make sure to set ingress.paths: ['/*'] +iap: + enabled: false + # Create Google Cloud OAuth credentials and set client id and secret + # clientId: + # clientSecret: diff --git a/charts/confluent/confluent-for-kubernetes/0.1033.22/Chart.yaml b/charts/confluent/confluent-for-kubernetes/0.1033.22/Chart.yaml new file mode 100644 index 0000000000..dcd99406f2 --- /dev/null +++ b/charts/confluent/confluent-for-kubernetes/0.1033.22/Chart.yaml @@ -0,0 +1,23 @@ +annotations: + catalog.cattle.io/certified: partner + catalog.cattle.io/display-name: Confluent for Kubernetes + catalog.cattle.io/kube-version: '>=1.15-0' + catalog.cattle.io/release-name: confluent-for-kubernetes +apiVersion: v1 +appVersion: 2.9.2 +description: A Helm chart to deploy Confluent for Kubernetes +home: https://www.confluent.io/ +icon: file://assets/icons/confluent-for-kubernetes.png +keywords: +- Confluent +- Confluent Operator +- Confluent Platform +- CFK +kubeVersion: '>=1.15-0' +maintainers: +- email: operator@confluent.io + name: Confluent Operator +name: confluent-for-kubernetes +sources: +- https://docs.confluent.io/current/index.html +version: 0.1033.22 diff --git a/charts/confluent/confluent-for-kubernetes/0.1033.22/README.md b/charts/confluent/confluent-for-kubernetes/0.1033.22/README.md new file mode 100644 index 0000000000..512ca36c7f --- /dev/null +++ b/charts/confluent/confluent-for-kubernetes/0.1033.22/README.md @@ -0,0 +1,72 @@ +Confluent for Kubernetes +================================================================== + +Confluent for Kubernetes (CFK) is a cloud-native control plane for deploying and managing Confluent in your private cloud environment. It provides standard and simple interface to customize, deploy, and manage Confluent Platform through declarative API. + +Confluent for Kubernetes runs on Kubernetes, the runtime for private cloud architectures. + + + + + + NOTE: Confluent for Kubernetes is the next generation of Confluent Operator. For Confluent Operator 1.x documentation, see [Confluent Operator 1](https://docs.confluent.io/operator/1.7.0/overview.html), or use the version picker to browse to a specific version of the documentation. + +See [Introducing Confluent for Kubernetes](https://www.confluent.io/blog/confluent-for-kubernetes-offers-cloud-native-kafka-automation/) for an overview. + +The following shows the high-level architecture of Confluent for Kubernetes and Confluent Platform in Kubernetes. + +[![_images/co-architecture.png](https://docs.confluent.io/operator/current/_images/co-architecture.png)](_images/co-architecture.png) + +Features +--------------------------------------------------- + +The following are summaries of the main, notable features of Confluent for Kubernetes. + +#### Cloud Native Declarative API + +* Declarative Kubernetes-native API approach to configure, deploy, and manage Confluent Platform components (Apache KafkaB., Connect workers, ksqlDB, Schema Registry, Confluent Control Center) and resources (topics, rolebindings) through Infrastructure as Code (IaC). +* Provides built-in automation for cloud-native security best practices: + * Complete granular RBAC, authentication and TLS network encryption + * Auto-generated certificates + * Support for credential management systems, such as Hashicorp Vault, to inject sensitive configurations in memory to Confluent deployments +* Provides server properties, JVM, and Log4j configuration overrides for customization of all Confluent Platform components. + +#### Upgrades + +* Provides automated rolling updates for configuration changes. +* Provides automated rolling upgrades with no impact to Kafka availability. + +#### Scaling + +* Provides single command, automated scaling and reliability checks of Confluent Platform. + +#### Resiliency + +* Restores a Kafka pod with the same Kafka broker ID, configuration, and persistent storage volumes if a failure occurs. +* Provides automated rack awareness to spread replicas of a partition across different racks (or zones), improving availability of Kafka brokers and limiting the risk of data loss. + +#### Scheduling + +* Supports Kubernetes labels and annotations to provide useful context to DevOps teams and ecosystem tooling. +* Supports Kubernetes tolerations and pod/node affinity for efficient resource utilization and pod placement. + +#### Monitoring + +* Supports metrics aggregation using JMX/Jolokia. +* Supports aggregated metrics export to Prometheus. + +Licensing +----------------------------------------------------- + +You can use Confluent for Kubernetes and Confluent Control Center for a 30-day trial period without a license key. + +After 30 days, Confluent for Kubernetes and Control Center require a license key. Confluent issues keys to subscribers, along with providing [enterprise-level support](https://www.confluent.io/subscription/) for Confluent components and Confluent for Kubernetes. + +If you are a subscriber, contact Confluent Support at [support@confluent.io](mailto:support@confluent.io) for more information. + +See [Update Confluent Platform License](co-license.html#co-license-key) if you have received a key for Confluent for Kubernetes. + +© Copyright 2021 , Confluent, Inc. [Privacy Policy](https://www.confluent.io/confluent-privacy-statement/) | [Terms & Conditions](https://www.confluent.io/terms-of-use/). Apache, Apache Kafka, Kafka and the Kafka logo are trademarks of the [Apache Software Foundation](http://www.apache.org/). All other trademarks, servicemarks, and copyrights are the property of their respective owners. + +[Please report any inaccuracies on this page or suggest an edit.](mailto:docs@confluent.io) + diff --git a/charts/confluent/confluent-for-kubernetes/0.1033.22/app-readme.md b/charts/confluent/confluent-for-kubernetes/0.1033.22/app-readme.md new file mode 100644 index 0000000000..cfcabdd219 --- /dev/null +++ b/charts/confluent/confluent-for-kubernetes/0.1033.22/app-readme.md @@ -0,0 +1,3 @@ +##Confluent For Kubernetes + +With Confluent for Kubernetes, Confluent brings a cloud-native experience for data in motion workloads in on-premises environments. Based on our expertise and learnings from operating over 5,000 clusters in Confluent Cloud, Confluent for Kubernetes offers an opinionated deployment of Confluent Platform that enhances the platformb's elasticity, ease of operations, and resiliency. diff --git a/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_clusterlinks.yaml b/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_clusterlinks.yaml new file mode 100644 index 0000000000..5c8a627c36 --- /dev/null +++ b/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_clusterlinks.yaml @@ -0,0 +1,883 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: clusterlinks.platform.confluent.io +spec: + group: platform.confluent.io + names: + categories: + - all + - confluent-platform + - confluent + kind: ClusterLink + listKind: ClusterLinkList + plural: clusterlinks + shortNames: + - cl + - clusterlink + - clink + singular: clusterlink + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.clusterLinkID + name: ID + type: string + - jsonPath: .status.state + name: Status + type: string + - jsonPath: .status.destinationKafkaClusterID + name: DestClusterID + type: string + - jsonPath: .status.sourceKafkaClusterID + name: SrcClusterID + type: string + - jsonPath: .status.numMirrorTopics + name: MirrorTopicCount + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: ClusterLink is the schema for the ClusterLink 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 defines the desired state of the cluster link. + properties: + aclFilters: + description: |- + aclFilters specify the list of ACLs to be migrated from the source cluster to the + destination cluster. + items: + description: |- + AclFilter defines the configuration for the ACLs filter. This follows the same pattern as defined in the + cluster linking documentation. More info: + https://docs.confluent.io/platform/current/multi-dc-deployments/cluster-linking/security.html#cluster-link-acls-migrate + properties: + accessFilter: + description: AclSyncAccessFilter defines the access filter for + ACLs. + properties: + host: + description: |- + host is the host for which operations can be coming from. + The default value is `*` that matches all hosts. + type: string + operation: + description: |- + operation specifies the operation type of the filter. It can be `ANY` or operations + based on resource type defined in the following Confluent documentation: + https://docs.confluent.io/platform/current/kafka/authorization.html#acl-operations + type: string + permissionType: + description: permissionType is the permission type of the + filter. Valid options are `any`, `allow`, and `deny`. + enum: + - any + - allow + - deny + type: string + principal: + description: |- + principal is the name of the principal. + The default value is `*`. + type: string + required: + - operation + - permissionType + type: object + resourceFilter: + description: AclSyncResourceFilter specifies the resource filter + for ACLs. + properties: + name: + description: |- + name is the name of the resource associated with this filter. + The default value is `*`. + type: string + patternType: + description: patternType is the pattern of the resource. + Valid options are `prefixed`, `literal`, `any`, and `match`. + enum: + - prefixed + - literal + - any + - match + type: string + resourceType: + description: resourceType is the type of the filter. Valid + options are `any`, `cluster`, `group`, `topic`, `transactionId`, + and `delegationToken`. + enum: + - any + - cluster + - group + - topic + - transcationId + - delegationToken + type: string + required: + - patternType + - resourceType + type: object + required: + - accessFilter + - resourceFilter + type: object + type: array + configs: + additionalProperties: + type: string + description: |- + configs is a map of string key and value pairs. It specifies additional configurations for the cluster link. + More info: https://docs.confluent.io/platform/current/multi-dc-deployments/cluster-linking/configs.html + type: object + x-kubernetes-map-type: granular + consumerGroupFilters: + description: |- + consumerGroupFilters specify a list of consumer groups to be migrated from + the source cluster to the destination cluster. + items: + description: ClusterLinkOptionsFilter defines the scheme for a filter + properties: + filterType: + description: filterType specifies the filter type. Valid options + are `INCLUDE` and `EXCLUDE`. + enum: + - INCLUDE + - EXCLUDE + type: string + name: + description: name is the resource name associated with this + filter. + type: string + patternType: + description: patternType is the pattern of the resource. Valid + options are `PREFIXED` and `LITERAL`. + enum: + - PREFIXED + - LITERAL + type: string + required: + - filterType + - name + - patternType + type: object + type: array + destinationKafkaCluster: + description: destinationKafkaCluster specifies the destination Kafka + cluster and its REST API configuration. + properties: + authentication: + description: authentication specifies the authentication for the + Kafka cluster. + properties: + jaasConfig: + description: jaasConfig specifies the Kafka client-side JaaS + configuration. + properties: + secretRef: + description: |- + secretRef references the secret containing the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + jaasConfigPassThrough: + description: jaasConfigPassThrough specifies another way to + provide the Kafka client-side JaaS configuration. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where required credentials are mounted. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + minLength: 1 + type: string + secretRef: + description: |- + secretRef references the secret containing the required credentials for authentication. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauthSettings: + description: |- + oauthSettings specifies the OAuth settings. + This needs to passed with the authentication type `oauth`. + properties: + audience: + description: audience specifies the audience claim in + the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected issuer + in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name of claim + in token for identifying the groups of subject in the + JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect timeout + with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout with + IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry backoff + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff with + IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim in JWT + to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + oauthbearer: + description: |- + oauthbearer is the authentication mechanism to provider principals. + Only supported in RBAC deployment. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container + where the credential is mounted. + minLength: 1 + type: string + secretRef: + description: |- + secretRef specifies the name of the secret that contains the credential. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#bearer-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + type: + description: |- + type specifies the Kafka client authentication type. + Valid options are `plain`, `oauthbearer`, `digest`, `mtls` and `oauth`. + enum: + - plain + - oauthbearer + - digest + - mtls + - oauth + type: string + required: + - type + type: object + bootstrapEndpoint: + description: |- + bootstrapEndpoint specifies the bootstrap endpoint for the Kafka cluster. + When `spec.sourceInitiatedLink.linkMode` is configured as `Source`, this is required for + `spec.destinationKafkaCluster` and not required for `spec.sourceKafkaCluster`. + For other cluster links this is required for `spec.sourceKafkaCluster` and not required for + `spec.destinationKafkaCluster`. + minLength: 1 + pattern: .+:[0-9]+ + type: string + clusterID: + description: |- + clusterID specifies the id of the Kafka cluster. + If clusterID is defined for the Kafka cluster, it takes precedence over using the REST API + for getting the cluster ID. + minLength: 1 + type: string + kafkaRestClassRef: + description: |- + kafkaRestClassRef references the KafkaRestClass application resource which + defines the Kafka REST API connection information. + When `spec.sourceInitiatedLink.linkMode` is configured as `Source`, this is required for + `spec.sourceKafkaCluster` and optional for `spec.destinationKafkaCluster` if `spec.clusterID` is set. + For other cluster links this is required for 'spec.destinationKafkaCluster` and optional for + `spec.sourceKafkaCluster` if the `spec.clusterID` is set. + properties: + name: + description: name specifies the name of the KafkaRestClass + application resource. + minLength: 1 + type: string + namespace: + description: namespace specifies the namespace of the KafkaRestClass. + type: string + required: + - name + type: object + tls: + description: tls specifies the client-side TLS configuration for + the Kafka cluster. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer contains the directory path in the container where + `fullchain.pem`, `privkey.pem`, `cacerts.pem` or `tls.crt`, `tls.key`, `ca.crt` keys are mounted. + minLength: 1 + type: string + enabled: + description: enabled specifies whether to enable the TLS configuration + for the cluster link. The default value is `false`. + type: boolean + keyPassword: + description: |- + keyPassword references the secret containing the SSL key password if the private key passed + in the secretRef above is encrypted. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + mirrorTopicOptions: + description: mirrorTopicOptions specify configuration options for + mirror topics. + properties: + autoCreateTopics: + description: |- + autoCreateTopics specifies configurations for the cluster link to + automatically create mirror topics on the destination cluster for topics that exist on the source cluster based on defined filters. + More info: https://docs.confluent.io/platform/current/multi-dc-deployments/cluster-linking/mirror-topics-cp.html#auto-create-mirror-topics + properties: + enabled: + description: |- + enabled specifies whether to auto-create mirror topics based on topics on the source cluster. + When set to “true”, mirror topics will be auto-created. Setting this option to “false” disables mirror topic creation and clears any existing filters. + type: boolean + topicFilters: + description: topicFilter contains an array of filters to apply + to indicate which topics should be mirrored. + items: + description: ClusterLinkOptionsFilter defines the scheme + for a filter + properties: + filterType: + description: filterType specifies the filter type. Valid + options are `INCLUDE` and `EXCLUDE`. + enum: + - INCLUDE + - EXCLUDE + type: string + name: + description: name is the resource name associated with + this filter. + type: string + patternType: + description: patternType is the pattern of the resource. + Valid options are `PREFIXED` and `LITERAL`. + enum: + - PREFIXED + - LITERAL + type: string + required: + - filterType + - name + - patternType + type: object + type: array + type: object + prefix: + description: |- + prefix specifies prefix for the mirror topics of the cluster link. + If configured, the valid mirror topic name should be defined with `` format + which mirrors the topic name of the format `` from source cluster. + When auto-create is enabled and the prefix is configured then the topics created on the destination will automatically contain the prefix. + Otherwise, `spec.mirrorTopic.name` should be defined with `` format. + maxLength: 255 + minLength: 1 + pattern: ^[a-zA-Z0-9\._\-]*$ + type: string + type: object + mirrorTopics: + description: mirrorTopics specify the mirror topics under this cluster + link. + items: + description: MirrorTopic defines the mirror topic configuration. + properties: + configs: + additionalProperties: + type: string + description: configs is a map of string key and value pairs. + It specifies any additional configuration or configuration + overrides for the mirror topic. + type: object + x-kubernetes-map-type: granular + name: + description: |- + name is the mirror topic name. If the sourceTopicName is not configured, + we assume that the sourceTopicName is the same as mirrorTopicName, + so a topic with the exact same name must exist on the source cluster and + no topic with this name should exist on the destination cluster. + When `spec.mirrorTopicOptions.prefix: ` is configured for the cluster link, + the name has to be of the format ``. + maxLength: 255 + minLength: 1 + pattern: ^[a-zA-Z0-9\._\-]*$ + type: string + replicationFactor: + description: |- + replicationFactor specifies the replication factor for the mirror topic on the destination cluster. + If this is not configured, mirror topic will inherit the broker `default.replication.factor` configuration. + format: int32 + type: integer + sourceTopicName: + description: |- + sourceTopicName is topic name on the source cluster that will be mirrored to the destination cluster. + When `spec.mirrorTopicOptions.prefix: ` is not configured, you should not configure this field. + If it is configured, a topic with the exact same name must exist on the source cluster. + maxLength: 255 + minLength: 1 + pattern: ^[a-zA-Z0-9\._\-]*$ + type: string + state: + description: |- + state specifies the desired state for this mirror topic. Valid options are + `ACTIVE`, `FAILOVER`, `PAUSE`, and `PROMOTE`. The default value is `ACTIVE`. + enum: + - PAUSE + - PROMOTE + - FAILOVER + - ACTIVE + type: string + required: + - name + type: object + type: array + name: + description: |- + name specifies the cluster link name. If not configured, then ClusterLink CR name is used + as the cluster link name. + maxLength: 255 + minLength: 1 + pattern: ^[a-zA-Z0-9\._\-]*$ + type: string + sourceInitiatedLink: + description: sourceInitiatedLink specify configs for source initiated + cluster links. + properties: + linkMode: + description: linkMode specifies if this source initiated cluster + link is in Source or Destination mode. + enum: + - Source + - Destination + - Bidirectional + type: string + required: + - linkMode + type: object + sourceKafkaCluster: + description: sourceKafkaCluster specifies the source Kafka cluster + and its REST API configuration. + properties: + authentication: + description: authentication specifies the authentication for the + Kafka cluster. + properties: + jaasConfig: + description: jaasConfig specifies the Kafka client-side JaaS + configuration. + properties: + secretRef: + description: |- + secretRef references the secret containing the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + jaasConfigPassThrough: + description: jaasConfigPassThrough specifies another way to + provide the Kafka client-side JaaS configuration. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where required credentials are mounted. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + minLength: 1 + type: string + secretRef: + description: |- + secretRef references the secret containing the required credentials for authentication. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauthSettings: + description: |- + oauthSettings specifies the OAuth settings. + This needs to passed with the authentication type `oauth`. + properties: + audience: + description: audience specifies the audience claim in + the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected issuer + in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name of claim + in token for identifying the groups of subject in the + JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect timeout + with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout with + IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry backoff + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff with + IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim in JWT + to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + oauthbearer: + description: |- + oauthbearer is the authentication mechanism to provider principals. + Only supported in RBAC deployment. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container + where the credential is mounted. + minLength: 1 + type: string + secretRef: + description: |- + secretRef specifies the name of the secret that contains the credential. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#bearer-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + type: + description: |- + type specifies the Kafka client authentication type. + Valid options are `plain`, `oauthbearer`, `digest`, `mtls` and `oauth`. + enum: + - plain + - oauthbearer + - digest + - mtls + - oauth + type: string + required: + - type + type: object + bootstrapEndpoint: + description: |- + bootstrapEndpoint specifies the bootstrap endpoint for the Kafka cluster. + When `spec.sourceInitiatedLink.linkMode` is configured as `Source`, this is required for + `spec.destinationKafkaCluster` and not required for `spec.sourceKafkaCluster`. + For other cluster links this is required for `spec.sourceKafkaCluster` and not required for + `spec.destinationKafkaCluster`. + minLength: 1 + pattern: .+:[0-9]+ + type: string + clusterID: + description: |- + clusterID specifies the id of the Kafka cluster. + If clusterID is defined for the Kafka cluster, it takes precedence over using the REST API + for getting the cluster ID. + minLength: 1 + type: string + kafkaRestClassRef: + description: |- + kafkaRestClassRef references the KafkaRestClass application resource which + defines the Kafka REST API connection information. + When `spec.sourceInitiatedLink.linkMode` is configured as `Source`, this is required for + `spec.sourceKafkaCluster` and optional for `spec.destinationKafkaCluster` if `spec.clusterID` is set. + For other cluster links this is required for 'spec.destinationKafkaCluster` and optional for + `spec.sourceKafkaCluster` if the `spec.clusterID` is set. + properties: + name: + description: name specifies the name of the KafkaRestClass + application resource. + minLength: 1 + type: string + namespace: + description: namespace specifies the namespace of the KafkaRestClass. + type: string + required: + - name + type: object + tls: + description: tls specifies the client-side TLS configuration for + the Kafka cluster. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer contains the directory path in the container where + `fullchain.pem`, `privkey.pem`, `cacerts.pem` or `tls.crt`, `tls.key`, `ca.crt` keys are mounted. + minLength: 1 + type: string + enabled: + description: enabled specifies whether to enable the TLS configuration + for the cluster link. The default value is `false`. + type: boolean + keyPassword: + description: |- + keyPassword references the secret containing the SSL key password if the private key passed + in the secretRef above is encrypted. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + required: + - destinationKafkaCluster + - sourceKafkaCluster + type: object + status: + description: status defines the observed state of the cluster link. + properties: + appState: + default: Unknown + description: appState is the current state of the cluster link application. + enum: + - Unknown + - Created + - Failed + - Deleted + type: string + clusterLinkID: + description: clusterLinkID is the id of the cluster link. + type: string + clusterLinkName: + description: clusterLinkName is the name of the cluster link. + type: string + conditions: + description: conditions are the latest available observations of the + cluster link's state. + items: + description: Condition represent the latest available observations + of the current state. + properties: + lastProbeTime: + description: lastProbeTime shows the last time the condition + was evaluated. + format: date-time + type: string + lastTransitionTime: + description: lastTransitionTime shows the last time the condition + was transitioned from one status to another. + format: date-time + type: string + message: + description: message shows a human-readable message with details + about the transition. + type: string + reason: + description: reason shows the reason for the last transition + of the condition. + type: string + status: + description: status shows the status of the condition, one of + `True`, `False`, or `Unknown`. + type: string + type: + description: type shows the condition type. + type: string + type: object + type: array + destinationKafkaClusterID: + description: destinationKafkaClusterID is the ID of the destination + Kafka cluster. + type: string + kafkaCluster: + description: 'kafkaCluster is the Kafka cluster this cluster link + belongs to. The format is: `/`' + type: string + mirrorTopics: + additionalProperties: + description: |- + MirrorTopicStatus specifies the status reported for each mirror topic as part of + the cluster link status. + properties: + observedGeneration: + description: observedGeneration is the most recent generation + observed for this Confluent component. + format: int64 + type: integer + replicationFactor: + description: replicationFactor specifies the replication factor + for the mirror topic on the destination cluster. + format: int32 + type: integer + sourceTopicName: + description: sourceTopicName is the name of the topic being + mirrored on the source cluster. + type: string + status: + description: |- + status is the status of the mirror topic. + It can be `ACTIVE`, `FAILED`, `PAUSED`, `STOPPED`, and `PENDING_STOPPED`. + type: string + type: object + description: mirrorTopics is a map of mirror topic name to its status + type: object + x-kubernetes-map-type: granular + numMirrorTopics: + description: numMirrorTopics is the number of mirror topics for the + cluster link. + type: integer + observedGeneration: + description: observedGeneration is the most recent generation observed + for this Confluent component. + format: int64 + type: integer + sourceKafkaClusterID: + description: sourceKafkaClusterID is the ID of the source Kafka cluster. + type: string + state: + description: state is the current state of the cluster link. + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_confluentrolebindings.yaml b/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_confluentrolebindings.yaml new file mode 100644 index 0000000000..8ff4d8c9e1 --- /dev/null +++ b/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_confluentrolebindings.yaml @@ -0,0 +1,296 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: confluentrolebindings.platform.confluent.io +spec: + group: platform.confluent.io + names: + categories: + - all + - confluent-platform + - confluent + kind: ConfluentRolebinding + listKind: ConfluentRolebindingList + plural: confluentrolebindings + shortNames: + - cfrb + - confluentrolebinding + singular: confluentrolebinding + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.state + name: Status + type: string + - jsonPath: .status.kafkaClusterID + name: KafkaClusterID + type: string + - jsonPath: .status.principal + name: Principal + type: string + - jsonPath: .status.role + name: Role + type: string + - jsonPath: .status.kafkaRestClass + name: KafkaRestClass + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.kafkaCluster + name: KafkaCluster + priority: 1 + type: string + - jsonPath: .status.clusterRegistryName + name: ClusterRegistryName + priority: 1 + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: ConfluentRolebinding is the schema for the ConfluentRolebinding + 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 defines the desired state of the ConfluentRolebinding. + properties: + clustersScopeByIds: + description: clustersScopeByIds specify the scope of the Confluent + component cluster(s) via cluster id(s). + properties: + connectClusterId: + description: connectClusterId specifies the Connect cluster id. + minLength: 1 + type: string + kafkaClusterId: + description: kafkaClusterId specifies the id of the Kafka cluster + id. + minLength: 1 + type: string + ksqlClusterId: + description: ksqlClusterId specifies the ksqlDB cluster id. + minLength: 1 + type: string + schemaRegistryClusterId: + description: schemaRegistryClusterId specifies the Schema Registry + cluster id. + minLength: 1 + type: string + type: object + clustersScopeByRegistryName: + description: clustersScopeByRegistryName specifies the unique cluster + name you registered in the cluster registry. + minLength: 1 + type: string + kafkaRestClassRef: + description: kafkaRestClassRef references the KafkaRestClass that + defines the Kafka REST API connection information. + properties: + name: + description: name specifies the name of the KafkaRestClass application + resource. + minLength: 1 + type: string + namespace: + description: namespace specifies the namespace of the KafkaRestClass. + type: string + required: + - name + type: object + principal: + description: RolebindingPrincipal defines the principal(user/group) + the rolebinding belongs to. + properties: + name: + description: name specifies the name of the principal. + minLength: 1 + type: string + type: + description: type specifies the type of the principal. Valid options + are `user` and `group`. + enum: + - user + - group + type: string + required: + - name + - type + type: object + resourcePatterns: + description: resourcePatterns specify the qualified resources associated + with this rolebinding. + items: + description: ResourcePattern specifies the qualified resource info + associated with this rolebinding. + properties: + name: + description: name specifies the name of the resource associated + with this rolebinding. + minLength: 1 + type: string + patternType: + description: |- + patternType specifies the pattern of the resource. Valid options are + `PREFIXED` or `LITERAL`. The default value is `LITERAL`. + enum: + - PREFIXED + - LITERAL + type: string + resourceType: + description: |- + resourceType refers to the type of the resource. + Valid options are `Topic`, `Group`, `Subject`, `KsqlCluster`, `Cluster`, `TransactionalId`, etc. + minLength: 1 + type: string + required: + - name + - resourceType + type: object + type: array + role: + description: role specifies the name of the role. + minLength: 1 + type: string + required: + - principal + - role + type: object + status: + description: status is the observed state of the ConfluentRolebinding. + properties: + appState: + default: Unknown + description: appState is the current state of the rolebinding application. + enum: + - Unknown + - Created + - Failed + - Deleted + type: string + clusterRegistryName: + description: clusterRegistryName is the cluster registry name the + rolebinding associated with. + type: string + conditions: + description: conditions are the latest available observations of the + rolebinding's state. + items: + description: Condition represent the latest available observations + of the current state. + properties: + lastProbeTime: + description: lastProbeTime shows the last time the condition + was evaluated. + format: date-time + type: string + lastTransitionTime: + description: lastTransitionTime shows the last time the condition + was transitioned from one status to another. + format: date-time + type: string + message: + description: message shows a human-readable message with details + about the transition. + type: string + reason: + description: reason shows the reason for the last transition + of the condition. + type: string + status: + description: status shows the status of the condition, one of + `True`, `False`, or `Unknown`. + type: string + type: + description: type shows the condition type. + type: string + type: object + type: array + kafkaCluster: + description: 'kafkaCluster is the Kafka cluster the rolebinding belongs + to. The format is: `/`.' + type: string + kafkaClusterID: + description: kafkaClusterID is the id of the Kafka cluster. + type: string + kafkaRestClass: + description: 'kafkaRestClass is the kafkaRestClass this rolebinding + uses. The format is: `/`.' + type: string + mdsEndpoint: + description: mdsEndpoint is the MDS endpoint. + type: string + observedGeneration: + description: observedGeneration is the most recent generation observed + for this Confluent component. + format: int64 + type: integer + principal: + description: 'principal is the principal the rolebinding belongs to. + The format is: `:`.' + type: string + resourcePatterns: + description: resourcePatterns are the resource patterns this rolebinding + is associated with. + items: + description: ResourcePattern specifies the qualified resource info + associated with this rolebinding. + properties: + name: + description: name specifies the name of the resource associated + with this rolebinding. + minLength: 1 + type: string + patternType: + description: |- + patternType specifies the pattern of the resource. Valid options are + `PREFIXED` or `LITERAL`. The default value is `LITERAL`. + enum: + - PREFIXED + - LITERAL + type: string + resourceType: + description: |- + resourceType refers to the type of the resource. + Valid options are `Topic`, `Group`, `Subject`, `KsqlCluster`, `Cluster`, `TransactionalId`, etc. + minLength: 1 + type: string + required: + - name + - resourceType + type: object + type: array + role: + description: role is the role this rolebinding is associated with. + type: string + state: + description: state is the state of this rolebinding. + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_connectors.yaml b/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_connectors.yaml new file mode 100644 index 0000000000..07bf6d1bb0 --- /dev/null +++ b/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_connectors.yaml @@ -0,0 +1,496 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: connectors.platform.confluent.io +spec: + group: platform.confluent.io + names: + categories: + - all + - confluent-platform + - confluent + kind: Connector + listKind: ConnectorList + plural: connectors + shortNames: + - ctr + - connector + singular: connector + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.state + name: Status + type: string + - jsonPath: .status.connectorState + name: ConnectorStatus + type: string + - jsonPath: .status.tasksReady + name: Tasks-Ready + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.connectRestEndpoint + name: ConnectEndpoint + priority: 1 + type: string + - jsonPath: .status.failedTasksCount + name: Tasks-Failed + priority: 1 + type: string + - jsonPath: .status.workerID + name: WorkerID + priority: 1 + type: string + - jsonPath: .status.restartPolicy.type + name: RestartPolicy + priority: 1 + type: string + - jsonPath: .status.kafkaClusterID + name: KafkaClusterID + priority: 1 + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: Connector is the schema for the Connector 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 defines the desired state of the Connector. + properties: + class: + description: |- + class specifies the class name of the connector. + The Connect cluster displays the supported class names in its status. + minLength: 1 + type: string + configs: + additionalProperties: + type: string + description: configs is a map of string key and value pairs. It specifies + the additional configurations for the connector. + type: object + x-kubernetes-map-type: granular + connectClusterRef: + description: connectClusterRef references the CFK managed Connect + cluster. + properties: + name: + description: name specifies the name of the Confluent Platform + component cluster. + type: string + namespace: + description: namespace specifies the namespace where the Confluent + Platform component cluster is running. + type: string + required: + - name + type: object + connectRest: + description: connectRest specifies the Connect REST API connection + configuration. + properties: + authentication: + description: authentication specifies the REST API authentication + mechanism. + properties: + basic: + description: basic specifies the basic authentication settings + for the REST API client. + properties: + debug: + description: debug enables the basic authentication debug + logs for JaaS configuration. + type: boolean + directoryPathInContainer: + description: |- + directoryPathInContainer allows to pass the basic credential through a directory path in the container. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + minLength: 1 + type: string + restrictedRoles: + description: |- + restrictedRoles specify the restricted roles on the server side only. + Changes will be only reflected in Control Center. + This configuration is ignored on the client side configuration. + items: + type: string + minItems: 1 + type: array + roles: + description: |- + roles specify the roles on the server side only. + This configuration is ignored on the client side configuration. + items: + type: string + type: array + secretRef: + description: |- + secretRef defines secret reference to pass the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + bearer: + description: bearer specifies the bearer authentication settings + for the REST API client. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container + where the credential is mounted. + minLength: 1 + type: string + secretRef: + description: |- + secretRef specifies the name of the secret that contains the credential. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#bearer-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauth: + description: oauth specifies the OAuth authentication settings + for the REST API client. + properties: + configuration: + description: configuration specifies the OAuth server + settings. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name of + claim in token for identifying the groups of subject + in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect timeout + with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + directoryPathInContainer: + description: directoryPathInContainer allows to pass the + basic credential through a directory path in the container. + minLength: 1 + type: string + secretRef: + description: secretRef defines secret reference to pass + the required credentials. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - configuration + type: object + type: + description: type specifies the REST API authentication type. + Valid options are `basic`, `bearer`, `mtls` and `oauth`. + enum: + - basic + - bearer + - mtls + - oauth + type: string + required: + - type + type: object + endpoint: + description: endpoint specifies where Confluent REST API is running. + minLength: 1 + pattern: ^https?://.* + type: string + kafkaClusterID: + description: |- + kafkaClusterID specifies the id of Kafka cluster. + It takes precedence over using the Kafka REST API to get the cluster id. + minLength: 1 + type: string + tls: + description: "tls specifies the custom TLS structure for the application + resources,\n\t// e.g. connector, topic, schema, of the Confluent + Platform components.\n\t// +optional" + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer contains the directory path in the container where + `keystore.jks`, `truststore.jks`, `jksPassword.txt` keys are mounted. + minLength: 1 + type: string + jksPassword: + description: jksPassword specifies the secret name that contains + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef specifies the secret name that contains the certificates. + More info about certificates key/value format: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + type: object + name: + description: |- + name specifies the connector name. If not configured, + the Connector CR name is used as the connector name. + maxLength: 255 + minLength: 1 + pattern: ^[a-zA-Z0-9\._\-]*$ + type: string + restartPolicy: + description: restartPolicy specifies the policy to restart failed + tasks of the connector. + properties: + maxRetry: + description: maxRetry specifies the max number of tries to restart + failed tasks when the `restartPolicy` type is `OnFailure`. The + default value is `10`. + format: int32 + minimum: 1 + type: integer + type: + description: |- + type specifies the policy type to restart connector tasks. Valid options are `OnFailure` and `Never`. + Default value is `OnFailure`, which means it will restart automatically when a task fails if the `maxRetry` value is not reached. + enum: + - OnFailure + - Never + type: string + required: + - type + type: object + taskMax: + description: |- + taskMax specifies the maximum number of tasks for the connector. It must be greater than 0. + The connector may create fewer tasks if it cannot achieve this level of parallelism. + format: int32 + minimum: 1 + type: integer + required: + - class + - taskMax + type: object + status: + description: status defines the observed state of the Connector. + properties: + appState: + default: Unknown + description: appState is the current state of the connector application. + enum: + - Unknown + - Created + - Failed + - Deleted + type: string + conditions: + description: conditions are the latest available observations of the + connector state. + items: + description: Condition represent the latest available observations + of the current state. + properties: + lastProbeTime: + description: lastProbeTime shows the last time the condition + was evaluated. + format: date-time + type: string + lastTransitionTime: + description: lastTransitionTime shows the last time the condition + was transitioned from one status to another. + format: date-time + type: string + message: + description: message shows a human-readable message with details + about the transition. + type: string + reason: + description: reason shows the reason for the last transition + of the condition. + type: string + status: + description: status shows the status of the condition, one of + `True`, `False`, or `Unknown`. + type: string + type: + description: type shows the condition type. + type: string + type: object + type: array + connectRestEndpoint: + description: connectRestEndpoint is the REST endpoint of the Connect + cluster. + type: string + connectorState: + description: connectorState is the status of the connector instance. + type: string + failedTasks: + additionalProperties: + description: TaskStatus defines the connector task status. + properties: + id: + description: Id is the id of the task. + format: int32 + type: integer + retryCount: + description: retryCount is the number of retry attempts to restart + the failed task. + format: int32 + type: integer + workerID: + description: workerID is the workerId for the task. + type: string + required: + - id + type: object + description: |- + failedTasks is the map of connector tasks in the `FAILED` state. + Error messages of failed tasks are logged in the CFK logs as `INFO`. + You can also get the error message via Connect REST API calls. + type: object + x-kubernetes-map-type: granular + failedTasksCount: + description: failedTasksCount is the number of failed tasks. + format: int32 + type: integer + kafkaClusterID: + description: kafkaClusterID is the Kafka cluster id the connector + belongs to. + type: string + observedGeneration: + description: observedGeneration is the most recent generation observed + for this Confluent component. + format: int64 + type: integer + restartPolicy: + description: restartPolicy is the policy to restart failed tasks of + the connector. + properties: + maxRetry: + description: maxRetry specifies the max number of tries to restart + failed tasks when the `restartPolicy` type is `OnFailure`. The + default value is `10`. + format: int32 + minimum: 1 + type: integer + type: + description: |- + type specifies the policy type to restart connector tasks. Valid options are `OnFailure` and `Never`. + Default value is `OnFailure`, which means it will restart automatically when a task fails if the `maxRetry` value is not reached. + enum: + - OnFailure + - Never + type: string + required: + - type + type: object + state: + description: state is the custom resource state of the connector. + This is not the connector state, which can be `CREATED`, `ERROR`, + etc. + type: string + tasksReady: + description: |- + tasksReady is the number of running tasks based on `taskMax`. + The value is in the following format: `/` + type: string + trace: + description: trace is the error trace message for the connector instance. + type: string + workerID: + description: workerID is the workerId of the connector instance. + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_connects.yaml b/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_connects.yaml new file mode 100644 index 0000000000..70e45faaae --- /dev/null +++ b/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_connects.yaml @@ -0,0 +1,6941 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: connects.platform.confluent.io +spec: + group: platform.confluent.io + names: + categories: + - all + - confluent-platform + - confluent + kind: Connect + listKind: ConnectList + plural: connects + shortNames: + - connect + singular: connect + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.replicas + name: Replicas + type: string + - jsonPath: .status.readyReplicas + name: Ready + type: string + - jsonPath: .status.phase + name: Status + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.kafka.bootstrapEndpoint + name: Kafka + priority: 1 + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: Connect is the schema for the Connect 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 defines the desired state of the Connect cluster. + properties: + authentication: + description: authentication specifies authentication configuration. + properties: + basic: + description: basic specifies the configuration for basic authentication. + properties: + debug: + description: debug enables the basic authentication debug + logs for JaaS configuration. + type: boolean + directoryPathInContainer: + description: |- + directoryPathInContainer allows to pass the basic credential through a directory path in the container. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + minLength: 1 + type: string + restrictedRoles: + description: |- + restrictedRoles specify the restricted roles on the server side only. + Changes will be only reflected in Control Center. + This configuration is ignored on the client side configuration. + items: + type: string + minItems: 1 + type: array + roles: + description: |- + roles specify the roles on the server side only. + This configuration is ignored on the client side configuration. + items: + type: string + type: array + secretRef: + description: |- + secretRef defines secret reference to pass the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauth: + description: oauth specifies the configuration for OAuth authentication. + properties: + configuration: + description: configuration specifies the OAuth server settings. + properties: + audience: + description: audience specifies the audience claim in + the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected issuer + in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name of claim + in token for identifying the groups of subject in the + JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect timeout + with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout with + IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry backoff + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff with + IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim in JWT + to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + directoryPathInContainer: + description: directoryPathInContainer allows to pass the basic + credential through a directory path in the container. + minLength: 1 + type: string + secretRef: + description: secretRef defines secret reference to pass the + required credentials. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - configuration + type: object + type: + description: type specifies the authentication scheme for the + REST API server. Valid options are `basic`, `oauth` and `mtls`. + enum: + - basic + - mtls + - oauth + type: string + required: + - type + type: object + authorization: + description: authorization specifies the authorization configuration. + properties: + kafkaRestClassRef: + description: |- + kafkaRestClassRef references the KafkaRestClass + which specifies the Kafka REST API connection configuration. + properties: + name: + description: name specifies the name of the KafkaRestClass + application resource. + minLength: 1 + type: string + namespace: + description: namespace specifies the namespace of the KafkaRestClass. + type: string + required: + - name + type: object + type: + description: type specifies the client-side authorization type. + The valid option is `rbac`. + enum: + - rbac + type: string + required: + - type + type: object + build: + description: build defines the build configurations for connector + plugins. + properties: + onDemand: + description: OnDemand defines the build configurations for the + `onDemand` build type. + properties: + plugins: + description: plugins define the installation information for + connector plugins. + properties: + confluentHub: + description: confluentHub contains a list of connector + plugins you get from Confluent Hub. + items: + description: ConfluentHubPlugin contains the required + information to get the connector plugin from Confluent + Hub. + properties: + name: + description: name specifies the name of the connector + plugin. + minLength: 1 + type: string + owner: + description: owner specifies the individual or organization + that provides the connector plugin, for example, + `confluentinc`. + minLength: 1 + type: string + version: + description: version specifies the version of the + connector plugin, which can be either the version + of the plugin or the literal `latest`. + minLength: 1 + type: string + required: + - name + - owner + - version + type: object + type: array + locationType: + description: This field is deprecated and will be ignored + if set. + enum: + - confluentHub + - url + type: string + url: + description: url contains a list of URL plugins you get + from external URLs. + items: + description: URLPlugin defines the information to get + the connector plugin from an external URL. + properties: + archivePath: + description: |- + archivePath specifies the archive path of the connector plugin. + Currently, only support ZIP archives. + minLength: 1 + pattern: ^https?://.* + type: string + checksum: + description: |- + checksum defines the sha512sum checksum of the connector plugin's remote file. + It is used to verify the remote file after it is downloaded. + type: string + name: + description: name specifies the connector plugin + name. + minLength: 1 + type: string + required: + - archivePath + - checksum + - name + type: object + type: array + type: object + storageLimit: + anyOf: + - type: integer + - type: string + description: storageLimit specifies the max amount of node + volume that can be used to store connector plugins. The + default value is `4G`. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + required: + - plugins + type: object + type: + description: type specifies the build type for connector plugins. + Currently only the `onDemand` type is supported. + enum: + - onDemand + type: string + required: + - type + type: object + configOverrides: + description: configOverrides specifies the configs to override the + server, JVM, Log4j properties for the Connect cluster. + properties: + jvm: + description: |- + jvm is a list of JVM configuration supported by the Confluent Platform component. + This will either add or update the existing configuration. + items: + type: string + type: array + log4j: + description: |- + log4j is a list of Log4J configuration supported by the Confluent Platform component. + This will either add or update the existing configuration. + items: + type: string + type: array + server: + description: |- + server is a list of server configuration supported by the Confluent Platform component. + This will either add or update existing configuration. + items: + type: string + type: array + type: object + connectorOverridePolicy: + description: |- + connectorOverridePolicy allows the policy to permit per-connector override configuration + for producer/consumer/admin prefix. + More info: https://docs.confluent.io/platform/current/connect/security.html#separate-principals + enum: + - All + - Principal + type: string + connectorTLSCerts: + description: |- + connectorTLSCerts are the custom TLS certificates injected into the Connect cluster for connectors to use. + Check the Connect status for the mount path of the certificates. + A change will roll the cluster. + items: + description: MountedCustomTLSCertificate defines the mounted custom + TLS structure for the Confluent Platform component. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer contains the directory path in the container where + `keystore.jks`, `truststore.jks`, `jksPassword.txt` keys are mounted. + minLength: 1 + type: string + jksPassword: + description: jksPassword specifies the secret name that contains + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef specifies the secret name that contains the certificates. + More info about certificates key/value format: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + type: array + dependencies: + description: ConnectDependencies contains the dependencies the Connect + requires or can enable. + properties: + admin: + description: |- + admin contains the security configuration to connect to the admin client. + If `bootstrapEndpoint` is not configured, the security is configured based on the Kafka dependency configuration. + Configure this property if different bootstrap endpoint is required for the admin client. + properties: + authentication: + description: authentication defines the authentication for + the Kafka cluster. + properties: + jaasConfig: + description: jaasConfig specifies the Kafka client-side + JaaS configuration. + properties: + secretRef: + description: |- + secretRef references the secret containing the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + jaasConfigPassThrough: + description: jaasConfigPassThrough specifies another way + to provide the Kafka client-side JaaS configuration. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where required credentials are mounted. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + minLength: 1 + type: string + secretRef: + description: |- + secretRef references the secret containing the required credentials for authentication. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauthSettings: + description: |- + oauthSettings specifies the OAuth settings. + This needs to passed with the authentication type `oauth`. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name of + claim in token for identifying the groups of subject + in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect timeout + with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + oauthbearer: + description: |- + oauthbearer is the authentication mechanism to provider principals. + Only supported in RBAC deployment. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container + where the credential is mounted. + minLength: 1 + type: string + secretRef: + description: |- + secretRef specifies the name of the secret that contains the credential. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#bearer-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + type: + description: |- + type specifies the Kafka client authentication type. + Valid options are `plain`, `oauthbearer`, `digest`, `mtls` and `oauth`. + enum: + - plain + - oauthbearer + - digest + - mtls + - oauth + type: string + required: + - type + type: object + bootstrapEndpoint: + description: bootstrapEndpoint specifies the Kafka bootstrap + endpoint. + minLength: 1 + pattern: .+:[0-9]+ + type: string + discovery: + description: discovery specifies the capability to discover + the Kafka cluster. + properties: + name: + description: name is the name of the Confluent Platform + component cluster. + type: string + namespace: + description: |- + namespace is where the Confluent Platform component is running. + The default value is the namespace where CFK is running. + type: string + secretRef: + description: secretRef is the name of the secret used + to discover the Confluent Platform component. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - name + type: object + tls: + description: tls defines the client-side TLS setting for the + Kafka cluster. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + consumer: + description: |- + consumer contains the security configuration to connect to the Kafka cluster. It is used for sink connectors. + If `bootstrapEndpoint` is not configured, the security is configured based on the Kafka dependency configuration. + Configure this property if different bootstrap endpoint is required for the consumer. + properties: + authentication: + description: authentication defines the authentication for + the Kafka cluster. + properties: + jaasConfig: + description: jaasConfig specifies the Kafka client-side + JaaS configuration. + properties: + secretRef: + description: |- + secretRef references the secret containing the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + jaasConfigPassThrough: + description: jaasConfigPassThrough specifies another way + to provide the Kafka client-side JaaS configuration. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where required credentials are mounted. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + minLength: 1 + type: string + secretRef: + description: |- + secretRef references the secret containing the required credentials for authentication. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauthSettings: + description: |- + oauthSettings specifies the OAuth settings. + This needs to passed with the authentication type `oauth`. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name of + claim in token for identifying the groups of subject + in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect timeout + with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + oauthbearer: + description: |- + oauthbearer is the authentication mechanism to provider principals. + Only supported in RBAC deployment. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container + where the credential is mounted. + minLength: 1 + type: string + secretRef: + description: |- + secretRef specifies the name of the secret that contains the credential. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#bearer-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + type: + description: |- + type specifies the Kafka client authentication type. + Valid options are `plain`, `oauthbearer`, `digest`, `mtls` and `oauth`. + enum: + - plain + - oauthbearer + - digest + - mtls + - oauth + type: string + required: + - type + type: object + bootstrapEndpoint: + description: bootstrapEndpoint specifies the Kafka bootstrap + endpoint. + minLength: 1 + pattern: .+:[0-9]+ + type: string + discovery: + description: discovery specifies the capability to discover + the Kafka cluster. + properties: + name: + description: name is the name of the Confluent Platform + component cluster. + type: string + namespace: + description: |- + namespace is where the Confluent Platform component is running. + The default value is the namespace where CFK is running. + type: string + secretRef: + description: secretRef is the name of the secret used + to discover the Confluent Platform component. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - name + type: object + tls: + description: tls defines the client-side TLS setting for the + Kafka cluster. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + interceptor: + description: interceptor contains the dependency configuration + for the monitoring interceptor. + properties: + configs: + description: |- + configs describe the configurations for the Confluent Platform interceptor. + The config override feature can be used to pass the configuration settings. + items: + type: string + type: array + consumer: + description: |- + consumer specifies the consumer configuration for the interceptor. If not + configured, it uses the Kafka dependency configuration. + properties: + authentication: + description: authentication defines the authentication + for the Kafka cluster. + properties: + jaasConfig: + description: jaasConfig specifies the Kafka client-side + JaaS configuration. + properties: + secretRef: + description: |- + secretRef references the secret containing the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + jaasConfigPassThrough: + description: jaasConfigPassThrough specifies another + way to provide the Kafka client-side JaaS configuration. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where required credentials are mounted. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + minLength: 1 + type: string + secretRef: + description: |- + secretRef references the secret containing the required credentials for authentication. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauthSettings: + description: |- + oauthSettings specifies the OAuth settings. + This needs to passed with the authentication type `oauth`. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name + of claim in token for identifying the groups + of subject in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect + timeout with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + oauthbearer: + description: |- + oauthbearer is the authentication mechanism to provider principals. + Only supported in RBAC deployment. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container + where the credential is mounted. + minLength: 1 + type: string + secretRef: + description: |- + secretRef specifies the name of the secret that contains the credential. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#bearer-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + type: + description: |- + type specifies the Kafka client authentication type. + Valid options are `plain`, `oauthbearer`, `digest`, `mtls` and `oauth`. + enum: + - plain + - oauthbearer + - digest + - mtls + - oauth + type: string + required: + - type + type: object + bootstrapEndpoint: + description: bootstrapEndpoint specifies the Kafka bootstrap + endpoint. + minLength: 1 + pattern: .+:[0-9]+ + type: string + discovery: + description: discovery specifies the capability to discover + the Kafka cluster. + properties: + name: + description: name is the name of the Confluent Platform + component cluster. + type: string + namespace: + description: |- + namespace is where the Confluent Platform component is running. + The default value is the namespace where CFK is running. + type: string + secretRef: + description: secretRef is the name of the secret used + to discover the Confluent Platform component. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - name + type: object + tls: + description: tls defines the client-side TLS setting for + the Kafka cluster. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + enabled: + description: enabled indicates whether the Confluent Platform + interceptor is enabled or disabled. + type: boolean + producer: + description: |- + producer specifies the producer configuration for the interceptor. If not + configured, it uses the Kafka dependency configuration. + properties: + authentication: + description: authentication defines the authentication + for the Kafka cluster. + properties: + jaasConfig: + description: jaasConfig specifies the Kafka client-side + JaaS configuration. + properties: + secretRef: + description: |- + secretRef references the secret containing the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + jaasConfigPassThrough: + description: jaasConfigPassThrough specifies another + way to provide the Kafka client-side JaaS configuration. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where required credentials are mounted. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + minLength: 1 + type: string + secretRef: + description: |- + secretRef references the secret containing the required credentials for authentication. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauthSettings: + description: |- + oauthSettings specifies the OAuth settings. + This needs to passed with the authentication type `oauth`. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name + of claim in token for identifying the groups + of subject in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect + timeout with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + oauthbearer: + description: |- + oauthbearer is the authentication mechanism to provider principals. + Only supported in RBAC deployment. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container + where the credential is mounted. + minLength: 1 + type: string + secretRef: + description: |- + secretRef specifies the name of the secret that contains the credential. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#bearer-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + type: + description: |- + type specifies the Kafka client authentication type. + Valid options are `plain`, `oauthbearer`, `digest`, `mtls` and `oauth`. + enum: + - plain + - oauthbearer + - digest + - mtls + - oauth + type: string + required: + - type + type: object + bootstrapEndpoint: + description: bootstrapEndpoint specifies the Kafka bootstrap + endpoint. + minLength: 1 + pattern: .+:[0-9]+ + type: string + discovery: + description: discovery specifies the capability to discover + the Kafka cluster. + properties: + name: + description: name is the name of the Confluent Platform + component cluster. + type: string + namespace: + description: |- + namespace is where the Confluent Platform component is running. + The default value is the namespace where CFK is running. + type: string + secretRef: + description: secretRef is the name of the secret used + to discover the Confluent Platform component. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - name + type: object + tls: + description: tls defines the client-side TLS setting for + the Kafka cluster. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + publishMs: + type: integer + required: + - enabled + type: object + kafka: + description: kafka contains the Connect dependency for connecting + to Kafka. The discovery method is used if this is not specified. + properties: + authentication: + description: authentication defines the authentication for + the Kafka cluster. + properties: + jaasConfig: + description: jaasConfig specifies the Kafka client-side + JaaS configuration. + properties: + secretRef: + description: |- + secretRef references the secret containing the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + jaasConfigPassThrough: + description: jaasConfigPassThrough specifies another way + to provide the Kafka client-side JaaS configuration. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where required credentials are mounted. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + minLength: 1 + type: string + secretRef: + description: |- + secretRef references the secret containing the required credentials for authentication. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauthSettings: + description: |- + oauthSettings specifies the OAuth settings. + This needs to passed with the authentication type `oauth`. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name of + claim in token for identifying the groups of subject + in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect timeout + with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + oauthbearer: + description: |- + oauthbearer is the authentication mechanism to provider principals. + Only supported in RBAC deployment. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container + where the credential is mounted. + minLength: 1 + type: string + secretRef: + description: |- + secretRef specifies the name of the secret that contains the credential. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#bearer-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + type: + description: |- + type specifies the Kafka client authentication type. + Valid options are `plain`, `oauthbearer`, `digest`, `mtls` and `oauth`. + enum: + - plain + - oauthbearer + - digest + - mtls + - oauth + type: string + required: + - type + type: object + bootstrapEndpoint: + description: bootstrapEndpoint specifies the Kafka bootstrap + endpoint. + minLength: 1 + pattern: .+:[0-9]+ + type: string + discovery: + description: discovery specifies the capability to discover + the Kafka cluster. + properties: + name: + description: name is the name of the Confluent Platform + component cluster. + type: string + namespace: + description: |- + namespace is where the Confluent Platform component is running. + The default value is the namespace where CFK is running. + type: string + secretRef: + description: secretRef is the name of the secret used + to discover the Confluent Platform component. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - name + type: object + tls: + description: tls defines the client-side TLS setting for the + Kafka cluster. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + licenseCluster: + description: |- + licenseCluster contains the security configuration to connect to the License containing Kafka cluster.Note that this entry is only needed + if the license topic is stored on a different Kafka cluster than the Kafka cluster that Connect uses. + properties: + kafka: + description: |- + KafkaClientDependency configures the Confluent Platform component dependency + for the Kafka cluster. + properties: + authentication: + description: authentication defines the authentication + for the Kafka cluster. + properties: + jaasConfig: + description: jaasConfig specifies the Kafka client-side + JaaS configuration. + properties: + secretRef: + description: |- + secretRef references the secret containing the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + jaasConfigPassThrough: + description: jaasConfigPassThrough specifies another + way to provide the Kafka client-side JaaS configuration. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where required credentials are mounted. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + minLength: 1 + type: string + secretRef: + description: |- + secretRef references the secret containing the required credentials for authentication. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauthSettings: + description: |- + oauthSettings specifies the OAuth settings. + This needs to passed with the authentication type `oauth`. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name + of claim in token for identifying the groups + of subject in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect + timeout with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + oauthbearer: + description: |- + oauthbearer is the authentication mechanism to provider principals. + Only supported in RBAC deployment. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container + where the credential is mounted. + minLength: 1 + type: string + secretRef: + description: |- + secretRef specifies the name of the secret that contains the credential. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#bearer-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + type: + description: |- + type specifies the Kafka client authentication type. + Valid options are `plain`, `oauthbearer`, `digest`, `mtls` and `oauth`. + enum: + - plain + - oauthbearer + - digest + - mtls + - oauth + type: string + required: + - type + type: object + bootstrapEndpoint: + description: bootstrapEndpoint specifies the Kafka bootstrap + endpoint. + minLength: 1 + pattern: .+:[0-9]+ + type: string + discovery: + description: discovery specifies the capability to discover + the Kafka cluster. + properties: + name: + description: name is the name of the Confluent Platform + component cluster. + type: string + namespace: + description: |- + namespace is where the Confluent Platform component is running. + The default value is the namespace where CFK is running. + type: string + secretRef: + description: secretRef is the name of the secret used + to discover the Confluent Platform component. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - name + type: object + tls: + description: tls defines the client-side TLS setting for + the Kafka cluster. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + topic: + description: The name of the Kafka topic where the license + is stored. This defaults to _confluent-command. + type: string + type: object + mds: + description: mds contains the configuration for MDS dependency + when RBAC is enabled. + properties: + authentication: + description: authentication specifies the client side authentication + configuration for the MDS. + properties: + bearer: + description: bearer specifies the bearer authentication + settings. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container + where the credential is mounted. + minLength: 1 + type: string + secretRef: + description: |- + secretRef specifies the name of the secret that contains the credential. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#bearer-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauth: + description: oauth specifies the OAuth authentication + settings. + properties: + configuration: + description: configuration specifies the OAuth server + settings. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name + of claim in token for identifying the groups + of subject in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect + timeout with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + directoryPathInContainer: + description: directoryPathInContainer allows to pass + the basic credential through a directory path in + the container. + minLength: 1 + type: string + secretRef: + description: secretRef defines secret reference to + pass the required credentials. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - configuration + type: object + type: + description: type specifies the authentication method + for the MDS. The valid option is `bearer`, `oauth`. + enum: + - bearer + - oauth + type: string + required: + - type + type: object + endpoint: + description: endpoint specifies the MDS endpoint. + minLength: 1 + pattern: ^https?://.* + type: string + ssoProtocol: + description: sso protocol, valid options are ldap and oidc. + enum: + - ldap + - oidc + type: string + tls: + description: ClientTLSConfig specifies the TLS configuration + for the Confluent component (dependencies, listeners). + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + tokenKeyPair: + description: tokenKeyPair specifies the token keypair to configure + the MDS. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer defines the directory path in the container + where the MDS token key pair are mounted. + minLength: 1 + type: string + encryptedTokenKey: + description: |- + EncryptedTokenKey boolean value indicating whether the tokenKeypair(private used for signing) is encrypted using a passphrase. If true, cfk + operator will look for a file named mdsTokenKeyPassphrase.txt containing key value pair + mdsTokenKeyPassphrase=. Relevant only for mds server. Ignored if set for a client configuration. + type: boolean + secretRef: + description: secretRef references the name of the secret + that contains the MDS token key pair. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + required: + - authentication + - endpoint + - tokenKeyPair + type: object + producer: + description: |- + producer contains the security configuration to connect to the Kafka cluster. It is used for source connectors. + If `bootstrapEndpoint` is not configured, the security is configured based on the Kafka dependency configuration. + Configure this property if different bootstrap endpoint of security is required for the producer. + properties: + authentication: + description: authentication defines the authentication for + the Kafka cluster. + properties: + jaasConfig: + description: jaasConfig specifies the Kafka client-side + JaaS configuration. + properties: + secretRef: + description: |- + secretRef references the secret containing the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + jaasConfigPassThrough: + description: jaasConfigPassThrough specifies another way + to provide the Kafka client-side JaaS configuration. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where required credentials are mounted. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + minLength: 1 + type: string + secretRef: + description: |- + secretRef references the secret containing the required credentials for authentication. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauthSettings: + description: |- + oauthSettings specifies the OAuth settings. + This needs to passed with the authentication type `oauth`. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name of + claim in token for identifying the groups of subject + in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect timeout + with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + oauthbearer: + description: |- + oauthbearer is the authentication mechanism to provider principals. + Only supported in RBAC deployment. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container + where the credential is mounted. + minLength: 1 + type: string + secretRef: + description: |- + secretRef specifies the name of the secret that contains the credential. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#bearer-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + type: + description: |- + type specifies the Kafka client authentication type. + Valid options are `plain`, `oauthbearer`, `digest`, `mtls` and `oauth`. + enum: + - plain + - oauthbearer + - digest + - mtls + - oauth + type: string + required: + - type + type: object + bootstrapEndpoint: + description: bootstrapEndpoint specifies the Kafka bootstrap + endpoint. + minLength: 1 + pattern: .+:[0-9]+ + type: string + discovery: + description: discovery specifies the capability to discover + the Kafka cluster. + properties: + name: + description: name is the name of the Confluent Platform + component cluster. + type: string + namespace: + description: |- + namespace is where the Confluent Platform component is running. + The default value is the namespace where CFK is running. + type: string + secretRef: + description: secretRef is the name of the secret used + to discover the Confluent Platform component. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - name + type: object + tls: + description: tls defines the client-side TLS setting for the + Kafka cluster. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + schemaRegistry: + description: schemaRegistry contains the dependency configuration + for the Schema Registry cluster. + properties: + authentication: + description: authentication specifies the authentication for + the Schema Registry cluster. + properties: + basic: + description: basic specifies the configuration for basic + authentication. + properties: + debug: + description: debug enables the basic authentication + debug logs for JaaS configuration. + type: boolean + directoryPathInContainer: + description: |- + directoryPathInContainer allows to pass the basic credential through a directory path in the container. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + minLength: 1 + type: string + restrictedRoles: + description: |- + restrictedRoles specify the restricted roles on the server side only. + Changes will be only reflected in Control Center. + This configuration is ignored on the client side configuration. + items: + type: string + minItems: 1 + type: array + roles: + description: |- + roles specify the roles on the server side only. + This configuration is ignored on the client side configuration. + items: + type: string + type: array + secretRef: + description: |- + secretRef defines secret reference to pass the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauth: + description: oauth specifies the configuration for OAuth + authentication. + properties: + configuration: + description: configuration specifies the OAuth server + settings. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name + of claim in token for identifying the groups + of subject in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect + timeout with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + directoryPathInContainer: + description: directoryPathInContainer allows to pass + the basic credential through a directory path in + the container. + minLength: 1 + type: string + secretRef: + description: secretRef defines secret reference to + pass the required credentials. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - configuration + type: object + type: + description: type specifies the authentication scheme + for the REST API client. Valid options are `basic`, + `oauth` and `mtls`. + enum: + - basic + - mtls + - oauth + type: string + required: + - type + type: object + tls: + description: tls defines the client-side TLS setting for the + Schema Registry cluster. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + url: + description: url specifies the URL endpoint of the Schema + Registry cluster. + minLength: 1 + pattern: ^https?://.* + type: string + required: + - url + type: object + type: object + enableExternalInterInstance: + description: |- + ExternalInterInstance is only needed for multi-cluster deployment or stretch cluster. + when set to true the connect server will use the external listener for inter-instance communication. + type: boolean + enableSchemas: + description: enableSchemas indicates whether to enable scheme or not. + type: boolean + externalAccess: + description: CPExternalAccess holds all external access policies for + the non-Kafka component clusters. + properties: + loadBalancer: + description: loadBalancer specifies the configuration to create + a Kubernetes load balancer service. + properties: + advertisedURL: + description: |- + advertisedURL specifies the configuration for advertised listener per pod. It is only supported for MDS currently. + If it is enabled, instead of using internal endpoint, the MDS advertised listener for each broker will be + set to: `://.` where podId starts from `0` to `replicaCount -1`. + This is only recommended if you cannot add internal SANs to the TLS certificates for MDS and + the external DNS must be resolved inside the Kubernetes cluster. + This configuration will not take effect if MDS enabled dual listener setup. + properties: + enabled: + description: |- + enabled indicates whether to set the MDS advertised listener url with external endpoint for each broker. + Has no effect with Zookeeper, which will always create a listener per pod. + type: boolean + prefix: + description: |- + prefix specifies the broker prefix for MDS/Zookeeper advertised endpoint. + If not configured, it uses `b` as default prefix for MDS, such as `b#.domain` where `#` will start from `0` to `replicaCount -1`. + It uses 'zookeeper' as default prefix for Zookeeper in the same way. + minLength: 1 + type: string + required: + - enabled + type: object + annotations: + additionalProperties: + type: string + description: annotations is a map of string key and value + pairs. It specifies Kubernetes annotations for this service. + type: object + x-kubernetes-map-type: granular + domain: + description: domain is the domain name of the component cluster. + minLength: 1 + type: string + externalTrafficPolicy: + description: externalTrafficPolicy specifies the external + traffic policy for the service. Valid options are `Local` + and `Cluster`. + enum: + - Local + - Cluster + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key and value pairs. + It specifies Kubernetes labels for this service. + type: object + x-kubernetes-map-type: granular + loadBalancerSourceRanges: + description: loadBalancerSourceRanges specify the source ranges. + items: + type: string + type: array + port: + description: |- + port specifies the external port for the client consumption. + If not configured, the same internal/external port is configured for the component. + Information about the port can be retrieved through the status API. + format: int32 + type: integer + prefix: + description: |- + prefix specify the prefix for the given domain. + The default value is the name of the cluster. + minLength: 1 + type: string + servicePorts: + description: servicePorts specify the user-provided service + port(s). + 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 + sessionAffinity: + description: |- + sessionAffinity defines the Kubernetes session affinity. The valid options are `ClientIP` and `None`. `ClientIP` enables the client IP-based session affinity. + The default value is `None`. + More info: https://kubernetes.io/docs/reference/networking/virtual-ips/#session-affinity. + enum: + - ClientIP + - None + type: string + sessionAffinityConfig: + description: SessionAffinityConfig contains the configurations + of the 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 + required: + - domain + type: object + nodePort: + description: nodePort specifies the configuration to create a + Kubernetes node port service. + properties: + advertisedURL: + description: |- + advertisedURL specifies the configuration for advertised listener per pod. It is only supported for MDS currently. + If it is enabled, instead of using internal endpoint, the MDS advertised listener for each broker will be + set to `://:, where`podId` starts from `0` to `replicaCount - 1`. + This is only recommended if you cannot add internal SANs to the TLS certificates for MDS and + the external DNS must be resolved inside the Kubernetes cluster. + properties: + enabled: + description: |- + enabled indicates whether to set the MDS advertised listener url with external endpoint for each broker. + Has no effect with Zookeeper, which will always create a listener per pod. + type: boolean + prefix: + description: |- + prefix specifies the broker prefix for MDS/Zookeeper advertised endpoint. + If not configured, it uses `b` as default prefix for MDS, such as `b#.domain` where `#` will start from `0` to `replicaCount -1`. + It uses 'zookeeper' as default prefix for Zookeeper in the same way. + minLength: 1 + type: string + required: + - enabled + type: object + annotations: + additionalProperties: + type: string + description: annotations is a map of string key and value + pairs. It specifies Kubernetes annotations for this service. + type: object + x-kubernetes-map-type: granular + externalTrafficPolicy: + description: |- + externalTrafficPolicy specifies the external traffic policy for the service. + Valid options are `Local` and `Cluster`. + enum: + - Local + - Cluster + type: string + host: + description: host defines the host name of the cluster. + minLength: 1 + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key and value pairs. + It specifies Kubernetes labels for this service. + type: object + x-kubernetes-map-type: granular + nodePortOffset: + description: |- + nodePortOffset specifies the starting offset of the node ports. The port numbers go in ascending order with respect + to the replicas count. + NodePort service creation fails if the node port is not in the range supported by the Kubernetes API server. + The default Kubernetes Node Port range is `30000` - `32762`. + format: int32 + minimum: 0 + type: integer + servicePorts: + description: |- + servicePorts specify user-provided service port(s). + For Kafka with the nodePort type, this setting is only applied to Kafka bootstrap service. + 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 + sessionAffinity: + description: |- + sessionAffinity defines the Kubernetes session affinity. The valid options are `ClientIP` and `None`. `ClientIP` enables the client IP-based session affinity. + The default value is `None`. + More info: https://kubernetes.io/docs/reference/networking/virtual-ips/#session-affinity. + enum: + - ClientIP + - None + type: string + sessionAffinityConfig: + description: SessionAffinityConfig contains the configurations + of the 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 + required: + - host + - nodePortOffset + type: object + route: + description: route specifies the configuration to create a route + service in OpenShift. + properties: + advertisedURL: + description: |- + advertisedURL specifies the configuration for advertised listener per pod. It is only supported for MDS currently. + If it is enabled, instead of using internal endpoint, the MDS advertised listener for each broker will be + set to: `://-http-external.` where podId starts from `0` to `replicaCount -1`. + This is only recommended if you cannot add internal SANs to the TLS certificates for MDS and + the external DNS must be resolved inside the Kubernetes cluster. + This configuration will not take effect if MDS enabled dual listener setup. + properties: + enabled: + description: |- + enabled indicates whether to set the MDS advertised listener url with external endpoint for each broker. + Has no effect with Zookeeper, which will always create a listener per pod. + type: boolean + prefix: + description: |- + prefix specifies the broker prefix for MDS/Zookeeper advertised endpoint. + If not configured, it uses `b` as default prefix for MDS, such as `b#.domain` where `#` will start from `0` to `replicaCount -1`. + It uses 'zookeeper' as default prefix for Zookeeper in the same way. + minLength: 1 + type: string + required: + - enabled + type: object + annotations: + additionalProperties: + type: string + description: annotations is a map of string key and value + pairs. It specifies Kubernetes annotations for this service. + type: object + x-kubernetes-map-type: granular + domain: + description: domain specifies the domain name of the Confluent + component cluster. + minLength: 1 + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key and value pairs. + It specifies Kubernetes labels for this service. + type: object + x-kubernetes-map-type: granular + prefix: + description: |- + prefix specifies the component prefix when configured for the domain. + The default value is the name of the cluster. + minLength: 1 + type: string + wildcardPolicy: + description: |- + wildcardPolicy allows you to define a route that covers all hosts within a domain. Valid options are `Subdomain` and `None`. + The default value is `None`. + enum: + - Subdomain + - None + type: string + required: + - domain + type: object + type: + description: |- + type specifies the Kubernetes external service for the component. + Valid options are `loadBalancer`, `nodePort`, and `route`. + enum: + - loadBalancer + - nodePort + - route + minLength: 1 + type: string + required: + - type + type: object + headlessService: + description: headlessService specifies the configuration of the Kubernetes + headless service. + properties: + annotations: + additionalProperties: + type: string + description: |- + annotations is a map of string key and value pairs. + It specifies the annotations to be added to the CFK-created headless service. + These annotations are merged with the injectAnnotations and take precedence. + type: object + x-kubernetes-map-type: granular + labels: + additionalProperties: + type: string + description: |- + labels is a map of string key and value pairs. + It specifies the labels to be added to the CFK-created headless service. + These labels are merged with the injectLabels and take precedence. + type: object + x-kubernetes-map-type: granular + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses specifies the publishNotReadyAddresses field. + For Kafka, this value must be true. The default value is true. + type: boolean + type: object + image: + description: |- + image specifies the application and the init docker image configurations. + A change to this setting will roll the cluster. + properties: + application: + description: |- + application is the Docker image name of the application. Specify + `//:`. + pattern: .+:.+ + type: string + init: + description: |- + init is the init-container name. Specify + `//:`. + pattern: .+:.+ + type: string + pullPolicy: + description: |- + pullPolicy is the policy for pulling images. Valid options are `Always`, `Never`, and `IfNotPresent`. + The default value is `IfNotPresent`. + enum: + - Always + - Never + - IfNotPresent + type: string + pullSecretRef: + description: |- + pullSecretRef references the secrets in the same namespace to be used for pulling images. + Image pull secrets are distinct from secrets because secrets + can be mounted in the pod, but image pull secrets are only accessed by `kubelet`. + More info: https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod + items: + type: string + type: array + required: + - application + - init + type: object + injectAnnotations: + additionalProperties: + type: string + description: |- + injectAnnotations are the annotations injected to the internal resources that CFK created. + The internal annotations are preserved and cannot be overridden. + For pod annotations, use `podTemplate.annotations`. + type: object + x-kubernetes-map-type: granular + injectLabels: + additionalProperties: + type: string + description: |- + injectLabels are the labels injected to the internal resources that CFK created. + The internal labels are preserved and cannot be overridden. + For pod labels, use `podTemplate.labels`. + type: object + x-kubernetes-map-type: granular + internalTopicReplicationFactor: + description: |- + internalTopicReplicationFactor specifies the replication factor for the internal topics. + The default value is `3`. + format: int32 + type: integer + k8sClusterDomain: + description: |- + k8sClusterDomain specifies the configuration of the Kubernetes cluster domain. + The default is the `cluster.local` domain. + type: string + keyConverterType: + description: |- + keyConverterType specifies the supported key converters package for the Confluent Platform. + For the supported converter types, see https://docs.confluent.io/current/connect/concepts.html#connect-converters. + The default value is `org.apache.kafka.connect.json.JsonConverter`. + minLength: 1 + type: string + license: + description: license specifies the license configuration for the Confluent + Platform component. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + the license key is mounted. More info: + https://docs.confluent.io/operator/current/co-license.html#update-component-level-licenses + minLength: 1 + type: string + globalLicense: + description: globalLicense specifies whether the Confluent Platform + component shares the common global license. + type: boolean + secretRef: + description: |- + secretRef references the secret that provides the license for the Confluent Platform component. + More info: https://docs.confluent.io/operator/current/co-license.html#update-component-level-licenses + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + metrics: + description: metrics specify the security settings for the metric + services. + properties: + authentication: + description: authentication specifies the authentication configuration + for the metrics. + properties: + type: + description: type specifies the metrics authentication method. + The valid option is `mtls`. + enum: + - mtls + type: string + required: + - type + type: object + prometheus: + description: prometheus specifies the configuration overrides + for the JMX-Prometheus exporter. + properties: + blacklist: + items: + type: string + type: array + rules: + items: + description: Rule defines the Prometheus Exporter rule override. + properties: + attrNameSnakeCase: + type: boolean + cache: + type: boolean + help: + minLength: 1 + type: string + labels: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: granular + name: + minLength: 1 + type: string + pattern: + minLength: 1 + type: string + type: + minLength: 1 + type: string + value: + minLength: 1 + type: string + valueFactor: + anyOf: + - type: integer + - type: string + default: 1 + 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: array + whitelist: + items: + type: string + type: array + type: object + tls: + description: tls specifies the TLS configuration for the metrics. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + mountedSecrets: + description: |- + mountedSecrets list the secrets injected to + the underlying statefulset configuration. The secret reference is mounted + in the default path `/mnt/secrets/`. The underlying resources + will follow the secret as a file configuration. + More info: https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets-as-files-from-a-pod. + A change to this setting will roll the cluster. + items: + description: |- + MountedSecrets provides a way to inject a custom secret to the underlying + statefulset. + properties: + keyItems: + description: keyItems are key and path names. + 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 + secretRef: + description: secretRef references the name of the secret. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + type: array + mountedVolumes: + description: |- + mountedVolumes list the custom volumes that need to be mounted into the + underlying statefulset. + A change to this setting will roll the cluster. + properties: + volumeMounts: + description: |- + volumeMounts specify the list of volume mounts for the pods in the + statefulset. + 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 + volumes: + description: |- + volumes specify the list of volumes that can be mounted into the pods + of statefulset. + 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 + 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: + 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 + 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 + 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: + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 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 + 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 + 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 + 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 + 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 + 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: + 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 + 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 + 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 + required: + - volumeMounts + - volumes + type: object + oneReplicaPerNode: + description: |- + oneReplicaPerNode controls whether to run 1 pod per node using the pod anti-affinity capability. + Enabling this configuration in an existing cluster will roll the cluster. + type: boolean + pdb: + description: |- + configures PodDisruptionBudget for the Confluent Platform component. + by default PDB is configured based on pre-detemined formula. + properties: + enabled: + description: enabled specifies whether the PodDisruptionBudget + is enabled + type: boolean + maxUnavailable: + description: maxUnavailable is the maximum number of pods that + can be unavailable during the disruption. + format: int32 + type: integer + required: + - enabled + type: object + podTemplate: + description: podTemplate specifies the statefulset pod template configuration. + properties: + affinity: + description: |- + affinity specifies a group of affinity scheduling rules. + More info: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity. + 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 + annotations: + additionalProperties: + type: string + description: |- + annotations is a map of string key and value pairs stored with the resource and + 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 + x-kubernetes-map-type: granular + envVars: + description: |- + envVars contain environment variables to be injected into containers. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container. + 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 + 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: + 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 + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + labels: + additionalProperties: + type: string + description: |- + labels is a map of string key and value pairs that can be used to organize and categorize + (scope and select) objects. + More info: http://kubernetes.io/docs/user-guide/labels. + type: object + x-kubernetes-map-type: granular + 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: + + + 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 + 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: + description: priorityClassName specifies the priority class for + the pod (if any). + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + probe: + description: probe contains the fields for standard Kubernetes + readiness/liveness probe configuration. + properties: + liveness: + description: |- + liveness configures the Kubernetes probe settings. The changes + will override the existing default configuration. + properties: + failureThreshold: + description: |- + failureThreshold is the minimum consecutive failures for the probe to be considered failed. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + initialDelaySeconds: + description: |- + initialDelaySeconds is the number of seconds after the container has started and before probes are initiated. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + path: + description: Path for the HTTP probe + type: string + periodSeconds: + description: |- + periodSeconds specifies how often to perform the probe. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + port: + description: Number of the port to access on the container + type: integer + successThreshold: + description: |- + successThreshold is the minimum consecutive successes for the probe to be considered successful after having failed. + The default values is `1`. Must be `1` for liveness and startup. The minimum value is `1`. + format: int32 + type: integer + timeoutSeconds: + description: |- + timeoutSeconds is the number of seconds after which the probe times out. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + type: object + readiness: + description: |- + readiness configures the Kubernetes probe setting. The changes + will override the existing default configuration. + properties: + failureThreshold: + description: |- + failureThreshold is the minimum consecutive failures for the probe to be considered failed. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + initialDelaySeconds: + description: |- + initialDelaySeconds is the number of seconds after the container has started and before probes are initiated. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + path: + description: Path for the HTTP probe + type: string + periodSeconds: + description: |- + periodSeconds specifies how often to perform the probe. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + port: + description: Number of the port to access on the container + type: integer + successThreshold: + description: |- + successThreshold is the minimum consecutive successes for the probe to be considered successful after having failed. + The default values is `1`. Must be `1` for liveness and startup. The minimum value is `1`. + format: int32 + type: integer + timeoutSeconds: + description: |- + timeoutSeconds is the number of seconds after which the probe times out. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + type: object + type: object + resources: + description: resources describe the compute resource requirements. + 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 + 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: + + + 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: + description: |- + ServiceAccountName is the name of the service account used to run this pod. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account. + type: string + terminationGracePeriodSeconds: + description: terminationGracePeriodSeconds is the grace period + before the pod is deleted. + format: int64 + type: integer + tolerations: + description: |- + tolerations specify the pods to schedule onto the nodes with matching taints, using + the triple `` and the matching operator ``. + 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 + topologySpreadConstraints: + description: |- + topologySpreadConstraints describe how a group of pods ought to spread across topology domains. Scheduler will + schedule pods based on 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 + 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 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. + + + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). + 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 + type: object + replicas: + description: |- + replicas is the desired number of replicas. + A change to this setting will roll the cluster. + format: int32 + type: integer + telemetry: + description: telemetry specifies the Confluent telemetry reporter + configuration. + properties: + global: + description: |- + global allows disabling telemetry configuration. + If CFK is deployed with telemetry, this field is only + used to disable telemetry. The default value is `true` if + telemetry is enabled at the global level. + type: boolean + type: object + tls: + description: tls specifies the global-level TLS configuration. + properties: + autoGeneratedCerts: + description: |- + autoGeneratedCerts specifies that the certificates are auto-generated based on + the CA key pair provided. + type: boolean + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + fips: + description: |- + fips specifies the configuration of FIPS compliant Bouncy Castle type Java Keystores for the cp component's + TLS settings. TLS Secrets must have the keys keystore.bcfks, truststore.bcfks, and jksPassword.txt + properties: + enabled: + description: enabled specifies whether to enable the FIPS + configuration for cp components. + type: boolean + required: + - enabled + type: object + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing the + JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + valueConverterType: + description: |- + valueConverterType specifies the supported value converters package for the Confluent Platform. + For the supported converter types, see https://docs.confluent.io/current/connect/concepts.html#connect-converters. + The default value is `org.apache.kafka.connect.json.JsonConverter`. + minLength: 1 + type: string + required: + - image + type: object + status: + description: status defines the observed state of the Connect cluster. + properties: + arbitraryData: + description: arbitraryData is the map for any arbitrary data associated + with this Confluent component. + x-kubernetes-preserve-unknown-fields: true + authorizationType: + description: authorizationType is the authorization type for this + Confluent component. + type: string + clusterName: + description: clusterName is the name of the Confluent Platform component + cluster. + type: string + clusterNamespace: + description: clusterNamespace is the namespace where the Confluent + Platform component cluster is running. + type: string + conditions: + description: conditions specify the latest available observations + of the current state. + items: + description: Condition represent the latest available observations + of the current state. + properties: + lastProbeTime: + description: lastProbeTime shows the last time the condition + was evaluated. + format: date-time + type: string + lastTransitionTime: + description: lastTransitionTime shows the last time the condition + was transitioned from one status to another. + format: date-time + type: string + message: + description: message shows a human-readable message with details + about the transition. + type: string + reason: + description: reason shows the reason for the last transition + of the condition. + type: string + status: + description: status shows the status of the condition, one of + `True`, `False`, or `Unknown`. + type: string + type: + description: type shows the condition type. + type: string + type: object + type: array + connectorPlugins: + description: connectorPlugins are the installed connector plugins. + items: + description: ConnectorPluginStatus defines the state of the connector + plugin. + properties: + class: + description: class specifies the class name of the connector + plugin. + type: string + type: + description: type is the connector plugin type, which can be + `SOURCE`, `SINK` or `UNKNOWN`. + type: string + version: + description: version is the current version of the connector + plugin. + type: string + required: + - class + type: object + type: array + connectorTLSFilePaths: + description: connectorTLSFilePaths are the connector TLS file paths. + items: + description: CustomTLSFilePathStatus specifies the file paths of + the custom TLS certificates. + properties: + jksPasswordPath: + description: jksPasswordPath contains the absolute path of the + `jksPassword.txt` file. + type: string + keyStorePath: + description: keyStorePath contains the absolute path of the + keystore file, `.jks` or `.p12`. + type: string + trustStorePath: + description: trustStorePath contains the absolute path of the + truststore file, `.jks` or `.p12`. + type: string + type: object + type: array + currentReplicas: + description: currentReplicas is the number of currently running replicas. + format: int32 + type: integer + groupID: + description: groupID is the group id of the Connect cluster. + type: string + internalSecrets: + description: |- + internalSecrets are internal secrets created + by CFK for this Confluent component. + items: + type: string + type: array + internalTopicNames: + description: internalTopicNames are the topics used by the component + for internal use. + items: + type: string + type: array + kafka: + description: kafka is the Kafka client side status for the Connect + cluster. + properties: + authenticationType: + description: authenticationType describes the authentication method + for the Kafka cluster. + type: string + bootstrapEndpoint: + description: bootstrapEndpoint specifies the Kafka bootstrap endpoint. + type: string + tls: + description: tls indicates whether TLS is enabled for the Kafka + dependency. + type: boolean + type: object + observedGeneration: + description: observedGeneration is the most recent generation observed + for this Confluent component. + format: int64 + type: integer + operatorVersion: + description: operatorVersion is the internal version of CFK. + type: string + phase: + description: |- + phase describes the state of the Confluent Platform component. This can either be 'PROVISIONING' + or 'RUNNING' + 'PROVISIONING' means the Confluent Platform component is currently getting deployed and not ready yet. + 'RUNNING' means the Confluent Platform component has been successfully deployed. + type: string + rbac: + description: rbac contains the RBAC-related status when RBAC is enabled. + properties: + clusterID: + description: clusterID specifies the id of the cluster. + type: string + internalRolebindings: + description: internalRolebindings specifies the internal rolebindings. + items: + type: string + type: array + type: object + readyReplicas: + description: readyReplicas is the number of currently ready replicas. + format: int32 + type: integer + replicas: + description: replicas is the number of replicas. + format: int32 + type: integer + restConfig: + description: restConfig is the REST configuration of the Connect cluster. + properties: + advertisedExternalEndpoints: + description: advertisedExternalEndpoints specifies other advertised + endpoints used, especially for Kafka. + items: + type: string + type: array + authenticationType: + description: authenticationType shows the authentication type + configured by the listener. + type: string + externalAccessType: + description: externalAccessType shows the external access type + used for the listener. + type: string + externalEndpoint: + description: externalEndpoint specifies the external endpoint + to connect to the Confluent component cluster. + type: string + internalEndpoint: + description: internalEndpoint specifies the internal endpoint + to connect to the Confluent component cluster. + type: string + tls: + description: tls shows whether TLS is configured for the listener. + type: boolean + type: object + selector: + description: |- + selector gets the label selector of the child pod. + The Horizontal Pod Autoscaler(HPA) will scale using the label selector of the child pod. + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.replicas + statusReplicasPath: .status.replicas + status: {} diff --git a/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_controlcenters.yaml b/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_controlcenters.yaml new file mode 100644 index 0000000000..0b1288d2f6 --- /dev/null +++ b/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_controlcenters.yaml @@ -0,0 +1,6394 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: controlcenters.platform.confluent.io +spec: + group: platform.confluent.io + names: + categories: + - all + - confluent-platform + - confluent + kind: ControlCenter + listKind: ControlCenterList + plural: controlcenters + shortNames: + - controlcenter + - c3 + singular: controlcenter + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.replicas + name: Replicas + type: string + - jsonPath: .status.readyReplicas + name: Ready + type: string + - jsonPath: .status.phase + name: Status + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.kafka.bootstrapEndpoint + name: Kafka + priority: 1 + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: ControlCenter is the schema for the Control Center 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 defines the desired state of the Control Center cluster. + properties: + authentication: + description: authentication specifies the authentication configurations. + properties: + basic: + description: basic specifies the configuration for basic authentication. + properties: + debug: + description: debug enables the basic authentication debug + logs for JaaS configuration. + type: boolean + directoryPathInContainer: + description: |- + directoryPathInContainer allows to pass the basic credential through a directory path in the container. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + minLength: 1 + type: string + restrictedRoles: + description: |- + restrictedRoles specify the restricted roles on the server side only. + Changes will be only reflected in Control Center. + This configuration is ignored on the client side configuration. + items: + type: string + minItems: 1 + type: array + roles: + description: |- + roles specify the roles on the server side only. + This configuration is ignored on the client side configuration. + items: + type: string + type: array + secretRef: + description: |- + secretRef defines secret reference to pass the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + ldap: + description: ldap specifies the configuration for Control Center + LDAP authentication. + properties: + debug: + description: debug enables basic authentication debug logs + for JaaS configuration. + type: boolean + property: + additionalProperties: + type: string + description: |- + property is a map of string key and value pairs that specifies the LDAP configuration. + Use a secret object to pass username/password. + type: object + x-kubernetes-map-type: granular + restrictedRoles: + description: restrictedRoles specify the restricted access + roles. + items: + type: string + minItems: 1 + type: array + roles: + description: roles specify the roles on the server side only. + items: + type: string + minItems: 1 + type: array + secretRef: + description: |- + secretRef references the secret to pass required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#ldap-authentication-for-c3 + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + type: + description: type specifies the authentication type of the Control + Center. Valid options are `basic`, `ldap`, and `mtls`. + enum: + - basic + - ldap + - mtls + type: string + required: + - type + type: object + authorization: + description: authorization specifies the authorization configurations. + properties: + kafkaRestClassRef: + description: |- + kafkaRestClassRef references the KafkaRestClass + which specifies the Kafka REST API connection configuration. + properties: + name: + description: name specifies the name of the KafkaRestClass + application resource. + minLength: 1 + type: string + namespace: + description: namespace specifies the namespace of the KafkaRestClass. + type: string + required: + - name + type: object + type: + description: type specifies the client-side authorization type. + The valid option is `rbac`. + enum: + - rbac + type: string + required: + - type + type: object + configOverrides: + description: configOverrides specifies the configs to override the + server, JVM, Log4j properties for the Control Center. + properties: + jvm: + description: |- + jvm is a list of JVM configuration supported by the Confluent Platform component. + This will either add or update the existing configuration. + items: + type: string + type: array + log4j: + description: |- + log4j is a list of Log4J configuration supported by the Confluent Platform component. + This will either add or update the existing configuration. + items: + type: string + type: array + server: + description: |- + server is a list of server configuration supported by the Confluent Platform component. + This will either add or update existing configuration. + items: + type: string + type: array + type: object + dataVolumeCapacity: + anyOf: + - type: integer + - type: string + description: dataVolumeCapacity specifies the data size for the persistent + volume. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + dependencies: + description: dependencies specify the dependencies configurations. + properties: + connect: + description: connect defines the Connect worker dependency configurations. + items: + description: ControlCenterConnectDependency defines the Connect + dependency settings. + properties: + authentication: + description: authentication specifies the authentication + configuration for the Connect cluster. + properties: + basic: + description: basic specifies the configuration for basic + authentication. + properties: + debug: + description: debug enables the basic authentication + debug logs for JaaS configuration. + type: boolean + directoryPathInContainer: + description: |- + directoryPathInContainer allows to pass the basic credential through a directory path in the container. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + minLength: 1 + type: string + restrictedRoles: + description: |- + restrictedRoles specify the restricted roles on the server side only. + Changes will be only reflected in Control Center. + This configuration is ignored on the client side configuration. + items: + type: string + minItems: 1 + type: array + roles: + description: |- + roles specify the roles on the server side only. + This configuration is ignored on the client side configuration. + items: + type: string + type: array + secretRef: + description: |- + secretRef defines secret reference to pass the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauth: + description: oauth specifies the configuration for OAuth + authentication. + properties: + configuration: + description: configuration specifies the OAuth server + settings. + properties: + audience: + description: audience specifies the audience + claim in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name + of claim in token for identifying the groups + of subject in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect + timeout with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max + retry backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry + backoff with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of + claim in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + directoryPathInContainer: + description: directoryPathInContainer allows to + pass the basic credential through a directory + path in the container. + minLength: 1 + type: string + secretRef: + description: secretRef defines secret reference + to pass the required credentials. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - configuration + type: object + type: + description: type specifies the authentication scheme + for the REST API client. Valid options are `basic`, + `oauth` and `mtls`. + enum: + - basic + - mtls + - oauth + type: string + required: + - type + type: object + name: + description: name specifies the Connect cluster name. + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + tls: + description: tls specifies the client-side TLS setting for + the Connect cluster. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + url: + description: url specifies the URL endpoint of the Connect + cluster. + minLength: 1 + pattern: ^https?://.* + type: string + required: + - name + - url + type: object + type: array + kafka: + description: kafka defines the Kafka dependency configurations. + properties: + authentication: + description: authentication defines the authentication for + the Kafka cluster. + properties: + jaasConfig: + description: jaasConfig specifies the Kafka client-side + JaaS configuration. + properties: + secretRef: + description: |- + secretRef references the secret containing the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + jaasConfigPassThrough: + description: jaasConfigPassThrough specifies another way + to provide the Kafka client-side JaaS configuration. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where required credentials are mounted. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + minLength: 1 + type: string + secretRef: + description: |- + secretRef references the secret containing the required credentials for authentication. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauthSettings: + description: |- + oauthSettings specifies the OAuth settings. + This needs to passed with the authentication type `oauth`. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name of + claim in token for identifying the groups of subject + in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect timeout + with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + oauthbearer: + description: |- + oauthbearer is the authentication mechanism to provider principals. + Only supported in RBAC deployment. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container + where the credential is mounted. + minLength: 1 + type: string + secretRef: + description: |- + secretRef specifies the name of the secret that contains the credential. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#bearer-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + type: + description: |- + type specifies the Kafka client authentication type. + Valid options are `plain`, `oauthbearer`, `digest`, `mtls` and `oauth`. + enum: + - plain + - oauthbearer + - digest + - mtls + - oauth + type: string + required: + - type + type: object + bootstrapEndpoint: + description: bootstrapEndpoint specifies the Kafka bootstrap + endpoint. + minLength: 1 + pattern: .+:[0-9]+ + type: string + discovery: + description: discovery specifies the capability to discover + the Kafka cluster. + properties: + name: + description: name is the name of the Confluent Platform + component cluster. + type: string + namespace: + description: |- + namespace is where the Confluent Platform component is running. + The default value is the namespace where CFK is running. + type: string + secretRef: + description: secretRef is the name of the secret used + to discover the Confluent Platform component. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - name + type: object + tls: + description: tls defines the client-side TLS setting for the + Kafka cluster. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + ksqldb: + description: ksqldb defines the ksqlDB dependency configurations. + items: + description: ControlCenterKSQLDependency defines the ksqlDB + dependency settings. + properties: + advertisedUrl: + description: advertisedUrl specifies the advertised URL + to use in the browser. + minLength: 1 + pattern: ^https?://.* + type: string + authentication: + description: authentication specifies the authentication + for the ksqlDB cluster. + properties: + basic: + description: basic specifies the configuration for basic + authentication. + properties: + debug: + description: debug enables the basic authentication + debug logs for JaaS configuration. + type: boolean + directoryPathInContainer: + description: |- + directoryPathInContainer allows to pass the basic credential through a directory path in the container. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + minLength: 1 + type: string + restrictedRoles: + description: |- + restrictedRoles specify the restricted roles on the server side only. + Changes will be only reflected in Control Center. + This configuration is ignored on the client side configuration. + items: + type: string + minItems: 1 + type: array + roles: + description: |- + roles specify the roles on the server side only. + This configuration is ignored on the client side configuration. + items: + type: string + type: array + secretRef: + description: |- + secretRef defines secret reference to pass the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauth: + description: oauth specifies the configuration for OAuth + authentication. + properties: + configuration: + description: configuration specifies the OAuth server + settings. + properties: + audience: + description: audience specifies the audience + claim in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name + of claim in token for identifying the groups + of subject in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect + timeout with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max + retry backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry + backoff with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of + claim in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + directoryPathInContainer: + description: directoryPathInContainer allows to + pass the basic credential through a directory + path in the container. + minLength: 1 + type: string + secretRef: + description: secretRef defines secret reference + to pass the required credentials. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - configuration + type: object + type: + description: type specifies the authentication scheme + for the REST API client. Valid options are `basic`, + `oauth` and `mtls`. + enum: + - basic + - mtls + - oauth + type: string + required: + - type + type: object + name: + description: name specifies the ksqlDB cluster name. + minLength: 1 + type: string + tls: + description: tls specifies the client-side TLS setting for + the ksqlDB cluster. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + url: + description: url specifies the URL endpoint of the ksqlDB + cluster. + minLength: 1 + pattern: ^https?://.* + type: string + required: + - name + - url + type: object + type: array + mds: + description: mds defines the RBAC dependency configurations. + properties: + authentication: + description: authentication specifies the client side authentication + configuration for the MDS. + properties: + bearer: + description: bearer specifies the bearer authentication + settings. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container + where the credential is mounted. + minLength: 1 + type: string + secretRef: + description: |- + secretRef specifies the name of the secret that contains the credential. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#bearer-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauth: + description: oauth specifies the OAuth authentication + settings. + properties: + configuration: + description: configuration specifies the OAuth server + settings. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name + of claim in token for identifying the groups + of subject in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect + timeout with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + directoryPathInContainer: + description: directoryPathInContainer allows to pass + the basic credential through a directory path in + the container. + minLength: 1 + type: string + secretRef: + description: secretRef defines secret reference to + pass the required credentials. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - configuration + type: object + type: + description: type specifies the authentication method + for the MDS. The valid option is `bearer`, `oauth`. + enum: + - bearer + - oauth + type: string + required: + - type + type: object + endpoint: + description: endpoint specifies the MDS endpoint. + minLength: 1 + pattern: ^https?://.* + type: string + ssoProtocol: + description: sso protocol, valid options are ldap and oidc. + enum: + - ldap + - oidc + type: string + tls: + description: ClientTLSConfig specifies the TLS configuration + for the Confluent component (dependencies, listeners). + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + tokenKeyPair: + description: tokenKeyPair specifies the token keypair to configure + the MDS. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer defines the directory path in the container + where the MDS token key pair are mounted. + minLength: 1 + type: string + encryptedTokenKey: + description: |- + EncryptedTokenKey boolean value indicating whether the tokenKeypair(private used for signing) is encrypted using a passphrase. If true, cfk + operator will look for a file named mdsTokenKeyPassphrase.txt containing key value pair + mdsTokenKeyPassphrase=. Relevant only for mds server. Ignored if set for a client configuration. + type: boolean + secretRef: + description: secretRef references the name of the secret + that contains the MDS token key pair. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + required: + - authentication + - endpoint + - tokenKeyPair + type: object + schemaRegistry: + description: schemaRegistry defines the Schema Registry dependency + configurations. + properties: + authentication: + description: authentication specifies the authentication for + the Schema Registry cluster. + properties: + basic: + description: basic specifies the configuration for basic + authentication. + properties: + debug: + description: debug enables the basic authentication + debug logs for JaaS configuration. + type: boolean + directoryPathInContainer: + description: |- + directoryPathInContainer allows to pass the basic credential through a directory path in the container. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + minLength: 1 + type: string + restrictedRoles: + description: |- + restrictedRoles specify the restricted roles on the server side only. + Changes will be only reflected in Control Center. + This configuration is ignored on the client side configuration. + items: + type: string + minItems: 1 + type: array + roles: + description: |- + roles specify the roles on the server side only. + This configuration is ignored on the client side configuration. + items: + type: string + type: array + secretRef: + description: |- + secretRef defines secret reference to pass the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauth: + description: oauth specifies the configuration for OAuth + authentication. + properties: + configuration: + description: configuration specifies the OAuth server + settings. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name + of claim in token for identifying the groups + of subject in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect + timeout with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + directoryPathInContainer: + description: directoryPathInContainer allows to pass + the basic credential through a directory path in + the container. + minLength: 1 + type: string + secretRef: + description: secretRef defines secret reference to + pass the required credentials. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - configuration + type: object + type: + description: type specifies the authentication scheme + for the REST API client. Valid options are `basic`, + `oauth` and `mtls`. + enum: + - basic + - mtls + - oauth + type: string + required: + - type + type: object + clusters: + items: + description: ControlCenterMultiSchemaRegistryDependency + defines the Schema Registry dependency List. + properties: + authentication: + description: authentication specifies the authentication + for the Schema Registry cluster. + properties: + basic: + description: basic specifies the configuration for + basic authentication. + properties: + debug: + description: debug enables the basic authentication + debug logs for JaaS configuration. + type: boolean + directoryPathInContainer: + description: |- + directoryPathInContainer allows to pass the basic credential through a directory path in the container. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + minLength: 1 + type: string + restrictedRoles: + description: |- + restrictedRoles specify the restricted roles on the server side only. + Changes will be only reflected in Control Center. + This configuration is ignored on the client side configuration. + items: + type: string + minItems: 1 + type: array + roles: + description: |- + roles specify the roles on the server side only. + This configuration is ignored on the client side configuration. + items: + type: string + type: array + secretRef: + description: |- + secretRef defines secret reference to pass the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauth: + description: oauth specifies the configuration for + OAuth authentication. + properties: + configuration: + description: configuration specifies the OAuth + server settings. + properties: + audience: + description: audience specifies the audience + claim in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the + expected issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the + name of claim in token for identifying + the groups of subject in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets + connect timeout with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read + timeout with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets + max retry backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry + backoff with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name + of claim in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + directoryPathInContainer: + description: directoryPathInContainer allows + to pass the basic credential through a directory + path in the container. + minLength: 1 + type: string + secretRef: + description: secretRef defines secret reference + to pass the required credentials. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - configuration + type: object + type: + description: type specifies the authentication scheme + for the REST API client. Valid options are `basic`, + `oauth` and `mtls`. + enum: + - basic + - mtls + - oauth + type: string + required: + - type + type: object + name: + description: name defines the Schema Registry cluster + name. + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + tls: + description: tls defines the client-side TLS setting + for the Schema Registry cluster. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS + configuration for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + url: + description: url specifies the URL endpoint of the Schema + Registry cluster. + minLength: 1 + pattern: ^https?://.* + type: string + required: + - name + - url + type: object + type: array + tls: + description: tls defines the client-side TLS setting for the + Schema Registry cluster. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + url: + description: url specifies the URL endpoint of the Schema + Registry cluster. + minLength: 1 + pattern: ^https?://.* + type: string + required: + - url + type: object + type: object + externalAccess: + description: externalAccess specifies the external access configuration + for the Control Center cluster. + properties: + loadBalancer: + description: loadBalancer specifies the configuration to create + a Kubernetes load balancer service. + properties: + advertisedURL: + description: |- + advertisedURL specifies the configuration for advertised listener per pod. It is only supported for MDS currently. + If it is enabled, instead of using internal endpoint, the MDS advertised listener for each broker will be + set to: `://.` where podId starts from `0` to `replicaCount -1`. + This is only recommended if you cannot add internal SANs to the TLS certificates for MDS and + the external DNS must be resolved inside the Kubernetes cluster. + This configuration will not take effect if MDS enabled dual listener setup. + properties: + enabled: + description: |- + enabled indicates whether to set the MDS advertised listener url with external endpoint for each broker. + Has no effect with Zookeeper, which will always create a listener per pod. + type: boolean + prefix: + description: |- + prefix specifies the broker prefix for MDS/Zookeeper advertised endpoint. + If not configured, it uses `b` as default prefix for MDS, such as `b#.domain` where `#` will start from `0` to `replicaCount -1`. + It uses 'zookeeper' as default prefix for Zookeeper in the same way. + minLength: 1 + type: string + required: + - enabled + type: object + annotations: + additionalProperties: + type: string + description: annotations is a map of string key and value + pairs. It specifies Kubernetes annotations for this service. + type: object + x-kubernetes-map-type: granular + domain: + description: domain is the domain name of the component cluster. + minLength: 1 + type: string + externalTrafficPolicy: + description: externalTrafficPolicy specifies the external + traffic policy for the service. Valid options are `Local` + and `Cluster`. + enum: + - Local + - Cluster + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key and value pairs. + It specifies Kubernetes labels for this service. + type: object + x-kubernetes-map-type: granular + loadBalancerSourceRanges: + description: loadBalancerSourceRanges specify the source ranges. + items: + type: string + type: array + port: + description: |- + port specifies the external port for the client consumption. + If not configured, the same internal/external port is configured for the component. + Information about the port can be retrieved through the status API. + format: int32 + type: integer + prefix: + description: |- + prefix specify the prefix for the given domain. + The default value is the name of the cluster. + minLength: 1 + type: string + servicePorts: + description: servicePorts specify the user-provided service + port(s). + 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 + sessionAffinity: + description: |- + sessionAffinity defines the Kubernetes session affinity. The valid options are `ClientIP` and `None`. `ClientIP` enables the client IP-based session affinity. + The default value is `None`. + More info: https://kubernetes.io/docs/reference/networking/virtual-ips/#session-affinity. + enum: + - ClientIP + - None + type: string + sessionAffinityConfig: + description: SessionAffinityConfig contains the configurations + of the 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 + required: + - domain + type: object + nodePort: + description: nodePort specifies the configuration to create a + Kubernetes node port service. + properties: + advertisedURL: + description: |- + advertisedURL specifies the configuration for advertised listener per pod. It is only supported for MDS currently. + If it is enabled, instead of using internal endpoint, the MDS advertised listener for each broker will be + set to `://:, where`podId` starts from `0` to `replicaCount - 1`. + This is only recommended if you cannot add internal SANs to the TLS certificates for MDS and + the external DNS must be resolved inside the Kubernetes cluster. + properties: + enabled: + description: |- + enabled indicates whether to set the MDS advertised listener url with external endpoint for each broker. + Has no effect with Zookeeper, which will always create a listener per pod. + type: boolean + prefix: + description: |- + prefix specifies the broker prefix for MDS/Zookeeper advertised endpoint. + If not configured, it uses `b` as default prefix for MDS, such as `b#.domain` where `#` will start from `0` to `replicaCount -1`. + It uses 'zookeeper' as default prefix for Zookeeper in the same way. + minLength: 1 + type: string + required: + - enabled + type: object + annotations: + additionalProperties: + type: string + description: annotations is a map of string key and value + pairs. It specifies Kubernetes annotations for this service. + type: object + x-kubernetes-map-type: granular + externalTrafficPolicy: + description: |- + externalTrafficPolicy specifies the external traffic policy for the service. + Valid options are `Local` and `Cluster`. + enum: + - Local + - Cluster + type: string + host: + description: host defines the host name of the cluster. + minLength: 1 + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key and value pairs. + It specifies Kubernetes labels for this service. + type: object + x-kubernetes-map-type: granular + nodePortOffset: + description: |- + nodePortOffset specifies the starting offset of the node ports. The port numbers go in ascending order with respect + to the replicas count. + NodePort service creation fails if the node port is not in the range supported by the Kubernetes API server. + The default Kubernetes Node Port range is `30000` - `32762`. + format: int32 + minimum: 0 + type: integer + servicePorts: + description: |- + servicePorts specify user-provided service port(s). + For Kafka with the nodePort type, this setting is only applied to Kafka bootstrap service. + 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 + sessionAffinity: + description: |- + sessionAffinity defines the Kubernetes session affinity. The valid options are `ClientIP` and `None`. `ClientIP` enables the client IP-based session affinity. + The default value is `None`. + More info: https://kubernetes.io/docs/reference/networking/virtual-ips/#session-affinity. + enum: + - ClientIP + - None + type: string + sessionAffinityConfig: + description: SessionAffinityConfig contains the configurations + of the 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 + required: + - host + - nodePortOffset + type: object + route: + description: route specifies the configuration to create a route + service in OpenShift. + properties: + advertisedURL: + description: |- + advertisedURL specifies the configuration for advertised listener per pod. It is only supported for MDS currently. + If it is enabled, instead of using internal endpoint, the MDS advertised listener for each broker will be + set to: `://-http-external.` where podId starts from `0` to `replicaCount -1`. + This is only recommended if you cannot add internal SANs to the TLS certificates for MDS and + the external DNS must be resolved inside the Kubernetes cluster. + This configuration will not take effect if MDS enabled dual listener setup. + properties: + enabled: + description: |- + enabled indicates whether to set the MDS advertised listener url with external endpoint for each broker. + Has no effect with Zookeeper, which will always create a listener per pod. + type: boolean + prefix: + description: |- + prefix specifies the broker prefix for MDS/Zookeeper advertised endpoint. + If not configured, it uses `b` as default prefix for MDS, such as `b#.domain` where `#` will start from `0` to `replicaCount -1`. + It uses 'zookeeper' as default prefix for Zookeeper in the same way. + minLength: 1 + type: string + required: + - enabled + type: object + annotations: + additionalProperties: + type: string + description: annotations is a map of string key and value + pairs. It specifies Kubernetes annotations for this service. + type: object + x-kubernetes-map-type: granular + domain: + description: domain specifies the domain name of the Confluent + component cluster. + minLength: 1 + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key and value pairs. + It specifies Kubernetes labels for this service. + type: object + x-kubernetes-map-type: granular + prefix: + description: |- + prefix specifies the component prefix when configured for the domain. + The default value is the name of the cluster. + minLength: 1 + type: string + wildcardPolicy: + description: |- + wildcardPolicy allows you to define a route that covers all hosts within a domain. Valid options are `Subdomain` and `None`. + The default value is `None`. + enum: + - Subdomain + - None + type: string + required: + - domain + type: object + type: + description: |- + type specifies the Kubernetes external service for the component. + Valid options are `loadBalancer`, `nodePort`, and `route`. + enum: + - loadBalancer + - nodePort + - route + minLength: 1 + type: string + required: + - type + type: object + headlessService: + description: headlessService specifies the configuration of the Kubernetes + headless service. + properties: + annotations: + additionalProperties: + type: string + description: |- + annotations is a map of string key and value pairs. + It specifies the annotations to be added to the CFK-created headless service. + These annotations are merged with the injectAnnotations and take precedence. + type: object + x-kubernetes-map-type: granular + labels: + additionalProperties: + type: string + description: |- + labels is a map of string key and value pairs. + It specifies the labels to be added to the CFK-created headless service. + These labels are merged with the injectLabels and take precedence. + type: object + x-kubernetes-map-type: granular + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses specifies the publishNotReadyAddresses field. + For Kafka, this value must be true. The default value is true. + type: boolean + type: object + id: + description: |- + id specifies the prefix used for this instance of Control Center + when multiple instances of Control Center co-exist. + format: int32 + type: integer + image: + description: |- + image specifies the application and the init docker image configurations. + A change to this setting will roll the cluster. + properties: + application: + description: |- + application is the Docker image name of the application. Specify + `//:`. + pattern: .+:.+ + type: string + init: + description: |- + init is the init-container name. Specify + `//:`. + pattern: .+:.+ + type: string + pullPolicy: + description: |- + pullPolicy is the policy for pulling images. Valid options are `Always`, `Never`, and `IfNotPresent`. + The default value is `IfNotPresent`. + enum: + - Always + - Never + - IfNotPresent + type: string + pullSecretRef: + description: |- + pullSecretRef references the secrets in the same namespace to be used for pulling images. + Image pull secrets are distinct from secrets because secrets + can be mounted in the pod, but image pull secrets are only accessed by `kubelet`. + More info: https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod + items: + type: string + type: array + required: + - application + - init + type: object + injectAnnotations: + additionalProperties: + type: string + description: |- + injectAnnotations are the annotations injected to the internal resources that CFK created. + The internal annotations are preserved and cannot be overridden. + For pod annotations, use `podTemplate.annotations`. + type: object + x-kubernetes-map-type: granular + injectLabels: + additionalProperties: + type: string + description: |- + injectLabels are the labels injected to the internal resources that CFK created. + The internal labels are preserved and cannot be overridden. + For pod labels, use `podTemplate.labels`. + type: object + x-kubernetes-map-type: granular + internalTopicReplicatorFactor: + description: internalTopicReplicationFactor specifies the replication + factor for internal topics. + format: int32 + type: integer + k8sClusterDomain: + description: |- + k8sClusterDomain specifies the configuration of the Kubernetes cluster domain. + The default is the `cluster.local` domain. + type: string + license: + description: license specifies the license configuration for the Confluent + Platform component. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + the license key is mounted. More info: + https://docs.confluent.io/operator/current/co-license.html#update-component-level-licenses + minLength: 1 + type: string + globalLicense: + description: globalLicense specifies whether the Confluent Platform + component shares the common global license. + type: boolean + secretRef: + description: |- + secretRef references the secret that provides the license for the Confluent Platform component. + More info: https://docs.confluent.io/operator/current/co-license.html#update-component-level-licenses + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + mail: + description: |- + mail specifies the settings that control the SMTP server and + account used when an alert triggers an email action. + properties: + authentication: + description: |- + authentication specifies the authentication for SMTP. SMP only supports basic authentication. + For other types of authentication, use the config overrides capability. + properties: + basic: + description: basic specifies the configuration for basic authentication. + properties: + debug: + description: debug enables the basic authentication debug + logs for JaaS configuration. + type: boolean + directoryPathInContainer: + description: |- + directoryPathInContainer allows to pass the basic credential through a directory path in the container. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + minLength: 1 + type: string + restrictedRoles: + description: |- + restrictedRoles specify the restricted roles on the server side only. + Changes will be only reflected in Control Center. + This configuration is ignored on the client side configuration. + items: + type: string + minItems: 1 + type: array + roles: + description: |- + roles specify the roles on the server side only. + This configuration is ignored on the client side configuration. + items: + type: string + type: array + secretRef: + description: |- + secretRef defines secret reference to pass the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauth: + description: oauth specifies the configuration for OAuth authentication. + properties: + configuration: + description: configuration specifies the OAuth server + settings. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name of + claim in token for identifying the groups of subject + in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect timeout + with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + directoryPathInContainer: + description: directoryPathInContainer allows to pass the + basic credential through a directory path in the container. + minLength: 1 + type: string + secretRef: + description: secretRef defines secret reference to pass + the required credentials. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - configuration + type: object + type: + description: type specifies the authentication scheme for + the REST API client. Valid options are `basic`, `oauth` + and `mtls`. + enum: + - basic + - mtls + - oauth + type: string + required: + - type + type: object + checkServerIdentity: + description: checkServerIdentity forces validation of server’s + certificate when using STARTTLS or SSL. + type: boolean + hostname: + description: hostname is the hostname of the outgoing SMTP server. + minLength: 1 + type: string + mailBounceAddress: + description: mailBounceAddress is the override for the `mailFrom` + config to send message. + minLength: 1 + type: string + mailFrom: + description: mailFrom is the originating address for emails sent + from the Control Center. + minLength: 1 + type: string + port: + description: port is the SMTP port open on the hostname. + format: int32 + type: integer + startTLSRequired: + description: startTLSRequired forces using STARTTLS. + type: boolean + required: + - hostname + type: object + metrics: + description: metrics specify the security settings for the metric + services. + properties: + authentication: + description: authentication specifies the authentication configuration + for the metrics. + properties: + type: + description: type specifies the metrics authentication method. + The valid option is `mtls`. + enum: + - mtls + type: string + required: + - type + type: object + prometheus: + description: prometheus specifies the configuration overrides + for the JMX-Prometheus exporter. + properties: + blacklist: + items: + type: string + type: array + rules: + items: + description: Rule defines the Prometheus Exporter rule override. + properties: + attrNameSnakeCase: + type: boolean + cache: + type: boolean + help: + minLength: 1 + type: string + labels: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: granular + name: + minLength: 1 + type: string + pattern: + minLength: 1 + type: string + type: + minLength: 1 + type: string + value: + minLength: 1 + type: string + valueFactor: + anyOf: + - type: integer + - type: string + default: 1 + 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: array + whitelist: + items: + type: string + type: array + type: object + tls: + description: tls specifies the TLS configuration for the metrics. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + monitoringKafkaClusters: + description: monitoringKafkaClusters specify the configurations for + the Kafka clusters that this Control Center monitors. + items: + description: MonitoringKafkaClusters defines the configuration of + the additional Kafka clusters the Control Center monitors. + properties: + authentication: + description: authentication defines the authentication for the + Kafka cluster. + properties: + jaasConfig: + description: jaasConfig specifies the Kafka client-side + JaaS configuration. + properties: + secretRef: + description: |- + secretRef references the secret containing the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + jaasConfigPassThrough: + description: jaasConfigPassThrough specifies another way + to provide the Kafka client-side JaaS configuration. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where required credentials are mounted. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + minLength: 1 + type: string + secretRef: + description: |- + secretRef references the secret containing the required credentials for authentication. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauthSettings: + description: |- + oauthSettings specifies the OAuth settings. + This needs to passed with the authentication type `oauth`. + properties: + audience: + description: audience specifies the audience claim in + the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected issuer + in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name of claim + in token for identifying the groups of subject in + the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect timeout + with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout with + IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry backoff + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim in + JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + oauthbearer: + description: |- + oauthbearer is the authentication mechanism to provider principals. + Only supported in RBAC deployment. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container + where the credential is mounted. + minLength: 1 + type: string + secretRef: + description: |- + secretRef specifies the name of the secret that contains the credential. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#bearer-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + type: + description: |- + type specifies the Kafka client authentication type. + Valid options are `plain`, `oauthbearer`, `digest`, `mtls` and `oauth`. + enum: + - plain + - oauthbearer + - digest + - mtls + - oauth + type: string + required: + - type + type: object + bootstrapEndpoint: + description: bootstrapEndpoint specifies the Kafka bootstrap + endpoint. + minLength: 1 + pattern: .+:[0-9]+ + type: string + discovery: + description: discovery specifies the capability to discover + the Kafka cluster. + properties: + name: + description: name is the name of the Confluent Platform + component cluster. + type: string + namespace: + description: |- + namespace is where the Confluent Platform component is running. + The default value is the namespace where CFK is running. + type: string + secretRef: + description: secretRef is the name of the secret used to + discover the Confluent Platform component. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - name + type: object + name: + description: name defines the Kafka cluster name. + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + tls: + description: tls defines the client-side TLS setting for the + Kafka cluster. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + required: + - name + type: object + type: array + mountedSecrets: + description: |- + mountedSecrets list the secrets injected to + the underlying statefulset configuration. The secret reference is mounted + in the default path `/mnt/secrets/`. The underlying resources + will follow the secret as a file configuration. + More info: https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets-as-files-from-a-pod. + A change to this setting will roll the cluster. + items: + description: |- + MountedSecrets provides a way to inject a custom secret to the underlying + statefulset. + properties: + keyItems: + description: keyItems are key and path names. + 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 + secretRef: + description: secretRef references the name of the secret. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + type: array + mountedVolumes: + description: |- + mountedVolumes list the custom volumes that need to be mounted into the + underlying statefulset. + A change to this setting will roll the cluster. + properties: + volumeMounts: + description: |- + volumeMounts specify the list of volume mounts for the pods in the + statefulset. + 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 + volumes: + description: |- + volumes specify the list of volumes that can be mounted into the pods + of statefulset. + 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 + 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: + 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 + 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 + 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: + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 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 + 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 + 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 + 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 + 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 + 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: + 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 + 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 + 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 + required: + - volumeMounts + - volumes + type: object + name: + description: name is the Control Center cluster name. + type: string + oneReplicaPerNode: + description: |- + oneReplicaPerNode controls whether to run 1 pod per node using the pod anti-affinity capability. + Enabling this configuration in an existing cluster will roll the cluster. + type: boolean + pdb: + description: |- + configures PodDisruptionBudget for the Confluent Platform component. + by default PDB is configured based on pre-detemined formula. + properties: + enabled: + description: enabled specifies whether the PodDisruptionBudget + is enabled + type: boolean + maxUnavailable: + description: maxUnavailable is the maximum number of pods that + can be unavailable during the disruption. + format: int32 + type: integer + required: + - enabled + type: object + podTemplate: + description: podTemplate specifies the statefulset pod template configuration. + properties: + affinity: + description: |- + affinity specifies a group of affinity scheduling rules. + More info: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity. + 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 + annotations: + additionalProperties: + type: string + description: |- + annotations is a map of string key and value pairs stored with the resource and + 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 + x-kubernetes-map-type: granular + envVars: + description: |- + envVars contain environment variables to be injected into containers. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container. + 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 + 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: + 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 + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + labels: + additionalProperties: + type: string + description: |- + labels is a map of string key and value pairs that can be used to organize and categorize + (scope and select) objects. + More info: http://kubernetes.io/docs/user-guide/labels. + type: object + x-kubernetes-map-type: granular + 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: + + + 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 + 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: + description: priorityClassName specifies the priority class for + the pod (if any). + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + probe: + description: probe contains the fields for standard Kubernetes + readiness/liveness probe configuration. + properties: + liveness: + description: |- + liveness configures the Kubernetes probe settings. The changes + will override the existing default configuration. + properties: + failureThreshold: + description: |- + failureThreshold is the minimum consecutive failures for the probe to be considered failed. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + initialDelaySeconds: + description: |- + initialDelaySeconds is the number of seconds after the container has started and before probes are initiated. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + path: + description: Path for the HTTP probe + type: string + periodSeconds: + description: |- + periodSeconds specifies how often to perform the probe. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + port: + description: Number of the port to access on the container + type: integer + successThreshold: + description: |- + successThreshold is the minimum consecutive successes for the probe to be considered successful after having failed. + The default values is `1`. Must be `1` for liveness and startup. The minimum value is `1`. + format: int32 + type: integer + timeoutSeconds: + description: |- + timeoutSeconds is the number of seconds after which the probe times out. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + type: object + readiness: + description: |- + readiness configures the Kubernetes probe setting. The changes + will override the existing default configuration. + properties: + failureThreshold: + description: |- + failureThreshold is the minimum consecutive failures for the probe to be considered failed. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + initialDelaySeconds: + description: |- + initialDelaySeconds is the number of seconds after the container has started and before probes are initiated. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + path: + description: Path for the HTTP probe + type: string + periodSeconds: + description: |- + periodSeconds specifies how often to perform the probe. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + port: + description: Number of the port to access on the container + type: integer + successThreshold: + description: |- + successThreshold is the minimum consecutive successes for the probe to be considered successful after having failed. + The default values is `1`. Must be `1` for liveness and startup. The minimum value is `1`. + format: int32 + type: integer + timeoutSeconds: + description: |- + timeoutSeconds is the number of seconds after which the probe times out. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + type: object + type: object + resources: + description: resources describe the compute resource requirements. + 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 + 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: + + + 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: + description: |- + ServiceAccountName is the name of the service account used to run this pod. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account. + type: string + terminationGracePeriodSeconds: + description: terminationGracePeriodSeconds is the grace period + before the pod is deleted. + format: int64 + type: integer + tolerations: + description: |- + tolerations specify the pods to schedule onto the nodes with matching taints, using + the triple `` and the matching operator ``. + 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 + topologySpreadConstraints: + description: |- + topologySpreadConstraints describe how a group of pods ought to spread across topology domains. Scheduler will + schedule pods based on 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 + 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 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. + + + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). + 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 + type: object + replicas: + description: |- + replicas is the desired number of replicas. + A change to this setting will roll the cluster. + format: int32 + type: integer + storageClass: + description: storageClass references the user-provided storage class. + properties: + name: + description: name is the storage class name. + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - name + type: object + telemetry: + description: telemetry specifies the Confluent telemetry reporter + configuration. + properties: + global: + description: |- + global allows disabling telemetry configuration. + If CFK is deployed with telemetry, this field is only + used to disable telemetry. The default value is `true` if + telemetry is enabled at the global level. + type: boolean + type: object + tls: + description: tls specifies the TLS configurations. + properties: + autoGeneratedCerts: + description: |- + autoGeneratedCerts specifies that the certificates are auto-generated based on + the CA key pair provided. + type: boolean + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + fips: + description: |- + fips specifies the configuration of FIPS compliant Bouncy Castle type Java Keystores for the cp component's + TLS settings. TLS Secrets must have the keys keystore.bcfks, truststore.bcfks, and jksPassword.txt + properties: + enabled: + description: enabled specifies whether to enable the FIPS + configuration for cp components. + type: boolean + required: + - enabled + type: object + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing the + JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + required: + - dataVolumeCapacity + - image + type: object + status: + description: status defines the observed state of the Control Center cluster. + properties: + arbitraryData: + description: arbitraryData is the map for any arbitrary data associated + with this Confluent component. + x-kubernetes-preserve-unknown-fields: true + authorizationType: + description: authorizationType is the authorization type for this + Confluent component. + type: string + clusterName: + description: clusterName is the name of the Confluent Platform component + cluster. + type: string + clusterNamespace: + description: clusterNamespace is the namespace where the Confluent + Platform component cluster is running. + type: string + conditions: + description: conditions specify the latest available observations + of the current state. + items: + description: Condition represent the latest available observations + of the current state. + properties: + lastProbeTime: + description: lastProbeTime shows the last time the condition + was evaluated. + format: date-time + type: string + lastTransitionTime: + description: lastTransitionTime shows the last time the condition + was transitioned from one status to another. + format: date-time + type: string + message: + description: message shows a human-readable message with details + about the transition. + type: string + reason: + description: reason shows the reason for the last transition + of the condition. + type: string + status: + description: status shows the status of the condition, one of + `True`, `False`, or `Unknown`. + type: string + type: + description: type shows the condition type. + type: string + type: object + type: array + controlCenterName: + description: name is the name of the Control Center cluster. + type: string + currentReplicas: + description: currentReplicas is the number of currently running replicas. + format: int32 + type: integer + id: + description: id is the identifier of the Control Center cluster. + format: int32 + type: integer + internalSecrets: + description: |- + internalSecrets are internal secrets created + by CFK for this Confluent component. + items: + type: string + type: array + internalTopicNames: + description: internalTopicNames are the topics used by the component + for internal use. + items: + type: string + type: array + kafka: + description: kafka is the Kafka client side status for the Control + Center cluster. + properties: + authenticationType: + description: authenticationType describes the authentication method + for the Kafka cluster. + type: string + bootstrapEndpoint: + description: bootstrapEndpoint specifies the Kafka bootstrap endpoint. + type: string + tls: + description: tls indicates whether TLS is enabled for the Kafka + dependency. + type: boolean + type: object + observedGeneration: + description: observedGeneration is the most recent generation observed + for this Confluent component. + format: int64 + type: integer + operatorVersion: + description: operatorVersion is the internal version of CFK. + type: string + phase: + description: |- + phase describes the state of the Confluent Platform component. This can either be 'PROVISIONING' + or 'RUNNING' + 'PROVISIONING' means the Confluent Platform component is currently getting deployed and not ready yet. + 'RUNNING' means the Confluent Platform component has been successfully deployed. + type: string + rbac: + description: rbac contains the RBAC-related status when RBAC is enabled. + properties: + clusterID: + description: clusterID specifies the id of the cluster. + type: string + internalRolebindings: + description: internalRolebindings specifies the internal rolebindings. + items: + type: string + type: array + type: object + readyReplicas: + description: readyReplicas is the number of currently ready replicas. + format: int32 + type: integer + replicas: + description: replicas is the number of replicas. + format: int32 + type: integer + restConfig: + description: restConfig is the REST API configuration of the Control + Center cluster. + properties: + advertisedExternalEndpoints: + description: advertisedExternalEndpoints specifies other advertised + endpoints used, especially for Kafka. + items: + type: string + type: array + authenticationType: + description: authenticationType shows the authentication type + configured by the listener. + type: string + externalAccessType: + description: externalAccessType shows the external access type + used for the listener. + type: string + externalEndpoint: + description: externalEndpoint specifies the external endpoint + to connect to the Confluent component cluster. + type: string + internalEndpoint: + description: internalEndpoint specifies the internal endpoint + to connect to the Confluent component cluster. + type: string + tls: + description: tls shows whether TLS is configured for the listener. + type: boolean + type: object + selector: + description: |- + selector gets the label selector of the child pod. + The Horizontal Pod Autoscaler(HPA) will scale using the label selector of the child pod. + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + scale: + specReplicasPath: .spec.replicas + statusReplicasPath: .status.replicas + status: {} diff --git a/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_kafkarestclasses.yaml b/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_kafkarestclasses.yaml new file mode 100644 index 0000000000..4eb8d72fc6 --- /dev/null +++ b/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_kafkarestclasses.yaml @@ -0,0 +1,557 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: kafkarestclasses.platform.confluent.io +spec: + group: platform.confluent.io + names: + categories: + - all + - confluent-platform + - confluent + kind: KafkaRestClass + listKind: KafkaRestClassList + plural: kafkarestclasses + shortNames: + - krc + - kafkarestclass + singular: kafkarestclass + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: KafkaRestClass is the schema for the Kafka REST 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 defines the desired state of the KafkaRestClass. + properties: + kafkaClusterRef: + description: kafkaClusterRef specifies the name of the Kafka cluster. + properties: + name: + description: name specifies the name of the Confluent Platform + component cluster. + type: string + namespace: + description: namespace specifies the namespace where the Confluent + Platform component cluster is running. + type: string + required: + - name + type: object + kafkaRest: + description: kafkaRest specifies the Kafka REST API configuration. + properties: + authentication: + description: authentication specifies the REST API authentication + mechanism. + properties: + basic: + description: basic specifies the basic authentication settings + for the REST API client. + properties: + debug: + description: debug enables the basic authentication debug + logs for JaaS configuration. + type: boolean + directoryPathInContainer: + description: |- + directoryPathInContainer allows to pass the basic credential through a directory path in the container. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + minLength: 1 + type: string + restrictedRoles: + description: |- + restrictedRoles specify the restricted roles on the server side only. + Changes will be only reflected in Control Center. + This configuration is ignored on the client side configuration. + items: + type: string + minItems: 1 + type: array + roles: + description: |- + roles specify the roles on the server side only. + This configuration is ignored on the client side configuration. + items: + type: string + type: array + secretRef: + description: |- + secretRef defines secret reference to pass the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + bearer: + description: bearer specifies the bearer authentication settings + for the REST API client. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container + where the credential is mounted. + minLength: 1 + type: string + secretRef: + description: |- + secretRef specifies the name of the secret that contains the credential. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#bearer-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauth: + description: oauth specifies the OAuth authentication settings + for the REST API client. + properties: + configuration: + description: configuration specifies the OAuth server + settings. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name of + claim in token for identifying the groups of subject + in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect timeout + with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + directoryPathInContainer: + description: directoryPathInContainer allows to pass the + basic credential through a directory path in the container. + minLength: 1 + type: string + secretRef: + description: secretRef defines secret reference to pass + the required credentials. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - configuration + type: object + type: + description: type specifies the REST API authentication type. + Valid options are `basic`, `bearer`, `mtls` and `oauth`. + enum: + - basic + - bearer + - mtls + - oauth + type: string + required: + - type + type: object + endpoint: + description: endpoint specifies where Confluent REST API is running. + minLength: 1 + pattern: ^https?://.* + type: string + kafkaClusterID: + description: |- + kafkaClusterID specifies the id of Kafka cluster. + It takes precedence over using the Kafka REST API to get the cluster id. + minLength: 1 + type: string + tls: + description: "tls specifies the custom TLS structure for the application + resources,\n\t// e.g. connector, topic, schema, of the Confluent + Platform components.\n\t// +optional" + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer contains the directory path in the container where + `keystore.jks`, `truststore.jks`, `jksPassword.txt` keys are mounted. + minLength: 1 + type: string + jksPassword: + description: jksPassword specifies the secret name that contains + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef specifies the secret name that contains the certificates. + More info about certificates key/value format: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + type: object + secondaryKafkaClusterRef: + description: secondaryKafkaClusterRef specifies the name of the secondary + Kafka cluster when using centralized RBAC. + properties: + name: + description: name specifies the name of the Confluent Platform + component cluster. + type: string + namespace: + description: namespace specifies the namespace where the Confluent + Platform component cluster is running. + type: string + required: + - name + type: object + secondaryKafkaRest: + description: secondaryKafkaRest specifies the secondary Kafka REST + API configuration when using centralized RBAC. + properties: + authentication: + description: authentication specifies the REST API authentication + mechanism. + properties: + basic: + description: basic specifies the basic authentication settings + for the REST API client. + properties: + debug: + description: debug enables the basic authentication debug + logs for JaaS configuration. + type: boolean + directoryPathInContainer: + description: |- + directoryPathInContainer allows to pass the basic credential through a directory path in the container. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + minLength: 1 + type: string + restrictedRoles: + description: |- + restrictedRoles specify the restricted roles on the server side only. + Changes will be only reflected in Control Center. + This configuration is ignored on the client side configuration. + items: + type: string + minItems: 1 + type: array + roles: + description: |- + roles specify the roles on the server side only. + This configuration is ignored on the client side configuration. + items: + type: string + type: array + secretRef: + description: |- + secretRef defines secret reference to pass the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + bearer: + description: bearer specifies the bearer authentication settings + for the REST API client. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container + where the credential is mounted. + minLength: 1 + type: string + secretRef: + description: |- + secretRef specifies the name of the secret that contains the credential. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#bearer-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauth: + description: oauth specifies the OAuth authentication settings + for the REST API client. + properties: + configuration: + description: configuration specifies the OAuth server + settings. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name of + claim in token for identifying the groups of subject + in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect timeout + with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + directoryPathInContainer: + description: directoryPathInContainer allows to pass the + basic credential through a directory path in the container. + minLength: 1 + type: string + secretRef: + description: secretRef defines secret reference to pass + the required credentials. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - configuration + type: object + type: + description: type specifies the REST API authentication type. + Valid options are `basic`, `bearer`, `mtls` and `oauth`. + enum: + - basic + - bearer + - mtls + - oauth + type: string + required: + - type + type: object + endpoint: + description: endpoint specifies where Confluent REST API is running. + minLength: 1 + pattern: ^https?://.* + type: string + kafkaClusterID: + description: |- + kafkaClusterID specifies the id of Kafka cluster. + It takes precedence over using the Kafka REST API to get the cluster id. + minLength: 1 + type: string + tls: + description: "tls specifies the custom TLS structure for the application + resources,\n\t// e.g. connector, topic, schema, of the Confluent + Platform components.\n\t// +optional" + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer contains the directory path in the container where + `keystore.jks`, `truststore.jks`, `jksPassword.txt` keys are mounted. + minLength: 1 + type: string + jksPassword: + description: jksPassword specifies the secret name that contains + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef specifies the secret name that contains the certificates. + More info about certificates key/value format: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + type: object + type: object + status: + description: status defines the observed state of the KafkaRestClass. + properties: + conditions: + description: conditions are the latest available observed state of + the kafkaRestClass. + items: + description: Condition represent the latest available observations + of the current state. + properties: + lastProbeTime: + description: lastProbeTime shows the last time the condition + was evaluated. + format: date-time + type: string + lastTransitionTime: + description: lastTransitionTime shows the last time the condition + was transitioned from one status to another. + format: date-time + type: string + message: + description: message shows a human-readable message with details + about the transition. + type: string + reason: + description: reason shows the reason for the last transition + of the condition. + type: string + status: + description: status shows the status of the condition, one of + `True`, `False`, or `Unknown`. + type: string + type: + description: type shows the condition type. + type: string + type: object + type: array + endpoint: + description: endpoint specifies the Kafka REST API / MDS endpoint. + type: string + kafkaClusterID: + description: |- + kafkaClusterID specifies the id of the Kafka cluster. + If using centralized RBAC and kafkaRestClass is for the secondary Kafka cluster, it will be the cluster id of the secondary Kafka cluster. + type: string + observedGeneration: + description: observedGeneration is the most recent generation observed + for this Confluent component. + format: int64 + type: integer + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_kafkarestproxies.yaml b/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_kafkarestproxies.yaml new file mode 100644 index 0000000000..2311a61180 --- /dev/null +++ b/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_kafkarestproxies.yaml @@ -0,0 +1,5834 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: kafkarestproxies.platform.confluent.io +spec: + group: platform.confluent.io + names: + categories: + - all + - confluent-platform + - confluent + kind: KafkaRestProxy + listKind: KafkaRestProxyList + plural: kafkarestproxies + shortNames: + - kafkarestproxy + - krp + singular: kafkarestproxy + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.replicas + name: Replicas + type: string + - jsonPath: .status.readyReplicas + name: Ready + type: string + - jsonPath: .status.phase + name: Status + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.kafka.bootstrapEndpoint + name: Kafka + priority: 1 + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: KafkaRestProxy is the schema for the Kafka REST Proxy 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 defines the desired state of the KafkaRestProxy cluster. + properties: + authentication: + description: authentication specifies the authentication configurations + for the KafkaRestProxy cluster. + properties: + basic: + description: basic specifies the configuration for basic authentication. + properties: + debug: + description: debug enables the basic authentication debug + logs for JaaS configuration. + type: boolean + directoryPathInContainer: + description: |- + directoryPathInContainer allows to pass the basic credential through a directory path in the container. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + minLength: 1 + type: string + restrictedRoles: + description: |- + restrictedRoles specify the restricted roles on the server side only. + Changes will be only reflected in Control Center. + This configuration is ignored on the client side configuration. + items: + type: string + minItems: 1 + type: array + roles: + description: |- + roles specify the roles on the server side only. + This configuration is ignored on the client side configuration. + items: + type: string + type: array + secretRef: + description: |- + secretRef defines secret reference to pass the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauth: + description: oauth specifies the configuration for OAuth authentication. + properties: + configuration: + description: configuration specifies the OAuth server settings. + properties: + audience: + description: audience specifies the audience claim in + the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected issuer + in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name of claim + in token for identifying the groups of subject in the + JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect timeout + with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout with + IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry backoff + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff with + IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim in JWT + to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + directoryPathInContainer: + description: directoryPathInContainer allows to pass the basic + credential through a directory path in the container. + minLength: 1 + type: string + secretRef: + description: secretRef defines secret reference to pass the + required credentials. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - configuration + type: object + type: + description: type specifies the authentication scheme for the + REST API server. Valid options are `basic`, `oauth` and `mtls`. + enum: + - basic + - mtls + - oauth + type: string + required: + - type + type: object + authorization: + description: authorization specifies the RBAC configuration for the + KafkaRestProxy cluster. + properties: + kafkaRestClassRef: + description: |- + kafkaRestClassRef references the KafkaRestClass + which specifies the Kafka REST API connection configuration. + properties: + name: + description: name specifies the name of the KafkaRestClass + application resource. + minLength: 1 + type: string + namespace: + description: namespace specifies the namespace of the KafkaRestClass. + type: string + required: + - name + type: object + type: + description: type specifies the client-side authorization type. + The valid option is `rbac`. + enum: + - rbac + type: string + required: + - type + type: object + configOverrides: + description: |- + configOverrides specifies the configs to override the server, JVM, Log4j properties for the KafkaRestProxy cluster. + A change will roll the cluster. + properties: + jvm: + description: |- + jvm is a list of JVM configuration supported by the Confluent Platform component. + This will either add or update the existing configuration. + items: + type: string + type: array + log4j: + description: |- + log4j is a list of Log4J configuration supported by the Confluent Platform component. + This will either add or update the existing configuration. + items: + type: string + type: array + server: + description: |- + server is a list of server configuration supported by the Confluent Platform component. + This will either add or update existing configuration. + items: + type: string + type: array + type: object + dependencies: + description: dependencies specifies the dependency configurations + for Kafka, Interceptor, Schema Registry, and the MDS. + properties: + interceptor: + description: interceptor specifies the interceptor dependency + configuration. + properties: + configs: + description: |- + configs describe the configurations for the Confluent Platform interceptor. + The config override feature can be used to pass the configuration settings. + items: + type: string + type: array + consumer: + description: |- + consumer specifies the consumer configuration for the interceptor. If not + configured, it uses the Kafka dependency configuration. + properties: + authentication: + description: authentication defines the authentication + for the Kafka cluster. + properties: + jaasConfig: + description: jaasConfig specifies the Kafka client-side + JaaS configuration. + properties: + secretRef: + description: |- + secretRef references the secret containing the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + jaasConfigPassThrough: + description: jaasConfigPassThrough specifies another + way to provide the Kafka client-side JaaS configuration. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where required credentials are mounted. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + minLength: 1 + type: string + secretRef: + description: |- + secretRef references the secret containing the required credentials for authentication. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauthSettings: + description: |- + oauthSettings specifies the OAuth settings. + This needs to passed with the authentication type `oauth`. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name + of claim in token for identifying the groups + of subject in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect + timeout with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + oauthbearer: + description: |- + oauthbearer is the authentication mechanism to provider principals. + Only supported in RBAC deployment. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container + where the credential is mounted. + minLength: 1 + type: string + secretRef: + description: |- + secretRef specifies the name of the secret that contains the credential. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#bearer-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + type: + description: |- + type specifies the Kafka client authentication type. + Valid options are `plain`, `oauthbearer`, `digest`, `mtls` and `oauth`. + enum: + - plain + - oauthbearer + - digest + - mtls + - oauth + type: string + required: + - type + type: object + bootstrapEndpoint: + description: bootstrapEndpoint specifies the Kafka bootstrap + endpoint. + minLength: 1 + pattern: .+:[0-9]+ + type: string + discovery: + description: discovery specifies the capability to discover + the Kafka cluster. + properties: + name: + description: name is the name of the Confluent Platform + component cluster. + type: string + namespace: + description: |- + namespace is where the Confluent Platform component is running. + The default value is the namespace where CFK is running. + type: string + secretRef: + description: secretRef is the name of the secret used + to discover the Confluent Platform component. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - name + type: object + tls: + description: tls defines the client-side TLS setting for + the Kafka cluster. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + enabled: + description: enabled indicates whether the Confluent Platform + interceptor is enabled or disabled. + type: boolean + producer: + description: |- + producer specifies the producer configuration for the interceptor. If not + configured, it uses the Kafka dependency configuration. + properties: + authentication: + description: authentication defines the authentication + for the Kafka cluster. + properties: + jaasConfig: + description: jaasConfig specifies the Kafka client-side + JaaS configuration. + properties: + secretRef: + description: |- + secretRef references the secret containing the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + jaasConfigPassThrough: + description: jaasConfigPassThrough specifies another + way to provide the Kafka client-side JaaS configuration. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where required credentials are mounted. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + minLength: 1 + type: string + secretRef: + description: |- + secretRef references the secret containing the required credentials for authentication. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauthSettings: + description: |- + oauthSettings specifies the OAuth settings. + This needs to passed with the authentication type `oauth`. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name + of claim in token for identifying the groups + of subject in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect + timeout with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + oauthbearer: + description: |- + oauthbearer is the authentication mechanism to provider principals. + Only supported in RBAC deployment. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container + where the credential is mounted. + minLength: 1 + type: string + secretRef: + description: |- + secretRef specifies the name of the secret that contains the credential. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#bearer-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + type: + description: |- + type specifies the Kafka client authentication type. + Valid options are `plain`, `oauthbearer`, `digest`, `mtls` and `oauth`. + enum: + - plain + - oauthbearer + - digest + - mtls + - oauth + type: string + required: + - type + type: object + bootstrapEndpoint: + description: bootstrapEndpoint specifies the Kafka bootstrap + endpoint. + minLength: 1 + pattern: .+:[0-9]+ + type: string + discovery: + description: discovery specifies the capability to discover + the Kafka cluster. + properties: + name: + description: name is the name of the Confluent Platform + component cluster. + type: string + namespace: + description: |- + namespace is where the Confluent Platform component is running. + The default value is the namespace where CFK is running. + type: string + secretRef: + description: secretRef is the name of the secret used + to discover the Confluent Platform component. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - name + type: object + tls: + description: tls defines the client-side TLS setting for + the Kafka cluster. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + publishMs: + type: integer + required: + - enabled + type: object + kafka: + description: kafka specifies the Kafka dependency configuration. + properties: + authentication: + description: authentication defines the authentication for + the Kafka cluster. + properties: + jaasConfig: + description: jaasConfig specifies the Kafka client-side + JaaS configuration. + properties: + secretRef: + description: |- + secretRef references the secret containing the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + jaasConfigPassThrough: + description: jaasConfigPassThrough specifies another way + to provide the Kafka client-side JaaS configuration. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where required credentials are mounted. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + minLength: 1 + type: string + secretRef: + description: |- + secretRef references the secret containing the required credentials for authentication. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauthSettings: + description: |- + oauthSettings specifies the OAuth settings. + This needs to passed with the authentication type `oauth`. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name of + claim in token for identifying the groups of subject + in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect timeout + with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + oauthbearer: + description: |- + oauthbearer is the authentication mechanism to provider principals. + Only supported in RBAC deployment. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container + where the credential is mounted. + minLength: 1 + type: string + secretRef: + description: |- + secretRef specifies the name of the secret that contains the credential. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#bearer-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + type: + description: |- + type specifies the Kafka client authentication type. + Valid options are `plain`, `oauthbearer`, `digest`, `mtls` and `oauth`. + enum: + - plain + - oauthbearer + - digest + - mtls + - oauth + type: string + required: + - type + type: object + bootstrapEndpoint: + description: bootstrapEndpoint specifies the Kafka bootstrap + endpoint. + minLength: 1 + pattern: .+:[0-9]+ + type: string + discovery: + description: discovery specifies the capability to discover + the Kafka cluster. + properties: + name: + description: name is the name of the Confluent Platform + component cluster. + type: string + namespace: + description: |- + namespace is where the Confluent Platform component is running. + The default value is the namespace where CFK is running. + type: string + secretRef: + description: secretRef is the name of the secret used + to discover the Confluent Platform component. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - name + type: object + tls: + description: tls defines the client-side TLS setting for the + Kafka cluster. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + mds: + description: mds specifies the MDS dependencies configuration. + properties: + authentication: + description: authentication specifies the client side authentication + configuration for the MDS. + properties: + bearer: + description: bearer specifies the bearer authentication + settings. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container + where the credential is mounted. + minLength: 1 + type: string + secretRef: + description: |- + secretRef specifies the name of the secret that contains the credential. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#bearer-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauth: + description: oauth specifies the OAuth authentication + settings. + properties: + configuration: + description: configuration specifies the OAuth server + settings. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name + of claim in token for identifying the groups + of subject in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect + timeout with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + directoryPathInContainer: + description: directoryPathInContainer allows to pass + the basic credential through a directory path in + the container. + minLength: 1 + type: string + secretRef: + description: secretRef defines secret reference to + pass the required credentials. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - configuration + type: object + type: + description: type specifies the authentication method + for the MDS. The valid option is `bearer`, `oauth`. + enum: + - bearer + - oauth + type: string + required: + - type + type: object + endpoint: + description: endpoint specifies the MDS endpoint. + minLength: 1 + pattern: ^https?://.* + type: string + ssoProtocol: + description: sso protocol, valid options are ldap and oidc. + enum: + - ldap + - oidc + type: string + tls: + description: ClientTLSConfig specifies the TLS configuration + for the Confluent component (dependencies, listeners). + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + tokenKeyPair: + description: tokenKeyPair specifies the token keypair to configure + the MDS. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer defines the directory path in the container + where the MDS token key pair are mounted. + minLength: 1 + type: string + encryptedTokenKey: + description: |- + EncryptedTokenKey boolean value indicating whether the tokenKeypair(private used for signing) is encrypted using a passphrase. If true, cfk + operator will look for a file named mdsTokenKeyPassphrase.txt containing key value pair + mdsTokenKeyPassphrase=. Relevant only for mds server. Ignored if set for a client configuration. + type: boolean + secretRef: + description: secretRef references the name of the secret + that contains the MDS token key pair. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + required: + - authentication + - endpoint + - tokenKeyPair + type: object + schemaRegistry: + description: schemaRegistry specifies the Schema Registry dependency + configuration. + properties: + authentication: + description: authentication specifies the authentication for + the Schema Registry cluster. + properties: + basic: + description: basic specifies the configuration for basic + authentication. + properties: + debug: + description: debug enables the basic authentication + debug logs for JaaS configuration. + type: boolean + directoryPathInContainer: + description: |- + directoryPathInContainer allows to pass the basic credential through a directory path in the container. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + minLength: 1 + type: string + restrictedRoles: + description: |- + restrictedRoles specify the restricted roles on the server side only. + Changes will be only reflected in Control Center. + This configuration is ignored on the client side configuration. + items: + type: string + minItems: 1 + type: array + roles: + description: |- + roles specify the roles on the server side only. + This configuration is ignored on the client side configuration. + items: + type: string + type: array + secretRef: + description: |- + secretRef defines secret reference to pass the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauth: + description: oauth specifies the configuration for OAuth + authentication. + properties: + configuration: + description: configuration specifies the OAuth server + settings. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name + of claim in token for identifying the groups + of subject in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect + timeout with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + directoryPathInContainer: + description: directoryPathInContainer allows to pass + the basic credential through a directory path in + the container. + minLength: 1 + type: string + secretRef: + description: secretRef defines secret reference to + pass the required credentials. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - configuration + type: object + type: + description: type specifies the authentication scheme + for the REST API client. Valid options are `basic`, + `oauth` and `mtls`. + enum: + - basic + - mtls + - oauth + type: string + required: + - type + type: object + tls: + description: tls defines the client-side TLS setting for the + Schema Registry cluster. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + url: + description: url specifies the URL endpoint of the Schema + Registry cluster. + minLength: 1 + pattern: ^https?://.* + type: string + required: + - url + type: object + type: object + externalAccess: + description: externalAccess specifies the external access configuration. + properties: + loadBalancer: + description: loadBalancer specifies the configuration to create + a Kubernetes load balancer service. + properties: + advertisedURL: + description: |- + advertisedURL specifies the configuration for advertised listener per pod. It is only supported for MDS currently. + If it is enabled, instead of using internal endpoint, the MDS advertised listener for each broker will be + set to: `://.` where podId starts from `0` to `replicaCount -1`. + This is only recommended if you cannot add internal SANs to the TLS certificates for MDS and + the external DNS must be resolved inside the Kubernetes cluster. + This configuration will not take effect if MDS enabled dual listener setup. + properties: + enabled: + description: |- + enabled indicates whether to set the MDS advertised listener url with external endpoint for each broker. + Has no effect with Zookeeper, which will always create a listener per pod. + type: boolean + prefix: + description: |- + prefix specifies the broker prefix for MDS/Zookeeper advertised endpoint. + If not configured, it uses `b` as default prefix for MDS, such as `b#.domain` where `#` will start from `0` to `replicaCount -1`. + It uses 'zookeeper' as default prefix for Zookeeper in the same way. + minLength: 1 + type: string + required: + - enabled + type: object + annotations: + additionalProperties: + type: string + description: annotations is a map of string key and value + pairs. It specifies Kubernetes annotations for this service. + type: object + x-kubernetes-map-type: granular + domain: + description: domain is the domain name of the component cluster. + minLength: 1 + type: string + externalTrafficPolicy: + description: externalTrafficPolicy specifies the external + traffic policy for the service. Valid options are `Local` + and `Cluster`. + enum: + - Local + - Cluster + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key and value pairs. + It specifies Kubernetes labels for this service. + type: object + x-kubernetes-map-type: granular + loadBalancerSourceRanges: + description: loadBalancerSourceRanges specify the source ranges. + items: + type: string + type: array + port: + description: |- + port specifies the external port for the client consumption. + If not configured, the same internal/external port is configured for the component. + Information about the port can be retrieved through the status API. + format: int32 + type: integer + prefix: + description: |- + prefix specify the prefix for the given domain. + The default value is the name of the cluster. + minLength: 1 + type: string + servicePorts: + description: servicePorts specify the user-provided service + port(s). + 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 + sessionAffinity: + description: |- + sessionAffinity defines the Kubernetes session affinity. The valid options are `ClientIP` and `None`. `ClientIP` enables the client IP-based session affinity. + The default value is `None`. + More info: https://kubernetes.io/docs/reference/networking/virtual-ips/#session-affinity. + enum: + - ClientIP + - None + type: string + sessionAffinityConfig: + description: SessionAffinityConfig contains the configurations + of the 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 + required: + - domain + type: object + nodePort: + description: nodePort specifies the configuration to create a + Kubernetes node port service. + properties: + advertisedURL: + description: |- + advertisedURL specifies the configuration for advertised listener per pod. It is only supported for MDS currently. + If it is enabled, instead of using internal endpoint, the MDS advertised listener for each broker will be + set to `://:, where`podId` starts from `0` to `replicaCount - 1`. + This is only recommended if you cannot add internal SANs to the TLS certificates for MDS and + the external DNS must be resolved inside the Kubernetes cluster. + properties: + enabled: + description: |- + enabled indicates whether to set the MDS advertised listener url with external endpoint for each broker. + Has no effect with Zookeeper, which will always create a listener per pod. + type: boolean + prefix: + description: |- + prefix specifies the broker prefix for MDS/Zookeeper advertised endpoint. + If not configured, it uses `b` as default prefix for MDS, such as `b#.domain` where `#` will start from `0` to `replicaCount -1`. + It uses 'zookeeper' as default prefix for Zookeeper in the same way. + minLength: 1 + type: string + required: + - enabled + type: object + annotations: + additionalProperties: + type: string + description: annotations is a map of string key and value + pairs. It specifies Kubernetes annotations for this service. + type: object + x-kubernetes-map-type: granular + externalTrafficPolicy: + description: |- + externalTrafficPolicy specifies the external traffic policy for the service. + Valid options are `Local` and `Cluster`. + enum: + - Local + - Cluster + type: string + host: + description: host defines the host name of the cluster. + minLength: 1 + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key and value pairs. + It specifies Kubernetes labels for this service. + type: object + x-kubernetes-map-type: granular + nodePortOffset: + description: |- + nodePortOffset specifies the starting offset of the node ports. The port numbers go in ascending order with respect + to the replicas count. + NodePort service creation fails if the node port is not in the range supported by the Kubernetes API server. + The default Kubernetes Node Port range is `30000` - `32762`. + format: int32 + minimum: 0 + type: integer + servicePorts: + description: |- + servicePorts specify user-provided service port(s). + For Kafka with the nodePort type, this setting is only applied to Kafka bootstrap service. + 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 + sessionAffinity: + description: |- + sessionAffinity defines the Kubernetes session affinity. The valid options are `ClientIP` and `None`. `ClientIP` enables the client IP-based session affinity. + The default value is `None`. + More info: https://kubernetes.io/docs/reference/networking/virtual-ips/#session-affinity. + enum: + - ClientIP + - None + type: string + sessionAffinityConfig: + description: SessionAffinityConfig contains the configurations + of the 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 + required: + - host + - nodePortOffset + type: object + route: + description: route specifies the configuration to create a route + service in OpenShift. + properties: + advertisedURL: + description: |- + advertisedURL specifies the configuration for advertised listener per pod. It is only supported for MDS currently. + If it is enabled, instead of using internal endpoint, the MDS advertised listener for each broker will be + set to: `://-http-external.` where podId starts from `0` to `replicaCount -1`. + This is only recommended if you cannot add internal SANs to the TLS certificates for MDS and + the external DNS must be resolved inside the Kubernetes cluster. + This configuration will not take effect if MDS enabled dual listener setup. + properties: + enabled: + description: |- + enabled indicates whether to set the MDS advertised listener url with external endpoint for each broker. + Has no effect with Zookeeper, which will always create a listener per pod. + type: boolean + prefix: + description: |- + prefix specifies the broker prefix for MDS/Zookeeper advertised endpoint. + If not configured, it uses `b` as default prefix for MDS, such as `b#.domain` where `#` will start from `0` to `replicaCount -1`. + It uses 'zookeeper' as default prefix for Zookeeper in the same way. + minLength: 1 + type: string + required: + - enabled + type: object + annotations: + additionalProperties: + type: string + description: annotations is a map of string key and value + pairs. It specifies Kubernetes annotations for this service. + type: object + x-kubernetes-map-type: granular + domain: + description: domain specifies the domain name of the Confluent + component cluster. + minLength: 1 + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key and value pairs. + It specifies Kubernetes labels for this service. + type: object + x-kubernetes-map-type: granular + prefix: + description: |- + prefix specifies the component prefix when configured for the domain. + The default value is the name of the cluster. + minLength: 1 + type: string + wildcardPolicy: + description: |- + wildcardPolicy allows you to define a route that covers all hosts within a domain. Valid options are `Subdomain` and `None`. + The default value is `None`. + enum: + - Subdomain + - None + type: string + required: + - domain + type: object + type: + description: |- + type specifies the Kubernetes external service for the component. + Valid options are `loadBalancer`, `nodePort`, and `route`. + enum: + - loadBalancer + - nodePort + - route + minLength: 1 + type: string + required: + - type + type: object + headlessService: + description: headlessService specifies the configuration of the Kubernetes + headless service. + properties: + annotations: + additionalProperties: + type: string + description: |- + annotations is a map of string key and value pairs. + It specifies the annotations to be added to the CFK-created headless service. + These annotations are merged with the injectAnnotations and take precedence. + type: object + x-kubernetes-map-type: granular + labels: + additionalProperties: + type: string + description: |- + labels is a map of string key and value pairs. + It specifies the labels to be added to the CFK-created headless service. + These labels are merged with the injectLabels and take precedence. + type: object + x-kubernetes-map-type: granular + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses specifies the publishNotReadyAddresses field. + For Kafka, this value must be true. The default value is true. + type: boolean + type: object + image: + description: |- + image specifies the application and the init docker image configurations. + A change to this setting will roll the cluster. + properties: + application: + description: |- + application is the Docker image name of the application. Specify + `//:`. + pattern: .+:.+ + type: string + init: + description: |- + init is the init-container name. Specify + `//:`. + pattern: .+:.+ + type: string + pullPolicy: + description: |- + pullPolicy is the policy for pulling images. Valid options are `Always`, `Never`, and `IfNotPresent`. + The default value is `IfNotPresent`. + enum: + - Always + - Never + - IfNotPresent + type: string + pullSecretRef: + description: |- + pullSecretRef references the secrets in the same namespace to be used for pulling images. + Image pull secrets are distinct from secrets because secrets + can be mounted in the pod, but image pull secrets are only accessed by `kubelet`. + More info: https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod + items: + type: string + type: array + required: + - application + - init + type: object + injectAnnotations: + additionalProperties: + type: string + description: |- + injectAnnotations are the annotations injected to the internal resources that CFK created. + The internal annotations are preserved and cannot be overridden. + For pod annotations, use `podTemplate.annotations`. + type: object + x-kubernetes-map-type: granular + injectLabels: + additionalProperties: + type: string + description: |- + injectLabels are the labels injected to the internal resources that CFK created. + The internal labels are preserved and cannot be overridden. + For pod labels, use `podTemplate.labels`. + type: object + x-kubernetes-map-type: granular + k8sClusterDomain: + description: |- + k8sClusterDomain specifies the configuration of the Kubernetes cluster domain. + The default is the `cluster.local` domain. + type: string + license: + description: license specifies the license configuration for the Confluent + Platform component. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + the license key is mounted. More info: + https://docs.confluent.io/operator/current/co-license.html#update-component-level-licenses + minLength: 1 + type: string + globalLicense: + description: globalLicense specifies whether the Confluent Platform + component shares the common global license. + type: boolean + secretRef: + description: |- + secretRef references the secret that provides the license for the Confluent Platform component. + More info: https://docs.confluent.io/operator/current/co-license.html#update-component-level-licenses + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + metrics: + description: metrics specify the security settings for the metric + services. + properties: + authentication: + description: authentication specifies the authentication configuration + for the metrics. + properties: + type: + description: type specifies the metrics authentication method. + The valid option is `mtls`. + enum: + - mtls + type: string + required: + - type + type: object + prometheus: + description: prometheus specifies the configuration overrides + for the JMX-Prometheus exporter. + properties: + blacklist: + items: + type: string + type: array + rules: + items: + description: Rule defines the Prometheus Exporter rule override. + properties: + attrNameSnakeCase: + type: boolean + cache: + type: boolean + help: + minLength: 1 + type: string + labels: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: granular + name: + minLength: 1 + type: string + pattern: + minLength: 1 + type: string + type: + minLength: 1 + type: string + value: + minLength: 1 + type: string + valueFactor: + anyOf: + - type: integer + - type: string + default: 1 + 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: array + whitelist: + items: + type: string + type: array + type: object + tls: + description: tls specifies the TLS configuration for the metrics. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + mountedSecrets: + description: |- + mountedSecrets list the secrets injected to + the underlying statefulset configuration. The secret reference is mounted + in the default path `/mnt/secrets/`. The underlying resources + will follow the secret as a file configuration. + More info: https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets-as-files-from-a-pod. + A change to this setting will roll the cluster. + items: + description: |- + MountedSecrets provides a way to inject a custom secret to the underlying + statefulset. + properties: + keyItems: + description: keyItems are key and path names. + 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 + secretRef: + description: secretRef references the name of the secret. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + type: array + mountedVolumes: + description: |- + mountedVolumes list the custom volumes that need to be mounted into the + underlying statefulset. + A change to this setting will roll the cluster. + properties: + volumeMounts: + description: |- + volumeMounts specify the list of volume mounts for the pods in the + statefulset. + 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 + volumes: + description: |- + volumes specify the list of volumes that can be mounted into the pods + of statefulset. + 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 + 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: + 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 + 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 + 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: + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 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 + 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 + 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 + 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 + 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 + 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: + 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 + 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 + 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 + required: + - volumeMounts + - volumes + type: object + oneReplicaPerNode: + description: |- + oneReplicaPerNode controls whether to run 1 pod per node using the pod anti-affinity capability. + Enabling this configuration in an existing cluster will roll the cluster. + type: boolean + pdb: + description: |- + configures PodDisruptionBudget for the Confluent Platform component. + by default PDB is configured based on pre-detemined formula. + properties: + enabled: + description: enabled specifies whether the PodDisruptionBudget + is enabled + type: boolean + maxUnavailable: + description: maxUnavailable is the maximum number of pods that + can be unavailable during the disruption. + format: int32 + type: integer + required: + - enabled + type: object + podTemplate: + description: podTemplate specifies the statefulset pod template configuration. + properties: + affinity: + description: |- + affinity specifies a group of affinity scheduling rules. + More info: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity. + 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 + annotations: + additionalProperties: + type: string + description: |- + annotations is a map of string key and value pairs stored with the resource and + 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 + x-kubernetes-map-type: granular + envVars: + description: |- + envVars contain environment variables to be injected into containers. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container. + 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 + 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: + 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 + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + labels: + additionalProperties: + type: string + description: |- + labels is a map of string key and value pairs that can be used to organize and categorize + (scope and select) objects. + More info: http://kubernetes.io/docs/user-guide/labels. + type: object + x-kubernetes-map-type: granular + 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: + + + 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 + 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: + description: priorityClassName specifies the priority class for + the pod (if any). + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + probe: + description: probe contains the fields for standard Kubernetes + readiness/liveness probe configuration. + properties: + liveness: + description: |- + liveness configures the Kubernetes probe settings. The changes + will override the existing default configuration. + properties: + failureThreshold: + description: |- + failureThreshold is the minimum consecutive failures for the probe to be considered failed. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + initialDelaySeconds: + description: |- + initialDelaySeconds is the number of seconds after the container has started and before probes are initiated. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + path: + description: Path for the HTTP probe + type: string + periodSeconds: + description: |- + periodSeconds specifies how often to perform the probe. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + port: + description: Number of the port to access on the container + type: integer + successThreshold: + description: |- + successThreshold is the minimum consecutive successes for the probe to be considered successful after having failed. + The default values is `1`. Must be `1` for liveness and startup. The minimum value is `1`. + format: int32 + type: integer + timeoutSeconds: + description: |- + timeoutSeconds is the number of seconds after which the probe times out. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + type: object + readiness: + description: |- + readiness configures the Kubernetes probe setting. The changes + will override the existing default configuration. + properties: + failureThreshold: + description: |- + failureThreshold is the minimum consecutive failures for the probe to be considered failed. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + initialDelaySeconds: + description: |- + initialDelaySeconds is the number of seconds after the container has started and before probes are initiated. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + path: + description: Path for the HTTP probe + type: string + periodSeconds: + description: |- + periodSeconds specifies how often to perform the probe. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + port: + description: Number of the port to access on the container + type: integer + successThreshold: + description: |- + successThreshold is the minimum consecutive successes for the probe to be considered successful after having failed. + The default values is `1`. Must be `1` for liveness and startup. The minimum value is `1`. + format: int32 + type: integer + timeoutSeconds: + description: |- + timeoutSeconds is the number of seconds after which the probe times out. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + type: object + type: object + resources: + description: resources describe the compute resource requirements. + 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 + 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: + + + 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: + description: |- + ServiceAccountName is the name of the service account used to run this pod. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account. + type: string + terminationGracePeriodSeconds: + description: terminationGracePeriodSeconds is the grace period + before the pod is deleted. + format: int64 + type: integer + tolerations: + description: |- + tolerations specify the pods to schedule onto the nodes with matching taints, using + the triple `` and the matching operator ``. + 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 + topologySpreadConstraints: + description: |- + topologySpreadConstraints describe how a group of pods ought to spread across topology domains. Scheduler will + schedule pods based on 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 + 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 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. + + + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). + 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 + type: object + replicas: + description: |- + replicas is the desired number of replicas. + A change to this setting will roll the cluster. + format: int32 + type: integer + telemetry: + description: telemetry specifies the Confluent telemetry reporter + configuration. + properties: + global: + description: |- + global allows disabling telemetry configuration. + If CFK is deployed with telemetry, this field is only + used to disable telemetry. The default value is `true` if + telemetry is enabled at the global level. + type: boolean + type: object + tls: + description: tls specifies the TLS configurations for the KafkaRestProxy + cluster. + properties: + autoGeneratedCerts: + description: |- + autoGeneratedCerts specifies that the certificates are auto-generated based on + the CA key pair provided. + type: boolean + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + fips: + description: |- + fips specifies the configuration of FIPS compliant Bouncy Castle type Java Keystores for the cp component's + TLS settings. TLS Secrets must have the keys keystore.bcfks, truststore.bcfks, and jksPassword.txt + properties: + enabled: + description: enabled specifies whether to enable the FIPS + configuration for cp components. + type: boolean + required: + - enabled + type: object + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing the + JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + required: + - image + type: object + status: + description: status defines the observed state of the KafkaRestProxy cluster. + properties: + arbitraryData: + description: arbitraryData is the map for any arbitrary data associated + with this Confluent component. + x-kubernetes-preserve-unknown-fields: true + authorizationType: + description: authorizationType is the authorization type for this + Confluent component. + type: string + clusterName: + description: clusterName is the name of the Confluent Platform component + cluster. + type: string + clusterNamespace: + description: clusterNamespace is the namespace where the Confluent + Platform component cluster is running. + type: string + conditions: + description: conditions specify the latest available observations + of the current state. + items: + description: Condition represent the latest available observations + of the current state. + properties: + lastProbeTime: + description: lastProbeTime shows the last time the condition + was evaluated. + format: date-time + type: string + lastTransitionTime: + description: lastTransitionTime shows the last time the condition + was transitioned from one status to another. + format: date-time + type: string + message: + description: message shows a human-readable message with details + about the transition. + type: string + reason: + description: reason shows the reason for the last transition + of the condition. + type: string + status: + description: status shows the status of the condition, one of + `True`, `False`, or `Unknown`. + type: string + type: + description: type shows the condition type. + type: string + type: object + type: array + currentReplicas: + description: currentReplicas is the number of currently running replicas. + format: int32 + type: integer + internalSecrets: + description: |- + internalSecrets are internal secrets created + by CFK for this Confluent component. + items: + type: string + type: array + internalTopicNames: + description: internalTopicNames are the topics used by the component + for internal use. + items: + type: string + type: array + kafka: + description: kafka is the Kafka client side status for the KafkaRestProxy + cluster. + properties: + authenticationType: + description: authenticationType describes the authentication method + for the Kafka cluster. + type: string + bootstrapEndpoint: + description: bootstrapEndpoint specifies the Kafka bootstrap endpoint. + type: string + tls: + description: tls indicates whether TLS is enabled for the Kafka + dependency. + type: boolean + type: object + metricPrefix: + description: metricPrefix is the prefix for the JMX metric of the + KafkaRestProxy. + type: string + observedGeneration: + description: observedGeneration is the most recent generation observed + for this Confluent component. + format: int64 + type: integer + operatorVersion: + description: operatorVersion is the internal version of CFK. + type: string + phase: + description: |- + phase describes the state of the Confluent Platform component. This can either be 'PROVISIONING' + or 'RUNNING' + 'PROVISIONING' means the Confluent Platform component is currently getting deployed and not ready yet. + 'RUNNING' means the Confluent Platform component has been successfully deployed. + type: string + rbac: + description: rbac contains the RBAC-related status when RBAC is enabled. + properties: + clusterID: + description: clusterID specifies the id of the cluster. + type: string + internalRolebindings: + description: internalRolebindings specifies the internal rolebindings. + items: + type: string + type: array + type: object + readyReplicas: + description: readyReplicas is the number of currently ready replicas. + format: int32 + type: integer + replicas: + description: replicas is the number of replicas. + format: int32 + type: integer + restConfig: + description: restConfig is the REST API configuration of the KafkaRestProxy. + properties: + advertisedExternalEndpoints: + description: advertisedExternalEndpoints specifies other advertised + endpoints used, especially for Kafka. + items: + type: string + type: array + authenticationType: + description: authenticationType shows the authentication type + configured by the listener. + type: string + externalAccessType: + description: externalAccessType shows the external access type + used for the listener. + type: string + externalEndpoint: + description: externalEndpoint specifies the external endpoint + to connect to the Confluent component cluster. + type: string + internalEndpoint: + description: internalEndpoint specifies the internal endpoint + to connect to the Confluent component cluster. + type: string + tls: + description: tls shows whether TLS is configured for the listener. + type: boolean + type: object + selector: + description: |- + selector gets the label selector of the child pod. + The Horizontal Pod Autoscaler(HPA) will scale using the label selector of the child pod. + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.replicas + statusReplicasPath: .status.replicas + status: {} diff --git a/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_kafkas.yaml b/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_kafkas.yaml new file mode 100644 index 0000000000..ad422466d9 --- /dev/null +++ b/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_kafkas.yaml @@ -0,0 +1,10948 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: kafkas.platform.confluent.io +spec: + group: platform.confluent.io + names: + categories: + - all + - confluent-platform + - confluent + kind: Kafka + listKind: KafkaList + plural: kafkas + shortNames: + - kafka + - broker + singular: kafka + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.replicas + name: Replicas + type: string + - jsonPath: .status.readyReplicas + name: Ready + type: string + - jsonPath: .status.phase + name: Status + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.zookeeperConnect + name: Zookeeper + priority: 1 + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: Kafka is the schema for the Kafka 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 defines the desired state of the Kafka cluster. + properties: + authorization: + description: authorization specifies the authorization configuration. + properties: + superUsers: + description: |- + superUsers specify the super users to give the admin privilege on the Kafka Cluster. + This list takes the format as `User:` + items: + type: string + type: array + type: + description: type specifies the authorization type. The valid + options are `rbac` and `simple`. + enum: + - rbac + - simple + type: string + required: + - type + type: object + configOverrides: + description: configOverrides specifies the configs to override the + server, JVM, Log4j properties for the Kafka cluster. + properties: + jvm: + description: |- + jvm is a list of JVM configuration supported by the Confluent Platform component. + This will either add or update the existing configuration. + items: + type: string + type: array + log4j: + description: |- + log4j is a list of Log4J configuration supported by the Confluent Platform component. + This will either add or update the existing configuration. + items: + type: string + type: array + server: + description: |- + server is a list of server configuration supported by the Confluent Platform component. + This will either add or update existing configuration. + items: + type: string + type: array + type: object + dataVolumeCapacity: + anyOf: + - type: integer + - type: string + description: dataVolumeCapacity specifies the persistent volume capacity + for the Kafka cluster. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + dependencies: + description: dependencies specify the Kafka dependencies, such as + Zookeeper and centralized MDS. + properties: + kRaftController: + description: |- + kRaftController specifies the dependency configuration for the KRaftController cluster. + You cannot configure both zookeeper and kRaftController dependencies. + properties: + clusterRef: + description: clusterRef specifies the name of the KRaft Controller + cluster. + properties: + name: + description: name specifies the name of the Confluent + Platform component cluster. + type: string + namespace: + description: namespace specifies the namespace where the + Confluent Platform component cluster is running. + type: string + required: + - name + type: object + controllerListener: + description: |- + controllerListener specifies the controller listener which must match + the controller listener on the referenced KRaft Controller cluster. + properties: + authentication: + description: authentication specifies the authentication + configuration for the listener. + properties: + jaasConfig: + description: |- + jaasConfig specifies the JaaS configuration. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + properties: + secretRef: + description: |- + secretRef references the secret containing the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + jaasConfigPassThrough: + description: |- + jaasConfigPassThrough specifies another way to provide JaaS configuration. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where required credentials are mounted. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + minLength: 1 + type: string + secretRef: + description: |- + secretRef references the secret containing the required credentials for authentication. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauthSettings: + description: |- + oauthSettings specifies the OAuth settings. + This needs to passed with the authentication type `oauth`. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name + of claim in token for identifying the groups + of subject in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect + timeout with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + principalMappingRules: + items: + type: string + type: array + type: + description: |- + type specifies the Kafka or Zookeeper authentication type. + Valid options are `plain`, `digest`, `mtls`, `ldap` & `oauth`. + enum: + - plain + - digest + - mtls + - ldap + - oauth + type: string + required: + - type + type: object + tls: + description: tls specifies the TLS configuration for the + listener. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + type: object + kafkaRest: + description: kafkaRest provides the REST client configuration + for the MDS when RBAC is enabled. + properties: + authentication: + description: authentication specifies the Kafka authentication + for Kafka REST API or MDS. + properties: + bearer: + description: |- + bearer is the authentication mechanism to provide principals. + Only supported in RBAC deployment. + Required when authentication type is set to `bearer`. + This field will be deprecated, please configure oauthbearer instead. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container + where the credential is mounted. + minLength: 1 + type: string + secretRef: + description: |- + secretRef specifies the name of the secret that contains the credential. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#bearer-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + jaasConfig: + description: jaasConfig specifies the Kafka client-side + JaaS configuration. + properties: + secretRef: + description: |- + secretRef references the secret containing the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + jaasConfigPassThrough: + description: jaasConfigPassThrough specifies another way + to provide the Kafka client-side JaaS configuration. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where required credentials are mounted. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + minLength: 1 + type: string + secretRef: + description: |- + secretRef references the secret containing the required credentials for authentication. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauthSettings: + description: |- + oauthSettings specifies the OAuth settings. + This needs to passed with the authentication type `oauth`. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name of + claim in token for identifying the groups of subject + in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect timeout + with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + oauthbearer: + description: |- + oauthbearer is the authentication mechanism to provide principals. + Only supported in RBAC deployment. + Required when authentication type is set to `oauthbearer`. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container + where the credential is mounted. + minLength: 1 + type: string + secretRef: + description: |- + secretRef specifies the name of the secret that contains the credential. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#bearer-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + type: + description: |- + type specifies the Kafka client authentication type. + Valid options are `plain`, `oauthbearer`, `bearer`, `mtls` and `oauth`. + enum: + - plain + - oauthbearer + - bearer + - mtls + - oauth + type: string + required: + - type + type: object + bootstrapEndpoint: + description: |- + bootstrapEndpoint specifies Kafka bootstrap endpoint for the admin REST API. It is not needed when RBAC is enabled. + If not configured, then default to the replication listener endpoint. + minLength: 1 + pattern: .+:[0-9]+ + type: string + endpoint: + description: endpoint specifies the custom MDS http|s endpoint. + Not required to configure in most of the scenarios. + minLength: 1 + pattern: ^https?://.* + type: string + tls: + description: tls specifies the client-side TLS configuration + to connect to the Kafka REST API. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + mds: + description: mds specifies the dependency configuration for the + primary MDS. + properties: + endpoint: + description: endpoint defines the primary Kafka cluster boostrap + endpoint. + minLength: 1 + pattern: ^https?://.* + type: string + kafka: + description: kafka specifies the dependency configuration + for Kafka cluster. + properties: + authentication: + description: authentication defines the authentication + for the Kafka cluster. + properties: + jaasConfig: + description: jaasConfig specifies the Kafka client-side + JaaS configuration. + properties: + secretRef: + description: |- + secretRef references the secret containing the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + jaasConfigPassThrough: + description: jaasConfigPassThrough specifies another + way to provide the Kafka client-side JaaS configuration. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where required credentials are mounted. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + minLength: 1 + type: string + secretRef: + description: |- + secretRef references the secret containing the required credentials for authentication. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauthSettings: + description: |- + oauthSettings specifies the OAuth settings. + This needs to passed with the authentication type `oauth`. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name + of claim in token for identifying the groups + of subject in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect + timeout with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + oauthbearer: + description: |- + oauthbearer is the authentication mechanism to provider principals. + Only supported in RBAC deployment. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container + where the credential is mounted. + minLength: 1 + type: string + secretRef: + description: |- + secretRef specifies the name of the secret that contains the credential. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#bearer-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + type: + description: |- + type specifies the Kafka client authentication type. + Valid options are `plain`, `oauthbearer`, `digest`, `mtls` and `oauth`. + enum: + - plain + - oauthbearer + - digest + - mtls + - oauth + type: string + required: + - type + type: object + bootstrapEndpoint: + description: bootstrapEndpoint specifies the Kafka bootstrap + endpoint. + minLength: 1 + pattern: .+:[0-9]+ + type: string + discovery: + description: discovery specifies the capability to discover + the Kafka cluster. + properties: + name: + description: name is the name of the Confluent Platform + component cluster. + type: string + namespace: + description: |- + namespace is where the Confluent Platform component is running. + The default value is the namespace where CFK is running. + type: string + secretRef: + description: secretRef is the name of the secret used + to discover the Confluent Platform component. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - name + type: object + tls: + description: tls defines the client-side TLS setting for + the Kafka cluster. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + tls: + description: tls specifies the TLS configuration for the primary + MDS. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + tokenKeyPair: + description: tokenKeyPair specifies the token key pair for + the MDS. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer defines the directory path in the container + where the MDS token key pair are mounted. + minLength: 1 + type: string + encryptedTokenKey: + description: |- + EncryptedTokenKey boolean value indicating whether the tokenKeypair(private used for signing) is encrypted using a passphrase. If true, cfk + operator will look for a file named mdsTokenKeyPassphrase.txt containing key value pair + mdsTokenKeyPassphrase=. Relevant only for mds server. Ignored if set for a client configuration. + type: boolean + secretRef: + description: secretRef references the name of the secret + that contains the MDS token key pair. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + required: + - endpoint + - kafka + - tokenKeyPair + type: object + schemaRegistry: + description: schemaRegistry specifies the dependency configuration + for the Schema Registry cluster. + properties: + authentication: + description: authentication specifies the authentication for + the Schema Registry cluster. + properties: + basic: + description: basic specifies the configuration for basic + authentication. + properties: + debug: + description: debug enables the basic authentication + debug logs for JaaS configuration. + type: boolean + directoryPathInContainer: + description: |- + directoryPathInContainer allows to pass the basic credential through a directory path in the container. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + minLength: 1 + type: string + restrictedRoles: + description: |- + restrictedRoles specify the restricted roles on the server side only. + Changes will be only reflected in Control Center. + This configuration is ignored on the client side configuration. + items: + type: string + minItems: 1 + type: array + roles: + description: |- + roles specify the roles on the server side only. + This configuration is ignored on the client side configuration. + items: + type: string + type: array + secretRef: + description: |- + secretRef defines secret reference to pass the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauth: + description: oauth specifies the configuration for OAuth + authentication. + properties: + configuration: + description: configuration specifies the OAuth server + settings. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name + of claim in token for identifying the groups + of subject in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect + timeout with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + directoryPathInContainer: + description: directoryPathInContainer allows to pass + the basic credential through a directory path in + the container. + minLength: 1 + type: string + secretRef: + description: secretRef defines secret reference to + pass the required credentials. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - configuration + type: object + type: + description: type specifies the authentication scheme + for the REST API client. Valid options are `basic`, + `oauth` and `mtls`. + enum: + - basic + - mtls + - oauth + type: string + required: + - type + type: object + tls: + description: tls defines the client-side TLS setting for the + Schema Registry cluster. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + url: + description: url specifies the URL endpoint of the Schema + Registry cluster. + minLength: 1 + pattern: ^https?://.* + type: string + required: + - url + type: object + zookeeper: + description: |- + zookeeper specifies the dependency configuration for Zookeeper. + You cannot configure both zookeeper and kRaftController dependencies. + properties: + authentication: + description: authentication specifies the client side authentication + configuration of Zookeeper for Kafka cluster. + properties: + jaasConfig: + description: jaasConfig specifies the Kafka client-side + JaaS configuration. + properties: + secretRef: + description: |- + secretRef references the secret containing the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + jaasConfigPassThrough: + description: jaasConfigPassThrough specifies another way + to provide the Kafka client-side JaaS configuration. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where required credentials are mounted. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + minLength: 1 + type: string + secretRef: + description: |- + secretRef references the secret containing the required credentials for authentication. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauthSettings: + description: |- + oauthSettings specifies the OAuth settings. + This needs to passed with the authentication type `oauth`. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name of + claim in token for identifying the groups of subject + in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect timeout + with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + oauthbearer: + description: |- + oauthbearer is the authentication mechanism to provider principals. + Only supported in RBAC deployment. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container + where the credential is mounted. + minLength: 1 + type: string + secretRef: + description: |- + secretRef specifies the name of the secret that contains the credential. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#bearer-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + type: + description: |- + type specifies the Kafka client authentication type. + Valid options are `plain`, `oauthbearer`, `digest`, `mtls` and `oauth`. + enum: + - plain + - oauthbearer + - digest + - mtls + - oauth + type: string + required: + - type + type: object + discovery: + description: discovery specifies the capability to discover + the Zookeeper cluster. + properties: + name: + description: name is the name of the Confluent Platform + component cluster. + type: string + namespace: + description: |- + namespace is where the Confluent Platform component is running. + The default value is the namespace where CFK is running. + type: string + secretRef: + description: secretRef is the name of the secret used + to discover the Confluent Platform component. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - name + type: object + endpoint: + description: endpoint specifies the Zookeeper endpoint. + minLength: 1 + pattern: .+:[0-9]+ + type: string + tls: + description: tls specifies the TLS configuration of Zookeeper + for Kafka cluster. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + type: object + fips: + description: |- + fips specifies the configuration of FIPS compliant Bouncy Castle type Java Keystores for the Kafka cluster's + TLS settings. TLS Secrets must have the keys keystore.bcfks, truststore.bcfks, and jksPassword.txt + properties: + enabled: + description: enabled specifies whether to enable the FIPS configuration + for cp components. + type: boolean + required: + - enabled + type: object + headlessService: + description: headlessService specifies the configuration of the Kubernetes + headless service. + properties: + annotations: + additionalProperties: + type: string + description: |- + annotations is a map of string key and value pairs. + It specifies the annotations to be added to the CFK-created headless service. + These annotations are merged with the injectAnnotations and take precedence. + type: object + x-kubernetes-map-type: granular + labels: + additionalProperties: + type: string + description: |- + labels is a map of string key and value pairs. + It specifies the labels to be added to the CFK-created headless service. + These labels are merged with the injectLabels and take precedence. + type: object + x-kubernetes-map-type: granular + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses specifies the publishNotReadyAddresses field. + For Kafka, this value must be true. The default value is true. + type: boolean + type: object + identityProvider: + description: |- + identityProvider specifies the identity provider configuration. + It is only required for the Kafka authentication type `ldap`. + When the MDS is enabled, this property is ignored, and + the LDAP configuration in `spec.services.mds.provider` will be used. + properties: + ldap: + description: ldap defines the LDAP service configuration. + properties: + address: + description: address defines the LDAP server address. + type: string + authentication: + description: LdapAuthentication specifies the LDAP authentication + configuration. + properties: + simple: + description: simple specifies simple authentication configuration + for the LDAP. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer defines the directory path in the container + where the credentials are mounted. + minLength: 1 + type: string + secretRef: + description: secretRef references the name of the + secret that contains the credentials. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + type: + description: type defines the authentication method for + LDAP. Valid options are `simple` and `mtls`. + enum: + - simple + - mtls + type: string + required: + - type + type: object + configurations: + description: configurations defines the LDAP configurations + for Confluent RBAC. + properties: + groupMemberAttribute: + description: groupMemberAttribute specifies the LDAP group + member attribute. + minLength: 1 + type: string + groupMemberAttributePattern: + description: groupMemberAttributePattern specifies the + regular expression pattern for the LDAP group member + attribute. + minLength: 1 + type: string + groupNameAttribute: + description: groupNameAttribute specifies the LDAP group + name attribute. + minLength: 1 + type: string + groupObjectClass: + description: groupObjectClass specifies the LDAP group + object class. + minLength: 1 + type: string + groupSearchBase: + description: groupSearchBase specifies the LDAP search + base for the group-based search. + minLength: 1 + type: string + groupSearchFilter: + description: groupSearchFilter specifies the LDAP search + filter for the group-based search. + minLength: 1 + type: string + groupSearchScope: + description: groupSearchScope specifies the LDAP search + scope for the group-based search. + format: int32 + type: integer + userMemberOfAttributePattern: + description: userMemberOfAttributePattern specifies the + regular expression pattern for the LDAP user member + attribute. + minLength: 1 + type: string + userNameAttribute: + description: userNameAttribute specifies the LDAP username + attribute. + minLength: 1 + type: string + userObjectClass: + description: userObjectClass specifies the LDAP user object + class. + minLength: 1 + type: string + userSearchBase: + description: userSearchBase specifies the LDAP search + base for the user-based search. + minLength: 1 + type: string + userSearchFilter: + description: userSearchFilter specifies the LDAP search + filter for the user-based search. + minLength: 1 + type: string + userSearchScope: + description: userSearchScope specifies the LDAP search + scope for the user-based search. + format: int32 + type: integer + type: object + tls: + description: tls specifies the TLS configuration for the LDAP. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + required: + - address + - authentication + - configurations + type: object + oauth: + description: oauth defines the OAuth service configuration. + properties: + configurations: + description: configurations defines the OAuth configurations. + properties: + audience: + description: audience specifies the audience claim in + the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected issuer + in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name of claim + in token for identifying the groups of subject in the + JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect timeout + with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout with + IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry backoff + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff with + IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim in JWT + to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + tls: + description: tls specifies the TLS configuration for the OAuth + IDP. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + required: + - configurations + type: object + oidc: + description: |- + this field has been superseded with sso field + oidc defines the OIDC service configuration. + properties: + clientCredentials: + description: clientCredentials define the IDP clientID and + clientSecret. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer defines the directory path in the container + where the credentials are mounted. + minLength: 1 + type: string + secretRef: + description: secretRef references the name of the secret + that contains the credentials. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + configurations: + description: configurations defines the OIDC configurations. + properties: + audience: + description: audience specifies the audience claim in + the JWT payload. + minLength: 1 + type: string + authorizeBaseEndpointUri: + description: authorizeBaseEndpointUri specifies the base + uri for authorize endpoint. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name of claim + in token for identifying the groups of subject in the + JWT payload. + minLength: 1 + type: string + groupsClaimScope: + description: |- + groupsClaimScope specifies additional scope needed for the token to contain groups claim (field). + Leave this field empty (or null) if id token always contains the claims identified as groups. + minLength: 1 + type: string + issuer: + description: |- + issuer specifies the authorization server's URL. + This value should match the issuer claim ("iss") in id tokens issued by Authorization Server? + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + refreshToken: + description: refreshToken specifies whether offline_access + scope should be requested in the authorization URI. + type: boolean + sessionMaxTimeout: + description: sessionMaxTimeout specifies the maximum expiration + time for a user's session. + format: int32 + type: integer + sessionTokenExpiry: + description: sessionTokenExpiry specifies the validity + of cookie issued by Confluent. + format: int32 + type: integer + subClaimName: + description: subClaimName specifies name of claim in JWT + to use for the subject. + minLength: 1 + type: string + tokenBaseEndpointUri: + description: tokenBaseEndpointUri specifies the base uri + for token endpoint. + minLength: 1 + type: string + required: + - authorizeBaseEndpointUri + - issuer + - jwksEndpointUri + - refreshToken + - tokenBaseEndpointUri + type: object + enabled: + default: true + description: |- + enabled specifies whether the SSO is enabled. + default is true. + type: boolean + required: + - clientCredentials + - configurations + type: object + sso: + description: sso defines the SSO service configuration. + properties: + clientCredentials: + description: clientCredentials define the IDP clientID and + clientSecret. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer defines the directory path in the container + where the credentials are mounted. + minLength: 1 + type: string + secretRef: + description: secretRef references the name of the secret + that contains the credentials. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + configurations: + description: configurations defines the OIDC configurations. + properties: + audience: + description: audience specifies the audience claim in + the JWT payload. + minLength: 1 + type: string + authorizeBaseEndpointUri: + description: authorizeBaseEndpointUri specifies the base + uri for authorize endpoint. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name of claim + in token for identifying the groups of subject in the + JWT payload. + minLength: 1 + type: string + groupsClaimScope: + description: |- + groupsClaimScope specifies additional scope needed for the token to contain groups claim (field). + Leave this field empty (or null) if id token always contains the claims identified as groups. + minLength: 1 + type: string + issuer: + description: |- + issuer specifies the authorization server's URL. + This value should match the issuer claim ("iss") in id tokens issued by Authorization Server? + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + refreshToken: + description: refreshToken specifies whether offline_access + scope should be requested in the authorization URI. + type: boolean + sessionMaxTimeout: + description: sessionMaxTimeout specifies the maximum expiration + time for a user's session. + format: int32 + type: integer + sessionTokenExpiry: + description: sessionTokenExpiry specifies the validity + of cookie issued by Confluent. + format: int32 + type: integer + subClaimName: + description: subClaimName specifies name of claim in JWT + to use for the subject. + minLength: 1 + type: string + tokenBaseEndpointUri: + description: tokenBaseEndpointUri specifies the base uri + for token endpoint. + minLength: 1 + type: string + required: + - authorizeBaseEndpointUri + - issuer + - jwksEndpointUri + - refreshToken + - tokenBaseEndpointUri + type: object + enabled: + default: true + description: |- + enabled specifies whether the SSO is enabled. + default is true. + type: boolean + required: + - clientCredentials + - configurations + type: object + type: + description: This field has been deprecated and its value will + be ignored if set. + type: string + type: object + image: + description: |- + image specifies the application and the init docker image configurations. + A change to this setting will roll the cluster. + properties: + application: + description: |- + application is the Docker image name of the application. Specify + `//:`. + pattern: .+:.+ + type: string + init: + description: |- + init is the init-container name. Specify + `//:`. + pattern: .+:.+ + type: string + pullPolicy: + description: |- + pullPolicy is the policy for pulling images. Valid options are `Always`, `Never`, and `IfNotPresent`. + The default value is `IfNotPresent`. + enum: + - Always + - Never + - IfNotPresent + type: string + pullSecretRef: + description: |- + pullSecretRef references the secrets in the same namespace to be used for pulling images. + Image pull secrets are distinct from secrets because secrets + can be mounted in the pod, but image pull secrets are only accessed by `kubelet`. + More info: https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod + items: + type: string + type: array + required: + - application + - init + type: object + injectAnnotations: + additionalProperties: + type: string + description: |- + injectAnnotations are the annotations injected to the internal resources that CFK created. + The internal annotations are preserved and cannot be overridden. + For pod annotations, use `podTemplate.annotations`. + type: object + x-kubernetes-map-type: granular + injectLabels: + additionalProperties: + type: string + description: |- + injectLabels are the labels injected to the internal resources that CFK created. + The internal labels are preserved and cannot be overridden. + For pod labels, use `podTemplate.labels`. + type: object + x-kubernetes-map-type: granular + k8sClusterDomain: + description: |- + k8sClusterDomain specifies the configuration of the Kubernetes cluster domain. + The default is the `cluster.local` domain. + type: string + license: + description: license specifies the license configuration for the Confluent + Platform component. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + the license key is mounted. More info: + https://docs.confluent.io/operator/current/co-license.html#update-component-level-licenses + minLength: 1 + type: string + globalLicense: + description: globalLicense specifies whether the Confluent Platform + component shares the common global license. + type: boolean + secretRef: + description: |- + secretRef references the secret that provides the license for the Confluent Platform component. + More info: https://docs.confluent.io/operator/current/co-license.html#update-component-level-licenses + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + listeners: + description: listeners specify the listeners configurations. + properties: + custom: + description: custom defines the list of KafkaCustomListener. + items: + description: KafkaCustomListener defines the Kafka custom listener. + properties: + authentication: + description: authentication specifies the authentication + configuration for the listener. + properties: + jaasConfig: + description: |- + jaasConfig specifies the JaaS configuration. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + properties: + secretRef: + description: |- + secretRef references the secret containing the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + jaasConfigPassThrough: + description: |- + jaasConfigPassThrough specifies another way to provide JaaS configuration. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where required credentials are mounted. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + minLength: 1 + type: string + secretRef: + description: |- + secretRef references the secret containing the required credentials for authentication. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauthSettings: + description: |- + oauthSettings specifies the OAuth settings. + This needs to passed with the authentication type `oauth`. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name + of claim in token for identifying the groups of + subject in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect + timeout with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + principalMappingRules: + items: + type: string + type: array + type: + description: |- + type specifies the Kafka or Zookeeper authentication type. + Valid options are `plain`, `digest`, `mtls`, `ldap` & `oauth`. + enum: + - plain + - digest + - mtls + - ldap + - oauth + type: string + required: + - type + type: object + externalAccess: + description: externalAccess defines the external access + configuration for the Kafka cluster. + properties: + loadBalancer: + description: loadBalancer specifies the configuration + to create Kubernetes load balancer services. + properties: + advertisedPort: + description: |- + advertisedPort specifies the advertised port for Kafka external access. + If not configured, it will be the same as the listener port. + Information about the advertised port can be retrieved through the status API. + format: int32 + type: integer + annotations: + additionalProperties: + type: string + description: annotations is a map of string key + and value pairs. It specifies Kubernetes annotations + for this service. + type: object + x-kubernetes-map-type: granular + bootstrapPrefix: + description: |- + bootstrapPrefix specifies the prefix for the Kafka bootstrap advertised endpoint and will be added as `bootstrapPrefix.domain`. + The default value is the Kafka cluster name. + minLength: 1 + type: string + brokerPrefix: + description: |- + brokerPrefix specifies the prefix for the Kafka broker advertised endpoint and will be added as `brokerPrefix.domain`. + The default value is `b`, such as `b#.domain` where `#` starts from `0` to the replicas count. + minLength: 1 + type: string + domain: + description: domain is the domain name of the component + cluster. + minLength: 1 + type: string + externalTrafficPolicy: + description: externalTrafficPolicy specifies the + external traffic policy for the service. Valid + options are `Local` and `Cluster`. + enum: + - Local + - Cluster + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key and value + pairs. It specifies Kubernetes labels for this + service. + type: object + x-kubernetes-map-type: granular + loadBalancerSourceRanges: + description: loadBalancerSourceRanges specify the + source ranges. + items: + type: string + type: array + servicePorts: + description: servicePorts specify the user-provided + service port(s). + 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 + sessionAffinity: + description: |- + sessionAffinity defines the Kubernetes session affinity. The valid options are `ClientIP` and `None`. `ClientIP` enables the client IP-based session affinity. + The default value is `None`. + More info: https://kubernetes.io/docs/reference/networking/virtual-ips/#session-affinity. + enum: + - ClientIP + - None + type: string + sessionAffinityConfig: + description: SessionAffinityConfig contains the + configurations of the 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 + required: + - domain + type: object + nodePort: + description: nodePort specifies the configuration to + create Kubernetes node port services. + properties: + advertisedURL: + description: |- + advertisedURL specifies the configuration for advertised listener per pod. It is only supported for MDS currently. + If it is enabled, instead of using internal endpoint, the MDS advertised listener for each broker will be + set to `://:, where`podId` starts from `0` to `replicaCount - 1`. + This is only recommended if you cannot add internal SANs to the TLS certificates for MDS and + the external DNS must be resolved inside the Kubernetes cluster. + properties: + enabled: + description: |- + enabled indicates whether to set the MDS advertised listener url with external endpoint for each broker. + Has no effect with Zookeeper, which will always create a listener per pod. + type: boolean + prefix: + description: |- + prefix specifies the broker prefix for MDS/Zookeeper advertised endpoint. + If not configured, it uses `b` as default prefix for MDS, such as `b#.domain` where `#` will start from `0` to `replicaCount -1`. + It uses 'zookeeper' as default prefix for Zookeeper in the same way. + minLength: 1 + type: string + required: + - enabled + type: object + annotations: + additionalProperties: + type: string + description: annotations is a map of string key + and value pairs. It specifies Kubernetes annotations + for this service. + type: object + x-kubernetes-map-type: granular + externalTrafficPolicy: + description: |- + externalTrafficPolicy specifies the external traffic policy for the service. + Valid options are `Local` and `Cluster`. + enum: + - Local + - Cluster + type: string + host: + description: host defines the host name of the cluster. + minLength: 1 + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key and value + pairs. It specifies Kubernetes labels for this + service. + type: object + x-kubernetes-map-type: granular + nodePortOffset: + description: |- + nodePortOffset specifies the starting offset of the node ports. The port numbers go in ascending order with respect + to the replicas count. + NodePort service creation fails if the node port is not in the range supported by the Kubernetes API server. + The default Kubernetes Node Port range is `30000` - `32762`. + format: int32 + minimum: 0 + type: integer + servicePorts: + description: |- + servicePorts specify user-provided service port(s). + For Kafka with the nodePort type, this setting is only applied to Kafka bootstrap service. + 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 + sessionAffinity: + description: |- + sessionAffinity defines the Kubernetes session affinity. The valid options are `ClientIP` and `None`. `ClientIP` enables the client IP-based session affinity. + The default value is `None`. + More info: https://kubernetes.io/docs/reference/networking/virtual-ips/#session-affinity. + enum: + - ClientIP + - None + type: string + sessionAffinityConfig: + description: SessionAffinityConfig contains the + configurations of the 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 + required: + - host + - nodePortOffset + type: object + route: + description: route specifies the configuration to create + route services in OpenShift. + properties: + annotations: + additionalProperties: + type: string + description: annotations is a map of string key + and value pairs. It specifies Kubernetes annotations + for this service. + type: object + x-kubernetes-map-type: granular + bootstrapPrefix: + description: |- + bootstrapPrefix specifies the prefix for the Kafka bootstrap advertised endpoint and will be added as `bootstrapPrefix.domain`. + The default value is the Kafka cluster name. + minLength: 1 + type: string + brokerPrefix: + description: |- + brokerPrefix specifies the prefix for the Kafka broker advertised endpoint and will be added as `brokerPrefix.domain`. + The default value is `b`, such as `b#.domain` where `#` starts from `0` to the replicas count. + minLength: 1 + type: string + domain: + description: domain specifies the domain name of + the Confluent component cluster. + minLength: 1 + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key and value + pairs. It specifies Kubernetes labels for this + service. + type: object + x-kubernetes-map-type: granular + wildcardPolicy: + description: |- + wildcardPolicy allows you to define a route that covers all hosts within a domain. Valid options are `Subdomain` and `None`. + The default value is `None`. + enum: + - Subdomain + - None + type: string + required: + - domain + type: object + staticForHostBasedRouting: + description: |- + staticForHostBasedRouting enables external access by doing host based + routing through the SNI capability. + With this schema, CFK only configures Kafka advertised listeners, and no Kubernetes external + service is created. + properties: + brokerPrefix: + description: |- + brokerPrefix specifies the prefix for the broker advertised endpoints and are added as `brokerPrefix.domain`. + If not configured, it will add `b` as a prefix, such as `b#.domain` where `#` will start from `0` to the replicas count. + minLength: 1 + type: string + domain: + description: domain specifies the domain name for + the Kafka cluster. + minLength: 1 + type: string + port: + description: port specifies the port to be used + in the advertised listener for a broker. + format: int32 + type: integer + required: + - domain + - port + type: object + staticForPortBasedRouting: + description: |- + staticForPortBasedRouting enables external access by port routing. + With this schema, CFK only configures Kafka advertised listeners, and no Kubernetes external + service is created. + properties: + host: + description: host defines the host name to be used + in the advertised listener for a broker. + minLength: 1 + type: string + portOffset: + description: |- + portOffset specifies the starting port number. The port numbers go in ascending order with + respect to the replicas count. + format: int32 + type: integer + required: + - host + - portOffset + type: object + type: + description: |- + type specifies the Kubernetes service for external access. + Valid options are `loadBalancer`, `nodePort`, `route`, `staticForPortBasedRouting`, and `staticForHostBasedRouting`. + enum: + - loadBalancer + - nodePort + - route + - staticForPortBasedRouting + - staticForHostBasedRouting + type: string + required: + - type + type: object + name: + description: |- + name specifies the name of the custom listener. + `internal`, `external`, and `token` are reserved by CFK and + can't be used for this property. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: |- + port binds the given port to the custom listener. Port numbers lower than `9093` are + reserved by CFK. + format: int32 + minimum: 9093 + type: integer + tls: + description: tls specifies the TLS configuration for the + listener. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + required: + - name + - port + type: object + type: array + external: + description: external specifies the Kafka external listener. + properties: + authentication: + description: authentication specifies the authentication configuration + for the listener. + properties: + jaasConfig: + description: |- + jaasConfig specifies the JaaS configuration. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + properties: + secretRef: + description: |- + secretRef references the secret containing the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + jaasConfigPassThrough: + description: |- + jaasConfigPassThrough specifies another way to provide JaaS configuration. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where required credentials are mounted. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + minLength: 1 + type: string + secretRef: + description: |- + secretRef references the secret containing the required credentials for authentication. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauthSettings: + description: |- + oauthSettings specifies the OAuth settings. + This needs to passed with the authentication type `oauth`. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name of + claim in token for identifying the groups of subject + in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect timeout + with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + principalMappingRules: + items: + type: string + type: array + type: + description: |- + type specifies the Kafka or Zookeeper authentication type. + Valid options are `plain`, `digest`, `mtls`, `ldap` & `oauth`. + enum: + - plain + - digest + - mtls + - ldap + - oauth + type: string + required: + - type + type: object + externalAccess: + description: externalAccess defines the external access configuration + for the Kafka cluster. + properties: + loadBalancer: + description: loadBalancer specifies the configuration + to create Kubernetes load balancer services. + properties: + advertisedPort: + description: |- + advertisedPort specifies the advertised port for Kafka external access. + If not configured, it will be the same as the listener port. + Information about the advertised port can be retrieved through the status API. + format: int32 + type: integer + annotations: + additionalProperties: + type: string + description: annotations is a map of string key and + value pairs. It specifies Kubernetes annotations + for this service. + type: object + x-kubernetes-map-type: granular + bootstrapPrefix: + description: |- + bootstrapPrefix specifies the prefix for the Kafka bootstrap advertised endpoint and will be added as `bootstrapPrefix.domain`. + The default value is the Kafka cluster name. + minLength: 1 + type: string + brokerPrefix: + description: |- + brokerPrefix specifies the prefix for the Kafka broker advertised endpoint and will be added as `brokerPrefix.domain`. + The default value is `b`, such as `b#.domain` where `#` starts from `0` to the replicas count. + minLength: 1 + type: string + domain: + description: domain is the domain name of the component + cluster. + minLength: 1 + type: string + externalTrafficPolicy: + description: externalTrafficPolicy specifies the external + traffic policy for the service. Valid options are + `Local` and `Cluster`. + enum: + - Local + - Cluster + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key and value + pairs. It specifies Kubernetes labels for this service. + type: object + x-kubernetes-map-type: granular + loadBalancerSourceRanges: + description: loadBalancerSourceRanges specify the + source ranges. + items: + type: string + type: array + servicePorts: + description: servicePorts specify the user-provided + service port(s). + 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 + sessionAffinity: + description: |- + sessionAffinity defines the Kubernetes session affinity. The valid options are `ClientIP` and `None`. `ClientIP` enables the client IP-based session affinity. + The default value is `None`. + More info: https://kubernetes.io/docs/reference/networking/virtual-ips/#session-affinity. + enum: + - ClientIP + - None + type: string + sessionAffinityConfig: + description: SessionAffinityConfig contains the configurations + of the 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 + required: + - domain + type: object + nodePort: + description: nodePort specifies the configuration to create + Kubernetes node port services. + properties: + advertisedURL: + description: |- + advertisedURL specifies the configuration for advertised listener per pod. It is only supported for MDS currently. + If it is enabled, instead of using internal endpoint, the MDS advertised listener for each broker will be + set to `://:, where`podId` starts from `0` to `replicaCount - 1`. + This is only recommended if you cannot add internal SANs to the TLS certificates for MDS and + the external DNS must be resolved inside the Kubernetes cluster. + properties: + enabled: + description: |- + enabled indicates whether to set the MDS advertised listener url with external endpoint for each broker. + Has no effect with Zookeeper, which will always create a listener per pod. + type: boolean + prefix: + description: |- + prefix specifies the broker prefix for MDS/Zookeeper advertised endpoint. + If not configured, it uses `b` as default prefix for MDS, such as `b#.domain` where `#` will start from `0` to `replicaCount -1`. + It uses 'zookeeper' as default prefix for Zookeeper in the same way. + minLength: 1 + type: string + required: + - enabled + type: object + annotations: + additionalProperties: + type: string + description: annotations is a map of string key and + value pairs. It specifies Kubernetes annotations + for this service. + type: object + x-kubernetes-map-type: granular + externalTrafficPolicy: + description: |- + externalTrafficPolicy specifies the external traffic policy for the service. + Valid options are `Local` and `Cluster`. + enum: + - Local + - Cluster + type: string + host: + description: host defines the host name of the cluster. + minLength: 1 + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key and value + pairs. It specifies Kubernetes labels for this service. + type: object + x-kubernetes-map-type: granular + nodePortOffset: + description: |- + nodePortOffset specifies the starting offset of the node ports. The port numbers go in ascending order with respect + to the replicas count. + NodePort service creation fails if the node port is not in the range supported by the Kubernetes API server. + The default Kubernetes Node Port range is `30000` - `32762`. + format: int32 + minimum: 0 + type: integer + servicePorts: + description: |- + servicePorts specify user-provided service port(s). + For Kafka with the nodePort type, this setting is only applied to Kafka bootstrap service. + 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 + sessionAffinity: + description: |- + sessionAffinity defines the Kubernetes session affinity. The valid options are `ClientIP` and `None`. `ClientIP` enables the client IP-based session affinity. + The default value is `None`. + More info: https://kubernetes.io/docs/reference/networking/virtual-ips/#session-affinity. + enum: + - ClientIP + - None + type: string + sessionAffinityConfig: + description: SessionAffinityConfig contains the configurations + of the 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 + required: + - host + - nodePortOffset + type: object + route: + description: route specifies the configuration to create + route services in OpenShift. + properties: + annotations: + additionalProperties: + type: string + description: annotations is a map of string key and + value pairs. It specifies Kubernetes annotations + for this service. + type: object + x-kubernetes-map-type: granular + bootstrapPrefix: + description: |- + bootstrapPrefix specifies the prefix for the Kafka bootstrap advertised endpoint and will be added as `bootstrapPrefix.domain`. + The default value is the Kafka cluster name. + minLength: 1 + type: string + brokerPrefix: + description: |- + brokerPrefix specifies the prefix for the Kafka broker advertised endpoint and will be added as `brokerPrefix.domain`. + The default value is `b`, such as `b#.domain` where `#` starts from `0` to the replicas count. + minLength: 1 + type: string + domain: + description: domain specifies the domain name of the + Confluent component cluster. + minLength: 1 + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key and value + pairs. It specifies Kubernetes labels for this service. + type: object + x-kubernetes-map-type: granular + wildcardPolicy: + description: |- + wildcardPolicy allows you to define a route that covers all hosts within a domain. Valid options are `Subdomain` and `None`. + The default value is `None`. + enum: + - Subdomain + - None + type: string + required: + - domain + type: object + staticForHostBasedRouting: + description: |- + staticForHostBasedRouting enables external access by doing host based + routing through the SNI capability. + With this schema, CFK only configures Kafka advertised listeners, and no Kubernetes external + service is created. + properties: + brokerPrefix: + description: |- + brokerPrefix specifies the prefix for the broker advertised endpoints and are added as `brokerPrefix.domain`. + If not configured, it will add `b` as a prefix, such as `b#.domain` where `#` will start from `0` to the replicas count. + minLength: 1 + type: string + domain: + description: domain specifies the domain name for + the Kafka cluster. + minLength: 1 + type: string + port: + description: port specifies the port to be used in + the advertised listener for a broker. + format: int32 + type: integer + required: + - domain + - port + type: object + staticForPortBasedRouting: + description: |- + staticForPortBasedRouting enables external access by port routing. + With this schema, CFK only configures Kafka advertised listeners, and no Kubernetes external + service is created. + properties: + host: + description: host defines the host name to be used + in the advertised listener for a broker. + minLength: 1 + type: string + portOffset: + description: |- + portOffset specifies the starting port number. The port numbers go in ascending order with + respect to the replicas count. + format: int32 + type: integer + required: + - host + - portOffset + type: object + type: + description: |- + type specifies the Kubernetes service for external access. + Valid options are `loadBalancer`, `nodePort`, `route`, `staticForPortBasedRouting`, and `staticForHostBasedRouting`. + enum: + - loadBalancer + - nodePort + - route + - staticForPortBasedRouting + - staticForHostBasedRouting + type: string + required: + - type + type: object + tls: + description: tls specifies the TLS configuration for the listener. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + internal: + description: internal specifies the internal listener. + properties: + authentication: + description: authentication specifies the authentication configuration + for the listener. + properties: + jaasConfig: + description: |- + jaasConfig specifies the JaaS configuration. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + properties: + secretRef: + description: |- + secretRef references the secret containing the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + jaasConfigPassThrough: + description: |- + jaasConfigPassThrough specifies another way to provide JaaS configuration. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where required credentials are mounted. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + minLength: 1 + type: string + secretRef: + description: |- + secretRef references the secret containing the required credentials for authentication. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauthSettings: + description: |- + oauthSettings specifies the OAuth settings. + This needs to passed with the authentication type `oauth`. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name of + claim in token for identifying the groups of subject + in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect timeout + with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + principalMappingRules: + items: + type: string + type: array + type: + description: |- + type specifies the Kafka or Zookeeper authentication type. + Valid options are `plain`, `digest`, `mtls`, `ldap` & `oauth`. + enum: + - plain + - digest + - mtls + - ldap + - oauth + type: string + required: + - type + type: object + tls: + description: tls specifies the TLS configuration for the listener. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + replication: + description: replication specifies the Kafka replication listener. + properties: + authentication: + description: authentication specifies the authentication configuration + for the listener. + properties: + jaasConfig: + description: |- + jaasConfig specifies the JaaS configuration. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + properties: + secretRef: + description: |- + secretRef references the secret containing the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + jaasConfigPassThrough: + description: |- + jaasConfigPassThrough specifies another way to provide JaaS configuration. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where required credentials are mounted. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + minLength: 1 + type: string + secretRef: + description: |- + secretRef references the secret containing the required credentials for authentication. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauthSettings: + description: |- + oauthSettings specifies the OAuth settings. + This needs to passed with the authentication type `oauth`. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name of + claim in token for identifying the groups of subject + in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect timeout + with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + principalMappingRules: + items: + type: string + type: array + type: + description: |- + type specifies the Kafka or Zookeeper authentication type. + Valid options are `plain`, `digest`, `mtls`, `ldap` & `oauth`. + enum: + - plain + - digest + - mtls + - ldap + - oauth + type: string + required: + - type + type: object + externalAccess: + description: externalAccess defines the external access configuration + for the Kafka cluster. + properties: + loadBalancer: + description: loadBalancer specifies the configuration + to create Kubernetes load balancer services. + properties: + advertisedPort: + description: |- + advertisedPort specifies the advertised port for Kafka external access. + If not configured, it will be the same as the listener port. + Information about the advertised port can be retrieved through the status API. + format: int32 + type: integer + annotations: + additionalProperties: + type: string + description: annotations is a map of string key and + value pairs. It specifies Kubernetes annotations + for this service. + type: object + x-kubernetes-map-type: granular + bootstrapPrefix: + description: |- + bootstrapPrefix specifies the prefix for the Kafka bootstrap advertised endpoint and will be added as `bootstrapPrefix.domain`. + The default value is the Kafka cluster name. + minLength: 1 + type: string + brokerPrefix: + description: |- + brokerPrefix specifies the prefix for the Kafka broker advertised endpoint and will be added as `brokerPrefix.domain`. + The default value is `b`, such as `b#.domain` where `#` starts from `0` to the replicas count. + minLength: 1 + type: string + domain: + description: domain is the domain name of the component + cluster. + minLength: 1 + type: string + externalTrafficPolicy: + description: externalTrafficPolicy specifies the external + traffic policy for the service. Valid options are + `Local` and `Cluster`. + enum: + - Local + - Cluster + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key and value + pairs. It specifies Kubernetes labels for this service. + type: object + x-kubernetes-map-type: granular + loadBalancerSourceRanges: + description: loadBalancerSourceRanges specify the + source ranges. + items: + type: string + type: array + servicePorts: + description: servicePorts specify the user-provided + service port(s). + 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 + sessionAffinity: + description: |- + sessionAffinity defines the Kubernetes session affinity. The valid options are `ClientIP` and `None`. `ClientIP` enables the client IP-based session affinity. + The default value is `None`. + More info: https://kubernetes.io/docs/reference/networking/virtual-ips/#session-affinity. + enum: + - ClientIP + - None + type: string + sessionAffinityConfig: + description: SessionAffinityConfig contains the configurations + of the 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 + required: + - domain + type: object + nodePort: + description: nodePort specifies the configuration to create + Kubernetes node port services. + properties: + advertisedURL: + description: |- + advertisedURL specifies the configuration for advertised listener per pod. It is only supported for MDS currently. + If it is enabled, instead of using internal endpoint, the MDS advertised listener for each broker will be + set to `://:, where`podId` starts from `0` to `replicaCount - 1`. + This is only recommended if you cannot add internal SANs to the TLS certificates for MDS and + the external DNS must be resolved inside the Kubernetes cluster. + properties: + enabled: + description: |- + enabled indicates whether to set the MDS advertised listener url with external endpoint for each broker. + Has no effect with Zookeeper, which will always create a listener per pod. + type: boolean + prefix: + description: |- + prefix specifies the broker prefix for MDS/Zookeeper advertised endpoint. + If not configured, it uses `b` as default prefix for MDS, such as `b#.domain` where `#` will start from `0` to `replicaCount -1`. + It uses 'zookeeper' as default prefix for Zookeeper in the same way. + minLength: 1 + type: string + required: + - enabled + type: object + annotations: + additionalProperties: + type: string + description: annotations is a map of string key and + value pairs. It specifies Kubernetes annotations + for this service. + type: object + x-kubernetes-map-type: granular + externalTrafficPolicy: + description: |- + externalTrafficPolicy specifies the external traffic policy for the service. + Valid options are `Local` and `Cluster`. + enum: + - Local + - Cluster + type: string + host: + description: host defines the host name of the cluster. + minLength: 1 + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key and value + pairs. It specifies Kubernetes labels for this service. + type: object + x-kubernetes-map-type: granular + nodePortOffset: + description: |- + nodePortOffset specifies the starting offset of the node ports. The port numbers go in ascending order with respect + to the replicas count. + NodePort service creation fails if the node port is not in the range supported by the Kubernetes API server. + The default Kubernetes Node Port range is `30000` - `32762`. + format: int32 + minimum: 0 + type: integer + servicePorts: + description: |- + servicePorts specify user-provided service port(s). + For Kafka with the nodePort type, this setting is only applied to Kafka bootstrap service. + 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 + sessionAffinity: + description: |- + sessionAffinity defines the Kubernetes session affinity. The valid options are `ClientIP` and `None`. `ClientIP` enables the client IP-based session affinity. + The default value is `None`. + More info: https://kubernetes.io/docs/reference/networking/virtual-ips/#session-affinity. + enum: + - ClientIP + - None + type: string + sessionAffinityConfig: + description: SessionAffinityConfig contains the configurations + of the 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 + required: + - host + - nodePortOffset + type: object + route: + description: route specifies the configuration to create + route services in OpenShift. + properties: + annotations: + additionalProperties: + type: string + description: annotations is a map of string key and + value pairs. It specifies Kubernetes annotations + for this service. + type: object + x-kubernetes-map-type: granular + bootstrapPrefix: + description: |- + bootstrapPrefix specifies the prefix for the Kafka bootstrap advertised endpoint and will be added as `bootstrapPrefix.domain`. + The default value is the Kafka cluster name. + minLength: 1 + type: string + brokerPrefix: + description: |- + brokerPrefix specifies the prefix for the Kafka broker advertised endpoint and will be added as `brokerPrefix.domain`. + The default value is `b`, such as `b#.domain` where `#` starts from `0` to the replicas count. + minLength: 1 + type: string + domain: + description: domain specifies the domain name of the + Confluent component cluster. + minLength: 1 + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key and value + pairs. It specifies Kubernetes labels for this service. + type: object + x-kubernetes-map-type: granular + wildcardPolicy: + description: |- + wildcardPolicy allows you to define a route that covers all hosts within a domain. Valid options are `Subdomain` and `None`. + The default value is `None`. + enum: + - Subdomain + - None + type: string + required: + - domain + type: object + staticForHostBasedRouting: + description: |- + staticForHostBasedRouting enables external access by doing host based + routing through the SNI capability. + With this schema, CFK only configures Kafka advertised listeners, and no Kubernetes external + service is created. + properties: + brokerPrefix: + description: |- + brokerPrefix specifies the prefix for the broker advertised endpoints and are added as `brokerPrefix.domain`. + If not configured, it will add `b` as a prefix, such as `b#.domain` where `#` will start from `0` to the replicas count. + minLength: 1 + type: string + domain: + description: domain specifies the domain name for + the Kafka cluster. + minLength: 1 + type: string + port: + description: port specifies the port to be used in + the advertised listener for a broker. + format: int32 + type: integer + required: + - domain + - port + type: object + staticForPortBasedRouting: + description: |- + staticForPortBasedRouting enables external access by port routing. + With this schema, CFK only configures Kafka advertised listeners, and no Kubernetes external + service is created. + properties: + host: + description: host defines the host name to be used + in the advertised listener for a broker. + minLength: 1 + type: string + portOffset: + description: |- + portOffset specifies the starting port number. The port numbers go in ascending order with + respect to the replicas count. + format: int32 + type: integer + required: + - host + - portOffset + type: object + type: + description: |- + type specifies the Kubernetes service for external access. + Valid options are `loadBalancer`, `nodePort`, `route`, `staticForPortBasedRouting`, and `staticForHostBasedRouting`. + enum: + - loadBalancer + - nodePort + - route + - staticForPortBasedRouting + - staticForHostBasedRouting + type: string + required: + - type + type: object + tls: + description: tls specifies the TLS configuration for the listener. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + type: object + metricReporter: + description: |- + metricsReporter specifies the configuration of the metric reporter. The metric reporter is enabled by default. + If authentication and TLS are not set, the metrics reporter uses internal listener's authentication and TLS . + properties: + authentication: + description: authentication specifies the Kafka client-side authentication + configuration. + properties: + jaasConfig: + description: jaasConfig specifies the Kafka client-side JaaS + configuration. + properties: + secretRef: + description: |- + secretRef references the secret containing the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + jaasConfigPassThrough: + description: jaasConfigPassThrough specifies another way to + provide the Kafka client-side JaaS configuration. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where required credentials are mounted. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + minLength: 1 + type: string + secretRef: + description: |- + secretRef references the secret containing the required credentials for authentication. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauthSettings: + description: |- + oauthSettings specifies the OAuth settings. + This needs to passed with the authentication type `oauth`. + properties: + audience: + description: audience specifies the audience claim in + the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected issuer + in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name of claim + in token for identifying the groups of subject in the + JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect timeout + with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout with + IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry backoff + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff with + IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim in JWT + to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + oauthbearer: + description: |- + oauthbearer is the authentication mechanism to provider principals. + Only supported in RBAC deployment. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container + where the credential is mounted. + minLength: 1 + type: string + secretRef: + description: |- + secretRef specifies the name of the secret that contains the credential. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#bearer-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + type: + description: |- + type specifies the Kafka client authentication type. + Valid options are `plain`, `oauthbearer`, `digest`, `mtls` and `oauth`. + enum: + - plain + - oauthbearer + - digest + - mtls + - oauth + type: string + required: + - type + type: object + bootstrapEndpoint: + description: bootstrapEndpoint specifies the Kafka bootstrap endpoint. + type: string + enabled: + description: enabled specifies whether to enable or disable the + metric reporter. + type: boolean + replicationFactor: + description: replicationFactor specifies the number of replicas + in the metric topic. + format: int32 + type: integer + tls: + description: tls specifies the Kafka client-side TLS configuration. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + required: + - enabled + type: object + metrics: + description: metrics specify the security settings for the metric + services. + properties: + authentication: + description: authentication specifies the authentication configuration + for the metrics. + properties: + type: + description: type specifies the metrics authentication method. + The valid option is `mtls`. + enum: + - mtls + type: string + required: + - type + type: object + prometheus: + description: prometheus specifies the configuration overrides + for the JMX-Prometheus exporter. + properties: + blacklist: + items: + type: string + type: array + rules: + items: + description: Rule defines the Prometheus Exporter rule override. + properties: + attrNameSnakeCase: + type: boolean + cache: + type: boolean + help: + minLength: 1 + type: string + labels: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: granular + name: + minLength: 1 + type: string + pattern: + minLength: 1 + type: string + type: + minLength: 1 + type: string + value: + minLength: 1 + type: string + valueFactor: + anyOf: + - type: integer + - type: string + default: 1 + 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: array + whitelist: + items: + type: string + type: array + type: object + tls: + description: tls specifies the TLS configuration for the metrics. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + mountedSecrets: + description: |- + mountedSecrets list the secrets injected to + the underlying statefulset configuration. The secret reference is mounted + in the default path `/mnt/secrets/`. The underlying resources + will follow the secret as a file configuration. + More info: https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets-as-files-from-a-pod. + A change to this setting will roll the cluster. + items: + description: |- + MountedSecrets provides a way to inject a custom secret to the underlying + statefulset. + properties: + keyItems: + description: keyItems are key and path names. + 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 + secretRef: + description: secretRef references the name of the secret. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + type: array + mountedVolumes: + description: |- + mountedVolumes list the custom volumes that need to be mounted into the + underlying statefulset. + A change to this setting will roll the cluster. + properties: + volumeMounts: + description: |- + volumeMounts specify the list of volume mounts for the pods in the + statefulset. + 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 + volumes: + description: |- + volumes specify the list of volumes that can be mounted into the pods + of statefulset. + 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 + 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: + 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 + 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 + 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: + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 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 + 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 + 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 + 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 + 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 + 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: + 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 + 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 + 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 + required: + - volumeMounts + - volumes + type: object + oneReplicaPerNode: + description: |- + oneReplicaPerNode controls whether to run 1 pod per node using the pod anti-affinity capability. + Enabling this configuration in an existing cluster will roll the cluster. + type: boolean + passwordEncoder: + description: passwordEncoder specifies password encoder secret for + Kafka. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer contains the directory path in the container where + the required secret is mounted. + Directory should have the file `password-encoder.txt`. The contents should include a new password. + Old password is optional and required only for rotation. + More info: https://docs.confluent.io/operator/current/co-password-encoder-secret. + type: string + secretRef: + description: |- + secretRef specifies the secret name. The secret should have the key + `password-encoder.txt`. The contents should include a new password. + Old password is optional and required only for rotation. + More info: https://docs.confluent.io/operator/current/co-password-encoder-secret. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + pdb: + description: |- + configures PodDisruptionBudget for the Confluent Platform component. + by default PDB is configured based on pre-detemined formula. + properties: + enabled: + description: enabled specifies whether the PodDisruptionBudget + is enabled + type: boolean + maxUnavailable: + description: maxUnavailable is the maximum number of pods that + can be unavailable during the disruption. + format: int32 + type: integer + required: + - enabled + type: object + podTemplate: + description: podTemplate specifies the statefulset pod template configuration. + properties: + affinity: + description: |- + affinity specifies a group of affinity scheduling rules. + More info: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity. + 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 + annotations: + additionalProperties: + type: string + description: |- + annotations is a map of string key and value pairs stored with the resource and + 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 + x-kubernetes-map-type: granular + envVars: + description: |- + envVars contain environment variables to be injected into containers. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container. + 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 + 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: + 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 + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + labels: + additionalProperties: + type: string + description: |- + labels is a map of string key and value pairs that can be used to organize and categorize + (scope and select) objects. + More info: http://kubernetes.io/docs/user-guide/labels. + type: object + x-kubernetes-map-type: granular + 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: + + + 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 + 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: + description: priorityClassName specifies the priority class for + the pod (if any). + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + probe: + description: probe contains the fields for standard Kubernetes + readiness/liveness probe configuration. + properties: + liveness: + description: |- + liveness configures the Kubernetes probe settings. The changes + will override the existing default configuration. + properties: + failureThreshold: + description: |- + failureThreshold is the minimum consecutive failures for the probe to be considered failed. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + initialDelaySeconds: + description: |- + initialDelaySeconds is the number of seconds after the container has started and before probes are initiated. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + path: + description: Path for the HTTP probe + type: string + periodSeconds: + description: |- + periodSeconds specifies how often to perform the probe. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + port: + description: Number of the port to access on the container + type: integer + successThreshold: + description: |- + successThreshold is the minimum consecutive successes for the probe to be considered successful after having failed. + The default values is `1`. Must be `1` for liveness and startup. The minimum value is `1`. + format: int32 + type: integer + timeoutSeconds: + description: |- + timeoutSeconds is the number of seconds after which the probe times out. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + type: object + readiness: + description: |- + readiness configures the Kubernetes probe setting. The changes + will override the existing default configuration. + properties: + failureThreshold: + description: |- + failureThreshold is the minimum consecutive failures for the probe to be considered failed. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + initialDelaySeconds: + description: |- + initialDelaySeconds is the number of seconds after the container has started and before probes are initiated. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + path: + description: Path for the HTTP probe + type: string + periodSeconds: + description: |- + periodSeconds specifies how often to perform the probe. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + port: + description: Number of the port to access on the container + type: integer + successThreshold: + description: |- + successThreshold is the minimum consecutive successes for the probe to be considered successful after having failed. + The default values is `1`. Must be `1` for liveness and startup. The minimum value is `1`. + format: int32 + type: integer + timeoutSeconds: + description: |- + timeoutSeconds is the number of seconds after which the probe times out. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + type: object + type: object + resources: + description: resources describe the compute resource requirements. + 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 + 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: + + + 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: + description: |- + ServiceAccountName is the name of the service account used to run this pod. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account. + type: string + terminationGracePeriodSeconds: + description: terminationGracePeriodSeconds is the grace period + before the pod is deleted. + format: int64 + type: integer + tolerations: + description: |- + tolerations specify the pods to schedule onto the nodes with matching taints, using + the triple `` and the matching operator ``. + 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 + topologySpreadConstraints: + description: |- + topologySpreadConstraints describe how a group of pods ought to spread across topology domains. Scheduler will + schedule pods based on 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 + 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 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. + + + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). + 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 + type: object + rackAssignment: + description: rackAssignment specifies the rack awareness capability + of the Kafka cluster. + properties: + availabilityZoneCount: + description: |- + availabilityZoneCount configures `broker.rack` with the formula (`pod_id % azCount`). + This is mainly for backwards compatibility with Operator 1.x. + format: int32 + type: integer + nodeLabels: + description: |- + nodeLabels use the Kubernetes node API + to retrieve the label values to be used in `broker.rack`. This + feature requires CFK to run with the cluster-level access. + items: + type: string + minItems: 1 + type: array + type: object + replicas: + description: |- + replicas is the desired number of replicas. + A change to this setting will roll the cluster. + format: int32 + type: integer + services: + description: services specify the supported Kafka services. + properties: + kafkaRest: + description: kafkaRest specifies the embedded REST API server + configuration. + properties: + authentication: + description: authentication specifies the REST API server + authentication configuration. + properties: + basic: + description: basic specifies the configuration for basic + authentication. + properties: + debug: + description: debug enables the basic authentication + debug logs for JaaS configuration. + type: boolean + directoryPathInContainer: + description: |- + directoryPathInContainer allows to pass the basic credential through a directory path in the container. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + minLength: 1 + type: string + restrictedRoles: + description: |- + restrictedRoles specify the restricted roles on the server side only. + Changes will be only reflected in Control Center. + This configuration is ignored on the client side configuration. + items: + type: string + minItems: 1 + type: array + roles: + description: |- + roles specify the roles on the server side only. + This configuration is ignored on the client side configuration. + items: + type: string + type: array + secretRef: + description: |- + secretRef defines secret reference to pass the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauth: + description: oauth specifies the configuration for OAuth + authentication. + properties: + configuration: + description: configuration specifies the OAuth server + settings. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name + of claim in token for identifying the groups + of subject in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect + timeout with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + directoryPathInContainer: + description: directoryPathInContainer allows to pass + the basic credential through a directory path in + the container. + minLength: 1 + type: string + secretRef: + description: secretRef defines secret reference to + pass the required credentials. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - configuration + type: object + type: + description: type specifies the authentication scheme + for the REST API server. Valid options are `basic`, + `oauth` and `mtls`. + enum: + - basic + - mtls + - oauth + type: string + required: + - type + type: object + externalAccess: + description: externalAccess specifies the external access + configuration. + properties: + loadBalancer: + description: loadBalancer specifies the configuration + to create a Kubernetes load balancer service. + properties: + advertisedURL: + description: |- + advertisedURL specifies the configuration for advertised listener per pod. It is only supported for MDS currently. + If it is enabled, instead of using internal endpoint, the MDS advertised listener for each broker will be + set to: `://.` where podId starts from `0` to `replicaCount -1`. + This is only recommended if you cannot add internal SANs to the TLS certificates for MDS and + the external DNS must be resolved inside the Kubernetes cluster. + This configuration will not take effect if MDS enabled dual listener setup. + properties: + enabled: + description: |- + enabled indicates whether to set the MDS advertised listener url with external endpoint for each broker. + Has no effect with Zookeeper, which will always create a listener per pod. + type: boolean + prefix: + description: |- + prefix specifies the broker prefix for MDS/Zookeeper advertised endpoint. + If not configured, it uses `b` as default prefix for MDS, such as `b#.domain` where `#` will start from `0` to `replicaCount -1`. + It uses 'zookeeper' as default prefix for Zookeeper in the same way. + minLength: 1 + type: string + required: + - enabled + type: object + annotations: + additionalProperties: + type: string + description: annotations is a map of string key and + value pairs. It specifies Kubernetes annotations + for this service. + type: object + x-kubernetes-map-type: granular + domain: + description: domain is the domain name of the component + cluster. + minLength: 1 + type: string + externalTrafficPolicy: + description: externalTrafficPolicy specifies the external + traffic policy for the service. Valid options are + `Local` and `Cluster`. + enum: + - Local + - Cluster + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key and value + pairs. It specifies Kubernetes labels for this service. + type: object + x-kubernetes-map-type: granular + loadBalancerSourceRanges: + description: loadBalancerSourceRanges specify the + source ranges. + items: + type: string + type: array + port: + description: |- + port specifies the external port for the client consumption. + If not configured, the same internal/external port is configured for the component. + Information about the port can be retrieved through the status API. + format: int32 + type: integer + prefix: + description: |- + prefix specify the prefix for the given domain. + The default value is the name of the cluster. + minLength: 1 + type: string + servicePorts: + description: servicePorts specify the user-provided + service port(s). + 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 + sessionAffinity: + description: |- + sessionAffinity defines the Kubernetes session affinity. The valid options are `ClientIP` and `None`. `ClientIP` enables the client IP-based session affinity. + The default value is `None`. + More info: https://kubernetes.io/docs/reference/networking/virtual-ips/#session-affinity. + enum: + - ClientIP + - None + type: string + sessionAffinityConfig: + description: SessionAffinityConfig contains the configurations + of the 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 + required: + - domain + type: object + nodePort: + description: nodePort specifies the configuration to create + a Kubernetes node port service. + properties: + advertisedURL: + description: |- + advertisedURL specifies the configuration for advertised listener per pod. It is only supported for MDS currently. + If it is enabled, instead of using internal endpoint, the MDS advertised listener for each broker will be + set to `://:, where`podId` starts from `0` to `replicaCount - 1`. + This is only recommended if you cannot add internal SANs to the TLS certificates for MDS and + the external DNS must be resolved inside the Kubernetes cluster. + properties: + enabled: + description: |- + enabled indicates whether to set the MDS advertised listener url with external endpoint for each broker. + Has no effect with Zookeeper, which will always create a listener per pod. + type: boolean + prefix: + description: |- + prefix specifies the broker prefix for MDS/Zookeeper advertised endpoint. + If not configured, it uses `b` as default prefix for MDS, such as `b#.domain` where `#` will start from `0` to `replicaCount -1`. + It uses 'zookeeper' as default prefix for Zookeeper in the same way. + minLength: 1 + type: string + required: + - enabled + type: object + annotations: + additionalProperties: + type: string + description: annotations is a map of string key and + value pairs. It specifies Kubernetes annotations + for this service. + type: object + x-kubernetes-map-type: granular + externalTrafficPolicy: + description: |- + externalTrafficPolicy specifies the external traffic policy for the service. + Valid options are `Local` and `Cluster`. + enum: + - Local + - Cluster + type: string + host: + description: host defines the host name of the cluster. + minLength: 1 + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key and value + pairs. It specifies Kubernetes labels for this service. + type: object + x-kubernetes-map-type: granular + nodePortOffset: + description: |- + nodePortOffset specifies the starting offset of the node ports. The port numbers go in ascending order with respect + to the replicas count. + NodePort service creation fails if the node port is not in the range supported by the Kubernetes API server. + The default Kubernetes Node Port range is `30000` - `32762`. + format: int32 + minimum: 0 + type: integer + servicePorts: + description: |- + servicePorts specify user-provided service port(s). + For Kafka with the nodePort type, this setting is only applied to Kafka bootstrap service. + 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 + sessionAffinity: + description: |- + sessionAffinity defines the Kubernetes session affinity. The valid options are `ClientIP` and `None`. `ClientIP` enables the client IP-based session affinity. + The default value is `None`. + More info: https://kubernetes.io/docs/reference/networking/virtual-ips/#session-affinity. + enum: + - ClientIP + - None + type: string + sessionAffinityConfig: + description: SessionAffinityConfig contains the configurations + of the 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 + required: + - host + - nodePortOffset + type: object + route: + description: route specifies the configuration to create + a route service in OpenShift. + properties: + advertisedURL: + description: |- + advertisedURL specifies the configuration for advertised listener per pod. It is only supported for MDS currently. + If it is enabled, instead of using internal endpoint, the MDS advertised listener for each broker will be + set to: `://-http-external.` where podId starts from `0` to `replicaCount -1`. + This is only recommended if you cannot add internal SANs to the TLS certificates for MDS and + the external DNS must be resolved inside the Kubernetes cluster. + This configuration will not take effect if MDS enabled dual listener setup. + properties: + enabled: + description: |- + enabled indicates whether to set the MDS advertised listener url with external endpoint for each broker. + Has no effect with Zookeeper, which will always create a listener per pod. + type: boolean + prefix: + description: |- + prefix specifies the broker prefix for MDS/Zookeeper advertised endpoint. + If not configured, it uses `b` as default prefix for MDS, such as `b#.domain` where `#` will start from `0` to `replicaCount -1`. + It uses 'zookeeper' as default prefix for Zookeeper in the same way. + minLength: 1 + type: string + required: + - enabled + type: object + annotations: + additionalProperties: + type: string + description: annotations is a map of string key and + value pairs. It specifies Kubernetes annotations + for this service. + type: object + x-kubernetes-map-type: granular + domain: + description: domain specifies the domain name of the + Confluent component cluster. + minLength: 1 + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key and value + pairs. It specifies Kubernetes labels for this service. + type: object + x-kubernetes-map-type: granular + prefix: + description: |- + prefix specifies the component prefix when configured for the domain. + The default value is the name of the cluster. + minLength: 1 + type: string + wildcardPolicy: + description: |- + wildcardPolicy allows you to define a route that covers all hosts within a domain. Valid options are `Subdomain` and `None`. + The default value is `None`. + enum: + - Subdomain + - None + type: string + required: + - domain + type: object + type: + description: |- + type specifies the Kubernetes external service for the component. + Valid options are `loadBalancer`, `nodePort`, and `route`. + enum: + - loadBalancer + - nodePort + - route + minLength: 1 + type: string + required: + - type + type: object + listeners: + description: listeners specify the listeners configurations + for embedded REST API server. + properties: + external: + description: external specifies the Confluent component + external listener. + properties: + externalAccess: + description: externalAccess defines the external access + configuration for the Confluent component. + properties: + loadBalancer: + description: loadBalancer specifies the configuration + to create a Kubernetes load balancer service. + properties: + advertisedURL: + description: |- + advertisedURL specifies the configuration for advertised listener per pod. It is only supported for MDS currently. + If it is enabled, instead of using internal endpoint, the MDS advertised listener for each broker will be + set to: `://.` where podId starts from `0` to `replicaCount -1`. + This is only recommended if you cannot add internal SANs to the TLS certificates for MDS and + the external DNS must be resolved inside the Kubernetes cluster. + This configuration will not take effect if MDS enabled dual listener setup. + properties: + enabled: + description: |- + enabled indicates whether to set the MDS advertised listener url with external endpoint for each broker. + Has no effect with Zookeeper, which will always create a listener per pod. + type: boolean + prefix: + description: |- + prefix specifies the broker prefix for MDS/Zookeeper advertised endpoint. + If not configured, it uses `b` as default prefix for MDS, such as `b#.domain` where `#` will start from `0` to `replicaCount -1`. + It uses 'zookeeper' as default prefix for Zookeeper in the same way. + minLength: 1 + type: string + required: + - enabled + type: object + annotations: + additionalProperties: + type: string + description: annotations is a map of string + key and value pairs. It specifies Kubernetes + annotations for this service. + type: object + x-kubernetes-map-type: granular + domain: + description: domain is the domain name of + the component cluster. + minLength: 1 + type: string + externalTrafficPolicy: + description: externalTrafficPolicy specifies + the external traffic policy for the service. + Valid options are `Local` and `Cluster`. + enum: + - Local + - Cluster + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key + and value pairs. It specifies Kubernetes + labels for this service. + type: object + x-kubernetes-map-type: granular + loadBalancerSourceRanges: + description: loadBalancerSourceRanges specify + the source ranges. + items: + type: string + type: array + port: + description: |- + port specifies the external port for the client consumption. + If not configured, the same internal/external port is configured for the component. + Information about the port can be retrieved through the status API. + format: int32 + type: integer + prefix: + description: |- + prefix specify the prefix for the given domain. + The default value is the name of the cluster. + minLength: 1 + type: string + servicePorts: + description: servicePorts specify the user-provided + service port(s). + 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 + sessionAffinity: + description: |- + sessionAffinity defines the Kubernetes session affinity. The valid options are `ClientIP` and `None`. `ClientIP` enables the client IP-based session affinity. + The default value is `None`. + More info: https://kubernetes.io/docs/reference/networking/virtual-ips/#session-affinity. + enum: + - ClientIP + - None + type: string + sessionAffinityConfig: + description: SessionAffinityConfig contains + the configurations of the 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 + required: + - domain + type: object + nodePort: + description: nodePort specifies the configuration + to create a Kubernetes node port service. + properties: + advertisedURL: + description: |- + advertisedURL specifies the configuration for advertised listener per pod. It is only supported for MDS currently. + If it is enabled, instead of using internal endpoint, the MDS advertised listener for each broker will be + set to `://:, where`podId` starts from `0` to `replicaCount - 1`. + This is only recommended if you cannot add internal SANs to the TLS certificates for MDS and + the external DNS must be resolved inside the Kubernetes cluster. + properties: + enabled: + description: |- + enabled indicates whether to set the MDS advertised listener url with external endpoint for each broker. + Has no effect with Zookeeper, which will always create a listener per pod. + type: boolean + prefix: + description: |- + prefix specifies the broker prefix for MDS/Zookeeper advertised endpoint. + If not configured, it uses `b` as default prefix for MDS, such as `b#.domain` where `#` will start from `0` to `replicaCount -1`. + It uses 'zookeeper' as default prefix for Zookeeper in the same way. + minLength: 1 + type: string + required: + - enabled + type: object + annotations: + additionalProperties: + type: string + description: annotations is a map of string + key and value pairs. It specifies Kubernetes + annotations for this service. + type: object + x-kubernetes-map-type: granular + externalTrafficPolicy: + description: |- + externalTrafficPolicy specifies the external traffic policy for the service. + Valid options are `Local` and `Cluster`. + enum: + - Local + - Cluster + type: string + host: + description: host defines the host name of + the cluster. + minLength: 1 + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key + and value pairs. It specifies Kubernetes + labels for this service. + type: object + x-kubernetes-map-type: granular + nodePortOffset: + description: |- + nodePortOffset specifies the starting offset of the node ports. The port numbers go in ascending order with respect + to the replicas count. + NodePort service creation fails if the node port is not in the range supported by the Kubernetes API server. + The default Kubernetes Node Port range is `30000` - `32762`. + format: int32 + minimum: 0 + type: integer + servicePorts: + description: |- + servicePorts specify user-provided service port(s). + For Kafka with the nodePort type, this setting is only applied to Kafka bootstrap service. + 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 + sessionAffinity: + description: |- + sessionAffinity defines the Kubernetes session affinity. The valid options are `ClientIP` and `None`. `ClientIP` enables the client IP-based session affinity. + The default value is `None`. + More info: https://kubernetes.io/docs/reference/networking/virtual-ips/#session-affinity. + enum: + - ClientIP + - None + type: string + sessionAffinityConfig: + description: SessionAffinityConfig contains + the configurations of the 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 + required: + - host + - nodePortOffset + type: object + route: + description: route specifies the configuration + to create a route service in OpenShift. + properties: + advertisedURL: + description: |- + advertisedURL specifies the configuration for advertised listener per pod. It is only supported for MDS currently. + If it is enabled, instead of using internal endpoint, the MDS advertised listener for each broker will be + set to: `://-http-external.` where podId starts from `0` to `replicaCount -1`. + This is only recommended if you cannot add internal SANs to the TLS certificates for MDS and + the external DNS must be resolved inside the Kubernetes cluster. + This configuration will not take effect if MDS enabled dual listener setup. + properties: + enabled: + description: |- + enabled indicates whether to set the MDS advertised listener url with external endpoint for each broker. + Has no effect with Zookeeper, which will always create a listener per pod. + type: boolean + prefix: + description: |- + prefix specifies the broker prefix for MDS/Zookeeper advertised endpoint. + If not configured, it uses `b` as default prefix for MDS, such as `b#.domain` where `#` will start from `0` to `replicaCount -1`. + It uses 'zookeeper' as default prefix for Zookeeper in the same way. + minLength: 1 + type: string + required: + - enabled + type: object + annotations: + additionalProperties: + type: string + description: annotations is a map of string + key and value pairs. It specifies Kubernetes + annotations for this service. + type: object + x-kubernetes-map-type: granular + domain: + description: domain specifies the domain name + of the Confluent component cluster. + minLength: 1 + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key + and value pairs. It specifies Kubernetes + labels for this service. + type: object + x-kubernetes-map-type: granular + prefix: + description: |- + prefix specifies the component prefix when configured for the domain. + The default value is the name of the cluster. + minLength: 1 + type: string + wildcardPolicy: + description: |- + wildcardPolicy allows you to define a route that covers all hosts within a domain. Valid options are `Subdomain` and `None`. + The default value is `None`. + enum: + - Subdomain + - None + type: string + required: + - domain + type: object + type: + description: |- + type specifies the Kubernetes external service for the component. + Valid options are `loadBalancer`, `nodePort`, and `route`. + enum: + - loadBalancer + - nodePort + - route + minLength: 1 + type: string + required: + - type + type: object + tls: + description: tls specifies the TLS configuration for + the listener. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS + configuration for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret + containing the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + internal: + description: |- + internal specifies the Confluent component's internal listener. + This internal listener is for intra-communication between the pods. + properties: + port: + description: |- + port binds the given port to the internal listener. If not configured, + it will be defaulted to the component-specific internal port. + Port numbers lower than `9093` are reserved by CFK. + format: int32 + minimum: 9093 + type: integer + tls: + description: tls specifies the TLS configuration for + the listener. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS + configuration for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret + containing the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + type: object + tls: + description: tls specifies the TLS configuration for embedded + REST API server. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + mds: + description: mds specifies the MDS server configuration. + properties: + authentication: + description: authentication specifies the MDS server authentication + configuration. + properties: + type: + description: type defines the MDS authentication type. + The valid option is `bearer`. + enum: + - bearer + type: string + required: + - type + type: object + externalAccess: + description: externalAccess specifies the external access + configuration. + properties: + loadBalancer: + description: loadBalancer specifies the configuration + to create a Kubernetes load balancer service. + properties: + advertisedURL: + description: |- + advertisedURL specifies the configuration for advertised listener per pod. It is only supported for MDS currently. + If it is enabled, instead of using internal endpoint, the MDS advertised listener for each broker will be + set to: `://.` where podId starts from `0` to `replicaCount -1`. + This is only recommended if you cannot add internal SANs to the TLS certificates for MDS and + the external DNS must be resolved inside the Kubernetes cluster. + This configuration will not take effect if MDS enabled dual listener setup. + properties: + enabled: + description: |- + enabled indicates whether to set the MDS advertised listener url with external endpoint for each broker. + Has no effect with Zookeeper, which will always create a listener per pod. + type: boolean + prefix: + description: |- + prefix specifies the broker prefix for MDS/Zookeeper advertised endpoint. + If not configured, it uses `b` as default prefix for MDS, such as `b#.domain` where `#` will start from `0` to `replicaCount -1`. + It uses 'zookeeper' as default prefix for Zookeeper in the same way. + minLength: 1 + type: string + required: + - enabled + type: object + annotations: + additionalProperties: + type: string + description: annotations is a map of string key and + value pairs. It specifies Kubernetes annotations + for this service. + type: object + x-kubernetes-map-type: granular + domain: + description: domain is the domain name of the component + cluster. + minLength: 1 + type: string + externalTrafficPolicy: + description: externalTrafficPolicy specifies the external + traffic policy for the service. Valid options are + `Local` and `Cluster`. + enum: + - Local + - Cluster + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key and value + pairs. It specifies Kubernetes labels for this service. + type: object + x-kubernetes-map-type: granular + loadBalancerSourceRanges: + description: loadBalancerSourceRanges specify the + source ranges. + items: + type: string + type: array + port: + description: |- + port specifies the external port for the client consumption. + If not configured, the same internal/external port is configured for the component. + Information about the port can be retrieved through the status API. + format: int32 + type: integer + prefix: + description: |- + prefix specify the prefix for the given domain. + The default value is the name of the cluster. + minLength: 1 + type: string + servicePorts: + description: servicePorts specify the user-provided + service port(s). + 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 + sessionAffinity: + description: |- + sessionAffinity defines the Kubernetes session affinity. The valid options are `ClientIP` and `None`. `ClientIP` enables the client IP-based session affinity. + The default value is `None`. + More info: https://kubernetes.io/docs/reference/networking/virtual-ips/#session-affinity. + enum: + - ClientIP + - None + type: string + sessionAffinityConfig: + description: SessionAffinityConfig contains the configurations + of the 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 + required: + - domain + type: object + nodePort: + description: nodePort specifies the configuration to create + a Kubernetes node port service. + properties: + advertisedURL: + description: |- + advertisedURL specifies the configuration for advertised listener per pod. It is only supported for MDS currently. + If it is enabled, instead of using internal endpoint, the MDS advertised listener for each broker will be + set to `://:, where`podId` starts from `0` to `replicaCount - 1`. + This is only recommended if you cannot add internal SANs to the TLS certificates for MDS and + the external DNS must be resolved inside the Kubernetes cluster. + properties: + enabled: + description: |- + enabled indicates whether to set the MDS advertised listener url with external endpoint for each broker. + Has no effect with Zookeeper, which will always create a listener per pod. + type: boolean + prefix: + description: |- + prefix specifies the broker prefix for MDS/Zookeeper advertised endpoint. + If not configured, it uses `b` as default prefix for MDS, such as `b#.domain` where `#` will start from `0` to `replicaCount -1`. + It uses 'zookeeper' as default prefix for Zookeeper in the same way. + minLength: 1 + type: string + required: + - enabled + type: object + annotations: + additionalProperties: + type: string + description: annotations is a map of string key and + value pairs. It specifies Kubernetes annotations + for this service. + type: object + x-kubernetes-map-type: granular + externalTrafficPolicy: + description: |- + externalTrafficPolicy specifies the external traffic policy for the service. + Valid options are `Local` and `Cluster`. + enum: + - Local + - Cluster + type: string + host: + description: host defines the host name of the cluster. + minLength: 1 + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key and value + pairs. It specifies Kubernetes labels for this service. + type: object + x-kubernetes-map-type: granular + nodePortOffset: + description: |- + nodePortOffset specifies the starting offset of the node ports. The port numbers go in ascending order with respect + to the replicas count. + NodePort service creation fails if the node port is not in the range supported by the Kubernetes API server. + The default Kubernetes Node Port range is `30000` - `32762`. + format: int32 + minimum: 0 + type: integer + servicePorts: + description: |- + servicePorts specify user-provided service port(s). + For Kafka with the nodePort type, this setting is only applied to Kafka bootstrap service. + 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 + sessionAffinity: + description: |- + sessionAffinity defines the Kubernetes session affinity. The valid options are `ClientIP` and `None`. `ClientIP` enables the client IP-based session affinity. + The default value is `None`. + More info: https://kubernetes.io/docs/reference/networking/virtual-ips/#session-affinity. + enum: + - ClientIP + - None + type: string + sessionAffinityConfig: + description: SessionAffinityConfig contains the configurations + of the 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 + required: + - host + - nodePortOffset + type: object + route: + description: route specifies the configuration to create + a route service in OpenShift. + properties: + advertisedURL: + description: |- + advertisedURL specifies the configuration for advertised listener per pod. It is only supported for MDS currently. + If it is enabled, instead of using internal endpoint, the MDS advertised listener for each broker will be + set to: `://-http-external.` where podId starts from `0` to `replicaCount -1`. + This is only recommended if you cannot add internal SANs to the TLS certificates for MDS and + the external DNS must be resolved inside the Kubernetes cluster. + This configuration will not take effect if MDS enabled dual listener setup. + properties: + enabled: + description: |- + enabled indicates whether to set the MDS advertised listener url with external endpoint for each broker. + Has no effect with Zookeeper, which will always create a listener per pod. + type: boolean + prefix: + description: |- + prefix specifies the broker prefix for MDS/Zookeeper advertised endpoint. + If not configured, it uses `b` as default prefix for MDS, such as `b#.domain` where `#` will start from `0` to `replicaCount -1`. + It uses 'zookeeper' as default prefix for Zookeeper in the same way. + minLength: 1 + type: string + required: + - enabled + type: object + annotations: + additionalProperties: + type: string + description: annotations is a map of string key and + value pairs. It specifies Kubernetes annotations + for this service. + type: object + x-kubernetes-map-type: granular + domain: + description: domain specifies the domain name of the + Confluent component cluster. + minLength: 1 + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key and value + pairs. It specifies Kubernetes labels for this service. + type: object + x-kubernetes-map-type: granular + prefix: + description: |- + prefix specifies the component prefix when configured for the domain. + The default value is the name of the cluster. + minLength: 1 + type: string + wildcardPolicy: + description: |- + wildcardPolicy allows you to define a route that covers all hosts within a domain. Valid options are `Subdomain` and `None`. + The default value is `None`. + enum: + - Subdomain + - None + type: string + required: + - domain + type: object + type: + description: |- + type specifies the Kubernetes external service for the component. + Valid options are `loadBalancer`, `nodePort`, and `route`. + enum: + - loadBalancer + - nodePort + - route + minLength: 1 + type: string + required: + - type + type: object + listeners: + description: listeners specify the listeners configurations + for MDS server. + properties: + external: + description: external specifies the Confluent component + external listener. + properties: + externalAccess: + description: externalAccess defines the external access + configuration for the Confluent component. + properties: + loadBalancer: + description: loadBalancer specifies the configuration + to create a Kubernetes load balancer service. + properties: + advertisedURL: + description: |- + advertisedURL specifies the configuration for advertised listener per pod. It is only supported for MDS currently. + If it is enabled, instead of using internal endpoint, the MDS advertised listener for each broker will be + set to: `://.` where podId starts from `0` to `replicaCount -1`. + This is only recommended if you cannot add internal SANs to the TLS certificates for MDS and + the external DNS must be resolved inside the Kubernetes cluster. + This configuration will not take effect if MDS enabled dual listener setup. + properties: + enabled: + description: |- + enabled indicates whether to set the MDS advertised listener url with external endpoint for each broker. + Has no effect with Zookeeper, which will always create a listener per pod. + type: boolean + prefix: + description: |- + prefix specifies the broker prefix for MDS/Zookeeper advertised endpoint. + If not configured, it uses `b` as default prefix for MDS, such as `b#.domain` where `#` will start from `0` to `replicaCount -1`. + It uses 'zookeeper' as default prefix for Zookeeper in the same way. + minLength: 1 + type: string + required: + - enabled + type: object + annotations: + additionalProperties: + type: string + description: annotations is a map of string + key and value pairs. It specifies Kubernetes + annotations for this service. + type: object + x-kubernetes-map-type: granular + domain: + description: domain is the domain name of + the component cluster. + minLength: 1 + type: string + externalTrafficPolicy: + description: externalTrafficPolicy specifies + the external traffic policy for the service. + Valid options are `Local` and `Cluster`. + enum: + - Local + - Cluster + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key + and value pairs. It specifies Kubernetes + labels for this service. + type: object + x-kubernetes-map-type: granular + loadBalancerSourceRanges: + description: loadBalancerSourceRanges specify + the source ranges. + items: + type: string + type: array + port: + description: |- + port specifies the external port for the client consumption. + If not configured, the same internal/external port is configured for the component. + Information about the port can be retrieved through the status API. + format: int32 + type: integer + prefix: + description: |- + prefix specify the prefix for the given domain. + The default value is the name of the cluster. + minLength: 1 + type: string + servicePorts: + description: servicePorts specify the user-provided + service port(s). + 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 + sessionAffinity: + description: |- + sessionAffinity defines the Kubernetes session affinity. The valid options are `ClientIP` and `None`. `ClientIP` enables the client IP-based session affinity. + The default value is `None`. + More info: https://kubernetes.io/docs/reference/networking/virtual-ips/#session-affinity. + enum: + - ClientIP + - None + type: string + sessionAffinityConfig: + description: SessionAffinityConfig contains + the configurations of the 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 + required: + - domain + type: object + nodePort: + description: nodePort specifies the configuration + to create a Kubernetes node port service. + properties: + advertisedURL: + description: |- + advertisedURL specifies the configuration for advertised listener per pod. It is only supported for MDS currently. + If it is enabled, instead of using internal endpoint, the MDS advertised listener for each broker will be + set to `://:, where`podId` starts from `0` to `replicaCount - 1`. + This is only recommended if you cannot add internal SANs to the TLS certificates for MDS and + the external DNS must be resolved inside the Kubernetes cluster. + properties: + enabled: + description: |- + enabled indicates whether to set the MDS advertised listener url with external endpoint for each broker. + Has no effect with Zookeeper, which will always create a listener per pod. + type: boolean + prefix: + description: |- + prefix specifies the broker prefix for MDS/Zookeeper advertised endpoint. + If not configured, it uses `b` as default prefix for MDS, such as `b#.domain` where `#` will start from `0` to `replicaCount -1`. + It uses 'zookeeper' as default prefix for Zookeeper in the same way. + minLength: 1 + type: string + required: + - enabled + type: object + annotations: + additionalProperties: + type: string + description: annotations is a map of string + key and value pairs. It specifies Kubernetes + annotations for this service. + type: object + x-kubernetes-map-type: granular + externalTrafficPolicy: + description: |- + externalTrafficPolicy specifies the external traffic policy for the service. + Valid options are `Local` and `Cluster`. + enum: + - Local + - Cluster + type: string + host: + description: host defines the host name of + the cluster. + minLength: 1 + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key + and value pairs. It specifies Kubernetes + labels for this service. + type: object + x-kubernetes-map-type: granular + nodePortOffset: + description: |- + nodePortOffset specifies the starting offset of the node ports. The port numbers go in ascending order with respect + to the replicas count. + NodePort service creation fails if the node port is not in the range supported by the Kubernetes API server. + The default Kubernetes Node Port range is `30000` - `32762`. + format: int32 + minimum: 0 + type: integer + servicePorts: + description: |- + servicePorts specify user-provided service port(s). + For Kafka with the nodePort type, this setting is only applied to Kafka bootstrap service. + 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 + sessionAffinity: + description: |- + sessionAffinity defines the Kubernetes session affinity. The valid options are `ClientIP` and `None`. `ClientIP` enables the client IP-based session affinity. + The default value is `None`. + More info: https://kubernetes.io/docs/reference/networking/virtual-ips/#session-affinity. + enum: + - ClientIP + - None + type: string + sessionAffinityConfig: + description: SessionAffinityConfig contains + the configurations of the 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 + required: + - host + - nodePortOffset + type: object + route: + description: route specifies the configuration + to create a route service in OpenShift. + properties: + advertisedURL: + description: |- + advertisedURL specifies the configuration for advertised listener per pod. It is only supported for MDS currently. + If it is enabled, instead of using internal endpoint, the MDS advertised listener for each broker will be + set to: `://-http-external.` where podId starts from `0` to `replicaCount -1`. + This is only recommended if you cannot add internal SANs to the TLS certificates for MDS and + the external DNS must be resolved inside the Kubernetes cluster. + This configuration will not take effect if MDS enabled dual listener setup. + properties: + enabled: + description: |- + enabled indicates whether to set the MDS advertised listener url with external endpoint for each broker. + Has no effect with Zookeeper, which will always create a listener per pod. + type: boolean + prefix: + description: |- + prefix specifies the broker prefix for MDS/Zookeeper advertised endpoint. + If not configured, it uses `b` as default prefix for MDS, such as `b#.domain` where `#` will start from `0` to `replicaCount -1`. + It uses 'zookeeper' as default prefix for Zookeeper in the same way. + minLength: 1 + type: string + required: + - enabled + type: object + annotations: + additionalProperties: + type: string + description: annotations is a map of string + key and value pairs. It specifies Kubernetes + annotations for this service. + type: object + x-kubernetes-map-type: granular + domain: + description: domain specifies the domain name + of the Confluent component cluster. + minLength: 1 + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key + and value pairs. It specifies Kubernetes + labels for this service. + type: object + x-kubernetes-map-type: granular + prefix: + description: |- + prefix specifies the component prefix when configured for the domain. + The default value is the name of the cluster. + minLength: 1 + type: string + wildcardPolicy: + description: |- + wildcardPolicy allows you to define a route that covers all hosts within a domain. Valid options are `Subdomain` and `None`. + The default value is `None`. + enum: + - Subdomain + - None + type: string + required: + - domain + type: object + type: + description: |- + type specifies the Kubernetes external service for the component. + Valid options are `loadBalancer`, `nodePort`, and `route`. + enum: + - loadBalancer + - nodePort + - route + minLength: 1 + type: string + required: + - type + type: object + tls: + description: tls specifies the TLS configuration for + the listener. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS + configuration for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret + containing the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + internal: + description: |- + internal specifies the Confluent component's internal listener. + This internal listener is for intra-communication between the pods. + properties: + port: + description: |- + port binds the given port to the internal listener. If not configured, + it will be defaulted to the component-specific internal port. + Port numbers lower than `9093` are reserved by CFK. + format: int32 + minimum: 9093 + type: integer + tls: + description: tls specifies the TLS configuration for + the listener. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS + configuration for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret + containing the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + type: object + provider: + description: provider specifies the identity provider configuration. + properties: + ldap: + description: ldap defines the LDAP service configuration. + properties: + address: + description: address defines the LDAP server address. + type: string + authentication: + description: LdapAuthentication specifies the LDAP + authentication configuration. + properties: + simple: + description: simple specifies simple authentication + configuration for the LDAP. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer defines the directory path in the container + where the credentials are mounted. + minLength: 1 + type: string + secretRef: + description: secretRef references the name + of the secret that contains the credentials. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + type: + description: type defines the authentication method + for LDAP. Valid options are `simple` and `mtls`. + enum: + - simple + - mtls + type: string + required: + - type + type: object + configurations: + description: configurations defines the LDAP configurations + for Confluent RBAC. + properties: + groupMemberAttribute: + description: groupMemberAttribute specifies the + LDAP group member attribute. + minLength: 1 + type: string + groupMemberAttributePattern: + description: groupMemberAttributePattern specifies + the regular expression pattern for the LDAP + group member attribute. + minLength: 1 + type: string + groupNameAttribute: + description: groupNameAttribute specifies the + LDAP group name attribute. + minLength: 1 + type: string + groupObjectClass: + description: groupObjectClass specifies the LDAP + group object class. + minLength: 1 + type: string + groupSearchBase: + description: groupSearchBase specifies the LDAP + search base for the group-based search. + minLength: 1 + type: string + groupSearchFilter: + description: groupSearchFilter specifies the LDAP + search filter for the group-based search. + minLength: 1 + type: string + groupSearchScope: + description: groupSearchScope specifies the LDAP + search scope for the group-based search. + format: int32 + type: integer + userMemberOfAttributePattern: + description: userMemberOfAttributePattern specifies + the regular expression pattern for the LDAP + user member attribute. + minLength: 1 + type: string + userNameAttribute: + description: userNameAttribute specifies the LDAP + username attribute. + minLength: 1 + type: string + userObjectClass: + description: userObjectClass specifies the LDAP + user object class. + minLength: 1 + type: string + userSearchBase: + description: userSearchBase specifies the LDAP + search base for the user-based search. + minLength: 1 + type: string + userSearchFilter: + description: userSearchFilter specifies the LDAP + search filter for the user-based search. + minLength: 1 + type: string + userSearchScope: + description: userSearchScope specifies the LDAP + search scope for the user-based search. + format: int32 + type: integer + type: object + tls: + description: tls specifies the TLS configuration for + the LDAP. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS + configuration for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret + containing the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + required: + - address + - authentication + - configurations + type: object + oauth: + description: oauth defines the OAuth service configuration. + properties: + configurations: + description: configurations defines the OAuth configurations. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name + of claim in token for identifying the groups + of subject in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect + timeout with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + tls: + description: tls specifies the TLS configuration for + the OAuth IDP. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS + configuration for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret + containing the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + required: + - configurations + type: object + oidc: + description: |- + this field has been superseded with sso field + oidc defines the OIDC service configuration. + properties: + clientCredentials: + description: clientCredentials define the IDP clientID + and clientSecret. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer defines the directory path in the container + where the credentials are mounted. + minLength: 1 + type: string + secretRef: + description: secretRef references the name of + the secret that contains the credentials. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + configurations: + description: configurations defines the OIDC configurations. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + authorizeBaseEndpointUri: + description: authorizeBaseEndpointUri specifies + the base uri for authorize endpoint. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name + of claim in token for identifying the groups + of subject in the JWT payload. + minLength: 1 + type: string + groupsClaimScope: + description: |- + groupsClaimScope specifies additional scope needed for the token to contain groups claim (field). + Leave this field empty (or null) if id token always contains the claims identified as groups. + minLength: 1 + type: string + issuer: + description: |- + issuer specifies the authorization server's URL. + This value should match the issuer claim ("iss") in id tokens issued by Authorization Server? + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + refreshToken: + description: refreshToken specifies whether offline_access + scope should be requested in the authorization + URI. + type: boolean + sessionMaxTimeout: + description: sessionMaxTimeout specifies the maximum + expiration time for a user's session. + format: int32 + type: integer + sessionTokenExpiry: + description: sessionTokenExpiry specifies the + validity of cookie issued by Confluent. + format: int32 + type: integer + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenBaseEndpointUri: + description: tokenBaseEndpointUri specifies the + base uri for token endpoint. + minLength: 1 + type: string + required: + - authorizeBaseEndpointUri + - issuer + - jwksEndpointUri + - refreshToken + - tokenBaseEndpointUri + type: object + enabled: + default: true + description: |- + enabled specifies whether the SSO is enabled. + default is true. + type: boolean + required: + - clientCredentials + - configurations + type: object + sso: + description: sso defines the SSO service configuration. + properties: + clientCredentials: + description: clientCredentials define the IDP clientID + and clientSecret. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer defines the directory path in the container + where the credentials are mounted. + minLength: 1 + type: string + secretRef: + description: secretRef references the name of + the secret that contains the credentials. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + configurations: + description: configurations defines the OIDC configurations. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + authorizeBaseEndpointUri: + description: authorizeBaseEndpointUri specifies + the base uri for authorize endpoint. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name + of claim in token for identifying the groups + of subject in the JWT payload. + minLength: 1 + type: string + groupsClaimScope: + description: |- + groupsClaimScope specifies additional scope needed for the token to contain groups claim (field). + Leave this field empty (or null) if id token always contains the claims identified as groups. + minLength: 1 + type: string + issuer: + description: |- + issuer specifies the authorization server's URL. + This value should match the issuer claim ("iss") in id tokens issued by Authorization Server? + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + refreshToken: + description: refreshToken specifies whether offline_access + scope should be requested in the authorization + URI. + type: boolean + sessionMaxTimeout: + description: sessionMaxTimeout specifies the maximum + expiration time for a user's session. + format: int32 + type: integer + sessionTokenExpiry: + description: sessionTokenExpiry specifies the + validity of cookie issued by Confluent. + format: int32 + type: integer + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenBaseEndpointUri: + description: tokenBaseEndpointUri specifies the + base uri for token endpoint. + minLength: 1 + type: string + required: + - authorizeBaseEndpointUri + - issuer + - jwksEndpointUri + - refreshToken + - tokenBaseEndpointUri + type: object + enabled: + default: true + description: |- + enabled specifies whether the SSO is enabled. + default is true. + type: boolean + required: + - clientCredentials + - configurations + type: object + type: + description: This field has been deprecated and its value + will be ignored if set. + type: string + type: object + tls: + description: tls specifies the TLS configuration for MDS server. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + tokenKeyPair: + description: tokenKeyPair specifies the token key pair for + the MDS. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer defines the directory path in the container + where the MDS token key pair are mounted. + minLength: 1 + type: string + encryptedTokenKey: + description: |- + EncryptedTokenKey boolean value indicating whether the tokenKeypair(private used for signing) is encrypted using a passphrase. If true, cfk + operator will look for a file named mdsTokenKeyPassphrase.txt containing key value pair + mdsTokenKeyPassphrase=. Relevant only for mds server. Ignored if set for a client configuration. + type: boolean + secretRef: + description: secretRef references the name of the secret + that contains the MDS token key pair. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + required: + - provider + - tokenKeyPair + type: object + type: object + storageClass: + description: |- + storageClass specifies the user-provided storage class. If not + configured, it will use the default storage class. + properties: + name: + description: name is the storage class name. + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - name + type: object + telemetry: + description: telemetry specifies the Confluent telemetry reporter + configuration. + properties: + global: + description: |- + global allows disabling telemetry configuration. + If CFK is deployed with telemetry, this field is only + used to disable telemetry. The default value is `true` if + telemetry is enabled at the global level. + type: boolean + type: object + tls: + description: |- + tls specifies the global-level TLS configuration which can be used by + listeners and services. + properties: + autoGeneratedCerts: + description: |- + autoGeneratedCerts specifies that the certificates are auto-generated based on + the CA key pair provided. + type: boolean + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + fips: + description: |- + fips specifies the configuration of FIPS compliant Bouncy Castle type Java Keystores for the cp component's + TLS settings. TLS Secrets must have the keys keystore.bcfks, truststore.bcfks, and jksPassword.txt + properties: + enabled: + description: enabled specifies whether to enable the FIPS + configuration for cp components. + type: boolean + required: + - enabled + type: object + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing the + JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + required: + - dataVolumeCapacity + - image + type: object + status: + description: status defines the observed state of the Kafka cluster. + properties: + arbitraryData: + description: arbitraryData is the map for any arbitrary data associated + with this Confluent component. + x-kubernetes-preserve-unknown-fields: true + authorizationType: + description: authorizationType is the authorization type for this + Confluent component. + type: string + brokerIdOffset: + description: brokerIdOffset is the broker id offset of the Kafka cluster. + format: int32 + type: integer + clusterID: + description: clusterID is the ID of the Kafka cluster. + type: string + clusterName: + description: clusterName is the name of the Confluent Platform component + cluster. + type: string + clusterNamespace: + description: clusterNamespace is the namespace where the Confluent + Platform component cluster is running. + type: string + conditions: + description: conditions specify the latest available observations + of the current state. + items: + description: Condition represent the latest available observations + of the current state. + properties: + lastProbeTime: + description: lastProbeTime shows the last time the condition + was evaluated. + format: date-time + type: string + lastTransitionTime: + description: lastTransitionTime shows the last time the condition + was transitioned from one status to another. + format: date-time + type: string + message: + description: message shows a human-readable message with details + about the transition. + type: string + reason: + description: reason shows the reason for the last transition + of the condition. + type: string + status: + description: status shows the status of the condition, one of + `True`, `False`, or `Unknown`. + type: string + type: + description: type shows the condition type. + type: string + type: object + type: array + currentClusterVersion: + description: currentClusterVersion is the current CP Server version + type: string + currentReplicas: + description: currentReplicas is the number of currently running replicas. + format: int32 + type: integer + internalSecrets: + description: |- + internalSecrets are internal secrets created + by CFK for this Confluent component. + items: + type: string + type: array + internalTopicNames: + description: internalTopicNames are the topics used by the component + for internal use. + items: + type: string + type: array + listeners: + additionalProperties: + properties: + advertisedExternalEndpoints: + description: advertisedExternalEndpoints specifies other advertised + endpoints used, especially for Kafka. + items: + type: string + type: array + authenticationType: + description: authenticationType shows the authentication type + configured by the listener. + type: string + client: + type: string + externalAccessType: + description: externalAccessType shows the external access type + used for the listener. + type: string + externalEndpoint: + description: externalEndpoint specifies the external endpoint + to connect to the Confluent component cluster. + type: string + internalEndpoint: + description: internalEndpoint specifies the internal endpoint + to connect to the Confluent component cluster. + type: string + tls: + description: tls shows whether TLS is configured for the listener. + type: boolean + type: object + description: listeners is a map for the status of Kafka Listeners. + type: object + x-kubernetes-map-type: granular + minISR: + description: minISR is the minimum number of in sync replicas in the + Kafka cluster. + format: int32 + type: integer + observedGeneration: + description: observedGeneration is the most recent generation observed + for this Confluent component. + format: int64 + type: integer + operatorVersion: + description: operatorVersion is the internal version of CFK. + type: string + phase: + description: |- + phase describes the state of the Confluent Platform component. This can either be 'PROVISIONING' + or 'RUNNING' + 'PROVISIONING' means the Confluent Platform component is currently getting deployed and not ready yet. + 'RUNNING' means the Confluent Platform component has been successfully deployed. + type: string + previousClusterVersion: + description: previousClusterVersion is the previous CP Server version + of the kafka cluster. + type: string + readyReplicas: + description: readyReplicas is the number of currently ready replicas. + format: int32 + type: integer + replicas: + description: replicas is the number of replicas. + format: int32 + type: integer + replicationFactor: + description: replicationFactor is the replication factor of the topics + in the Kafka cluster. + format: int32 + type: integer + selector: + description: |- + selector gets the label selector of the child pod. + The Horizontal Pod Autoscaler(HPA) will scale using the label selector of the child pod. + type: string + services: + additionalProperties: + description: ListenerStatus describes general information about + the listeners. + properties: + advertisedExternalEndpoints: + description: advertisedExternalEndpoints specifies other advertised + endpoints used, especially for Kafka. + items: + type: string + type: array + authenticationType: + description: authenticationType shows the authentication type + configured by the listener. + type: string + externalAccessType: + description: externalAccessType shows the external access type + used for the listener. + type: string + externalEndpoint: + description: externalEndpoint specifies the external endpoint + to connect to the Confluent component cluster. + type: string + internalEndpoint: + description: internalEndpoint specifies the internal endpoint + to connect to the Confluent component cluster. + type: string + tls: + description: tls shows whether TLS is configured for the listener. + type: boolean + type: object + description: services is a map for the Kafka services. + type: object + x-kubernetes-map-type: granular + zookeeperConnect: + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.replicas + statusReplicasPath: .status.replicas + status: {} diff --git a/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_kafkatopics.yaml b/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_kafkatopics.yaml new file mode 100644 index 0000000000..0a71576b27 --- /dev/null +++ b/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_kafkatopics.yaml @@ -0,0 +1,410 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: kafkatopics.platform.confluent.io +spec: + group: platform.confluent.io + names: + categories: + - all + - confluent-platform + - confluent + kind: KafkaTopic + listKind: KafkaTopicList + plural: kafkatopics + shortNames: + - kt + - topic + singular: kafkatopic + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.replicas + name: Replicas + type: string + - jsonPath: .status.partitionCount + name: Partition + type: string + - jsonPath: .status.state + name: Status + type: string + - jsonPath: .status.kafkaClusterID + name: ClusterID + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.kafkaCluster + name: KafkaCluster + priority: 1 + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: KafkaTopic is the schema for the Kafka Topic 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 defines the desired state of the KafkaTopic. + properties: + configs: + additionalProperties: + type: string + description: |- + configs is a map of string key and value pairs that are used to pass the configuration settings for the topic. + More info: https://docs.confluent.io/current/installation/configuration/topic-configs.html. + type: object + x-kubernetes-map-type: granular + kafkaClusterRef: + description: kafkaClusterRef specifies the name of the Kafka cluster. + properties: + name: + description: name specifies the name of the Confluent Platform + component cluster. + type: string + namespace: + description: namespace specifies the namespace where the Confluent + Platform component cluster is running. + type: string + required: + - name + type: object + kafkaRest: + description: kafkaRest specifies the Kafka REST API configuration. + properties: + authentication: + description: authentication specifies the REST API authentication + mechanism. + properties: + basic: + description: basic specifies the basic authentication settings + for the REST API client. + properties: + debug: + description: debug enables the basic authentication debug + logs for JaaS configuration. + type: boolean + directoryPathInContainer: + description: |- + directoryPathInContainer allows to pass the basic credential through a directory path in the container. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + minLength: 1 + type: string + restrictedRoles: + description: |- + restrictedRoles specify the restricted roles on the server side only. + Changes will be only reflected in Control Center. + This configuration is ignored on the client side configuration. + items: + type: string + minItems: 1 + type: array + roles: + description: |- + roles specify the roles on the server side only. + This configuration is ignored on the client side configuration. + items: + type: string + type: array + secretRef: + description: |- + secretRef defines secret reference to pass the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + bearer: + description: bearer specifies the bearer authentication settings + for the REST API client. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container + where the credential is mounted. + minLength: 1 + type: string + secretRef: + description: |- + secretRef specifies the name of the secret that contains the credential. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#bearer-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauth: + description: oauth specifies the OAuth authentication settings + for the REST API client. + properties: + configuration: + description: configuration specifies the OAuth server + settings. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name of + claim in token for identifying the groups of subject + in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect timeout + with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + directoryPathInContainer: + description: directoryPathInContainer allows to pass the + basic credential through a directory path in the container. + minLength: 1 + type: string + secretRef: + description: secretRef defines secret reference to pass + the required credentials. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - configuration + type: object + type: + description: type specifies the REST API authentication type. + Valid options are `basic`, `bearer`, `mtls` and `oauth`. + enum: + - basic + - bearer + - mtls + - oauth + type: string + required: + - type + type: object + endpoint: + description: endpoint specifies where Confluent REST API is running. + minLength: 1 + pattern: ^https?://.* + type: string + kafkaClusterID: + description: |- + kafkaClusterID specifies the id of Kafka cluster. + It takes precedence over using the Kafka REST API to get the cluster id. + minLength: 1 + type: string + tls: + description: "tls specifies the custom TLS structure for the application + resources,\n\t// e.g. connector, topic, schema, of the Confluent + Platform components.\n\t// +optional" + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer contains the directory path in the container where + `keystore.jks`, `truststore.jks`, `jksPassword.txt` keys are mounted. + minLength: 1 + type: string + jksPassword: + description: jksPassword specifies the secret name that contains + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef specifies the secret name that contains the certificates. + More info about certificates key/value format: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + type: object + kafkaRestClassRef: + description: kafkaRestClassRef references the KafkaRestClass which + defines Kafka REST API connection information. + properties: + name: + description: name specifies the name of the KafkaRestClass application + resource. + minLength: 1 + type: string + namespace: + description: namespace specifies the namespace of the KafkaRestClass. + type: string + required: + - name + type: object + name: + description: |- + name specifies the topic name. If not configured, the KafkaTopic CR name is used + as the topic name. + maxLength: 255 + minLength: 1 + pattern: ^[a-zA-Z0-9\._\-]*$ + type: string + partitionCount: + description: |- + partitionCount specifies the number of partitions for the topic. + If not configured, it will be defaulted to the partition count that Kafka REST V3 API supports. + format: int32 + type: integer + replicas: + description: |- + replicas specifies the replication factor for the topic. + If not configured, it will be defaulted to the replication factor that Kafka REST V3 API supports. + format: int32 + type: integer + type: object + status: + description: status defines the observed state of the KafkaTopic. + properties: + appState: + default: Unknown + description: appState is the current state of the topic application. + enum: + - Unknown + - Created + - Failed + - Deleted + type: string + conditions: + description: conditions are the latest available observed states of + the topic. + items: + description: Condition represent the latest available observations + of the current state. + properties: + lastProbeTime: + description: lastProbeTime shows the last time the condition + was evaluated. + format: date-time + type: string + lastTransitionTime: + description: lastTransitionTime shows the last time the condition + was transitioned from one status to another. + format: date-time + type: string + message: + description: message shows a human-readable message with details + about the transition. + type: string + reason: + description: reason shows the reason for the last transition + of the condition. + type: string + status: + description: status shows the status of the condition, one of + `True`, `False`, or `Unknown`. + type: string + type: + description: type shows the condition type. + type: string + type: object + type: array + kafkaCluster: + type: string + kafkaClusterID: + description: kafkaClusterID is the id of the Kafka cluster. + type: string + kafkaRestEndpoint: + description: kafkaRestEndpoint is the endpoint of the Kafka REST API. + type: string + observedGeneration: + description: observedGeneration is the most recent generation observed + for this Confluent component. + format: int64 + type: integer + partitionCount: + description: partitionCount is the partition count of the topic. + format: int32 + type: integer + replicas: + description: replicas is the replication factor of the topic. + format: int32 + type: integer + state: + description: state is the state of the topic. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_kraftcontrollers.yaml b/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_kraftcontrollers.yaml new file mode 100644 index 0000000000..dc6bd45ba0 --- /dev/null +++ b/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_kraftcontrollers.yaml @@ -0,0 +1,5752 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: kraftcontrollers.platform.confluent.io +spec: + group: platform.confluent.io + names: + categories: + - all + - confluent-platform + - confluent + kind: KRaftController + listKind: KRaftControllerList + plural: kraftcontrollers + shortNames: + - kraftcontroller + - kraft + singular: kraftcontroller + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.replicas + name: Replicas + type: string + - jsonPath: .status.readyReplicas + name: Ready + type: string + - jsonPath: .status.phase + name: Status + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.controllerQuorumVoters + name: ControllerQuorumVoters + priority: 1 + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: KRaftController is the schema for the KRaft Controller 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 defines the desired state of the KRaft Controller cluster. + properties: + authorization: + description: authorization specifies the authorization configuration. + properties: + superUsers: + description: |- + superUsers specify the super users to give the admin privilege on the Kafka Cluster. + This list takes the format as `User:` + items: + type: string + type: array + type: + description: type specifies the authorization type. The valid + options are `rbac` and `simple`. + enum: + - rbac + - simple + type: string + required: + - type + type: object + clusterID: + description: |- + clusterID specifies the ID of the KRaft Controller cluster. It must contain only alphanumeric characters and the + hyphen character and be of length 22. If omitted, a clusterID will be autogenerated. + In the case of attaching to existing Persistent Volumes, you must match the old clusterID. + maxLength: 22 + minLength: 22 + pattern: ^[a-zA-Z0-9\-\_]*$ + type: string + configOverrides: + description: configOverrides specifies the configs to override the + server, JVM, Log4j properties for the KRaft Controller cluster. + properties: + jvm: + description: |- + jvm is a list of JVM configuration supported by the Confluent Platform component. + This will either add or update the existing configuration. + items: + type: string + type: array + log4j: + description: |- + log4j is a list of Log4J configuration supported by the Confluent Platform component. + This will either add or update the existing configuration. + items: + type: string + type: array + server: + description: |- + server is a list of server configuration supported by the Confluent Platform component. + This will either add or update existing configuration. + items: + type: string + type: array + type: object + controllerQuorumVoters: + description: |- + QuorumVoters specify a list of kraft controllers. This is only required when deploying stretch + kafka clusters for MRC deployments in multiple DCs (or K8s clusters) and should include all the kraft controllers in other DCs that form the ensemble. + items: + description: ControllerQuorumVoter defines the KRaft controller + quorum voter. + properties: + brokerEndpoint: + description: brokerEndpoint is the endpoint of the KRaft Controller. + type: string + nodeId: + description: nodeId is the nodeId of the KRaft Controller. + format: int32 + type: integer + required: + - brokerEndpoint + - nodeId + type: object + type: array + dataVolumeCapacity: + anyOf: + - type: integer + - type: string + description: dataVolumeCapacity specifies the persistent volume capacity + for the KRaft Controller cluster. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + dependencies: + description: de + properties: + mdsKafkaCluster: + properties: + authentication: + description: authentication defines the authentication for + the Kafka cluster. + properties: + jaasConfig: + description: jaasConfig specifies the Kafka client-side + JaaS configuration. + properties: + secretRef: + description: |- + secretRef references the secret containing the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + jaasConfigPassThrough: + description: jaasConfigPassThrough specifies another way + to provide the Kafka client-side JaaS configuration. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where required credentials are mounted. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + minLength: 1 + type: string + secretRef: + description: |- + secretRef references the secret containing the required credentials for authentication. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauthSettings: + description: |- + oauthSettings specifies the OAuth settings. + This needs to passed with the authentication type `oauth`. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name of + claim in token for identifying the groups of subject + in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect timeout + with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + oauthbearer: + description: |- + oauthbearer is the authentication mechanism to provider principals. + Only supported in RBAC deployment. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container + where the credential is mounted. + minLength: 1 + type: string + secretRef: + description: |- + secretRef specifies the name of the secret that contains the credential. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#bearer-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + type: + description: |- + type specifies the Kafka client authentication type. + Valid options are `plain`, `oauthbearer`, `digest`, `mtls` and `oauth`. + enum: + - plain + - oauthbearer + - digest + - mtls + - oauth + type: string + required: + - type + type: object + bootstrapEndpoint: + description: bootstrapEndpoint specifies the Kafka bootstrap + endpoint. + minLength: 1 + pattern: .+:[0-9]+ + type: string + tls: + description: tls defines the client-side TLS setting for the + Kafka cluster. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + type: object + fips: + description: |- + fips specifies the configuration of FIPS compliant Bouncy Castle type Java Keystores for the KRaft Controller + cluster's TLS settings. TLS Secrets must have the keys keystore.bcfks, truststore.bcfks, and jksPassword.txt + properties: + enabled: + description: enabled specifies whether to enable the FIPS configuration + for cp components. + type: boolean + required: + - enabled + type: object + headlessService: + description: headlessService specifies the configuration of the Kubernetes + headless service. + properties: + annotations: + additionalProperties: + type: string + description: |- + annotations is a map of string key and value pairs. + It specifies the annotations to be added to the CFK-created headless service. + These annotations are merged with the injectAnnotations and take precedence. + type: object + x-kubernetes-map-type: granular + labels: + additionalProperties: + type: string + description: |- + labels is a map of string key and value pairs. + It specifies the labels to be added to the CFK-created headless service. + These labels are merged with the injectLabels and take precedence. + type: object + x-kubernetes-map-type: granular + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses specifies the publishNotReadyAddresses field. + For Kafka, this value must be true. The default value is true. + type: boolean + type: object + identityProvider: + description: |- + identityProvider specifies the identity provider configuration. + It is only required for the Kafka authentication type `ldap`. + properties: + ldap: + description: ldap defines the LDAP service configuration. + properties: + address: + description: address defines the LDAP server address. + type: string + authentication: + description: LdapAuthentication specifies the LDAP authentication + configuration. + properties: + simple: + description: simple specifies simple authentication configuration + for the LDAP. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer defines the directory path in the container + where the credentials are mounted. + minLength: 1 + type: string + secretRef: + description: secretRef references the name of the + secret that contains the credentials. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + type: + description: type defines the authentication method for + LDAP. Valid options are `simple` and `mtls`. + enum: + - simple + - mtls + type: string + required: + - type + type: object + configurations: + description: configurations defines the LDAP configurations + for Confluent RBAC. + properties: + groupMemberAttribute: + description: groupMemberAttribute specifies the LDAP group + member attribute. + minLength: 1 + type: string + groupMemberAttributePattern: + description: groupMemberAttributePattern specifies the + regular expression pattern for the LDAP group member + attribute. + minLength: 1 + type: string + groupNameAttribute: + description: groupNameAttribute specifies the LDAP group + name attribute. + minLength: 1 + type: string + groupObjectClass: + description: groupObjectClass specifies the LDAP group + object class. + minLength: 1 + type: string + groupSearchBase: + description: groupSearchBase specifies the LDAP search + base for the group-based search. + minLength: 1 + type: string + groupSearchFilter: + description: groupSearchFilter specifies the LDAP search + filter for the group-based search. + minLength: 1 + type: string + groupSearchScope: + description: groupSearchScope specifies the LDAP search + scope for the group-based search. + format: int32 + type: integer + userMemberOfAttributePattern: + description: userMemberOfAttributePattern specifies the + regular expression pattern for the LDAP user member + attribute. + minLength: 1 + type: string + userNameAttribute: + description: userNameAttribute specifies the LDAP username + attribute. + minLength: 1 + type: string + userObjectClass: + description: userObjectClass specifies the LDAP user object + class. + minLength: 1 + type: string + userSearchBase: + description: userSearchBase specifies the LDAP search + base for the user-based search. + minLength: 1 + type: string + userSearchFilter: + description: userSearchFilter specifies the LDAP search + filter for the user-based search. + minLength: 1 + type: string + userSearchScope: + description: userSearchScope specifies the LDAP search + scope for the user-based search. + format: int32 + type: integer + type: object + tls: + description: tls specifies the TLS configuration for the LDAP. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + required: + - address + - authentication + - configurations + type: object + oauth: + description: oauth defines the OAuth service configuration. + properties: + configurations: + description: configurations defines the OAuth configurations. + properties: + audience: + description: audience specifies the audience claim in + the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected issuer + in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name of claim + in token for identifying the groups of subject in the + JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect timeout + with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout with + IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry backoff + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff with + IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim in JWT + to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + tls: + description: tls specifies the TLS configuration for the OAuth + IDP. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + required: + - configurations + type: object + oidc: + description: |- + this field has been superseded with sso field + oidc defines the OIDC service configuration. + properties: + clientCredentials: + description: clientCredentials define the IDP clientID and + clientSecret. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer defines the directory path in the container + where the credentials are mounted. + minLength: 1 + type: string + secretRef: + description: secretRef references the name of the secret + that contains the credentials. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + configurations: + description: configurations defines the OIDC configurations. + properties: + audience: + description: audience specifies the audience claim in + the JWT payload. + minLength: 1 + type: string + authorizeBaseEndpointUri: + description: authorizeBaseEndpointUri specifies the base + uri for authorize endpoint. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name of claim + in token for identifying the groups of subject in the + JWT payload. + minLength: 1 + type: string + groupsClaimScope: + description: |- + groupsClaimScope specifies additional scope needed for the token to contain groups claim (field). + Leave this field empty (or null) if id token always contains the claims identified as groups. + minLength: 1 + type: string + issuer: + description: |- + issuer specifies the authorization server's URL. + This value should match the issuer claim ("iss") in id tokens issued by Authorization Server? + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + refreshToken: + description: refreshToken specifies whether offline_access + scope should be requested in the authorization URI. + type: boolean + sessionMaxTimeout: + description: sessionMaxTimeout specifies the maximum expiration + time for a user's session. + format: int32 + type: integer + sessionTokenExpiry: + description: sessionTokenExpiry specifies the validity + of cookie issued by Confluent. + format: int32 + type: integer + subClaimName: + description: subClaimName specifies name of claim in JWT + to use for the subject. + minLength: 1 + type: string + tokenBaseEndpointUri: + description: tokenBaseEndpointUri specifies the base uri + for token endpoint. + minLength: 1 + type: string + required: + - authorizeBaseEndpointUri + - issuer + - jwksEndpointUri + - refreshToken + - tokenBaseEndpointUri + type: object + enabled: + default: true + description: |- + enabled specifies whether the SSO is enabled. + default is true. + type: boolean + required: + - clientCredentials + - configurations + type: object + sso: + description: sso defines the SSO service configuration. + properties: + clientCredentials: + description: clientCredentials define the IDP clientID and + clientSecret. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer defines the directory path in the container + where the credentials are mounted. + minLength: 1 + type: string + secretRef: + description: secretRef references the name of the secret + that contains the credentials. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + configurations: + description: configurations defines the OIDC configurations. + properties: + audience: + description: audience specifies the audience claim in + the JWT payload. + minLength: 1 + type: string + authorizeBaseEndpointUri: + description: authorizeBaseEndpointUri specifies the base + uri for authorize endpoint. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name of claim + in token for identifying the groups of subject in the + JWT payload. + minLength: 1 + type: string + groupsClaimScope: + description: |- + groupsClaimScope specifies additional scope needed for the token to contain groups claim (field). + Leave this field empty (or null) if id token always contains the claims identified as groups. + minLength: 1 + type: string + issuer: + description: |- + issuer specifies the authorization server's URL. + This value should match the issuer claim ("iss") in id tokens issued by Authorization Server? + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + refreshToken: + description: refreshToken specifies whether offline_access + scope should be requested in the authorization URI. + type: boolean + sessionMaxTimeout: + description: sessionMaxTimeout specifies the maximum expiration + time for a user's session. + format: int32 + type: integer + sessionTokenExpiry: + description: sessionTokenExpiry specifies the validity + of cookie issued by Confluent. + format: int32 + type: integer + subClaimName: + description: subClaimName specifies name of claim in JWT + to use for the subject. + minLength: 1 + type: string + tokenBaseEndpointUri: + description: tokenBaseEndpointUri specifies the base uri + for token endpoint. + minLength: 1 + type: string + required: + - authorizeBaseEndpointUri + - issuer + - jwksEndpointUri + - refreshToken + - tokenBaseEndpointUri + type: object + enabled: + default: true + description: |- + enabled specifies whether the SSO is enabled. + default is true. + type: boolean + required: + - clientCredentials + - configurations + type: object + type: + description: This field has been deprecated and its value will + be ignored if set. + type: string + type: object + image: + description: |- + image specifies the application and the init docker image configurations. + A change to this setting will roll the cluster. + properties: + application: + description: |- + application is the Docker image name of the application. Specify + `//:`. + pattern: .+:.+ + type: string + init: + description: |- + init is the init-container name. Specify + `//:`. + pattern: .+:.+ + type: string + pullPolicy: + description: |- + pullPolicy is the policy for pulling images. Valid options are `Always`, `Never`, and `IfNotPresent`. + The default value is `IfNotPresent`. + enum: + - Always + - Never + - IfNotPresent + type: string + pullSecretRef: + description: |- + pullSecretRef references the secrets in the same namespace to be used for pulling images. + Image pull secrets are distinct from secrets because secrets + can be mounted in the pod, but image pull secrets are only accessed by `kubelet`. + More info: https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod + items: + type: string + type: array + required: + - application + - init + type: object + injectAnnotations: + additionalProperties: + type: string + description: |- + injectAnnotations are the annotations injected to the internal resources that CFK created. + The internal annotations are preserved and cannot be overridden. + For pod annotations, use `podTemplate.annotations`. + type: object + x-kubernetes-map-type: granular + injectLabels: + additionalProperties: + type: string + description: |- + injectLabels are the labels injected to the internal resources that CFK created. + The internal labels are preserved and cannot be overridden. + For pod labels, use `podTemplate.labels`. + type: object + x-kubernetes-map-type: granular + k8sClusterDomain: + description: |- + k8sClusterDomain specifies the configuration of the Kubernetes cluster domain. + The default is the `cluster.local` domain. + type: string + license: + description: license specifies the license configuration for the Confluent + Platform component. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + the license key is mounted. More info: + https://docs.confluent.io/operator/current/co-license.html#update-component-level-licenses + minLength: 1 + type: string + globalLicense: + description: globalLicense specifies whether the Confluent Platform + component shares the common global license. + type: boolean + secretRef: + description: |- + secretRef references the secret that provides the license for the Confluent Platform component. + More info: https://docs.confluent.io/operator/current/co-license.html#update-component-level-licenses + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + listeners: + description: listeners specify the listeners configurations. + properties: + controller: + description: controller specifies the controller listener. + properties: + authentication: + description: authentication specifies the authentication configuration + for the listener. + properties: + jaasConfig: + description: |- + jaasConfig specifies the JaaS configuration. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + properties: + secretRef: + description: |- + secretRef references the secret containing the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + jaasConfigPassThrough: + description: |- + jaasConfigPassThrough specifies another way to provide JaaS configuration. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where required credentials are mounted. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + minLength: 1 + type: string + secretRef: + description: |- + secretRef references the secret containing the required credentials for authentication. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauthSettings: + description: |- + oauthSettings specifies the OAuth settings. + This needs to passed with the authentication type `oauth`. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name of + claim in token for identifying the groups of subject + in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect timeout + with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + principalMappingRules: + items: + type: string + type: array + type: + description: |- + type specifies the Kafka or Zookeeper authentication type. + Valid options are `plain`, `digest`, `mtls`, `ldap` & `oauth`. + enum: + - plain + - digest + - mtls + - ldap + - oauth + type: string + required: + - type + type: object + externalAccess: + description: externalAccess defines the external access configuration + for the Kafka cluster. + properties: + loadBalancer: + description: loadBalancer specifies the configuration + to create Kubernetes load balancer services. + properties: + advertisedPort: + description: |- + advertisedPort specifies the advertised port for Kafka external access. + If not configured, it will be the same as the listener port. + Information about the advertised port can be retrieved through the status API. + format: int32 + type: integer + annotations: + additionalProperties: + type: string + description: annotations is a map of string key and + value pairs. It specifies Kubernetes annotations + for this service. + type: object + x-kubernetes-map-type: granular + bootstrapPrefix: + description: |- + bootstrapPrefix specifies the prefix for the Kafka bootstrap advertised endpoint and will be added as `bootstrapPrefix.domain`. + The default value is the Kafka cluster name. + minLength: 1 + type: string + brokerPrefix: + description: |- + brokerPrefix specifies the prefix for the Kafka broker advertised endpoint and will be added as `brokerPrefix.domain`. + The default value is `b`, such as `b#.domain` where `#` starts from `0` to the replicas count. + minLength: 1 + type: string + domain: + description: domain is the domain name of the component + cluster. + minLength: 1 + type: string + externalTrafficPolicy: + description: externalTrafficPolicy specifies the external + traffic policy for the service. Valid options are + `Local` and `Cluster`. + enum: + - Local + - Cluster + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key and value + pairs. It specifies Kubernetes labels for this service. + type: object + x-kubernetes-map-type: granular + loadBalancerSourceRanges: + description: loadBalancerSourceRanges specify the + source ranges. + items: + type: string + type: array + servicePorts: + description: servicePorts specify the user-provided + service port(s). + 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 + sessionAffinity: + description: |- + sessionAffinity defines the Kubernetes session affinity. The valid options are `ClientIP` and `None`. `ClientIP` enables the client IP-based session affinity. + The default value is `None`. + More info: https://kubernetes.io/docs/reference/networking/virtual-ips/#session-affinity. + enum: + - ClientIP + - None + type: string + sessionAffinityConfig: + description: SessionAffinityConfig contains the configurations + of the 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 + required: + - domain + type: object + nodePort: + description: nodePort specifies the configuration to create + Kubernetes node port services. + properties: + advertisedURL: + description: |- + advertisedURL specifies the configuration for advertised listener per pod. It is only supported for MDS currently. + If it is enabled, instead of using internal endpoint, the MDS advertised listener for each broker will be + set to `://:, where`podId` starts from `0` to `replicaCount - 1`. + This is only recommended if you cannot add internal SANs to the TLS certificates for MDS and + the external DNS must be resolved inside the Kubernetes cluster. + properties: + enabled: + description: |- + enabled indicates whether to set the MDS advertised listener url with external endpoint for each broker. + Has no effect with Zookeeper, which will always create a listener per pod. + type: boolean + prefix: + description: |- + prefix specifies the broker prefix for MDS/Zookeeper advertised endpoint. + If not configured, it uses `b` as default prefix for MDS, such as `b#.domain` where `#` will start from `0` to `replicaCount -1`. + It uses 'zookeeper' as default prefix for Zookeeper in the same way. + minLength: 1 + type: string + required: + - enabled + type: object + annotations: + additionalProperties: + type: string + description: annotations is a map of string key and + value pairs. It specifies Kubernetes annotations + for this service. + type: object + x-kubernetes-map-type: granular + externalTrafficPolicy: + description: |- + externalTrafficPolicy specifies the external traffic policy for the service. + Valid options are `Local` and `Cluster`. + enum: + - Local + - Cluster + type: string + host: + description: host defines the host name of the cluster. + minLength: 1 + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key and value + pairs. It specifies Kubernetes labels for this service. + type: object + x-kubernetes-map-type: granular + nodePortOffset: + description: |- + nodePortOffset specifies the starting offset of the node ports. The port numbers go in ascending order with respect + to the replicas count. + NodePort service creation fails if the node port is not in the range supported by the Kubernetes API server. + The default Kubernetes Node Port range is `30000` - `32762`. + format: int32 + minimum: 0 + type: integer + servicePorts: + description: |- + servicePorts specify user-provided service port(s). + For Kafka with the nodePort type, this setting is only applied to Kafka bootstrap service. + 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 + sessionAffinity: + description: |- + sessionAffinity defines the Kubernetes session affinity. The valid options are `ClientIP` and `None`. `ClientIP` enables the client IP-based session affinity. + The default value is `None`. + More info: https://kubernetes.io/docs/reference/networking/virtual-ips/#session-affinity. + enum: + - ClientIP + - None + type: string + sessionAffinityConfig: + description: SessionAffinityConfig contains the configurations + of the 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 + required: + - host + - nodePortOffset + type: object + route: + description: route specifies the configuration to create + route services in OpenShift. + properties: + annotations: + additionalProperties: + type: string + description: annotations is a map of string key and + value pairs. It specifies Kubernetes annotations + for this service. + type: object + x-kubernetes-map-type: granular + bootstrapPrefix: + description: |- + bootstrapPrefix specifies the prefix for the Kafka bootstrap advertised endpoint and will be added as `bootstrapPrefix.domain`. + The default value is the Kafka cluster name. + minLength: 1 + type: string + brokerPrefix: + description: |- + brokerPrefix specifies the prefix for the Kafka broker advertised endpoint and will be added as `brokerPrefix.domain`. + The default value is `b`, such as `b#.domain` where `#` starts from `0` to the replicas count. + minLength: 1 + type: string + domain: + description: domain specifies the domain name of the + Confluent component cluster. + minLength: 1 + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key and value + pairs. It specifies Kubernetes labels for this service. + type: object + x-kubernetes-map-type: granular + wildcardPolicy: + description: |- + wildcardPolicy allows you to define a route that covers all hosts within a domain. Valid options are `Subdomain` and `None`. + The default value is `None`. + enum: + - Subdomain + - None + type: string + required: + - domain + type: object + staticForHostBasedRouting: + description: |- + staticForHostBasedRouting enables external access by doing host based + routing through the SNI capability. + With this schema, CFK only configures Kafka advertised listeners, and no Kubernetes external + service is created. + properties: + brokerPrefix: + description: |- + brokerPrefix specifies the prefix for the broker advertised endpoints and are added as `brokerPrefix.domain`. + If not configured, it will add `b` as a prefix, such as `b#.domain` where `#` will start from `0` to the replicas count. + minLength: 1 + type: string + domain: + description: domain specifies the domain name for + the Kafka cluster. + minLength: 1 + type: string + port: + description: port specifies the port to be used in + the advertised listener for a broker. + format: int32 + type: integer + required: + - domain + - port + type: object + staticForPortBasedRouting: + description: |- + staticForPortBasedRouting enables external access by port routing. + With this schema, CFK only configures Kafka advertised listeners, and no Kubernetes external + service is created. + properties: + host: + description: host defines the host name to be used + in the advertised listener for a broker. + minLength: 1 + type: string + portOffset: + description: |- + portOffset specifies the starting port number. The port numbers go in ascending order with + respect to the replicas count. + format: int32 + type: integer + required: + - host + - portOffset + type: object + type: + description: |- + type specifies the Kubernetes service for external access. + Valid options are `loadBalancer`, `nodePort`, `route`, `staticForPortBasedRouting`, and `staticForHostBasedRouting`. + enum: + - loadBalancer + - nodePort + - route + - staticForPortBasedRouting + - staticForHostBasedRouting + type: string + required: + - type + type: object + tls: + description: tls specifies the TLS configuration for the listener. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + type: object + metricReporter: + description: |- + metricsReporter specifies the configuration of the metric reporter. The metric reporter is enabled by default. + If authentication and TLS are not set, the metrics reporter uses internal listener's authentication and TLS . + properties: + authentication: + description: authentication specifies the Kafka client-side authentication + configuration. + properties: + jaasConfig: + description: jaasConfig specifies the Kafka client-side JaaS + configuration. + properties: + secretRef: + description: |- + secretRef references the secret containing the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + jaasConfigPassThrough: + description: jaasConfigPassThrough specifies another way to + provide the Kafka client-side JaaS configuration. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where required credentials are mounted. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + minLength: 1 + type: string + secretRef: + description: |- + secretRef references the secret containing the required credentials for authentication. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauthSettings: + description: |- + oauthSettings specifies the OAuth settings. + This needs to passed with the authentication type `oauth`. + properties: + audience: + description: audience specifies the audience claim in + the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected issuer + in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name of claim + in token for identifying the groups of subject in the + JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect timeout + with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout with + IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry backoff + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff with + IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim in JWT + to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + oauthbearer: + description: |- + oauthbearer is the authentication mechanism to provider principals. + Only supported in RBAC deployment. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container + where the credential is mounted. + minLength: 1 + type: string + secretRef: + description: |- + secretRef specifies the name of the secret that contains the credential. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#bearer-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + type: + description: |- + type specifies the Kafka client authentication type. + Valid options are `plain`, `oauthbearer`, `digest`, `mtls` and `oauth`. + enum: + - plain + - oauthbearer + - digest + - mtls + - oauth + type: string + required: + - type + type: object + bootstrapEndpoint: + description: bootstrapEndpoint specifies the Kafka bootstrap endpoint. + type: string + enabled: + description: enabled specifies whether to enable or disable the + metric reporter. + type: boolean + replicationFactor: + description: replicationFactor specifies the number of replicas + in the metric topic. + format: int32 + type: integer + tls: + description: tls specifies the Kafka client-side TLS configuration. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + required: + - enabled + type: object + metrics: + description: metrics specify the security settings for the metric + services. + properties: + authentication: + description: authentication specifies the authentication configuration + for the metrics. + properties: + type: + description: type specifies the metrics authentication method. + The valid option is `mtls`. + enum: + - mtls + type: string + required: + - type + type: object + prometheus: + description: prometheus specifies the configuration overrides + for the JMX-Prometheus exporter. + properties: + blacklist: + items: + type: string + type: array + rules: + items: + description: Rule defines the Prometheus Exporter rule override. + properties: + attrNameSnakeCase: + type: boolean + cache: + type: boolean + help: + minLength: 1 + type: string + labels: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: granular + name: + minLength: 1 + type: string + pattern: + minLength: 1 + type: string + type: + minLength: 1 + type: string + value: + minLength: 1 + type: string + valueFactor: + anyOf: + - type: integer + - type: string + default: 1 + 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: array + whitelist: + items: + type: string + type: array + type: object + tls: + description: tls specifies the TLS configuration for the metrics. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + mountedSecrets: + description: |- + mountedSecrets list the secrets injected to + the underlying statefulset configuration. The secret reference is mounted + in the default path `/mnt/secrets/`. The underlying resources + will follow the secret as a file configuration. + More info: https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets-as-files-from-a-pod. + A change to this setting will roll the cluster. + items: + description: |- + MountedSecrets provides a way to inject a custom secret to the underlying + statefulset. + properties: + keyItems: + description: keyItems are key and path names. + 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 + secretRef: + description: secretRef references the name of the secret. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + type: array + mountedVolumes: + description: |- + mountedVolumes list the custom volumes that need to be mounted into the + underlying statefulset. + A change to this setting will roll the cluster. + properties: + volumeMounts: + description: |- + volumeMounts specify the list of volume mounts for the pods in the + statefulset. + 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 + volumes: + description: |- + volumes specify the list of volumes that can be mounted into the pods + of statefulset. + 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 + 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: + 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 + 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 + 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: + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 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 + 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 + 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 + 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 + 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 + 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: + 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 + 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 + 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 + required: + - volumeMounts + - volumes + type: object + oneReplicaPerNode: + description: |- + oneReplicaPerNode controls whether to run 1 pod per node using the pod anti-affinity capability. + Enabling this configuration in an existing cluster will roll the cluster. + type: boolean + pdb: + description: |- + configures PodDisruptionBudget for the Confluent Platform component. + by default PDB is configured based on pre-detemined formula. + properties: + enabled: + description: enabled specifies whether the PodDisruptionBudget + is enabled + type: boolean + maxUnavailable: + description: maxUnavailable is the maximum number of pods that + can be unavailable during the disruption. + format: int32 + type: integer + required: + - enabled + type: object + podTemplate: + description: podTemplate specifies the statefulset pod template configuration. + properties: + affinity: + description: |- + affinity specifies a group of affinity scheduling rules. + More info: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity. + 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 + annotations: + additionalProperties: + type: string + description: |- + annotations is a map of string key and value pairs stored with the resource and + 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 + x-kubernetes-map-type: granular + envVars: + description: |- + envVars contain environment variables to be injected into containers. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container. + 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 + 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: + 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 + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + labels: + additionalProperties: + type: string + description: |- + labels is a map of string key and value pairs that can be used to organize and categorize + (scope and select) objects. + More info: http://kubernetes.io/docs/user-guide/labels. + type: object + x-kubernetes-map-type: granular + 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: + + + 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 + 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: + description: priorityClassName specifies the priority class for + the pod (if any). + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + probe: + description: probe contains the fields for standard Kubernetes + readiness/liveness probe configuration. + properties: + liveness: + description: |- + liveness configures the Kubernetes probe settings. The changes + will override the existing default configuration. + properties: + failureThreshold: + description: |- + failureThreshold is the minimum consecutive failures for the probe to be considered failed. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + initialDelaySeconds: + description: |- + initialDelaySeconds is the number of seconds after the container has started and before probes are initiated. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + path: + description: Path for the HTTP probe + type: string + periodSeconds: + description: |- + periodSeconds specifies how often to perform the probe. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + port: + description: Number of the port to access on the container + type: integer + successThreshold: + description: |- + successThreshold is the minimum consecutive successes for the probe to be considered successful after having failed. + The default values is `1`. Must be `1` for liveness and startup. The minimum value is `1`. + format: int32 + type: integer + timeoutSeconds: + description: |- + timeoutSeconds is the number of seconds after which the probe times out. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + type: object + readiness: + description: |- + readiness configures the Kubernetes probe setting. The changes + will override the existing default configuration. + properties: + failureThreshold: + description: |- + failureThreshold is the minimum consecutive failures for the probe to be considered failed. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + initialDelaySeconds: + description: |- + initialDelaySeconds is the number of seconds after the container has started and before probes are initiated. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + path: + description: Path for the HTTP probe + type: string + periodSeconds: + description: |- + periodSeconds specifies how often to perform the probe. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + port: + description: Number of the port to access on the container + type: integer + successThreshold: + description: |- + successThreshold is the minimum consecutive successes for the probe to be considered successful after having failed. + The default values is `1`. Must be `1` for liveness and startup. The minimum value is `1`. + format: int32 + type: integer + timeoutSeconds: + description: |- + timeoutSeconds is the number of seconds after which the probe times out. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + type: object + type: object + resources: + description: resources describe the compute resource requirements. + 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 + 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: + + + 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: + description: |- + ServiceAccountName is the name of the service account used to run this pod. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account. + type: string + terminationGracePeriodSeconds: + description: terminationGracePeriodSeconds is the grace period + before the pod is deleted. + format: int64 + type: integer + tolerations: + description: |- + tolerations specify the pods to schedule onto the nodes with matching taints, using + the triple `` and the matching operator ``. + 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 + topologySpreadConstraints: + description: |- + topologySpreadConstraints describe how a group of pods ought to spread across topology domains. Scheduler will + schedule pods based on 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 + 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 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. + + + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). + 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 + type: object + replicas: + description: |- + replicas is the desired number of replicas. + A change to this setting will roll the cluster. + format: int32 + type: integer + storageClass: + description: |- + storageClass specifies the user-provided storage class. If not + configured, it will use the default storage class. + properties: + name: + description: name is the storage class name. + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - name + type: object + telemetry: + description: telemetry specifies the Confluent telemetry reporter + configuration. + properties: + global: + description: |- + global allows disabling telemetry configuration. + If CFK is deployed with telemetry, this field is only + used to disable telemetry. The default value is `true` if + telemetry is enabled at the global level. + type: boolean + type: object + tls: + description: |- + tls specifies the global-level TLS configuration which can be used by + listeners and services. + properties: + autoGeneratedCerts: + description: |- + autoGeneratedCerts specifies that the certificates are auto-generated based on + the CA key pair provided. + type: boolean + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + fips: + description: |- + fips specifies the configuration of FIPS compliant Bouncy Castle type Java Keystores for the cp component's + TLS settings. TLS Secrets must have the keys keystore.bcfks, truststore.bcfks, and jksPassword.txt + properties: + enabled: + description: enabled specifies whether to enable the FIPS + configuration for cp components. + type: boolean + required: + - enabled + type: object + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing the + JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + required: + - dataVolumeCapacity + - image + type: object + status: + description: status defines the observed state of the KRaft Controller + cluster. + properties: + arbitraryData: + description: arbitraryData is the map for any arbitrary data associated + with this Confluent component. + x-kubernetes-preserve-unknown-fields: true + authorizationType: + description: authorizationType is the authorization type for this + Confluent component. + type: string + brokerIdOffset: + description: brokerIdOffset is the broker id offset of the KRaft Controller + cluster. + format: int32 + type: integer + clusterID: + description: clusterID is the ID of the KRaft Controller cluster. + type: string + clusterName: + description: clusterName is the name of the Confluent Platform component + cluster. + type: string + clusterNamespace: + description: clusterNamespace is the namespace where the Confluent + Platform component cluster is running. + type: string + conditions: + description: conditions specify the latest available observations + of the current state. + items: + description: Condition represent the latest available observations + of the current state. + properties: + lastProbeTime: + description: lastProbeTime shows the last time the condition + was evaluated. + format: date-time + type: string + lastTransitionTime: + description: lastTransitionTime shows the last time the condition + was transitioned from one status to another. + format: date-time + type: string + message: + description: message shows a human-readable message with details + about the transition. + type: string + reason: + description: reason shows the reason for the last transition + of the condition. + type: string + status: + description: status shows the status of the condition, one of + `True`, `False`, or `Unknown`. + type: string + type: + description: type shows the condition type. + type: string + type: object + type: array + controllerQuorumVoters: + description: controllerQuorumVoters is the list KRaft Controller Quorum + Voters. + items: + description: ControllerQuorumVoter defines the KRaft controller + quorum voter. + properties: + brokerEndpoint: + description: brokerEndpoint is the endpoint of the KRaft Controller. + type: string + nodeId: + description: nodeId is the nodeId of the KRaft Controller. + format: int32 + type: integer + required: + - brokerEndpoint + - nodeId + type: object + type: array + currentReplicas: + description: currentReplicas is the number of currently running replicas. + format: int32 + type: integer + internalSecrets: + description: |- + internalSecrets are internal secrets created + by CFK for this Confluent component. + items: + type: string + type: array + internalTopicNames: + description: internalTopicNames are the topics used by the component + for internal use. + items: + type: string + type: array + listeners: + additionalProperties: + description: ListenerStatus describes general information about + the listeners. + properties: + advertisedExternalEndpoints: + description: advertisedExternalEndpoints specifies other advertised + endpoints used, especially for Kafka. + items: + type: string + type: array + authenticationType: + description: authenticationType shows the authentication type + configured by the listener. + type: string + externalAccessType: + description: externalAccessType shows the external access type + used for the listener. + type: string + externalEndpoint: + description: externalEndpoint specifies the external endpoint + to connect to the Confluent component cluster. + type: string + internalEndpoint: + description: internalEndpoint specifies the internal endpoint + to connect to the Confluent component cluster. + type: string + tls: + description: tls shows whether TLS is configured for the listener. + type: boolean + type: object + description: listeners is a map for the status of Kafka Listeners. + type: object + x-kubernetes-map-type: granular + observedGeneration: + description: observedGeneration is the most recent generation observed + for this Confluent component. + format: int64 + type: integer + operatorVersion: + description: operatorVersion is the internal version of CFK. + type: string + phase: + description: |- + phase describes the state of the Confluent Platform component. This can either be 'PROVISIONING' + or 'RUNNING' + 'PROVISIONING' means the Confluent Platform component is currently getting deployed and not ready yet. + 'RUNNING' means the Confluent Platform component has been successfully deployed. + type: string + readyReplicas: + description: readyReplicas is the number of currently ready replicas. + format: int32 + type: integer + replicas: + description: replicas is the number of replicas. + format: int32 + type: integer + selector: + description: |- + selector gets the label selector of the child pod. + The Horizontal Pod Autoscaler(HPA) will scale using the label selector of the child pod. + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.replicas + statusReplicasPath: .status.replicas + status: {} diff --git a/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_kraftmigrationjobs.yaml b/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_kraftmigrationjobs.yaml new file mode 100644 index 0000000000..2e819ad8a9 --- /dev/null +++ b/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_kraftmigrationjobs.yaml @@ -0,0 +1,194 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: kraftmigrationjobs.platform.confluent.io +spec: + group: platform.confluent.io + names: + categories: + - all + - confluent-platform + - confluent + kind: KRaftMigrationJob + listKind: KRaftMigrationJobList + plural: kraftmigrationjobs + shortNames: + - kraftmigrationjob + - kmj + singular: kraftmigrationjob + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.phase + name: Status + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: KRaftMigrationJob is the schema for the KRaftMigrationJob 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 defines the desired state of the KRaftMigrationJob. + properties: + dependencies: + description: dependencies specify the Kafka Broker, Zookeeper and + KRaft Controllers. + properties: + kRaftController: + description: |- + kRaftController specifies the dependency configuration for the KRaftController cluster. + You cannot configure both zookeeper and kRaftController dependencies. + properties: + name: + description: name specifies the name of the Confluent Platform + component cluster. + type: string + namespace: + description: namespace specifies the namespace where the Confluent + Platform component cluster is running. + type: string + required: + - name + type: object + kafka: + description: kafka defines the Kafka dependency configurations. + properties: + name: + description: name specifies the name of the Confluent Platform + component cluster. + type: string + namespace: + description: namespace specifies the namespace where the Confluent + Platform component cluster is running. + type: string + required: + - name + type: object + zookeeper: + description: zookeeper specifies the dependency configuration + for Zookeeper. + properties: + name: + description: name specifies the name of the Confluent Platform + component cluster. + type: string + namespace: + description: namespace specifies the namespace where the Confluent + Platform component cluster is running. + type: string + required: + - name + type: object + required: + - kRaftController + - kafka + - zookeeper + type: object + required: + - dependencies + type: object + status: + description: status defines the observed state of the KRaftMigrationJob. + properties: + conditions: + description: conditions represents the latest available observations + of the kraft migration job. + items: + description: Condition represent the latest available observations + of the current state. + properties: + lastProbeTime: + description: lastProbeTime shows the last time the condition + was evaluated. + format: date-time + type: string + lastTransitionTime: + description: lastTransitionTime shows the last time the condition + was transitioned from one status to another. + format: date-time + type: string + message: + description: message shows a human-readable message with details + about the transition. + type: string + reason: + description: reason shows the reason for the last transition + of the condition. + type: string + status: + description: status shows the status of the condition, one of + `True`, `False`, or `Unknown`. + type: string + type: + description: type shows the condition type. + type: string + type: object + type: array + kafkaClusterId: + description: clusterId is the clusterId for migrating cluster + type: string + kafkaGeneration: + description: |- + kafkaGeneration is the last generation at which + kafka cluster was updated during migration workflow + format: int64 + type: integer + kraftControllerGeneration: + description: |- + kraftControllerGeneration is the last generation at which + kraftController cluster was updated during migration workflow + format: int64 + type: integer + phase: + description: phase is the state of the kraft migration job. + type: string + subPhase: + description: subPhase is the state of the kraft migration job. + type: string + zkEndpointWithNode: + description: |- + zkEndpointWithNode is the zkEndpoint with node fetched from kafka + / + type: string + required: + - kafkaClusterId + - kafkaGeneration + - kraftControllerGeneration + - phase + - subPhase + - zkEndpointWithNode + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.replicas + statusReplicasPath: .status.replicas + status: {} diff --git a/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_ksqldbs.yaml b/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_ksqldbs.yaml new file mode 100644 index 0000000000..c2a2e60fab --- /dev/null +++ b/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_ksqldbs.yaml @@ -0,0 +1,6646 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: ksqldbs.platform.confluent.io +spec: + group: platform.confluent.io + names: + categories: + - all + - confluent-platform + - confluent + kind: KsqlDB + listKind: KsqlDBList + plural: ksqldbs + shortNames: + - ksqldb + - ksql + singular: ksqldb + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.replicas + name: Replicas + type: string + - jsonPath: .status.readyReplicas + name: Ready + type: string + - jsonPath: .status.phase + name: Status + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.kafka.bootstrapEndpoint + name: Kafka + priority: 1 + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: KsqlDB is the schema for the ksqlDB 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 defines the desired state of the ksqlDB cluster. + properties: + authentication: + description: authentication specifies whether authentication is needed + when accessing the ksqlDB cluster. + properties: + basic: + description: basic specifies the configuration for basic authentication. + properties: + debug: + description: debug enables the basic authentication debug + logs for JaaS configuration. + type: boolean + directoryPathInContainer: + description: |- + directoryPathInContainer allows to pass the basic credential through a directory path in the container. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + minLength: 1 + type: string + restrictedRoles: + description: |- + restrictedRoles specify the restricted roles on the server side only. + Changes will be only reflected in Control Center. + This configuration is ignored on the client side configuration. + items: + type: string + minItems: 1 + type: array + roles: + description: |- + roles specify the roles on the server side only. + This configuration is ignored on the client side configuration. + items: + type: string + type: array + secretRef: + description: |- + secretRef defines secret reference to pass the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauth: + description: oauth specifies the configuration for OAuth authentication. + properties: + configuration: + description: configuration specifies the OAuth server settings. + properties: + audience: + description: audience specifies the audience claim in + the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected issuer + in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name of claim + in token for identifying the groups of subject in the + JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect timeout + with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout with + IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry backoff + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff with + IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim in JWT + to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + directoryPathInContainer: + description: directoryPathInContainer allows to pass the basic + credential through a directory path in the container. + minLength: 1 + type: string + secretRef: + description: secretRef defines secret reference to pass the + required credentials. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - configuration + type: object + type: + description: type specifies the authentication scheme for the + REST API server. Valid options are `basic`, `oauth` and `mtls`. + enum: + - basic + - mtls + - oauth + type: string + required: + - type + type: object + authorization: + description: authorization specifies the RBAC configuration for the + ksqlDB cluster. + properties: + kafkaRestClassRef: + description: |- + kafkaRestClassRef references the KafkaRestClass + which specifies the Kafka REST API connection configuration. + properties: + name: + description: name specifies the name of the KafkaRestClass + application resource. + minLength: 1 + type: string + namespace: + description: namespace specifies the namespace of the KafkaRestClass. + type: string + required: + - name + type: object + type: + description: type specifies the client-side authorization type. + The valid option is `rbac`. + enum: + - rbac + type: string + required: + - type + type: object + configOverrides: + description: |- + configOverrides specifies the configs to override the server, JVM, Log4j properties for the ksqlDB cluster. + A change will roll the cluster. + properties: + jvm: + description: |- + jvm is a list of JVM configuration supported by the Confluent Platform component. + This will either add or update the existing configuration. + items: + type: string + type: array + log4j: + description: |- + log4j is a list of Log4J configuration supported by the Confluent Platform component. + This will either add or update the existing configuration. + items: + type: string + type: array + server: + description: |- + server is a list of server configuration supported by the Confluent Platform component. + This will either add or update existing configuration. + items: + type: string + type: array + type: object + dataVolumeCapacity: + anyOf: + - type: integer + - type: string + description: dataVolumeCapacity specifies the data volume for the + ksqlDB cluster. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + dependencies: + description: dependencies specifies the dependency configurations + for Kafka, Interceptor, Schema Registry, the MDS, and Connect. + properties: + connect: + description: connect specifies the Connect dependency configuration. + properties: + authentication: + description: authentication specifies the authentication configuration + for the Connect cluster. + properties: + basic: + description: basic specifies the configuration for basic + authentication. + properties: + debug: + description: debug enables the basic authentication + debug logs for JaaS configuration. + type: boolean + directoryPathInContainer: + description: |- + directoryPathInContainer allows to pass the basic credential through a directory path in the container. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + minLength: 1 + type: string + restrictedRoles: + description: |- + restrictedRoles specify the restricted roles on the server side only. + Changes will be only reflected in Control Center. + This configuration is ignored on the client side configuration. + items: + type: string + minItems: 1 + type: array + roles: + description: |- + roles specify the roles on the server side only. + This configuration is ignored on the client side configuration. + items: + type: string + type: array + secretRef: + description: |- + secretRef defines secret reference to pass the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauth: + description: oauth specifies the configuration for OAuth + authentication. + properties: + configuration: + description: configuration specifies the OAuth server + settings. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name + of claim in token for identifying the groups + of subject in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect + timeout with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + directoryPathInContainer: + description: directoryPathInContainer allows to pass + the basic credential through a directory path in + the container. + minLength: 1 + type: string + secretRef: + description: secretRef defines secret reference to + pass the required credentials. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - configuration + type: object + type: + description: type specifies the authentication scheme + for the REST API client. Valid options are `basic`, + `oauth` and `mtls`. + enum: + - basic + - mtls + - oauth + type: string + required: + - type + type: object + tls: + description: tls specifies the client-side TLS setting for + the Connect cluster. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + url: + description: url specifies the URL endpoint of the Connect + cluster. + minLength: 1 + pattern: ^https?://.* + type: string + required: + - url + type: object + interceptor: + description: interceptor specifies the interceptor dependency + configuration. + properties: + configs: + description: |- + configs describe the configurations for the Confluent Platform interceptor. + The config override feature can be used to pass the configuration settings. + items: + type: string + type: array + consumer: + description: |- + consumer specifies the consumer configuration for the interceptor. If not + configured, it uses the Kafka dependency configuration. + properties: + authentication: + description: authentication defines the authentication + for the Kafka cluster. + properties: + jaasConfig: + description: jaasConfig specifies the Kafka client-side + JaaS configuration. + properties: + secretRef: + description: |- + secretRef references the secret containing the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + jaasConfigPassThrough: + description: jaasConfigPassThrough specifies another + way to provide the Kafka client-side JaaS configuration. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where required credentials are mounted. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + minLength: 1 + type: string + secretRef: + description: |- + secretRef references the secret containing the required credentials for authentication. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauthSettings: + description: |- + oauthSettings specifies the OAuth settings. + This needs to passed with the authentication type `oauth`. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name + of claim in token for identifying the groups + of subject in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect + timeout with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + oauthbearer: + description: |- + oauthbearer is the authentication mechanism to provider principals. + Only supported in RBAC deployment. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container + where the credential is mounted. + minLength: 1 + type: string + secretRef: + description: |- + secretRef specifies the name of the secret that contains the credential. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#bearer-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + type: + description: |- + type specifies the Kafka client authentication type. + Valid options are `plain`, `oauthbearer`, `digest`, `mtls` and `oauth`. + enum: + - plain + - oauthbearer + - digest + - mtls + - oauth + type: string + required: + - type + type: object + bootstrapEndpoint: + description: bootstrapEndpoint specifies the Kafka bootstrap + endpoint. + minLength: 1 + pattern: .+:[0-9]+ + type: string + discovery: + description: discovery specifies the capability to discover + the Kafka cluster. + properties: + name: + description: name is the name of the Confluent Platform + component cluster. + type: string + namespace: + description: |- + namespace is where the Confluent Platform component is running. + The default value is the namespace where CFK is running. + type: string + secretRef: + description: secretRef is the name of the secret used + to discover the Confluent Platform component. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - name + type: object + tls: + description: tls defines the client-side TLS setting for + the Kafka cluster. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + enabled: + description: enabled indicates whether the Confluent Platform + interceptor is enabled or disabled. + type: boolean + producer: + description: |- + producer specifies the producer configuration for the interceptor. If not + configured, it uses the Kafka dependency configuration. + properties: + authentication: + description: authentication defines the authentication + for the Kafka cluster. + properties: + jaasConfig: + description: jaasConfig specifies the Kafka client-side + JaaS configuration. + properties: + secretRef: + description: |- + secretRef references the secret containing the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + jaasConfigPassThrough: + description: jaasConfigPassThrough specifies another + way to provide the Kafka client-side JaaS configuration. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where required credentials are mounted. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + minLength: 1 + type: string + secretRef: + description: |- + secretRef references the secret containing the required credentials for authentication. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauthSettings: + description: |- + oauthSettings specifies the OAuth settings. + This needs to passed with the authentication type `oauth`. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name + of claim in token for identifying the groups + of subject in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect + timeout with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + oauthbearer: + description: |- + oauthbearer is the authentication mechanism to provider principals. + Only supported in RBAC deployment. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container + where the credential is mounted. + minLength: 1 + type: string + secretRef: + description: |- + secretRef specifies the name of the secret that contains the credential. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#bearer-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + type: + description: |- + type specifies the Kafka client authentication type. + Valid options are `plain`, `oauthbearer`, `digest`, `mtls` and `oauth`. + enum: + - plain + - oauthbearer + - digest + - mtls + - oauth + type: string + required: + - type + type: object + bootstrapEndpoint: + description: bootstrapEndpoint specifies the Kafka bootstrap + endpoint. + minLength: 1 + pattern: .+:[0-9]+ + type: string + discovery: + description: discovery specifies the capability to discover + the Kafka cluster. + properties: + name: + description: name is the name of the Confluent Platform + component cluster. + type: string + namespace: + description: |- + namespace is where the Confluent Platform component is running. + The default value is the namespace where CFK is running. + type: string + secretRef: + description: secretRef is the name of the secret used + to discover the Confluent Platform component. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - name + type: object + tls: + description: tls defines the client-side TLS setting for + the Kafka cluster. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + publishMs: + type: integer + required: + - enabled + type: object + kafka: + description: kafka specifies the Kafka dependency configuration. + properties: + authentication: + description: authentication defines the authentication for + the Kafka cluster. + properties: + jaasConfig: + description: jaasConfig specifies the Kafka client-side + JaaS configuration. + properties: + secretRef: + description: |- + secretRef references the secret containing the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + jaasConfigPassThrough: + description: jaasConfigPassThrough specifies another way + to provide the Kafka client-side JaaS configuration. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where required credentials are mounted. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + minLength: 1 + type: string + secretRef: + description: |- + secretRef references the secret containing the required credentials for authentication. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauthSettings: + description: |- + oauthSettings specifies the OAuth settings. + This needs to passed with the authentication type `oauth`. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name of + claim in token for identifying the groups of subject + in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect timeout + with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + oauthbearer: + description: |- + oauthbearer is the authentication mechanism to provider principals. + Only supported in RBAC deployment. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container + where the credential is mounted. + minLength: 1 + type: string + secretRef: + description: |- + secretRef specifies the name of the secret that contains the credential. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#bearer-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + type: + description: |- + type specifies the Kafka client authentication type. + Valid options are `plain`, `oauthbearer`, `digest`, `mtls` and `oauth`. + enum: + - plain + - oauthbearer + - digest + - mtls + - oauth + type: string + required: + - type + type: object + bootstrapEndpoint: + description: bootstrapEndpoint specifies the Kafka bootstrap + endpoint. + minLength: 1 + pattern: .+:[0-9]+ + type: string + discovery: + description: discovery specifies the capability to discover + the Kafka cluster. + properties: + name: + description: name is the name of the Confluent Platform + component cluster. + type: string + namespace: + description: |- + namespace is where the Confluent Platform component is running. + The default value is the namespace where CFK is running. + type: string + secretRef: + description: secretRef is the name of the secret used + to discover the Confluent Platform component. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - name + type: object + tls: + description: tls defines the client-side TLS setting for the + Kafka cluster. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + mds: + description: mds specifies the MDS dependencies configuration. + properties: + authentication: + description: authentication specifies the client side authentication + configuration for the MDS. + properties: + bearer: + description: bearer specifies the bearer authentication + settings. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container + where the credential is mounted. + minLength: 1 + type: string + secretRef: + description: |- + secretRef specifies the name of the secret that contains the credential. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#bearer-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauth: + description: oauth specifies the OAuth authentication + settings. + properties: + configuration: + description: configuration specifies the OAuth server + settings. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name + of claim in token for identifying the groups + of subject in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect + timeout with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + directoryPathInContainer: + description: directoryPathInContainer allows to pass + the basic credential through a directory path in + the container. + minLength: 1 + type: string + secretRef: + description: secretRef defines secret reference to + pass the required credentials. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - configuration + type: object + type: + description: type specifies the authentication method + for the MDS. The valid option is `bearer`, `oauth`. + enum: + - bearer + - oauth + type: string + required: + - type + type: object + endpoint: + description: endpoint specifies the MDS endpoint. + minLength: 1 + pattern: ^https?://.* + type: string + ssoProtocol: + description: sso protocol, valid options are ldap and oidc. + enum: + - ldap + - oidc + type: string + tls: + description: ClientTLSConfig specifies the TLS configuration + for the Confluent component (dependencies, listeners). + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + tokenKeyPair: + description: tokenKeyPair specifies the token keypair to configure + the MDS. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer defines the directory path in the container + where the MDS token key pair are mounted. + minLength: 1 + type: string + encryptedTokenKey: + description: |- + EncryptedTokenKey boolean value indicating whether the tokenKeypair(private used for signing) is encrypted using a passphrase. If true, cfk + operator will look for a file named mdsTokenKeyPassphrase.txt containing key value pair + mdsTokenKeyPassphrase=. Relevant only for mds server. Ignored if set for a client configuration. + type: boolean + secretRef: + description: secretRef references the name of the secret + that contains the MDS token key pair. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + required: + - authentication + - endpoint + - tokenKeyPair + type: object + schemaRegistry: + description: schemaRegistry specifies the Schema Registry dependency + configuration. + properties: + authentication: + description: authentication specifies the authentication for + the Schema Registry cluster. + properties: + basic: + description: basic specifies the configuration for basic + authentication. + properties: + debug: + description: debug enables the basic authentication + debug logs for JaaS configuration. + type: boolean + directoryPathInContainer: + description: |- + directoryPathInContainer allows to pass the basic credential through a directory path in the container. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + minLength: 1 + type: string + restrictedRoles: + description: |- + restrictedRoles specify the restricted roles on the server side only. + Changes will be only reflected in Control Center. + This configuration is ignored on the client side configuration. + items: + type: string + minItems: 1 + type: array + roles: + description: |- + roles specify the roles on the server side only. + This configuration is ignored on the client side configuration. + items: + type: string + type: array + secretRef: + description: |- + secretRef defines secret reference to pass the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauth: + description: oauth specifies the configuration for OAuth + authentication. + properties: + configuration: + description: configuration specifies the OAuth server + settings. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name + of claim in token for identifying the groups + of subject in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect + timeout with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + directoryPathInContainer: + description: directoryPathInContainer allows to pass + the basic credential through a directory path in + the container. + minLength: 1 + type: string + secretRef: + description: secretRef defines secret reference to + pass the required credentials. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - configuration + type: object + type: + description: type specifies the authentication scheme + for the REST API client. Valid options are `basic`, + `oauth` and `mtls`. + enum: + - basic + - mtls + - oauth + type: string + required: + - type + type: object + tls: + description: tls defines the client-side TLS setting for the + Schema Registry cluster. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + url: + description: url specifies the URL endpoint of the Schema + Registry cluster. + minLength: 1 + pattern: ^https?://.* + type: string + required: + - url + type: object + type: object + externalAccess: + description: |- + externalAccess specifies the configurations for the endpoints and services to make the ksqlDB + accessible from outside the cluster. + When `spec.listeners` is configured, configuring `spec.externalAccess` is not allowed. + Please configure `spec.listeners.external.externalAccess` instead". + properties: + loadBalancer: + description: loadBalancer specifies the configuration to create + a Kubernetes load balancer service. + properties: + advertisedURL: + description: |- + advertisedURL specifies the configuration for advertised listener per pod. It is only supported for MDS currently. + If it is enabled, instead of using internal endpoint, the MDS advertised listener for each broker will be + set to: `://.` where podId starts from `0` to `replicaCount -1`. + This is only recommended if you cannot add internal SANs to the TLS certificates for MDS and + the external DNS must be resolved inside the Kubernetes cluster. + This configuration will not take effect if MDS enabled dual listener setup. + properties: + enabled: + description: |- + enabled indicates whether to set the MDS advertised listener url with external endpoint for each broker. + Has no effect with Zookeeper, which will always create a listener per pod. + type: boolean + prefix: + description: |- + prefix specifies the broker prefix for MDS/Zookeeper advertised endpoint. + If not configured, it uses `b` as default prefix for MDS, such as `b#.domain` where `#` will start from `0` to `replicaCount -1`. + It uses 'zookeeper' as default prefix for Zookeeper in the same way. + minLength: 1 + type: string + required: + - enabled + type: object + annotations: + additionalProperties: + type: string + description: annotations is a map of string key and value + pairs. It specifies Kubernetes annotations for this service. + type: object + x-kubernetes-map-type: granular + domain: + description: domain is the domain name of the component cluster. + minLength: 1 + type: string + externalTrafficPolicy: + description: externalTrafficPolicy specifies the external + traffic policy for the service. Valid options are `Local` + and `Cluster`. + enum: + - Local + - Cluster + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key and value pairs. + It specifies Kubernetes labels for this service. + type: object + x-kubernetes-map-type: granular + loadBalancerSourceRanges: + description: loadBalancerSourceRanges specify the source ranges. + items: + type: string + type: array + port: + description: |- + port specifies the external port for the client consumption. + If not configured, the same internal/external port is configured for the component. + Information about the port can be retrieved through the status API. + format: int32 + type: integer + prefix: + description: |- + prefix specify the prefix for the given domain. + The default value is the name of the cluster. + minLength: 1 + type: string + servicePorts: + description: servicePorts specify the user-provided service + port(s). + 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 + sessionAffinity: + description: |- + sessionAffinity defines the Kubernetes session affinity. The valid options are `ClientIP` and `None`. `ClientIP` enables the client IP-based session affinity. + The default value is `None`. + More info: https://kubernetes.io/docs/reference/networking/virtual-ips/#session-affinity. + enum: + - ClientIP + - None + type: string + sessionAffinityConfig: + description: SessionAffinityConfig contains the configurations + of the 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 + required: + - domain + type: object + nodePort: + description: nodePort specifies the configuration to create a + Kubernetes node port service. + properties: + advertisedURL: + description: |- + advertisedURL specifies the configuration for advertised listener per pod. It is only supported for MDS currently. + If it is enabled, instead of using internal endpoint, the MDS advertised listener for each broker will be + set to `://:, where`podId` starts from `0` to `replicaCount - 1`. + This is only recommended if you cannot add internal SANs to the TLS certificates for MDS and + the external DNS must be resolved inside the Kubernetes cluster. + properties: + enabled: + description: |- + enabled indicates whether to set the MDS advertised listener url with external endpoint for each broker. + Has no effect with Zookeeper, which will always create a listener per pod. + type: boolean + prefix: + description: |- + prefix specifies the broker prefix for MDS/Zookeeper advertised endpoint. + If not configured, it uses `b` as default prefix for MDS, such as `b#.domain` where `#` will start from `0` to `replicaCount -1`. + It uses 'zookeeper' as default prefix for Zookeeper in the same way. + minLength: 1 + type: string + required: + - enabled + type: object + annotations: + additionalProperties: + type: string + description: annotations is a map of string key and value + pairs. It specifies Kubernetes annotations for this service. + type: object + x-kubernetes-map-type: granular + externalTrafficPolicy: + description: |- + externalTrafficPolicy specifies the external traffic policy for the service. + Valid options are `Local` and `Cluster`. + enum: + - Local + - Cluster + type: string + host: + description: host defines the host name of the cluster. + minLength: 1 + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key and value pairs. + It specifies Kubernetes labels for this service. + type: object + x-kubernetes-map-type: granular + nodePortOffset: + description: |- + nodePortOffset specifies the starting offset of the node ports. The port numbers go in ascending order with respect + to the replicas count. + NodePort service creation fails if the node port is not in the range supported by the Kubernetes API server. + The default Kubernetes Node Port range is `30000` - `32762`. + format: int32 + minimum: 0 + type: integer + servicePorts: + description: |- + servicePorts specify user-provided service port(s). + For Kafka with the nodePort type, this setting is only applied to Kafka bootstrap service. + 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 + sessionAffinity: + description: |- + sessionAffinity defines the Kubernetes session affinity. The valid options are `ClientIP` and `None`. `ClientIP` enables the client IP-based session affinity. + The default value is `None`. + More info: https://kubernetes.io/docs/reference/networking/virtual-ips/#session-affinity. + enum: + - ClientIP + - None + type: string + sessionAffinityConfig: + description: SessionAffinityConfig contains the configurations + of the 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 + required: + - host + - nodePortOffset + type: object + route: + description: route specifies the configuration to create a route + service in OpenShift. + properties: + advertisedURL: + description: |- + advertisedURL specifies the configuration for advertised listener per pod. It is only supported for MDS currently. + If it is enabled, instead of using internal endpoint, the MDS advertised listener for each broker will be + set to: `://-http-external.` where podId starts from `0` to `replicaCount -1`. + This is only recommended if you cannot add internal SANs to the TLS certificates for MDS and + the external DNS must be resolved inside the Kubernetes cluster. + This configuration will not take effect if MDS enabled dual listener setup. + properties: + enabled: + description: |- + enabled indicates whether to set the MDS advertised listener url with external endpoint for each broker. + Has no effect with Zookeeper, which will always create a listener per pod. + type: boolean + prefix: + description: |- + prefix specifies the broker prefix for MDS/Zookeeper advertised endpoint. + If not configured, it uses `b` as default prefix for MDS, such as `b#.domain` where `#` will start from `0` to `replicaCount -1`. + It uses 'zookeeper' as default prefix for Zookeeper in the same way. + minLength: 1 + type: string + required: + - enabled + type: object + annotations: + additionalProperties: + type: string + description: annotations is a map of string key and value + pairs. It specifies Kubernetes annotations for this service. + type: object + x-kubernetes-map-type: granular + domain: + description: domain specifies the domain name of the Confluent + component cluster. + minLength: 1 + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key and value pairs. + It specifies Kubernetes labels for this service. + type: object + x-kubernetes-map-type: granular + prefix: + description: |- + prefix specifies the component prefix when configured for the domain. + The default value is the name of the cluster. + minLength: 1 + type: string + wildcardPolicy: + description: |- + wildcardPolicy allows you to define a route that covers all hosts within a domain. Valid options are `Subdomain` and `None`. + The default value is `None`. + enum: + - Subdomain + - None + type: string + required: + - domain + type: object + type: + description: |- + type specifies the Kubernetes external service for the component. + Valid options are `loadBalancer`, `nodePort`, and `route`. + enum: + - loadBalancer + - nodePort + - route + minLength: 1 + type: string + required: + - type + type: object + headlessService: + description: headlessService specifies the configuration of the Kubernetes + headless service. + properties: + annotations: + additionalProperties: + type: string + description: |- + annotations is a map of string key and value pairs. + It specifies the annotations to be added to the CFK-created headless service. + These annotations are merged with the injectAnnotations and take precedence. + type: object + x-kubernetes-map-type: granular + labels: + additionalProperties: + type: string + description: |- + labels is a map of string key and value pairs. + It specifies the labels to be added to the CFK-created headless service. + These labels are merged with the injectLabels and take precedence. + type: object + x-kubernetes-map-type: granular + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses specifies the publishNotReadyAddresses field. + For Kafka, this value must be true. The default value is true. + type: boolean + type: object + image: + description: |- + image specifies the application and the init docker image configurations. + A change to this setting will roll the cluster. + properties: + application: + description: |- + application is the Docker image name of the application. Specify + `//:`. + pattern: .+:.+ + type: string + init: + description: |- + init is the init-container name. Specify + `//:`. + pattern: .+:.+ + type: string + pullPolicy: + description: |- + pullPolicy is the policy for pulling images. Valid options are `Always`, `Never`, and `IfNotPresent`. + The default value is `IfNotPresent`. + enum: + - Always + - Never + - IfNotPresent + type: string + pullSecretRef: + description: |- + pullSecretRef references the secrets in the same namespace to be used for pulling images. + Image pull secrets are distinct from secrets because secrets + can be mounted in the pod, but image pull secrets are only accessed by `kubelet`. + More info: https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod + items: + type: string + type: array + required: + - application + - init + type: object + injectAnnotations: + additionalProperties: + type: string + description: |- + injectAnnotations are the annotations injected to the internal resources that CFK created. + The internal annotations are preserved and cannot be overridden. + For pod annotations, use `podTemplate.annotations`. + type: object + x-kubernetes-map-type: granular + injectLabels: + additionalProperties: + type: string + description: |- + injectLabels are the labels injected to the internal resources that CFK created. + The internal labels are preserved and cannot be overridden. + For pod labels, use `podTemplate.labels`. + type: object + x-kubernetes-map-type: granular + internalTopicReplicationFactor: + description: internalTopicReplicationFactor specifies the replication + factor for internal topics. + format: int32 + type: integer + k8sClusterDomain: + description: |- + k8sClusterDomain specifies the configuration of the Kubernetes cluster domain. + The default is the `cluster.local` domain. + type: string + license: + description: license specifies the license configuration for the Confluent + Platform component. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + the license key is mounted. More info: + https://docs.confluent.io/operator/current/co-license.html#update-component-level-licenses + minLength: 1 + type: string + globalLicense: + description: globalLicense specifies whether the Confluent Platform + component shares the common global license. + type: boolean + secretRef: + description: |- + secretRef references the secret that provides the license for the Confluent Platform component. + More info: https://docs.confluent.io/operator/current/co-license.html#update-component-level-licenses + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + listeners: + description: listeners specify the listeners configurations. + properties: + external: + description: external specifies the Confluent component external + listener. + properties: + externalAccess: + description: externalAccess defines the external access configuration + for the Confluent component. + properties: + loadBalancer: + description: loadBalancer specifies the configuration + to create a Kubernetes load balancer service. + properties: + advertisedURL: + description: |- + advertisedURL specifies the configuration for advertised listener per pod. It is only supported for MDS currently. + If it is enabled, instead of using internal endpoint, the MDS advertised listener for each broker will be + set to: `://.` where podId starts from `0` to `replicaCount -1`. + This is only recommended if you cannot add internal SANs to the TLS certificates for MDS and + the external DNS must be resolved inside the Kubernetes cluster. + This configuration will not take effect if MDS enabled dual listener setup. + properties: + enabled: + description: |- + enabled indicates whether to set the MDS advertised listener url with external endpoint for each broker. + Has no effect with Zookeeper, which will always create a listener per pod. + type: boolean + prefix: + description: |- + prefix specifies the broker prefix for MDS/Zookeeper advertised endpoint. + If not configured, it uses `b` as default prefix for MDS, such as `b#.domain` where `#` will start from `0` to `replicaCount -1`. + It uses 'zookeeper' as default prefix for Zookeeper in the same way. + minLength: 1 + type: string + required: + - enabled + type: object + annotations: + additionalProperties: + type: string + description: annotations is a map of string key and + value pairs. It specifies Kubernetes annotations + for this service. + type: object + x-kubernetes-map-type: granular + domain: + description: domain is the domain name of the component + cluster. + minLength: 1 + type: string + externalTrafficPolicy: + description: externalTrafficPolicy specifies the external + traffic policy for the service. Valid options are + `Local` and `Cluster`. + enum: + - Local + - Cluster + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key and value + pairs. It specifies Kubernetes labels for this service. + type: object + x-kubernetes-map-type: granular + loadBalancerSourceRanges: + description: loadBalancerSourceRanges specify the + source ranges. + items: + type: string + type: array + port: + description: |- + port specifies the external port for the client consumption. + If not configured, the same internal/external port is configured for the component. + Information about the port can be retrieved through the status API. + format: int32 + type: integer + prefix: + description: |- + prefix specify the prefix for the given domain. + The default value is the name of the cluster. + minLength: 1 + type: string + servicePorts: + description: servicePorts specify the user-provided + service port(s). + 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 + sessionAffinity: + description: |- + sessionAffinity defines the Kubernetes session affinity. The valid options are `ClientIP` and `None`. `ClientIP` enables the client IP-based session affinity. + The default value is `None`. + More info: https://kubernetes.io/docs/reference/networking/virtual-ips/#session-affinity. + enum: + - ClientIP + - None + type: string + sessionAffinityConfig: + description: SessionAffinityConfig contains the configurations + of the 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 + required: + - domain + type: object + nodePort: + description: nodePort specifies the configuration to create + a Kubernetes node port service. + properties: + advertisedURL: + description: |- + advertisedURL specifies the configuration for advertised listener per pod. It is only supported for MDS currently. + If it is enabled, instead of using internal endpoint, the MDS advertised listener for each broker will be + set to `://:, where`podId` starts from `0` to `replicaCount - 1`. + This is only recommended if you cannot add internal SANs to the TLS certificates for MDS and + the external DNS must be resolved inside the Kubernetes cluster. + properties: + enabled: + description: |- + enabled indicates whether to set the MDS advertised listener url with external endpoint for each broker. + Has no effect with Zookeeper, which will always create a listener per pod. + type: boolean + prefix: + description: |- + prefix specifies the broker prefix for MDS/Zookeeper advertised endpoint. + If not configured, it uses `b` as default prefix for MDS, such as `b#.domain` where `#` will start from `0` to `replicaCount -1`. + It uses 'zookeeper' as default prefix for Zookeeper in the same way. + minLength: 1 + type: string + required: + - enabled + type: object + annotations: + additionalProperties: + type: string + description: annotations is a map of string key and + value pairs. It specifies Kubernetes annotations + for this service. + type: object + x-kubernetes-map-type: granular + externalTrafficPolicy: + description: |- + externalTrafficPolicy specifies the external traffic policy for the service. + Valid options are `Local` and `Cluster`. + enum: + - Local + - Cluster + type: string + host: + description: host defines the host name of the cluster. + minLength: 1 + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key and value + pairs. It specifies Kubernetes labels for this service. + type: object + x-kubernetes-map-type: granular + nodePortOffset: + description: |- + nodePortOffset specifies the starting offset of the node ports. The port numbers go in ascending order with respect + to the replicas count. + NodePort service creation fails if the node port is not in the range supported by the Kubernetes API server. + The default Kubernetes Node Port range is `30000` - `32762`. + format: int32 + minimum: 0 + type: integer + servicePorts: + description: |- + servicePorts specify user-provided service port(s). + For Kafka with the nodePort type, this setting is only applied to Kafka bootstrap service. + 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 + sessionAffinity: + description: |- + sessionAffinity defines the Kubernetes session affinity. The valid options are `ClientIP` and `None`. `ClientIP` enables the client IP-based session affinity. + The default value is `None`. + More info: https://kubernetes.io/docs/reference/networking/virtual-ips/#session-affinity. + enum: + - ClientIP + - None + type: string + sessionAffinityConfig: + description: SessionAffinityConfig contains the configurations + of the 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 + required: + - host + - nodePortOffset + type: object + route: + description: route specifies the configuration to create + a route service in OpenShift. + properties: + advertisedURL: + description: |- + advertisedURL specifies the configuration for advertised listener per pod. It is only supported for MDS currently. + If it is enabled, instead of using internal endpoint, the MDS advertised listener for each broker will be + set to: `://-http-external.` where podId starts from `0` to `replicaCount -1`. + This is only recommended if you cannot add internal SANs to the TLS certificates for MDS and + the external DNS must be resolved inside the Kubernetes cluster. + This configuration will not take effect if MDS enabled dual listener setup. + properties: + enabled: + description: |- + enabled indicates whether to set the MDS advertised listener url with external endpoint for each broker. + Has no effect with Zookeeper, which will always create a listener per pod. + type: boolean + prefix: + description: |- + prefix specifies the broker prefix for MDS/Zookeeper advertised endpoint. + If not configured, it uses `b` as default prefix for MDS, such as `b#.domain` where `#` will start from `0` to `replicaCount -1`. + It uses 'zookeeper' as default prefix for Zookeeper in the same way. + minLength: 1 + type: string + required: + - enabled + type: object + annotations: + additionalProperties: + type: string + description: annotations is a map of string key and + value pairs. It specifies Kubernetes annotations + for this service. + type: object + x-kubernetes-map-type: granular + domain: + description: domain specifies the domain name of the + Confluent component cluster. + minLength: 1 + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key and value + pairs. It specifies Kubernetes labels for this service. + type: object + x-kubernetes-map-type: granular + prefix: + description: |- + prefix specifies the component prefix when configured for the domain. + The default value is the name of the cluster. + minLength: 1 + type: string + wildcardPolicy: + description: |- + wildcardPolicy allows you to define a route that covers all hosts within a domain. Valid options are `Subdomain` and `None`. + The default value is `None`. + enum: + - Subdomain + - None + type: string + required: + - domain + type: object + type: + description: |- + type specifies the Kubernetes external service for the component. + Valid options are `loadBalancer`, `nodePort`, and `route`. + enum: + - loadBalancer + - nodePort + - route + minLength: 1 + type: string + required: + - type + type: object + tls: + description: tls specifies the TLS configuration for the listener. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + internal: + description: |- + internal specifies the Confluent component's internal listener. + This internal listener is for intra-communication between the pods. + properties: + port: + description: |- + port binds the given port to the internal listener. If not configured, + it will be defaulted to the component-specific internal port. + Port numbers lower than `9093` are reserved by CFK. + format: int32 + minimum: 9093 + type: integer + tls: + description: tls specifies the TLS configuration for the listener. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + type: object + metrics: + description: metrics specify the security settings for the metric + services. + properties: + authentication: + description: authentication specifies the authentication configuration + for the metrics. + properties: + type: + description: type specifies the metrics authentication method. + The valid option is `mtls`. + enum: + - mtls + type: string + required: + - type + type: object + prometheus: + description: prometheus specifies the configuration overrides + for the JMX-Prometheus exporter. + properties: + blacklist: + items: + type: string + type: array + rules: + items: + description: Rule defines the Prometheus Exporter rule override. + properties: + attrNameSnakeCase: + type: boolean + cache: + type: boolean + help: + minLength: 1 + type: string + labels: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: granular + name: + minLength: 1 + type: string + pattern: + minLength: 1 + type: string + type: + minLength: 1 + type: string + value: + minLength: 1 + type: string + valueFactor: + anyOf: + - type: integer + - type: string + default: 1 + 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: array + whitelist: + items: + type: string + type: array + type: object + tls: + description: tls specifies the TLS configuration for the metrics. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + mountedSecrets: + description: |- + mountedSecrets list the secrets injected to + the underlying statefulset configuration. The secret reference is mounted + in the default path `/mnt/secrets/`. The underlying resources + will follow the secret as a file configuration. + More info: https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets-as-files-from-a-pod. + A change to this setting will roll the cluster. + items: + description: |- + MountedSecrets provides a way to inject a custom secret to the underlying + statefulset. + properties: + keyItems: + description: keyItems are key and path names. + 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 + secretRef: + description: secretRef references the name of the secret. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + type: array + mountedVolumes: + description: |- + mountedVolumes list the custom volumes that need to be mounted into the + underlying statefulset. + A change to this setting will roll the cluster. + properties: + volumeMounts: + description: |- + volumeMounts specify the list of volume mounts for the pods in the + statefulset. + 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 + volumes: + description: |- + volumes specify the list of volumes that can be mounted into the pods + of statefulset. + 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 + 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: + 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 + 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 + 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: + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 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 + 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 + 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 + 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 + 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 + 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: + 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 + 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 + 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 + required: + - volumeMounts + - volumes + type: object + oneReplicaPerNode: + description: |- + oneReplicaPerNode controls whether to run 1 pod per node using the pod anti-affinity capability. + Enabling this configuration in an existing cluster will roll the cluster. + type: boolean + pdb: + description: |- + configures PodDisruptionBudget for the Confluent Platform component. + by default PDB is configured based on pre-detemined formula. + properties: + enabled: + description: enabled specifies whether the PodDisruptionBudget + is enabled + type: boolean + maxUnavailable: + description: maxUnavailable is the maximum number of pods that + can be unavailable during the disruption. + format: int32 + type: integer + required: + - enabled + type: object + podTemplate: + description: podTemplate specifies the statefulset pod template configuration. + properties: + affinity: + description: |- + affinity specifies a group of affinity scheduling rules. + More info: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity. + 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 + annotations: + additionalProperties: + type: string + description: |- + annotations is a map of string key and value pairs stored with the resource and + 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 + x-kubernetes-map-type: granular + envVars: + description: |- + envVars contain environment variables to be injected into containers. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container. + 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 + 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: + 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 + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + labels: + additionalProperties: + type: string + description: |- + labels is a map of string key and value pairs that can be used to organize and categorize + (scope and select) objects. + More info: http://kubernetes.io/docs/user-guide/labels. + type: object + x-kubernetes-map-type: granular + 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: + + + 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 + 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: + description: priorityClassName specifies the priority class for + the pod (if any). + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + probe: + description: probe contains the fields for standard Kubernetes + readiness/liveness probe configuration. + properties: + liveness: + description: |- + liveness configures the Kubernetes probe settings. The changes + will override the existing default configuration. + properties: + failureThreshold: + description: |- + failureThreshold is the minimum consecutive failures for the probe to be considered failed. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + initialDelaySeconds: + description: |- + initialDelaySeconds is the number of seconds after the container has started and before probes are initiated. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + path: + description: Path for the HTTP probe + type: string + periodSeconds: + description: |- + periodSeconds specifies how often to perform the probe. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + port: + description: Number of the port to access on the container + type: integer + successThreshold: + description: |- + successThreshold is the minimum consecutive successes for the probe to be considered successful after having failed. + The default values is `1`. Must be `1` for liveness and startup. The minimum value is `1`. + format: int32 + type: integer + timeoutSeconds: + description: |- + timeoutSeconds is the number of seconds after which the probe times out. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + type: object + readiness: + description: |- + readiness configures the Kubernetes probe setting. The changes + will override the existing default configuration. + properties: + failureThreshold: + description: |- + failureThreshold is the minimum consecutive failures for the probe to be considered failed. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + initialDelaySeconds: + description: |- + initialDelaySeconds is the number of seconds after the container has started and before probes are initiated. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + path: + description: Path for the HTTP probe + type: string + periodSeconds: + description: |- + periodSeconds specifies how often to perform the probe. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + port: + description: Number of the port to access on the container + type: integer + successThreshold: + description: |- + successThreshold is the minimum consecutive successes for the probe to be considered successful after having failed. + The default values is `1`. Must be `1` for liveness and startup. The minimum value is `1`. + format: int32 + type: integer + timeoutSeconds: + description: |- + timeoutSeconds is the number of seconds after which the probe times out. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + type: object + type: object + resources: + description: resources describe the compute resource requirements. + 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 + 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: + + + 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: + description: |- + ServiceAccountName is the name of the service account used to run this pod. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account. + type: string + terminationGracePeriodSeconds: + description: terminationGracePeriodSeconds is the grace period + before the pod is deleted. + format: int64 + type: integer + tolerations: + description: |- + tolerations specify the pods to schedule onto the nodes with matching taints, using + the triple `` and the matching operator ``. + 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 + topologySpreadConstraints: + description: |- + topologySpreadConstraints describe how a group of pods ought to spread across topology domains. Scheduler will + schedule pods based on 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 + 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 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. + + + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). + 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 + type: object + replicas: + description: |- + replicas is the desired number of replicas. + A change to this setting will roll the cluster. + format: int32 + type: integer + storageClass: + description: storageClass specifies the storage class used for creating + the PVC for the ksqlDB cluster. + properties: + name: + description: name is the storage class name. + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - name + type: object + telemetry: + description: telemetry specifies the Confluent telemetry reporter + configuration. + properties: + global: + description: |- + global allows disabling telemetry configuration. + If CFK is deployed with telemetry, this field is only + used to disable telemetry. The default value is `true` if + telemetry is enabled at the global level. + type: boolean + type: object + tls: + description: tls specifies the global TLS configurations for the ksqlDB + cluster. + properties: + autoGeneratedCerts: + description: |- + autoGeneratedCerts specifies that the certificates are auto-generated based on + the CA key pair provided. + type: boolean + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + fips: + description: |- + fips specifies the configuration of FIPS compliant Bouncy Castle type Java Keystores for the cp component's + TLS settings. TLS Secrets must have the keys keystore.bcfks, truststore.bcfks, and jksPassword.txt + properties: + enabled: + description: enabled specifies whether to enable the FIPS + configuration for cp components. + type: boolean + required: + - enabled + type: object + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing the + JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + required: + - dataVolumeCapacity + - image + type: object + status: + description: status defines the observed state of ksqlDB Server. + properties: + arbitraryData: + description: arbitraryData is the map for any arbitrary data associated + with this Confluent component. + x-kubernetes-preserve-unknown-fields: true + authorizationType: + description: authorizationType is the authorization type for this + Confluent component. + type: string + clusterName: + description: clusterName is the name of the Confluent Platform component + cluster. + type: string + clusterNamespace: + description: clusterNamespace is the namespace where the Confluent + Platform component cluster is running. + type: string + conditions: + description: conditions specify the latest available observations + of the current state. + items: + description: Condition represent the latest available observations + of the current state. + properties: + lastProbeTime: + description: lastProbeTime shows the last time the condition + was evaluated. + format: date-time + type: string + lastTransitionTime: + description: lastTransitionTime shows the last time the condition + was transitioned from one status to another. + format: date-time + type: string + message: + description: message shows a human-readable message with details + about the transition. + type: string + reason: + description: reason shows the reason for the last transition + of the condition. + type: string + status: + description: status shows the status of the condition, one of + `True`, `False`, or `Unknown`. + type: string + type: + description: type shows the condition type. + type: string + type: object + type: array + currentReplicas: + description: currentReplicas is the number of currently running replicas. + format: int32 + type: integer + internalSecrets: + description: |- + internalSecrets are internal secrets created + by CFK for this Confluent component. + items: + type: string + type: array + internalTopicNames: + description: internalTopicNames are the topics used by the component + for internal use. + items: + type: string + type: array + kafka: + description: kafka is the Kafka client side status for the ksqlDB + cluster. + properties: + authenticationType: + description: authenticationType describes the authentication method + for the Kafka cluster. + type: string + bootstrapEndpoint: + description: bootstrapEndpoint specifies the Kafka bootstrap endpoint. + type: string + tls: + description: tls indicates whether TLS is enabled for the Kafka + dependency. + type: boolean + type: object + listeners: + additionalProperties: + description: ListenerStatus describes general information about + the listeners. + properties: + advertisedExternalEndpoints: + description: advertisedExternalEndpoints specifies other advertised + endpoints used, especially for Kafka. + items: + type: string + type: array + authenticationType: + description: authenticationType shows the authentication type + configured by the listener. + type: string + externalAccessType: + description: externalAccessType shows the external access type + used for the listener. + type: string + externalEndpoint: + description: externalEndpoint specifies the external endpoint + to connect to the Confluent component cluster. + type: string + internalEndpoint: + description: internalEndpoint specifies the internal endpoint + to connect to the Confluent component cluster. + type: string + tls: + description: tls shows whether TLS is configured for the listener. + type: boolean + type: object + description: listeners is a map of listener type and the status of + KsqlDB Listeners. + type: object + x-kubernetes-map-type: granular + observedGeneration: + description: observedGeneration is the most recent generation observed + for this Confluent component. + format: int64 + type: integer + operatorVersion: + description: operatorVersion is the internal version of CFK. + type: string + phase: + description: |- + phase describes the state of the Confluent Platform component. This can either be 'PROVISIONING' + or 'RUNNING' + 'PROVISIONING' means the Confluent Platform component is currently getting deployed and not ready yet. + 'RUNNING' means the Confluent Platform component has been successfully deployed. + type: string + rbac: + description: rbac contains the RBAC-related status when RBAC is enabled. + properties: + clusterID: + description: clusterID specifies the id of the cluster. + type: string + internalRolebindings: + description: internalRolebindings specifies the internal rolebindings. + items: + type: string + type: array + type: object + readyReplicas: + description: readyReplicas is the number of currently ready replicas. + format: int32 + type: integer + replicas: + description: replicas is the number of replicas. + format: int32 + type: integer + restConfig: + description: restConfig is the REST API configuration of the ksqlDB + cluster. + properties: + advertisedExternalEndpoints: + description: advertisedExternalEndpoints specifies other advertised + endpoints used, especially for Kafka. + items: + type: string + type: array + authenticationType: + description: authenticationType shows the authentication type + configured by the listener. + type: string + externalAccessType: + description: externalAccessType shows the external access type + used for the listener. + type: string + externalEndpoint: + description: externalEndpoint specifies the external endpoint + to connect to the Confluent component cluster. + type: string + internalEndpoint: + description: internalEndpoint specifies the internal endpoint + to connect to the Confluent component cluster. + type: string + tls: + description: tls shows whether TLS is configured for the listener. + type: boolean + type: object + selector: + description: |- + selector gets the label selector of the child pod. + The Horizontal Pod Autoscaler(HPA) will scale using the label selector of the child pod. + type: string + serviceID: + description: serviceID is the id of the ksqlDB service. + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.replicas + statusReplicasPath: .status.replicas + status: {} diff --git a/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_schemaexporters.yaml b/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_schemaexporters.yaml new file mode 100644 index 0000000000..fd23b7028a --- /dev/null +++ b/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_schemaexporters.yaml @@ -0,0 +1,688 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: schemaexporters.platform.confluent.io +spec: + group: platform.confluent.io + names: + categories: + - all + - confluent-platform + - confluent + kind: SchemaExporter + listKind: SchemaExporterList + plural: schemaexporters + shortNames: + - se + - schemaexporter + singular: schemaexporter + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.contextName + name: ContextName + type: string + - jsonPath: .status.exporterStatus + name: ExporterStatus + type: string + - jsonPath: .status.state + name: Status + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.sourceSchemaRegistry.endpoint + name: SourceSchemaRegistryEndpoint + priority: 1 + type: string + - jsonPath: .status.destinationSchemaRegistry.endpoint + name: DestinationSchemaRegistryEndpoint + priority: 1 + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: SchemaExporter is the schema for the SchemaExporter 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 defines the desired state of the schema exporter. + properties: + configs: + additionalProperties: + type: string + description: |- + configs is a map of string key and value pairs. It specifies additional configurations for the schema exporter. More info: + https://docs.confluent.io/platform/current/schema-registry/schema-linking-cp.html#create-a-configuration-file-for-the-exporter + type: object + x-kubernetes-map-type: granular + contextName: + description: |- + contextName specifies the custom context name in the destination Schema Registry cluster where the + schemas will be exported. If this is defined, contextType will be ignored. If this is not defined, + schemas will be exported to context in destination based on contextType. + type: string + contextType: + description: |- + contextType specifies the type of context created in the destination Schema Registry cluster of + the schema exporter. + Valid options are `AUTO` and `NONE`. + The default value is `AUTO`. + enum: + - AUTO + - NONE + type: string + destinationCluster: + description: |- + destinationCluster specifies the destination Schema Registry cluster. If this is not defined, + sourceCluster is chosen as the destination and the schema exporter will be exporting + schemas across contexts within the sourceCluster. + Schema exporter should be enabled in Schema Registry cluster CR with `spec.enableSchemaExporter`. + properties: + schemaRegistryClusterRef: + description: schemaRegistryClusterRef references the CFK-managed + Schema Registry cluster. + properties: + name: + description: name specifies the name of the Confluent Platform + component cluster. + type: string + namespace: + description: namespace specifies the namespace where the Confluent + Platform component cluster is running. + type: string + required: + - name + type: object + schemaRegistryRest: + description: schemaRegistryRest specifies the Schema Registry + REST API configuration. + properties: + authentication: + description: authentication specifies the REST API authentication + mechanism. + properties: + basic: + description: basic specifies the basic authentication + settings for the REST API client. + properties: + debug: + description: debug enables the basic authentication + debug logs for JaaS configuration. + type: boolean + directoryPathInContainer: + description: |- + directoryPathInContainer allows to pass the basic credential through a directory path in the container. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + minLength: 1 + type: string + restrictedRoles: + description: |- + restrictedRoles specify the restricted roles on the server side only. + Changes will be only reflected in Control Center. + This configuration is ignored on the client side configuration. + items: + type: string + minItems: 1 + type: array + roles: + description: |- + roles specify the roles on the server side only. + This configuration is ignored on the client side configuration. + items: + type: string + type: array + secretRef: + description: |- + secretRef defines secret reference to pass the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + bearer: + description: bearer specifies the bearer authentication + settings for the REST API client. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container + where the credential is mounted. + minLength: 1 + type: string + secretRef: + description: |- + secretRef specifies the name of the secret that contains the credential. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#bearer-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauth: + description: oauth specifies the OAuth authentication + settings for the REST API client. + properties: + configuration: + description: configuration specifies the OAuth server + settings. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name + of claim in token for identifying the groups + of subject in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect + timeout with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + directoryPathInContainer: + description: directoryPathInContainer allows to pass + the basic credential through a directory path in + the container. + minLength: 1 + type: string + secretRef: + description: secretRef defines secret reference to + pass the required credentials. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - configuration + type: object + type: + description: type specifies the REST API authentication + type. Valid options are `basic`, `bearer`, `mtls` and + `oauth`. + enum: + - basic + - bearer + - mtls + - oauth + type: string + required: + - type + type: object + endpoint: + description: endpoint specifies where Confluent REST API is + running. + minLength: 1 + pattern: ^https?://.* + type: string + kafkaClusterID: + description: |- + kafkaClusterID specifies the id of Kafka cluster. + It takes precedence over using the Kafka REST API to get the cluster id. + minLength: 1 + type: string + tls: + description: "tls specifies the custom TLS structure for the + application resources,\n\t// e.g. connector, topic, schema, + of the Confluent Platform components.\n\t// +optional" + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer contains the directory path in the container where + `keystore.jks`, `truststore.jks`, `jksPassword.txt` keys are mounted. + minLength: 1 + type: string + jksPassword: + description: jksPassword specifies the secret name that + contains the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef specifies the secret name that contains the certificates. + More info about certificates key/value format: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + type: object + type: object + sourceCluster: + description: |- + sourceCluster specifies the source Schema Registry cluster. Schema exporter will be set + up in the source cluster. If this is not defined, controller will try to auto discover Schema Registry + in the namespace of the schema exporter. If it cannot discover a Schema Registry cluster or more than + one Schema Registry clusters are found, controller will return error. + Schema exporter should be enabled in Schema Registry cluster CR with `spec.enableSchemaExporter`. + properties: + schemaRegistryClusterRef: + description: schemaRegistryClusterRef references the CFK-managed + Schema Registry cluster. + properties: + name: + description: name specifies the name of the Confluent Platform + component cluster. + type: string + namespace: + description: namespace specifies the namespace where the Confluent + Platform component cluster is running. + type: string + required: + - name + type: object + schemaRegistryRest: + description: schemaRegistryRest specifies the Schema Registry + REST API configuration. + properties: + authentication: + description: authentication specifies the REST API authentication + mechanism. + properties: + basic: + description: basic specifies the basic authentication + settings for the REST API client. + properties: + debug: + description: debug enables the basic authentication + debug logs for JaaS configuration. + type: boolean + directoryPathInContainer: + description: |- + directoryPathInContainer allows to pass the basic credential through a directory path in the container. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + minLength: 1 + type: string + restrictedRoles: + description: |- + restrictedRoles specify the restricted roles on the server side only. + Changes will be only reflected in Control Center. + This configuration is ignored on the client side configuration. + items: + type: string + minItems: 1 + type: array + roles: + description: |- + roles specify the roles on the server side only. + This configuration is ignored on the client side configuration. + items: + type: string + type: array + secretRef: + description: |- + secretRef defines secret reference to pass the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + bearer: + description: bearer specifies the bearer authentication + settings for the REST API client. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container + where the credential is mounted. + minLength: 1 + type: string + secretRef: + description: |- + secretRef specifies the name of the secret that contains the credential. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#bearer-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauth: + description: oauth specifies the OAuth authentication + settings for the REST API client. + properties: + configuration: + description: configuration specifies the OAuth server + settings. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name + of claim in token for identifying the groups + of subject in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect + timeout with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + directoryPathInContainer: + description: directoryPathInContainer allows to pass + the basic credential through a directory path in + the container. + minLength: 1 + type: string + secretRef: + description: secretRef defines secret reference to + pass the required credentials. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - configuration + type: object + type: + description: type specifies the REST API authentication + type. Valid options are `basic`, `bearer`, `mtls` and + `oauth`. + enum: + - basic + - bearer + - mtls + - oauth + type: string + required: + - type + type: object + endpoint: + description: endpoint specifies where Confluent REST API is + running. + minLength: 1 + pattern: ^https?://.* + type: string + kafkaClusterID: + description: |- + kafkaClusterID specifies the id of Kafka cluster. + It takes precedence over using the Kafka REST API to get the cluster id. + minLength: 1 + type: string + tls: + description: "tls specifies the custom TLS structure for the + application resources,\n\t// e.g. connector, topic, schema, + of the Confluent Platform components.\n\t// +optional" + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer contains the directory path in the container where + `keystore.jks`, `truststore.jks`, `jksPassword.txt` keys are mounted. + minLength: 1 + type: string + jksPassword: + description: jksPassword specifies the secret name that + contains the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef specifies the secret name that contains the certificates. + More info about certificates key/value format: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + type: object + type: object + subjectRenameFormat: + description: |- + subjectRenameFormat specifies the rename format for the subjects exported to the destination. + For example, if the value is `my-${subject}`, subjects at destination will become `my-firstSubject` + where `firstSubject` is the original subject name. + type: string + subjects: + description: |- + subjects specifies the list of subjects to be exported by schema exporter. + The default value is `["*"]`. This indicates all subjects in the default context. + items: + type: string + type: array + type: object + status: + description: status defines the observed state of the schema exporter. + properties: + appState: + default: Unknown + description: appState is the current state of the schema exporter + application. + enum: + - Unknown + - Created + - Failed + - Deleted + type: string + conditions: + description: conditions are the latest available observations of the + schema exporter's state. + items: + description: Condition represent the latest available observations + of the current state. + properties: + lastProbeTime: + description: lastProbeTime shows the last time the condition + was evaluated. + format: date-time + type: string + lastTransitionTime: + description: lastTransitionTime shows the last time the condition + was transitioned from one status to another. + format: date-time + type: string + message: + description: message shows a human-readable message with details + about the transition. + type: string + reason: + description: reason shows the reason for the last transition + of the condition. + type: string + status: + description: status shows the status of the condition, one of + `True`, `False`, or `Unknown`. + type: string + type: + description: type shows the condition type. + type: string + type: object + type: array + contextName: + description: |- + contextName shows the name of the context in the destination Schema Registry cluster + where the schemas will be exported. + type: string + contextType: + description: contextType is the contextType of the schema exporter. + type: string + destinationSchemaRegistry: + description: |- + destinationSchemaRegistry shows the destination Schema Registry endpoint, authentication type + and if it is using TLS. + properties: + authenticationType: + description: authenticationType is the authentication method used + for Schema Registry. + type: string + endpoint: + description: endpoint is the Schema Registry REST endpoint. + type: string + tls: + description: tls shows whether the Schema Registry is using TLS. + type: boolean + type: object + exporterStatus: + description: exporterStatus is the status of the schema exporter. + type: string + observedGeneration: + description: observedGeneration is the most recent generation observed + for this Confluent component. + format: int64 + type: integer + sourceSchemaRegistry: + description: |- + sourceSchemaRegistry shows the source Schema Registry endpoint, authentication type + and if it is using TLS. + properties: + authenticationType: + description: authenticationType is the authentication method used + for Schema Registry. + type: string + endpoint: + description: endpoint is the Schema Registry REST endpoint. + type: string + tls: + description: tls shows whether the Schema Registry is using TLS. + type: boolean + type: object + state: + description: state is the current state of the schema exporter. + type: string + subjects: + description: subjects is the list of subjects exported by the schema + exporter. + items: + type: string + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_schemaregistries.yaml b/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_schemaregistries.yaml new file mode 100644 index 0000000000..2cc59aaf4b --- /dev/null +++ b/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_schemaregistries.yaml @@ -0,0 +1,5801 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: schemaregistries.platform.confluent.io +spec: + group: platform.confluent.io + names: + categories: + - all + - confluent-platform + - confluent + kind: SchemaRegistry + listKind: SchemaRegistryList + plural: schemaregistries + shortNames: + - schemaregistry + - sr + singular: schemaregistry + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.replicas + name: Replicas + type: string + - jsonPath: .status.readyReplicas + name: Ready + type: string + - jsonPath: .status.phase + name: Status + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.kafka.bootstrapEndpoint + name: Kafka + priority: 1 + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: SchemaRegistry is the schema for the Schema Registry 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 defines the desired state of the Schema Registry cluster. + properties: + authentication: + description: authentication specifies the authentication configurations + for the REST API endpoint. + properties: + basic: + description: basic specifies the configuration for basic authentication. + properties: + debug: + description: debug enables the basic authentication debug + logs for JaaS configuration. + type: boolean + directoryPathInContainer: + description: |- + directoryPathInContainer allows to pass the basic credential through a directory path in the container. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + minLength: 1 + type: string + restrictedRoles: + description: |- + restrictedRoles specify the restricted roles on the server side only. + Changes will be only reflected in Control Center. + This configuration is ignored on the client side configuration. + items: + type: string + minItems: 1 + type: array + roles: + description: |- + roles specify the roles on the server side only. + This configuration is ignored on the client side configuration. + items: + type: string + type: array + secretRef: + description: |- + secretRef defines secret reference to pass the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauth: + description: oauth specifies the configuration for OAuth authentication. + properties: + configuration: + description: configuration specifies the OAuth server settings. + properties: + audience: + description: audience specifies the audience claim in + the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected issuer + in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name of claim + in token for identifying the groups of subject in the + JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect timeout + with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout with + IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry backoff + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff with + IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim in JWT + to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + directoryPathInContainer: + description: directoryPathInContainer allows to pass the basic + credential through a directory path in the container. + minLength: 1 + type: string + secretRef: + description: secretRef defines secret reference to pass the + required credentials. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - configuration + type: object + type: + description: type specifies the authentication scheme for the + REST API server. Valid options are `basic`, `oauth` and `mtls`. + enum: + - basic + - mtls + - oauth + type: string + required: + - type + type: object + authorization: + description: authorization specifies the authorization configurations. + properties: + kafkaRestClassRef: + description: |- + kafkaRestClassRef references the KafkaRestClass + which specifies the Kafka REST API connection configuration. + properties: + name: + description: name specifies the name of the KafkaRestClass + application resource. + minLength: 1 + type: string + namespace: + description: namespace specifies the namespace of the KafkaRestClass. + type: string + required: + - name + type: object + type: + description: type specifies the client-side authorization type. + The valid option is `rbac`. + enum: + - rbac + type: string + required: + - type + type: object + configOverrides: + description: |- + configOverrides specifies the configs to override the server, JVM, Log4j properties for the Schema Registry cluster. + A change will roll the cluster. + properties: + jvm: + description: |- + jvm is a list of JVM configuration supported by the Confluent Platform component. + This will either add or update the existing configuration. + items: + type: string + type: array + log4j: + description: |- + log4j is a list of Log4J configuration supported by the Confluent Platform component. + This will either add or update the existing configuration. + items: + type: string + type: array + server: + description: |- + server is a list of server configuration supported by the Confluent Platform component. + This will either add or update existing configuration. + items: + type: string + type: array + type: object + dependencies: + description: dependencies specify the dependency configurations for + the Schema Registry. + properties: + kafka: + description: kafka specifies the Kafka dependency configuration. + properties: + authentication: + description: authentication defines the authentication for + the Kafka cluster. + properties: + jaasConfig: + description: jaasConfig specifies the Kafka client-side + JaaS configuration. + properties: + secretRef: + description: |- + secretRef references the secret containing the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + jaasConfigPassThrough: + description: jaasConfigPassThrough specifies another way + to provide the Kafka client-side JaaS configuration. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where required credentials are mounted. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + minLength: 1 + type: string + secretRef: + description: |- + secretRef references the secret containing the required credentials for authentication. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauthSettings: + description: |- + oauthSettings specifies the OAuth settings. + This needs to passed with the authentication type `oauth`. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name of + claim in token for identifying the groups of subject + in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect timeout + with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + oauthbearer: + description: |- + oauthbearer is the authentication mechanism to provider principals. + Only supported in RBAC deployment. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container + where the credential is mounted. + minLength: 1 + type: string + secretRef: + description: |- + secretRef specifies the name of the secret that contains the credential. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#bearer-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + type: + description: |- + type specifies the Kafka client authentication type. + Valid options are `plain`, `oauthbearer`, `digest`, `mtls` and `oauth`. + enum: + - plain + - oauthbearer + - digest + - mtls + - oauth + type: string + required: + - type + type: object + bootstrapEndpoint: + description: bootstrapEndpoint specifies the Kafka bootstrap + endpoint. + minLength: 1 + pattern: .+:[0-9]+ + type: string + discovery: + description: discovery specifies the capability to discover + the Kafka cluster. + properties: + name: + description: name is the name of the Confluent Platform + component cluster. + type: string + namespace: + description: |- + namespace is where the Confluent Platform component is running. + The default value is the namespace where CFK is running. + type: string + secretRef: + description: secretRef is the name of the secret used + to discover the Confluent Platform component. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - name + type: object + tls: + description: tls defines the client-side TLS setting for the + Kafka cluster. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + mds: + description: mds specifies the MDS dependencies configurations. + properties: + authentication: + description: authentication specifies the client side authentication + configuration for the MDS. + properties: + bearer: + description: bearer specifies the bearer authentication + settings. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container + where the credential is mounted. + minLength: 1 + type: string + secretRef: + description: |- + secretRef specifies the name of the secret that contains the credential. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#bearer-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauth: + description: oauth specifies the OAuth authentication + settings. + properties: + configuration: + description: configuration specifies the OAuth server + settings. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name + of claim in token for identifying the groups + of subject in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect + timeout with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + directoryPathInContainer: + description: directoryPathInContainer allows to pass + the basic credential through a directory path in + the container. + minLength: 1 + type: string + secretRef: + description: secretRef defines secret reference to + pass the required credentials. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - configuration + type: object + type: + description: type specifies the authentication method + for the MDS. The valid option is `bearer`, `oauth`. + enum: + - bearer + - oauth + type: string + required: + - type + type: object + endpoint: + description: endpoint specifies the MDS endpoint. + minLength: 1 + pattern: ^https?://.* + type: string + ssoProtocol: + description: sso protocol, valid options are ldap and oidc. + enum: + - ldap + - oidc + type: string + tls: + description: ClientTLSConfig specifies the TLS configuration + for the Confluent component (dependencies, listeners). + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + tokenKeyPair: + description: tokenKeyPair specifies the token keypair to configure + the MDS. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer defines the directory path in the container + where the MDS token key pair are mounted. + minLength: 1 + type: string + encryptedTokenKey: + description: |- + EncryptedTokenKey boolean value indicating whether the tokenKeypair(private used for signing) is encrypted using a passphrase. If true, cfk + operator will look for a file named mdsTokenKeyPassphrase.txt containing key value pair + mdsTokenKeyPassphrase=. Relevant only for mds server. Ignored if set for a client configuration. + type: boolean + secretRef: + description: secretRef references the name of the secret + that contains the MDS token key pair. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + required: + - authentication + - endpoint + - tokenKeyPair + type: object + type: object + enableSchemaExporter: + description: enableSchemaExporter enables schema exporter in the Schema + Registry. + type: boolean + externalAccess: + description: |- + externalAccess specifies the external access configuration. + When `spec.listeners` is configured, configuring `spec.externalAccess` is not allowed. + Please configure `spec.listeners.external.externalAccess` instead". + properties: + loadBalancer: + description: loadBalancer specifies the configuration to create + a Kubernetes load balancer service. + properties: + advertisedURL: + description: |- + advertisedURL specifies the configuration for advertised listener per pod. It is only supported for MDS currently. + If it is enabled, instead of using internal endpoint, the MDS advertised listener for each broker will be + set to: `://.` where podId starts from `0` to `replicaCount -1`. + This is only recommended if you cannot add internal SANs to the TLS certificates for MDS and + the external DNS must be resolved inside the Kubernetes cluster. + This configuration will not take effect if MDS enabled dual listener setup. + properties: + enabled: + description: |- + enabled indicates whether to set the MDS advertised listener url with external endpoint for each broker. + Has no effect with Zookeeper, which will always create a listener per pod. + type: boolean + prefix: + description: |- + prefix specifies the broker prefix for MDS/Zookeeper advertised endpoint. + If not configured, it uses `b` as default prefix for MDS, such as `b#.domain` where `#` will start from `0` to `replicaCount -1`. + It uses 'zookeeper' as default prefix for Zookeeper in the same way. + minLength: 1 + type: string + required: + - enabled + type: object + annotations: + additionalProperties: + type: string + description: annotations is a map of string key and value + pairs. It specifies Kubernetes annotations for this service. + type: object + x-kubernetes-map-type: granular + domain: + description: domain is the domain name of the component cluster. + minLength: 1 + type: string + externalTrafficPolicy: + description: externalTrafficPolicy specifies the external + traffic policy for the service. Valid options are `Local` + and `Cluster`. + enum: + - Local + - Cluster + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key and value pairs. + It specifies Kubernetes labels for this service. + type: object + x-kubernetes-map-type: granular + loadBalancerSourceRanges: + description: loadBalancerSourceRanges specify the source ranges. + items: + type: string + type: array + port: + description: |- + port specifies the external port for the client consumption. + If not configured, the same internal/external port is configured for the component. + Information about the port can be retrieved through the status API. + format: int32 + type: integer + prefix: + description: |- + prefix specify the prefix for the given domain. + The default value is the name of the cluster. + minLength: 1 + type: string + servicePorts: + description: servicePorts specify the user-provided service + port(s). + 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 + sessionAffinity: + description: |- + sessionAffinity defines the Kubernetes session affinity. The valid options are `ClientIP` and `None`. `ClientIP` enables the client IP-based session affinity. + The default value is `None`. + More info: https://kubernetes.io/docs/reference/networking/virtual-ips/#session-affinity. + enum: + - ClientIP + - None + type: string + sessionAffinityConfig: + description: SessionAffinityConfig contains the configurations + of the 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 + required: + - domain + type: object + nodePort: + description: nodePort specifies the configuration to create a + Kubernetes node port service. + properties: + advertisedURL: + description: |- + advertisedURL specifies the configuration for advertised listener per pod. It is only supported for MDS currently. + If it is enabled, instead of using internal endpoint, the MDS advertised listener for each broker will be + set to `://:, where`podId` starts from `0` to `replicaCount - 1`. + This is only recommended if you cannot add internal SANs to the TLS certificates for MDS and + the external DNS must be resolved inside the Kubernetes cluster. + properties: + enabled: + description: |- + enabled indicates whether to set the MDS advertised listener url with external endpoint for each broker. + Has no effect with Zookeeper, which will always create a listener per pod. + type: boolean + prefix: + description: |- + prefix specifies the broker prefix for MDS/Zookeeper advertised endpoint. + If not configured, it uses `b` as default prefix for MDS, such as `b#.domain` where `#` will start from `0` to `replicaCount -1`. + It uses 'zookeeper' as default prefix for Zookeeper in the same way. + minLength: 1 + type: string + required: + - enabled + type: object + annotations: + additionalProperties: + type: string + description: annotations is a map of string key and value + pairs. It specifies Kubernetes annotations for this service. + type: object + x-kubernetes-map-type: granular + externalTrafficPolicy: + description: |- + externalTrafficPolicy specifies the external traffic policy for the service. + Valid options are `Local` and `Cluster`. + enum: + - Local + - Cluster + type: string + host: + description: host defines the host name of the cluster. + minLength: 1 + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key and value pairs. + It specifies Kubernetes labels for this service. + type: object + x-kubernetes-map-type: granular + nodePortOffset: + description: |- + nodePortOffset specifies the starting offset of the node ports. The port numbers go in ascending order with respect + to the replicas count. + NodePort service creation fails if the node port is not in the range supported by the Kubernetes API server. + The default Kubernetes Node Port range is `30000` - `32762`. + format: int32 + minimum: 0 + type: integer + servicePorts: + description: |- + servicePorts specify user-provided service port(s). + For Kafka with the nodePort type, this setting is only applied to Kafka bootstrap service. + 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 + sessionAffinity: + description: |- + sessionAffinity defines the Kubernetes session affinity. The valid options are `ClientIP` and `None`. `ClientIP` enables the client IP-based session affinity. + The default value is `None`. + More info: https://kubernetes.io/docs/reference/networking/virtual-ips/#session-affinity. + enum: + - ClientIP + - None + type: string + sessionAffinityConfig: + description: SessionAffinityConfig contains the configurations + of the 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 + required: + - host + - nodePortOffset + type: object + route: + description: route specifies the configuration to create a route + service in OpenShift. + properties: + advertisedURL: + description: |- + advertisedURL specifies the configuration for advertised listener per pod. It is only supported for MDS currently. + If it is enabled, instead of using internal endpoint, the MDS advertised listener for each broker will be + set to: `://-http-external.` where podId starts from `0` to `replicaCount -1`. + This is only recommended if you cannot add internal SANs to the TLS certificates for MDS and + the external DNS must be resolved inside the Kubernetes cluster. + This configuration will not take effect if MDS enabled dual listener setup. + properties: + enabled: + description: |- + enabled indicates whether to set the MDS advertised listener url with external endpoint for each broker. + Has no effect with Zookeeper, which will always create a listener per pod. + type: boolean + prefix: + description: |- + prefix specifies the broker prefix for MDS/Zookeeper advertised endpoint. + If not configured, it uses `b` as default prefix for MDS, such as `b#.domain` where `#` will start from `0` to `replicaCount -1`. + It uses 'zookeeper' as default prefix for Zookeeper in the same way. + minLength: 1 + type: string + required: + - enabled + type: object + annotations: + additionalProperties: + type: string + description: annotations is a map of string key and value + pairs. It specifies Kubernetes annotations for this service. + type: object + x-kubernetes-map-type: granular + domain: + description: domain specifies the domain name of the Confluent + component cluster. + minLength: 1 + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key and value pairs. + It specifies Kubernetes labels for this service. + type: object + x-kubernetes-map-type: granular + prefix: + description: |- + prefix specifies the component prefix when configured for the domain. + The default value is the name of the cluster. + minLength: 1 + type: string + wildcardPolicy: + description: |- + wildcardPolicy allows you to define a route that covers all hosts within a domain. Valid options are `Subdomain` and `None`. + The default value is `None`. + enum: + - Subdomain + - None + type: string + required: + - domain + type: object + type: + description: |- + type specifies the Kubernetes external service for the component. + Valid options are `loadBalancer`, `nodePort`, and `route`. + enum: + - loadBalancer + - nodePort + - route + minLength: 1 + type: string + required: + - type + type: object + headlessService: + description: headlessService specifies the configuration of the Kubernetes + headless service. + properties: + annotations: + additionalProperties: + type: string + description: |- + annotations is a map of string key and value pairs. + It specifies the annotations to be added to the CFK-created headless service. + These annotations are merged with the injectAnnotations and take precedence. + type: object + x-kubernetes-map-type: granular + labels: + additionalProperties: + type: string + description: |- + labels is a map of string key and value pairs. + It specifies the labels to be added to the CFK-created headless service. + These labels are merged with the injectLabels and take precedence. + type: object + x-kubernetes-map-type: granular + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses specifies the publishNotReadyAddresses field. + For Kafka, this value must be true. The default value is true. + type: boolean + type: object + image: + description: |- + image specifies the application and the init docker image configurations. + A change to this setting will roll the cluster. + properties: + application: + description: |- + application is the Docker image name of the application. Specify + `//:`. + pattern: .+:.+ + type: string + init: + description: |- + init is the init-container name. Specify + `//:`. + pattern: .+:.+ + type: string + pullPolicy: + description: |- + pullPolicy is the policy for pulling images. Valid options are `Always`, `Never`, and `IfNotPresent`. + The default value is `IfNotPresent`. + enum: + - Always + - Never + - IfNotPresent + type: string + pullSecretRef: + description: |- + pullSecretRef references the secrets in the same namespace to be used for pulling images. + Image pull secrets are distinct from secrets because secrets + can be mounted in the pod, but image pull secrets are only accessed by `kubelet`. + More info: https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod + items: + type: string + type: array + required: + - application + - init + type: object + injectAnnotations: + additionalProperties: + type: string + description: |- + injectAnnotations are the annotations injected to the internal resources that CFK created. + The internal annotations are preserved and cannot be overridden. + For pod annotations, use `podTemplate.annotations`. + type: object + x-kubernetes-map-type: granular + injectLabels: + additionalProperties: + type: string + description: |- + injectLabels are the labels injected to the internal resources that CFK created. + The internal labels are preserved and cannot be overridden. + For pod labels, use `podTemplate.labels`. + type: object + x-kubernetes-map-type: granular + internalTopicReplicatorFactor: + description: internalTopicReplicatorFactor specifies the replication + factor for internal topics. + format: int32 + minimum: 1 + type: integer + k8sClusterDomain: + description: |- + k8sClusterDomain specifies the configuration of the Kubernetes cluster domain. + The default is the `cluster.local` domain. + type: string + license: + description: license specifies the license configuration for the Confluent + Platform component. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + the license key is mounted. More info: + https://docs.confluent.io/operator/current/co-license.html#update-component-level-licenses + minLength: 1 + type: string + globalLicense: + description: globalLicense specifies whether the Confluent Platform + component shares the common global license. + type: boolean + secretRef: + description: |- + secretRef references the secret that provides the license for the Confluent Platform component. + More info: https://docs.confluent.io/operator/current/co-license.html#update-component-level-licenses + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + listeners: + description: listeners specify the listeners configurations. + properties: + external: + description: external specifies the Confluent component external + listener. + properties: + externalAccess: + description: externalAccess defines the external access configuration + for the Confluent component. + properties: + loadBalancer: + description: loadBalancer specifies the configuration + to create a Kubernetes load balancer service. + properties: + advertisedURL: + description: |- + advertisedURL specifies the configuration for advertised listener per pod. It is only supported for MDS currently. + If it is enabled, instead of using internal endpoint, the MDS advertised listener for each broker will be + set to: `://.` where podId starts from `0` to `replicaCount -1`. + This is only recommended if you cannot add internal SANs to the TLS certificates for MDS and + the external DNS must be resolved inside the Kubernetes cluster. + This configuration will not take effect if MDS enabled dual listener setup. + properties: + enabled: + description: |- + enabled indicates whether to set the MDS advertised listener url with external endpoint for each broker. + Has no effect with Zookeeper, which will always create a listener per pod. + type: boolean + prefix: + description: |- + prefix specifies the broker prefix for MDS/Zookeeper advertised endpoint. + If not configured, it uses `b` as default prefix for MDS, such as `b#.domain` where `#` will start from `0` to `replicaCount -1`. + It uses 'zookeeper' as default prefix for Zookeeper in the same way. + minLength: 1 + type: string + required: + - enabled + type: object + annotations: + additionalProperties: + type: string + description: annotations is a map of string key and + value pairs. It specifies Kubernetes annotations + for this service. + type: object + x-kubernetes-map-type: granular + domain: + description: domain is the domain name of the component + cluster. + minLength: 1 + type: string + externalTrafficPolicy: + description: externalTrafficPolicy specifies the external + traffic policy for the service. Valid options are + `Local` and `Cluster`. + enum: + - Local + - Cluster + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key and value + pairs. It specifies Kubernetes labels for this service. + type: object + x-kubernetes-map-type: granular + loadBalancerSourceRanges: + description: loadBalancerSourceRanges specify the + source ranges. + items: + type: string + type: array + port: + description: |- + port specifies the external port for the client consumption. + If not configured, the same internal/external port is configured for the component. + Information about the port can be retrieved through the status API. + format: int32 + type: integer + prefix: + description: |- + prefix specify the prefix for the given domain. + The default value is the name of the cluster. + minLength: 1 + type: string + servicePorts: + description: servicePorts specify the user-provided + service port(s). + 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 + sessionAffinity: + description: |- + sessionAffinity defines the Kubernetes session affinity. The valid options are `ClientIP` and `None`. `ClientIP` enables the client IP-based session affinity. + The default value is `None`. + More info: https://kubernetes.io/docs/reference/networking/virtual-ips/#session-affinity. + enum: + - ClientIP + - None + type: string + sessionAffinityConfig: + description: SessionAffinityConfig contains the configurations + of the 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 + required: + - domain + type: object + nodePort: + description: nodePort specifies the configuration to create + a Kubernetes node port service. + properties: + advertisedURL: + description: |- + advertisedURL specifies the configuration for advertised listener per pod. It is only supported for MDS currently. + If it is enabled, instead of using internal endpoint, the MDS advertised listener for each broker will be + set to `://:, where`podId` starts from `0` to `replicaCount - 1`. + This is only recommended if you cannot add internal SANs to the TLS certificates for MDS and + the external DNS must be resolved inside the Kubernetes cluster. + properties: + enabled: + description: |- + enabled indicates whether to set the MDS advertised listener url with external endpoint for each broker. + Has no effect with Zookeeper, which will always create a listener per pod. + type: boolean + prefix: + description: |- + prefix specifies the broker prefix for MDS/Zookeeper advertised endpoint. + If not configured, it uses `b` as default prefix for MDS, such as `b#.domain` where `#` will start from `0` to `replicaCount -1`. + It uses 'zookeeper' as default prefix for Zookeeper in the same way. + minLength: 1 + type: string + required: + - enabled + type: object + annotations: + additionalProperties: + type: string + description: annotations is a map of string key and + value pairs. It specifies Kubernetes annotations + for this service. + type: object + x-kubernetes-map-type: granular + externalTrafficPolicy: + description: |- + externalTrafficPolicy specifies the external traffic policy for the service. + Valid options are `Local` and `Cluster`. + enum: + - Local + - Cluster + type: string + host: + description: host defines the host name of the cluster. + minLength: 1 + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key and value + pairs. It specifies Kubernetes labels for this service. + type: object + x-kubernetes-map-type: granular + nodePortOffset: + description: |- + nodePortOffset specifies the starting offset of the node ports. The port numbers go in ascending order with respect + to the replicas count. + NodePort service creation fails if the node port is not in the range supported by the Kubernetes API server. + The default Kubernetes Node Port range is `30000` - `32762`. + format: int32 + minimum: 0 + type: integer + servicePorts: + description: |- + servicePorts specify user-provided service port(s). + For Kafka with the nodePort type, this setting is only applied to Kafka bootstrap service. + 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 + sessionAffinity: + description: |- + sessionAffinity defines the Kubernetes session affinity. The valid options are `ClientIP` and `None`. `ClientIP` enables the client IP-based session affinity. + The default value is `None`. + More info: https://kubernetes.io/docs/reference/networking/virtual-ips/#session-affinity. + enum: + - ClientIP + - None + type: string + sessionAffinityConfig: + description: SessionAffinityConfig contains the configurations + of the 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 + required: + - host + - nodePortOffset + type: object + route: + description: route specifies the configuration to create + a route service in OpenShift. + properties: + advertisedURL: + description: |- + advertisedURL specifies the configuration for advertised listener per pod. It is only supported for MDS currently. + If it is enabled, instead of using internal endpoint, the MDS advertised listener for each broker will be + set to: `://-http-external.` where podId starts from `0` to `replicaCount -1`. + This is only recommended if you cannot add internal SANs to the TLS certificates for MDS and + the external DNS must be resolved inside the Kubernetes cluster. + This configuration will not take effect if MDS enabled dual listener setup. + properties: + enabled: + description: |- + enabled indicates whether to set the MDS advertised listener url with external endpoint for each broker. + Has no effect with Zookeeper, which will always create a listener per pod. + type: boolean + prefix: + description: |- + prefix specifies the broker prefix for MDS/Zookeeper advertised endpoint. + If not configured, it uses `b` as default prefix for MDS, such as `b#.domain` where `#` will start from `0` to `replicaCount -1`. + It uses 'zookeeper' as default prefix for Zookeeper in the same way. + minLength: 1 + type: string + required: + - enabled + type: object + annotations: + additionalProperties: + type: string + description: annotations is a map of string key and + value pairs. It specifies Kubernetes annotations + for this service. + type: object + x-kubernetes-map-type: granular + domain: + description: domain specifies the domain name of the + Confluent component cluster. + minLength: 1 + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key and value + pairs. It specifies Kubernetes labels for this service. + type: object + x-kubernetes-map-type: granular + prefix: + description: |- + prefix specifies the component prefix when configured for the domain. + The default value is the name of the cluster. + minLength: 1 + type: string + wildcardPolicy: + description: |- + wildcardPolicy allows you to define a route that covers all hosts within a domain. Valid options are `Subdomain` and `None`. + The default value is `None`. + enum: + - Subdomain + - None + type: string + required: + - domain + type: object + type: + description: |- + type specifies the Kubernetes external service for the component. + Valid options are `loadBalancer`, `nodePort`, and `route`. + enum: + - loadBalancer + - nodePort + - route + minLength: 1 + type: string + required: + - type + type: object + tls: + description: tls specifies the TLS configuration for the listener. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + internal: + description: |- + internal specifies the Confluent component's internal listener. + This internal listener is for intra-communication between the pods. + properties: + port: + description: |- + port binds the given port to the internal listener. If not configured, + it will be defaulted to the component-specific internal port. + Port numbers lower than `9093` are reserved by CFK. + format: int32 + minimum: 9093 + type: integer + tls: + description: tls specifies the TLS configuration for the listener. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + type: object + metrics: + description: metrics specify the security settings for the metric + services. + properties: + authentication: + description: authentication specifies the authentication configuration + for the metrics. + properties: + type: + description: type specifies the metrics authentication method. + The valid option is `mtls`. + enum: + - mtls + type: string + required: + - type + type: object + prometheus: + description: prometheus specifies the configuration overrides + for the JMX-Prometheus exporter. + properties: + blacklist: + items: + type: string + type: array + rules: + items: + description: Rule defines the Prometheus Exporter rule override. + properties: + attrNameSnakeCase: + type: boolean + cache: + type: boolean + help: + minLength: 1 + type: string + labels: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: granular + name: + minLength: 1 + type: string + pattern: + minLength: 1 + type: string + type: + minLength: 1 + type: string + value: + minLength: 1 + type: string + valueFactor: + anyOf: + - type: integer + - type: string + default: 1 + 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: array + whitelist: + items: + type: string + type: array + type: object + tls: + description: tls specifies the TLS configuration for the metrics. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + mountedSecrets: + description: |- + mountedSecrets list the secrets injected to + the underlying statefulset configuration. The secret reference is mounted + in the default path `/mnt/secrets/`. The underlying resources + will follow the secret as a file configuration. + More info: https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets-as-files-from-a-pod. + A change to this setting will roll the cluster. + items: + description: |- + MountedSecrets provides a way to inject a custom secret to the underlying + statefulset. + properties: + keyItems: + description: keyItems are key and path names. + 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 + secretRef: + description: secretRef references the name of the secret. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + type: array + mountedVolumes: + description: |- + mountedVolumes list the custom volumes that need to be mounted into the + underlying statefulset. + A change to this setting will roll the cluster. + properties: + volumeMounts: + description: |- + volumeMounts specify the list of volume mounts for the pods in the + statefulset. + 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 + volumes: + description: |- + volumes specify the list of volumes that can be mounted into the pods + of statefulset. + 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 + 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: + 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 + 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 + 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: + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 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 + 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 + 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 + 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 + 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 + 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: + 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 + 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 + 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 + required: + - volumeMounts + - volumes + type: object + oneReplicaPerNode: + description: |- + oneReplicaPerNode controls whether to run 1 pod per node using the pod anti-affinity capability. + Enabling this configuration in an existing cluster will roll the cluster. + type: boolean + passwordEncoder: + description: passwordEncoder specifies password encoder secret for + Schema Registry. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer contains the directory path in the container where + the required secret is mounted. + Directory should have the file `password-encoder.txt`. The contents should include a new password. + Old password is optional and required only for rotation. + More info: https://docs.confluent.io/operator/current/co-password-encoder-secret. + type: string + secretRef: + description: |- + secretRef specifies the secret name. The secret should have the key + `password-encoder.txt`. The contents should include a new password. + Old password is optional and required only for rotation. + More info: https://docs.confluent.io/operator/current/co-password-encoder-secret. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + pdb: + description: |- + configures PodDisruptionBudget for the Confluent Platform component. + by default PDB is configured based on pre-detemined formula. + properties: + enabled: + description: enabled specifies whether the PodDisruptionBudget + is enabled + type: boolean + maxUnavailable: + description: maxUnavailable is the maximum number of pods that + can be unavailable during the disruption. + format: int32 + type: integer + required: + - enabled + type: object + podTemplate: + description: podTemplate specifies the statefulset pod template configuration. + properties: + affinity: + description: |- + affinity specifies a group of affinity scheduling rules. + More info: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity. + 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 + annotations: + additionalProperties: + type: string + description: |- + annotations is a map of string key and value pairs stored with the resource and + 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 + x-kubernetes-map-type: granular + envVars: + description: |- + envVars contain environment variables to be injected into containers. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container. + 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 + 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: + 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 + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + labels: + additionalProperties: + type: string + description: |- + labels is a map of string key and value pairs that can be used to organize and categorize + (scope and select) objects. + More info: http://kubernetes.io/docs/user-guide/labels. + type: object + x-kubernetes-map-type: granular + 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: + + + 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 + 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: + description: priorityClassName specifies the priority class for + the pod (if any). + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + probe: + description: probe contains the fields for standard Kubernetes + readiness/liveness probe configuration. + properties: + liveness: + description: |- + liveness configures the Kubernetes probe settings. The changes + will override the existing default configuration. + properties: + failureThreshold: + description: |- + failureThreshold is the minimum consecutive failures for the probe to be considered failed. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + initialDelaySeconds: + description: |- + initialDelaySeconds is the number of seconds after the container has started and before probes are initiated. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + path: + description: Path for the HTTP probe + type: string + periodSeconds: + description: |- + periodSeconds specifies how often to perform the probe. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + port: + description: Number of the port to access on the container + type: integer + successThreshold: + description: |- + successThreshold is the minimum consecutive successes for the probe to be considered successful after having failed. + The default values is `1`. Must be `1` for liveness and startup. The minimum value is `1`. + format: int32 + type: integer + timeoutSeconds: + description: |- + timeoutSeconds is the number of seconds after which the probe times out. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + type: object + readiness: + description: |- + readiness configures the Kubernetes probe setting. The changes + will override the existing default configuration. + properties: + failureThreshold: + description: |- + failureThreshold is the minimum consecutive failures for the probe to be considered failed. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + initialDelaySeconds: + description: |- + initialDelaySeconds is the number of seconds after the container has started and before probes are initiated. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + path: + description: Path for the HTTP probe + type: string + periodSeconds: + description: |- + periodSeconds specifies how often to perform the probe. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + port: + description: Number of the port to access on the container + type: integer + successThreshold: + description: |- + successThreshold is the minimum consecutive successes for the probe to be considered successful after having failed. + The default values is `1`. Must be `1` for liveness and startup. The minimum value is `1`. + format: int32 + type: integer + timeoutSeconds: + description: |- + timeoutSeconds is the number of seconds after which the probe times out. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + type: object + type: object + resources: + description: resources describe the compute resource requirements. + 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 + 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: + + + 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: + description: |- + ServiceAccountName is the name of the service account used to run this pod. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account. + type: string + terminationGracePeriodSeconds: + description: terminationGracePeriodSeconds is the grace period + before the pod is deleted. + format: int64 + type: integer + tolerations: + description: |- + tolerations specify the pods to schedule onto the nodes with matching taints, using + the triple `` and the matching operator ``. + 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 + topologySpreadConstraints: + description: |- + topologySpreadConstraints describe how a group of pods ought to spread across topology domains. Scheduler will + schedule pods based on 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 + 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 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. + + + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). + 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 + type: object + replicas: + description: |- + replicas is the desired number of replicas. + A change to this setting will roll the cluster. + format: int32 + type: integer + telemetry: + description: telemetry specifies the Confluent telemetry reporter + configuration. + properties: + global: + description: |- + global allows disabling telemetry configuration. + If CFK is deployed with telemetry, this field is only + used to disable telemetry. The default value is `true` if + telemetry is enabled at the global level. + type: boolean + type: object + tls: + description: tls specifies the global TLS configurations for the REST + API endpoint. + properties: + autoGeneratedCerts: + description: |- + autoGeneratedCerts specifies that the certificates are auto-generated based on + the CA key pair provided. + type: boolean + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + fips: + description: |- + fips specifies the configuration of FIPS compliant Bouncy Castle type Java Keystores for the cp component's + TLS settings. TLS Secrets must have the keys keystore.bcfks, truststore.bcfks, and jksPassword.txt + properties: + enabled: + description: enabled specifies whether to enable the FIPS + configuration for cp components. + type: boolean + required: + - enabled + type: object + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing the + JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + required: + - image + type: object + status: + description: status defines the observed state of the Schema Registry + cluster. + properties: + arbitraryData: + description: arbitraryData is the map for any arbitrary data associated + with this Confluent component. + x-kubernetes-preserve-unknown-fields: true + authorizationType: + description: authorizationType is the authorization type for this + Confluent component. + type: string + clusterName: + description: clusterName is the name of the Confluent Platform component + cluster. + type: string + clusterNamespace: + description: clusterNamespace is the namespace where the Confluent + Platform component cluster is running. + type: string + conditions: + description: conditions specify the latest available observations + of the current state. + items: + description: Condition represent the latest available observations + of the current state. + properties: + lastProbeTime: + description: lastProbeTime shows the last time the condition + was evaluated. + format: date-time + type: string + lastTransitionTime: + description: lastTransitionTime shows the last time the condition + was transitioned from one status to another. + format: date-time + type: string + message: + description: message shows a human-readable message with details + about the transition. + type: string + reason: + description: reason shows the reason for the last transition + of the condition. + type: string + status: + description: status shows the status of the condition, one of + `True`, `False`, or `Unknown`. + type: string + type: + description: type shows the condition type. + type: string + type: object + type: array + currentReplicas: + description: currentReplicas is the number of currently running replicas. + format: int32 + type: integer + groupId: + description: groupId is the group id of the Schema Registry cluster. + type: string + internalSecrets: + description: |- + internalSecrets are internal secrets created + by CFK for this Confluent component. + items: + type: string + type: array + internalTopicNames: + description: internalTopicNames are the topics used by the component + for internal use. + items: + type: string + type: array + kafka: + description: kafka is the Kafka client side status for the Schema + Registry cluster. + properties: + authenticationType: + description: authenticationType describes the authentication method + for the Kafka cluster. + type: string + bootstrapEndpoint: + description: bootstrapEndpoint specifies the Kafka bootstrap endpoint. + type: string + tls: + description: tls indicates whether TLS is enabled for the Kafka + dependency. + type: boolean + type: object + listeners: + additionalProperties: + description: ListenerStatus describes general information about + the listeners. + properties: + advertisedExternalEndpoints: + description: advertisedExternalEndpoints specifies other advertised + endpoints used, especially for Kafka. + items: + type: string + type: array + authenticationType: + description: authenticationType shows the authentication type + configured by the listener. + type: string + externalAccessType: + description: externalAccessType shows the external access type + used for the listener. + type: string + externalEndpoint: + description: externalEndpoint specifies the external endpoint + to connect to the Confluent component cluster. + type: string + internalEndpoint: + description: internalEndpoint specifies the internal endpoint + to connect to the Confluent component cluster. + type: string + tls: + description: tls shows whether TLS is configured for the listener. + type: boolean + type: object + description: listeners is a map of listener type and the status of + Schema Registry Listeners. + type: object + x-kubernetes-map-type: granular + metricPrefix: + description: metricPrefix is the prefix for the JMX metric of the + Schema Registry cluster. + type: string + observedGeneration: + description: observedGeneration is the most recent generation observed + for this Confluent component. + format: int64 + type: integer + operatorVersion: + description: operatorVersion is the internal version of CFK. + type: string + phase: + description: |- + phase describes the state of the Confluent Platform component. This can either be 'PROVISIONING' + or 'RUNNING' + 'PROVISIONING' means the Confluent Platform component is currently getting deployed and not ready yet. + 'RUNNING' means the Confluent Platform component has been successfully deployed. + type: string + rbac: + description: rbac contains the RBAC-related status when RBAC is enabled. + properties: + clusterID: + description: clusterID specifies the id of the cluster. + type: string + internalRolebindings: + description: internalRolebindings specifies the internal rolebindings. + items: + type: string + type: array + type: object + readyReplicas: + description: readyReplicas is the number of currently ready replicas. + format: int32 + type: integer + replicas: + description: replicas is the number of replicas. + format: int32 + type: integer + restConfig: + description: restConfig is the REST API configuration of the Schema + Registry cluster. + properties: + advertisedExternalEndpoints: + description: advertisedExternalEndpoints specifies other advertised + endpoints used, especially for Kafka. + items: + type: string + type: array + authenticationType: + description: authenticationType shows the authentication type + configured by the listener. + type: string + externalAccessType: + description: externalAccessType shows the external access type + used for the listener. + type: string + externalEndpoint: + description: externalEndpoint specifies the external endpoint + to connect to the Confluent component cluster. + type: string + internalEndpoint: + description: internalEndpoint specifies the internal endpoint + to connect to the Confluent component cluster. + type: string + tls: + description: tls shows whether TLS is configured for the listener. + type: boolean + type: object + selector: + description: |- + selector gets the label selector of the child pod. + The Horizontal Pod Autoscaler(HPA) will scale using the label selector of the child pod. + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.replicas + statusReplicasPath: .status.replicas + status: {} diff --git a/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_schemas.yaml b/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_schemas.yaml new file mode 100644 index 0000000000..b50396d441 --- /dev/null +++ b/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_schemas.yaml @@ -0,0 +1,590 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: schemas.platform.confluent.io +spec: + group: platform.confluent.io + names: + categories: + - all + - confluent-platform + - confluent + kind: Schema + listKind: SchemaList + plural: schemas + shortNames: + - schema + singular: schema + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.format + name: Format + type: string + - jsonPath: .status.id + name: ID + type: string + - jsonPath: .status.version + name: Version + type: string + - jsonPath: .status.phase + name: Status + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.schemaRegistryEndpoint + name: SchemaRegistryEndpoint + priority: 1 + type: string + name: v1beta1 + schema: + openAPIV3Schema: + 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 defines the desired state of the Schema. + properties: + compatibilityLevel: + description: |- + compatibilityLevel specifies the compatibility level requirement for the schema under the specified subject. + Valid options are `BACKWARD`, `BACKWARD_TRANSITIVE`, `FORWARD`, `FORWARD_TRANSITIVE`, `FULL`, `FULL_TRANSITIVE` and `NONE`. + more info: https://docs.confluent.io/platform/current/schema-registry/avro.html#schema-evolution-and-compatibility + enum: + - BACKWARD + - BACKWARD_TRANSITIVE + - FORWARD + - FORWARD_TRANSITIVE + - FULL + - FULL_TRANSITIVE + - NONE + type: string + data: + description: data defines the data required to create the schema. + properties: + configRef: + description: configRef is the name of the Kubernetes ConfigMap + resource containing the schema. + minLength: 1 + type: string + format: + description: format is the format type of the encoded schema. + Valid options are `avro`, `json`, and `protobuf`. + enum: + - avro + - json + - protobuf + minLength: 1 + type: string + required: + - configRef + - format + type: object + mode: + description: |- + Mode specifies the schema registry mode for the schemas under the specified subject. + Valid options are `IMPORT`, `READONLY`, `READWRITE`. + enum: + - IMPORT + - READONLY + - READWRITE + type: string + name: + description: |- + name specifies the subject name of schema. If not configured, the Schema CR name is used + as the subject name. + maxLength: 255 + minLength: 1 + pattern: ^[^\\]*$ + type: string + normalize: + description: |- + Normalize specifies whether to normalize the schema at the time of registering to schema registry. + more info: https://docs.confluent.io/platform/current/schema-registry/fundamentals/serdes-develop/index.html#schema-normalization + type: boolean + schemaReferences: + description: schemaReferences defines the schema references in the + schema data. + items: + description: SchemaReference is the schema to be used as a reference + for the new schema. + properties: + avro: + description: avro is the data for the referenced Avro schema. + properties: + avro: + description: name is the fully qualified name of the referenced + Avro schema. + minLength: 1 + type: string + required: + - avro + type: object + format: + description: format is the format type of the referenced schema. + Valid options are `avro`, `json`, and `protobuf`. + enum: + - avro + - json + - protobuf + minLength: 1 + type: string + json: + description: json is the data for the referenced JSON schema. + properties: + url: + description: url is the referenced JSON schema url. + minLength: 1 + type: string + required: + - url + type: object + protobuf: + description: protobuf is the data for the referenced Protobuf + schema. + properties: + file: + description: file is the file name of the referenced Protobuf + schema. + minLength: 1 + type: string + required: + - file + type: object + subject: + description: subject is the subject name for the referenced + schema through the configRef. + minLength: 1 + type: string + version: + description: version is the version type of the referenced schema. + format: int32 + type: integer + required: + - format + - subject + - version + type: object + type: array + schemaRegistryClusterRef: + description: schemaRegistryClusterRef references the CFK-managed Schema + Registry cluster. + properties: + name: + description: name specifies the name of the Confluent Platform + component cluster. + type: string + namespace: + description: namespace specifies the namespace where the Confluent + Platform component cluster is running. + type: string + required: + - name + type: object + schemaRegistryRest: + description: schemaRegistryRest specifies the Schema Registry REST + API configuration. + properties: + authentication: + description: authentication specifies the REST API authentication + mechanism. + properties: + basic: + description: basic specifies the basic authentication settings + for the REST API client. + properties: + debug: + description: debug enables the basic authentication debug + logs for JaaS configuration. + type: boolean + directoryPathInContainer: + description: |- + directoryPathInContainer allows to pass the basic credential through a directory path in the container. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + minLength: 1 + type: string + restrictedRoles: + description: |- + restrictedRoles specify the restricted roles on the server side only. + Changes will be only reflected in Control Center. + This configuration is ignored on the client side configuration. + items: + type: string + minItems: 1 + type: array + roles: + description: |- + roles specify the roles on the server side only. + This configuration is ignored on the client side configuration. + items: + type: string + type: array + secretRef: + description: |- + secretRef defines secret reference to pass the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#basic-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + bearer: + description: bearer specifies the bearer authentication settings + for the REST API client. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container + where the credential is mounted. + minLength: 1 + type: string + secretRef: + description: |- + secretRef specifies the name of the secret that contains the credential. + More info: https://docs.confluent.io/operator/current/co-authenticate.html#bearer-authentication + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauth: + description: oauth specifies the OAuth authentication settings + for the REST API client. + properties: + configuration: + description: configuration specifies the OAuth server + settings. + properties: + audience: + description: audience specifies the audience claim + in the JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected + issuer in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name of + claim in token for identifying the groups of subject + in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect timeout + with IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry + backoff with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff + with IDP in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim + in JWT to use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + directoryPathInContainer: + description: directoryPathInContainer allows to pass the + basic credential through a directory path in the container. + minLength: 1 + type: string + secretRef: + description: secretRef defines secret reference to pass + the required credentials. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - configuration + type: object + type: + description: type specifies the REST API authentication type. + Valid options are `basic`, `bearer`, `mtls` and `oauth`. + enum: + - basic + - bearer + - mtls + - oauth + type: string + required: + - type + type: object + endpoint: + description: endpoint specifies where Confluent REST API is running. + minLength: 1 + pattern: ^https?://.* + type: string + kafkaClusterID: + description: |- + kafkaClusterID specifies the id of Kafka cluster. + It takes precedence over using the Kafka REST API to get the cluster id. + minLength: 1 + type: string + tls: + description: "tls specifies the custom TLS structure for the application + resources,\n\t// e.g. connector, topic, schema, of the Confluent + Platform components.\n\t// +optional" + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer contains the directory path in the container where + `keystore.jks`, `truststore.jks`, `jksPassword.txt` keys are mounted. + minLength: 1 + type: string + jksPassword: + description: jksPassword specifies the secret name that contains + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef specifies the secret name that contains the certificates. + More info about certificates key/value format: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + type: object + required: + - data + type: object + status: + description: status defines the observed state of the Schema. + properties: + appState: + default: Unknown + description: appState is the current state of the Schema application. + enum: + - Unknown + - Created + - Failed + - Deleted + type: string + compatibilityLevel: + description: compatibilityLevel specifies the compatibility level + of the schema under the subject. + type: string + conditions: + description: conditions are the latest available observed state of + the schema. + items: + description: Condition represent the latest available observations + of the current state. + properties: + lastProbeTime: + description: lastProbeTime shows the last time the condition + was evaluated. + format: date-time + type: string + lastTransitionTime: + description: lastTransitionTime shows the last time the condition + was transitioned from one status to another. + format: date-time + type: string + message: + description: message shows a human-readable message with details + about the transition. + type: string + reason: + description: reason shows the reason for the last transition + of the condition. + type: string + status: + description: status shows the status of the condition, one of + `True`, `False`, or `Unknown`. + type: string + type: + description: type shows the condition type. + type: string + type: object + type: array + deletedVersions: + description: deletedVersions are the successfully hard deleted versions + for the subject. + items: + format: int32 + type: integer + type: array + format: + description: format is the format of the latest schema for the subject. + type: string + id: + description: id is the id of the latest schema for the subject. + format: int32 + type: integer + mode: + description: Mode specifies the operating mode of schema under the + subject. + type: string + normalize: + description: Normalize specifies whether schema has been normalized + at the time of registering. + type: boolean + observedGeneration: + description: observedGeneration is the most recent generation observed + for this Confluent component. + format: int64 + type: integer + schemaReferences: + description: schemaReferences are the schema references for the subject. + items: + description: SchemaReference is the schema to be used as a reference + for the new schema. + properties: + avro: + description: avro is the data for the referenced Avro schema. + properties: + avro: + description: name is the fully qualified name of the referenced + Avro schema. + minLength: 1 + type: string + required: + - avro + type: object + format: + description: format is the format type of the referenced schema. + Valid options are `avro`, `json`, and `protobuf`. + enum: + - avro + - json + - protobuf + minLength: 1 + type: string + json: + description: json is the data for the referenced JSON schema. + properties: + url: + description: url is the referenced JSON schema url. + minLength: 1 + type: string + required: + - url + type: object + protobuf: + description: protobuf is the data for the referenced Protobuf + schema. + properties: + file: + description: file is the file name of the referenced Protobuf + schema. + minLength: 1 + type: string + required: + - file + type: object + subject: + description: subject is the subject name for the referenced + schema through the configRef. + minLength: 1 + type: string + version: + description: version is the version type of the referenced schema. + format: int32 + type: integer + required: + - format + - subject + - version + type: object + type: array + schemaRegistryAuthenticationType: + description: schemaRegistryAuthenticationType is the authentication + method used. + type: string + schemaRegistryEndpoint: + description: schemaRegistryEndpoint is the Schema Registry REST endpoint. + type: string + schemaRegistryTLS: + description: schemaRegistryTLS shows whether the Schema Registry is + using TLS. + type: boolean + softDeletedVersions: + description: softDeletedVersions are the successfully soft deleted + versions for the subject. + items: + format: int32 + type: integer + type: array + state: + description: state is the state of the Schema CR. + type: string + subject: + description: subject is the subject of the schema. + type: string + version: + description: version is the version of the latest schema for the subject. + format: int32 + type: integer + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_zookeepers.yaml b/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_zookeepers.yaml new file mode 100644 index 0000000000..5a89c94c79 --- /dev/null +++ b/charts/confluent/confluent-for-kubernetes/0.1033.22/crds/platform.confluent.io_zookeepers.yaml @@ -0,0 +1,4713 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: zookeepers.platform.confluent.io +spec: + group: platform.confluent.io + names: + categories: + - all + - confluent-platform + - confluent + kind: Zookeeper + listKind: ZookeeperList + plural: zookeepers + shortNames: + - zookeeper + - zk + singular: zookeeper + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.replicas + name: Replicas + type: string + - jsonPath: .status.readyReplicas + name: Ready + type: string + - jsonPath: .status.phase + name: Status + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.endpoint + name: Endpoint + priority: 1 + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: Zookeeper is the schema for the Zookeeper 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 defines the desired state of the Zookeeper cluster. + properties: + authentication: + description: authentication specifies the authentication configuration. + properties: + jaasConfig: + description: |- + jaasConfig specifies the JaaS configuration. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + properties: + secretRef: + description: |- + secretRef references the secret containing the required credentials. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + jaasConfigPassThrough: + description: |- + jaasConfigPassThrough specifies another way to provide JaaS configuration. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where required credentials are mounted. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + minLength: 1 + type: string + secretRef: + description: |- + secretRef references the secret containing the required credentials for authentication. + More info: https://docs.confluent.io/operator/current/co-authenticate.html + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + oauthSettings: + description: |- + oauthSettings specifies the OAuth settings. + This needs to passed with the authentication type `oauth`. + properties: + audience: + description: audience specifies the audience claim in the + JWT payload. + minLength: 1 + type: string + expectedIssuer: + description: expectedIssuer specifies the expected issuer + in the JWT payload. + minLength: 1 + type: string + groupsClaimName: + description: groupsClaimName specifies the name of claim in + token for identifying the groups of subject in the JWT payload. + minLength: 1 + type: string + jwksEndpointUri: + description: |- + jwksEndpointUri specifies the uri for the JSON Web Key Set (JWKS). + It is used to get set of keys containing the public keys used to verify any JWT issued by the IdP's Authorization Server. + minLength: 1 + type: string + loginConnectTimeoutMs: + description: LoginConnectTimeoutMs sets connect timeout with + IDP in ms + format: int32 + type: integer + loginReadTimeoutMs: + description: LoginReadTimeoutMs sets read timeout with IDP + in ms + format: int32 + type: integer + loginRetryBackoffMaxMs: + description: LoginRetryBackoffMaxMs sets max retry backoff + with IDP in ms + format: int32 + type: integer + loginRetryBackoffMs: + description: LoginRetryBackoffMs sets retry backoff with IDP + in ms + format: int32 + type: integer + scope: + description: |- + scope is optional and required only when your identity provider doesn't have + a default scope or your groups claim is linked to a scope. + minLength: 1 + type: string + subClaimName: + description: subClaimName specifies name of claim in JWT to + use for the subject. + minLength: 1 + type: string + tokenEndpointUri: + description: |- + tokenBaseEndpointUri specifies the base uri for token endpoint. + This is required for OAuth for inter broker communication along with + clientId & clientSecret in JassConfig or JassConfigPassthrough + minLength: 1 + type: string + type: object + principalMappingRules: + items: + type: string + type: array + type: + description: |- + type specifies the Kafka or Zookeeper authentication type. + Valid options are `plain`, `digest`, `mtls`, `ldap` & `oauth`. + enum: + - plain + - digest + - mtls + - ldap + - oauth + type: string + required: + - type + type: object + configOverrides: + description: |- + configOverrides specifies configs to override the server/JVM/log4j/peer + properties for the Zookeeper cluster. + A change to this property will roll the cluster. + properties: + jvm: + description: |- + jvm is a list of JVM configuration supported by the Confluent Platform component. + This will either add or update the existing configuration. + items: + type: string + type: array + log4j: + description: |- + log4j is a list of Log4J configuration supported by the Confluent Platform component. + This will either add or update the existing configuration. + items: + type: string + type: array + peers: + description: |- + peers specify a list of dynamic peer configurations for the Zookeeper cluster. This is only required when deploying stretch + Zookeeper for MRC deployments and should include all the Zookeeper peers in other DCs that form the ensemble. + This will either add or update the existing configuration. + items: + type: string + type: array + server: + description: |- + server is a list of server configuration supported by the Confluent Platform component. + This will either add or update existing configuration. + items: + type: string + type: array + type: object + dataVolumeCapacity: + anyOf: + - type: integer + - type: string + description: dataVolumeCapacity specifies the data volume size. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + externalAccess: + description: |- + externalAccess specifies the external access configuration. + Should only be specified when Zookeeper peers are on another network. + properties: + loadBalancer: + description: loadBalancer specifies the configuration to create + a Kubernetes load balancer service. + properties: + advertisedURL: + description: |- + advertisedURL specifies the configuration for advertised listener per pod. It is only supported for MDS currently. + If it is enabled, instead of using internal endpoint, the MDS advertised listener for each broker will be + set to: `://.` where podId starts from `0` to `replicaCount -1`. + This is only recommended if you cannot add internal SANs to the TLS certificates for MDS and + the external DNS must be resolved inside the Kubernetes cluster. + This configuration will not take effect if MDS enabled dual listener setup. + properties: + enabled: + description: |- + enabled indicates whether to set the MDS advertised listener url with external endpoint for each broker. + Has no effect with Zookeeper, which will always create a listener per pod. + type: boolean + prefix: + description: |- + prefix specifies the broker prefix for MDS/Zookeeper advertised endpoint. + If not configured, it uses `b` as default prefix for MDS, such as `b#.domain` where `#` will start from `0` to `replicaCount -1`. + It uses 'zookeeper' as default prefix for Zookeeper in the same way. + minLength: 1 + type: string + required: + - enabled + type: object + annotations: + additionalProperties: + type: string + description: annotations is a map of string key and value + pairs. It specifies Kubernetes annotations for this service. + type: object + x-kubernetes-map-type: granular + domain: + description: domain is the domain name of the component cluster. + minLength: 1 + type: string + externalTrafficPolicy: + description: externalTrafficPolicy specifies the external + traffic policy for the service. Valid options are `Local` + and `Cluster`. + enum: + - Local + - Cluster + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key and value pairs. + It specifies Kubernetes labels for this service. + type: object + x-kubernetes-map-type: granular + loadBalancerSourceRanges: + description: loadBalancerSourceRanges specify the source ranges. + items: + type: string + type: array + port: + description: |- + port specifies the external port for the client consumption. + If not configured, the same internal/external port is configured for the component. + Information about the port can be retrieved through the status API. + format: int32 + type: integer + prefix: + description: |- + prefix specify the prefix for the given domain. + The default value is the name of the cluster. + minLength: 1 + type: string + servicePorts: + description: servicePorts specify the user-provided service + port(s). + 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 + sessionAffinity: + description: |- + sessionAffinity defines the Kubernetes session affinity. The valid options are `ClientIP` and `None`. `ClientIP` enables the client IP-based session affinity. + The default value is `None`. + More info: https://kubernetes.io/docs/reference/networking/virtual-ips/#session-affinity. + enum: + - ClientIP + - None + type: string + sessionAffinityConfig: + description: SessionAffinityConfig contains the configurations + of the 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 + required: + - domain + type: object + nodePort: + description: nodePort specifies the configuration to create a + Kubernetes node port service. + properties: + advertisedURL: + description: |- + advertisedURL specifies the configuration for advertised listener per pod. It is only supported for MDS currently. + If it is enabled, instead of using internal endpoint, the MDS advertised listener for each broker will be + set to `://:, where`podId` starts from `0` to `replicaCount - 1`. + This is only recommended if you cannot add internal SANs to the TLS certificates for MDS and + the external DNS must be resolved inside the Kubernetes cluster. + properties: + enabled: + description: |- + enabled indicates whether to set the MDS advertised listener url with external endpoint for each broker. + Has no effect with Zookeeper, which will always create a listener per pod. + type: boolean + prefix: + description: |- + prefix specifies the broker prefix for MDS/Zookeeper advertised endpoint. + If not configured, it uses `b` as default prefix for MDS, such as `b#.domain` where `#` will start from `0` to `replicaCount -1`. + It uses 'zookeeper' as default prefix for Zookeeper in the same way. + minLength: 1 + type: string + required: + - enabled + type: object + annotations: + additionalProperties: + type: string + description: annotations is a map of string key and value + pairs. It specifies Kubernetes annotations for this service. + type: object + x-kubernetes-map-type: granular + externalTrafficPolicy: + description: |- + externalTrafficPolicy specifies the external traffic policy for the service. + Valid options are `Local` and `Cluster`. + enum: + - Local + - Cluster + type: string + host: + description: host defines the host name of the cluster. + minLength: 1 + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key and value pairs. + It specifies Kubernetes labels for this service. + type: object + x-kubernetes-map-type: granular + nodePortOffset: + description: |- + nodePortOffset specifies the starting offset of the node ports. The port numbers go in ascending order with respect + to the replicas count. + NodePort service creation fails if the node port is not in the range supported by the Kubernetes API server. + The default Kubernetes Node Port range is `30000` - `32762`. + format: int32 + minimum: 0 + type: integer + servicePorts: + description: |- + servicePorts specify user-provided service port(s). + For Kafka with the nodePort type, this setting is only applied to Kafka bootstrap service. + 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 + sessionAffinity: + description: |- + sessionAffinity defines the Kubernetes session affinity. The valid options are `ClientIP` and `None`. `ClientIP` enables the client IP-based session affinity. + The default value is `None`. + More info: https://kubernetes.io/docs/reference/networking/virtual-ips/#session-affinity. + enum: + - ClientIP + - None + type: string + sessionAffinityConfig: + description: SessionAffinityConfig contains the configurations + of the 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 + required: + - host + - nodePortOffset + type: object + route: + description: route specifies the configuration to create a route + service in OpenShift. + properties: + advertisedURL: + description: |- + advertisedURL specifies the configuration for advertised listener per pod. It is only supported for MDS currently. + If it is enabled, instead of using internal endpoint, the MDS advertised listener for each broker will be + set to: `://-http-external.` where podId starts from `0` to `replicaCount -1`. + This is only recommended if you cannot add internal SANs to the TLS certificates for MDS and + the external DNS must be resolved inside the Kubernetes cluster. + This configuration will not take effect if MDS enabled dual listener setup. + properties: + enabled: + description: |- + enabled indicates whether to set the MDS advertised listener url with external endpoint for each broker. + Has no effect with Zookeeper, which will always create a listener per pod. + type: boolean + prefix: + description: |- + prefix specifies the broker prefix for MDS/Zookeeper advertised endpoint. + If not configured, it uses `b` as default prefix for MDS, such as `b#.domain` where `#` will start from `0` to `replicaCount -1`. + It uses 'zookeeper' as default prefix for Zookeeper in the same way. + minLength: 1 + type: string + required: + - enabled + type: object + annotations: + additionalProperties: + type: string + description: annotations is a map of string key and value + pairs. It specifies Kubernetes annotations for this service. + type: object + x-kubernetes-map-type: granular + domain: + description: domain specifies the domain name of the Confluent + component cluster. + minLength: 1 + type: string + labels: + additionalProperties: + type: string + description: labels is a map of string key and value pairs. + It specifies Kubernetes labels for this service. + type: object + x-kubernetes-map-type: granular + prefix: + description: |- + prefix specifies the component prefix when configured for the domain. + The default value is the name of the cluster. + minLength: 1 + type: string + wildcardPolicy: + description: |- + wildcardPolicy allows you to define a route that covers all hosts within a domain. Valid options are `Subdomain` and `None`. + The default value is `None`. + enum: + - Subdomain + - None + type: string + required: + - domain + type: object + type: + description: |- + type specifies the Kubernetes external service for the component. + Valid options are `loadBalancer`, `nodePort`, and `route`. + enum: + - loadBalancer + - nodePort + - route + minLength: 1 + type: string + required: + - type + type: object + headlessService: + description: headlessService specifies the configuration of the Kubernetes + headless service. + properties: + annotations: + additionalProperties: + type: string + description: |- + annotations is a map of string key and value pairs. + It specifies the annotations to be added to the CFK-created headless service. + These annotations are merged with the injectAnnotations and take precedence. + type: object + x-kubernetes-map-type: granular + labels: + additionalProperties: + type: string + description: |- + labels is a map of string key and value pairs. + It specifies the labels to be added to the CFK-created headless service. + These labels are merged with the injectLabels and take precedence. + type: object + x-kubernetes-map-type: granular + publishNotReadyAddresses: + description: |- + publishNotReadyAddresses specifies the publishNotReadyAddresses field. + For Kafka, this value must be true. The default value is true. + type: boolean + type: object + image: + description: |- + image specifies the application and the init docker image configurations. + A change to this setting will roll the cluster. + properties: + application: + description: |- + application is the Docker image name of the application. Specify + `//:`. + pattern: .+:.+ + type: string + init: + description: |- + init is the init-container name. Specify + `//:`. + pattern: .+:.+ + type: string + pullPolicy: + description: |- + pullPolicy is the policy for pulling images. Valid options are `Always`, `Never`, and `IfNotPresent`. + The default value is `IfNotPresent`. + enum: + - Always + - Never + - IfNotPresent + type: string + pullSecretRef: + description: |- + pullSecretRef references the secrets in the same namespace to be used for pulling images. + Image pull secrets are distinct from secrets because secrets + can be mounted in the pod, but image pull secrets are only accessed by `kubelet`. + More info: https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod + items: + type: string + type: array + required: + - application + - init + type: object + injectAnnotations: + additionalProperties: + type: string + description: |- + injectAnnotations are the annotations injected to the internal resources that CFK created. + The internal annotations are preserved and cannot be overridden. + For pod annotations, use `podTemplate.annotations`. + type: object + x-kubernetes-map-type: granular + injectLabels: + additionalProperties: + type: string + description: |- + injectLabels are the labels injected to the internal resources that CFK created. + The internal labels are preserved and cannot be overridden. + For pod labels, use `podTemplate.labels`. + type: object + x-kubernetes-map-type: granular + k8sClusterDomain: + description: |- + k8sClusterDomain specifies the configuration of the Kubernetes cluster domain. + The default is the `cluster.local` domain. + type: string + license: + description: license specifies the license configuration for the Confluent + Platform component. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + the license key is mounted. More info: + https://docs.confluent.io/operator/current/co-license.html#update-component-level-licenses + minLength: 1 + type: string + globalLicense: + description: globalLicense specifies whether the Confluent Platform + component shares the common global license. + type: boolean + secretRef: + description: |- + secretRef references the secret that provides the license for the Confluent Platform component. + More info: https://docs.confluent.io/operator/current/co-license.html#update-component-level-licenses + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + logVolumeCapacity: + anyOf: + - type: integer + - type: string + description: logVolumeCapacity specifies the log volume size. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + metrics: + description: metrics specify the security settings for the metric + services. + properties: + authentication: + description: authentication specifies the authentication configuration + for the metrics. + properties: + type: + description: type specifies the metrics authentication method. + The valid option is `mtls`. + enum: + - mtls + type: string + required: + - type + type: object + prometheus: + description: prometheus specifies the configuration overrides + for the JMX-Prometheus exporter. + properties: + blacklist: + items: + type: string + type: array + rules: + items: + description: Rule defines the Prometheus Exporter rule override. + properties: + attrNameSnakeCase: + type: boolean + cache: + type: boolean + help: + minLength: 1 + type: string + labels: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: granular + name: + minLength: 1 + type: string + pattern: + minLength: 1 + type: string + type: + minLength: 1 + type: string + value: + minLength: 1 + type: string + valueFactor: + anyOf: + - type: integer + - type: string + default: 1 + 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: array + whitelist: + items: + type: string + type: array + type: object + tls: + description: tls specifies the TLS configuration for the metrics. + properties: + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + enabled: + description: enabled specifies to enable the TLS configuration + for the Confluent component. + type: boolean + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing + the JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - enabled + type: object + type: object + mountedSecrets: + description: |- + mountedSecrets list the secrets injected to + the underlying statefulset configuration. The secret reference is mounted + in the default path `/mnt/secrets/`. The underlying resources + will follow the secret as a file configuration. + More info: https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets-as-files-from-a-pod. + A change to this setting will roll the cluster. + items: + description: |- + MountedSecrets provides a way to inject a custom secret to the underlying + statefulset. + properties: + keyItems: + description: keyItems are key and path names. + 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 + secretRef: + description: secretRef references the name of the secret. + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + type: array + mountedVolumes: + description: |- + mountedVolumes list the custom volumes that need to be mounted into the + underlying statefulset. + A change to this setting will roll the cluster. + properties: + volumeMounts: + description: |- + volumeMounts specify the list of volume mounts for the pods in the + statefulset. + 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 + volumes: + description: |- + volumes specify the list of volumes that can be mounted into the pods + of statefulset. + 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 + 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: + 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 + 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 + 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: + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 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 + 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 + 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 + 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 + 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 + 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: + 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 + 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 + 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 + required: + - volumeMounts + - volumes + type: object + oneReplicaPerNode: + description: |- + oneReplicaPerNode controls whether to run 1 pod per node using the pod anti-affinity capability. + Enabling this configuration in an existing cluster will roll the cluster. + type: boolean + pdb: + description: |- + configures PodDisruptionBudget for the Confluent Platform component. + by default PDB is configured based on pre-detemined formula. + properties: + enabled: + description: enabled specifies whether the PodDisruptionBudget + is enabled + type: boolean + maxUnavailable: + description: maxUnavailable is the maximum number of pods that + can be unavailable during the disruption. + format: int32 + type: integer + required: + - enabled + type: object + peers: + description: |- + peers specify a list of dynamic peer configurations for the Zookeeper cluster. This is only required when deploying stretch + Zookeeper for MRC deployments and should include all the Zookeeper peers in other DCs that form the ensemble. + This will either add or update the existing configuration. + items: + type: string + type: array + podTemplate: + description: podTemplate specifies the statefulset pod template configuration. + properties: + affinity: + description: |- + affinity specifies a group of affinity scheduling rules. + More info: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity. + 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 + annotations: + additionalProperties: + type: string + description: |- + annotations is a map of string key and value pairs stored with the resource and + 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 + x-kubernetes-map-type: granular + envVars: + description: |- + envVars contain environment variables to be injected into containers. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container. + 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 + 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: + 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 + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + labels: + additionalProperties: + type: string + description: |- + labels is a map of string key and value pairs that can be used to organize and categorize + (scope and select) objects. + More info: http://kubernetes.io/docs/user-guide/labels. + type: object + x-kubernetes-map-type: granular + 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: + + + 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 + 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: + description: priorityClassName specifies the priority class for + the pod (if any). + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + probe: + description: probe contains the fields for standard Kubernetes + readiness/liveness probe configuration. + properties: + liveness: + description: |- + liveness configures the Kubernetes probe settings. The changes + will override the existing default configuration. + properties: + failureThreshold: + description: |- + failureThreshold is the minimum consecutive failures for the probe to be considered failed. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + initialDelaySeconds: + description: |- + initialDelaySeconds is the number of seconds after the container has started and before probes are initiated. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + path: + description: Path for the HTTP probe + type: string + periodSeconds: + description: |- + periodSeconds specifies how often to perform the probe. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + port: + description: Number of the port to access on the container + type: integer + successThreshold: + description: |- + successThreshold is the minimum consecutive successes for the probe to be considered successful after having failed. + The default values is `1`. Must be `1` for liveness and startup. The minimum value is `1`. + format: int32 + type: integer + timeoutSeconds: + description: |- + timeoutSeconds is the number of seconds after which the probe times out. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + type: object + readiness: + description: |- + readiness configures the Kubernetes probe setting. The changes + will override the existing default configuration. + properties: + failureThreshold: + description: |- + failureThreshold is the minimum consecutive failures for the probe to be considered failed. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + initialDelaySeconds: + description: |- + initialDelaySeconds is the number of seconds after the container has started and before probes are initiated. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + path: + description: Path for the HTTP probe + type: string + periodSeconds: + description: |- + periodSeconds specifies how often to perform the probe. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + port: + description: Number of the port to access on the container + type: integer + successThreshold: + description: |- + successThreshold is the minimum consecutive successes for the probe to be considered successful after having failed. + The default values is `1`. Must be `1` for liveness and startup. The minimum value is `1`. + format: int32 + type: integer + timeoutSeconds: + description: |- + timeoutSeconds is the number of seconds after which the probe times out. + Confluent Platform components come with the right configuration, and this setting is not required to change most of the time. + format: int32 + type: integer + type: object + type: object + resources: + description: resources describe the compute resource requirements. + 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 + 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: + + + 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: + description: |- + ServiceAccountName is the name of the service account used to run this pod. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account. + type: string + terminationGracePeriodSeconds: + description: terminationGracePeriodSeconds is the grace period + before the pod is deleted. + format: int64 + type: integer + tolerations: + description: |- + tolerations specify the pods to schedule onto the nodes with matching taints, using + the triple `` and the matching operator ``. + 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 + topologySpreadConstraints: + description: |- + topologySpreadConstraints describe how a group of pods ought to spread across topology domains. Scheduler will + schedule pods based on 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 + 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 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. + + + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). + 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 + type: object + replicas: + description: |- + replicas is the desired number of replicas. + A change to this setting will roll the cluster. + format: int32 + type: integer + storageClass: + description: |- + storageClass specifies the user-provided storage class. If not + configured, the default storage class is used. + properties: + name: + description: name is the storage class name. + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - name + type: object + tls: + description: tls specifies the TLS configuration. + properties: + autoGeneratedCerts: + description: |- + autoGeneratedCerts specifies that the certificates are auto-generated based on + the CA key pair provided. + type: boolean + directoryPathInContainer: + description: |- + directoryPathInContainer specifies the directory path in the container where + `keystore.jks`, `truststore.jks`, and `jksPassword.txt` keys are mounted. + `truststore.jks` is not configured and can be ignored when the `ignoreTrustStoreConfig` field is set to `true`. + minLength: 1 + type: string + fips: + description: |- + fips specifies the configuration of FIPS compliant Bouncy Castle type Java Keystores for the cp component's + TLS settings. TLS Secrets must have the keys keystore.bcfks, truststore.bcfks, and jksPassword.txt + properties: + enabled: + description: enabled specifies whether to enable the FIPS + configuration for cp components. + type: boolean + required: + - enabled + type: object + ignoreTrustStoreConfig: + description: |- + ignoreTrustStoreConfig indicates whether to ignore the truststore configuration + for the Confluent component. + type: boolean + jksPassword: + description: jksPassword references the secret containing the + JKS password. + properties: + secretRef: + description: |- + secretRef references the name of the secret containing the JKS password. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - secretRef + type: object + secretRef: + description: |- + secretRef references the secret containing the certificates. + More info: https://docs.confluent.io/operator/current/co-network-encryption.html#configure-user-provided-tls-certificates + maxLength: 30 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + required: + - dataVolumeCapacity + - image + - logVolumeCapacity + type: object + status: + description: status defines the observed state of the Zookeeper cluster. + properties: + arbitraryData: + description: arbitraryData is the map for any arbitrary data associated + with this Confluent component. + x-kubernetes-preserve-unknown-fields: true + authorizationType: + description: authorizationType is the authorization type for this + Confluent component. + type: string + clusterName: + description: clusterName is the name of the Confluent Platform component + cluster. + type: string + clusterNamespace: + description: clusterNamespace is the namespace where the Confluent + Platform component cluster is running. + type: string + conditions: + description: conditions specify the latest available observations + of the current state. + items: + description: Condition represent the latest available observations + of the current state. + properties: + lastProbeTime: + description: lastProbeTime shows the last time the condition + was evaluated. + format: date-time + type: string + lastTransitionTime: + description: lastTransitionTime shows the last time the condition + was transitioned from one status to another. + format: date-time + type: string + message: + description: message shows a human-readable message with details + about the transition. + type: string + reason: + description: reason shows the reason for the last transition + of the condition. + type: string + status: + description: status shows the status of the condition, one of + `True`, `False`, or `Unknown`. + type: string + type: + description: type shows the condition type. + type: string + type: object + type: array + currentReplicas: + description: currentReplicas is the number of currently running replicas. + format: int32 + type: integer + internalSecrets: + description: |- + internalSecrets are internal secrets created + by CFK for this Confluent component. + items: + type: string + type: array + internalTopicNames: + description: internalTopicNames are the topics used by the component + for internal use. + items: + type: string + type: array + myIdOffset: + description: myIdOffset shows the MyId offset configuration. + format: int32 + type: integer + observedGeneration: + description: observedGeneration is the most recent generation observed + for this Confluent component. + format: int64 + type: integer + operatorVersion: + description: operatorVersion is the internal version of CFK. + type: string + phase: + description: |- + phase describes the state of the Confluent Platform component. This can either be 'PROVISIONING' + or 'RUNNING' + 'PROVISIONING' means the Confluent Platform component is currently getting deployed and not ready yet. + 'RUNNING' means the Confluent Platform component has been successfully deployed. + type: string + readyReplicas: + description: readyReplicas is the number of currently ready replicas. + format: int32 + type: integer + replicas: + description: replicas is the number of replicas. + format: int32 + type: integer + restConfig: + description: restConfig is the REST API configuration of the Zookeeper + cluster. + properties: + advertisedExternalEndpoints: + description: advertisedExternalEndpoints specifies other advertised + endpoints used, especially for Kafka. + items: + type: string + type: array + authenticationType: + description: authenticationType shows the authentication type + configured by the listener. + type: string + externalAccessType: + description: externalAccessType shows the external access type + used for the listener. + type: string + externalEndpoint: + description: externalEndpoint specifies the external endpoint + to connect to the Confluent component cluster. + type: string + internalEndpoint: + description: internalEndpoint specifies the internal endpoint + to connect to the Confluent component cluster. + type: string + tls: + description: tls shows whether TLS is configured for the listener. + type: boolean + type: object + selector: + description: |- + selector gets the label selector of the child pod. + The Horizontal Pod Autoscaler(HPA) will scale using the label selector of the child pod. + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + scale: + specReplicasPath: .spec.replicas + statusReplicasPath: .status.replicas + status: {} diff --git a/charts/confluent/confluent-for-kubernetes/0.1033.22/templates/NOTES.txt b/charts/confluent/confluent-for-kubernetes/0.1033.22/templates/NOTES.txt new file mode 100644 index 0000000000..13dc5b3bca --- /dev/null +++ b/charts/confluent/confluent-for-kubernetes/0.1033.22/templates/NOTES.txt @@ -0,0 +1,4 @@ + The Confluent Operator + +The Confluent Operator brings the component (Confluent Services) specific controllers for kubernetes by providing components specific Custom Resource +Definition (CRD) as well as managing other Confluent Platform services diff --git a/charts/confluent/confluent-for-kubernetes/0.1033.22/templates/_helpers.tpl b/charts/confluent/confluent-for-kubernetes/0.1033.22/templates/_helpers.tpl new file mode 100644 index 0000000000..2815a83749 --- /dev/null +++ b/charts/confluent/confluent-for-kubernetes/0.1033.22/templates/_helpers.tpl @@ -0,0 +1,42 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "confluent-operator.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 "confluent-operator.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 "confluent-operator.service-account" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "confluent-operator.name" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "confluent-operator.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} diff --git a/charts/confluent/confluent-for-kubernetes/0.1033.22/templates/clusterrole.yaml b/charts/confluent/confluent-for-kubernetes/0.1033.22/templates/clusterrole.yaml new file mode 100644 index 0000000000..c689bfb5d2 --- /dev/null +++ b/charts/confluent/confluent-for-kubernetes/0.1033.22/templates/clusterrole.yaml @@ -0,0 +1,172 @@ +{{- if .Values.rbac }} +{{- $clusterRole := or (not .Values.namespaced) (.Values.kRaftEnabled) (gt (len .Values.namespaceList) 0)}} +apiVersion: rbac.authorization.k8s.io/v1 +{{- if not $clusterRole }} +kind: Role +{{- else }} +kind: ClusterRole +{{- end }} +metadata: + labels: + app: {{ include "confluent-operator.name" . }} + app.kubernetes.io/name: {{ include "confluent-operator.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/component: "confluent-operator" + helm.sh/chart: {{ include "confluent-operator.chart" . }} + name: {{ .Values.name }} + {{- if not $clusterRole }} + namespace: {{ .Release.Namespace }} + {{- end }} +rules: +- apiGroups: + - platform.confluent.io + resources: + - '*' + verbs: + - '*' +- apiGroups: + - policy + resources: + - poddisruptionbudgets + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +{{- if .Values.clusterRole.openshift }} +- apiGroups: + - route.openshift.io + resources: + - routes + - routes/custom-host + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +{{- end }} +- apiGroups: + - apps + resources: + - statefulsets + - statefulsets/scale + - statefulsets/status + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - apps + resources: + - deployments + verbs: + - get +- apiGroups: + - "" + resources: + - configmaps + - persistentvolumeclaims + - persistentvolumes + - secrets + - secrets/finalizers + - pods + - services + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +{{- if gt (int (.Values.replicas)) 1 }} +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - create + - get + - update +{{- end }} +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +- apiGroups: + - networking.k8s.io + resources: + - ingresses + - ingresses/status + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - "" + resources: + - namespaces + verbs: + - get +{{- if $clusterRole }} + - list + - watch +{{- end }} +{{- if .Values.webhooks.enabled }} +# Webhook configurations are cluster scoped +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app: {{ include "confluent-operator.name" . }} + app.kubernetes.io/name: {{ include "confluent-operator.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/component: "confluent-operator" + helm.sh/chart: {{ include "confluent-operator.chart" . }} + name: {{ .Values.name }}-webhook-{{ .Release.Namespace }} +rules: + - apiGroups: + - admissionregistration.k8s.io + resources: + - validatingwebhookconfigurations + verbs: + - get + - update + - apiGroups: + - "" + resources: + - persistentvolumes + verbs: + - get + - list + - watch + - apiGroups: + - "" + resources: + - namespaces + verbs: + - get + - list + - watch +{{- end }} +{{- end }} diff --git a/charts/confluent/confluent-for-kubernetes/0.1033.22/templates/clusterrolebinding.yaml b/charts/confluent/confluent-for-kubernetes/0.1033.22/templates/clusterrolebinding.yaml new file mode 100644 index 0000000000..58aa9d0431 --- /dev/null +++ b/charts/confluent/confluent-for-kubernetes/0.1033.22/templates/clusterrolebinding.yaml @@ -0,0 +1,56 @@ +{{- if .Values.rbac }} +{{- $clusterRoleBinding := or (not .Values.namespaced) (.Values.kRaftEnabled) (gt (len .Values.namespaceList) 0)}} +{{- if not $clusterRoleBinding }} +kind: RoleBinding +{{- else }} +kind: ClusterRoleBinding +{{- end }} +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + labels: + app: {{ include "confluent-operator.name" . }} + app.kubernetes.io/name: {{ include "confluent-operator.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/component: "confluent-operator" + helm.sh/chart: {{ include "confluent-operator.chart" . }} + name: {{ .Values.name }} + {{- if not $clusterRoleBinding }} + namespace: {{ .Release.Namespace }} + {{- end }} +subjects: +- kind: ServiceAccount + name: {{ template "confluent-operator.service-account" . }} + namespace: {{ .Release.Namespace }} +roleRef: + {{- if not $clusterRoleBinding }} + kind: Role + {{- else }} + kind: ClusterRole + {{- end }} + name: {{ .Values.name }} + apiGroup: rbac.authorization.k8s.io +# Webhook configurations are cluster scoped +{{- if and (.Values.webhooks.enabled) }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app: {{ include "confluent-operator.name" . }} + app.kubernetes.io/name: {{ include "confluent-operator.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/component: "confluent-operator" + helm.sh/chart: {{ include "confluent-operator.chart" . }} + name: {{ .Values.name }}-webhook-{{ .Release.Namespace }} +subjects: + - kind: ServiceAccount + name: {{ template "confluent-operator.service-account" . }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: {{ .Values.name }}-webhook-{{ .Release.Namespace }} + apiGroup: rbac.authorization.k8s.io + {{- end }} +{{- end }} diff --git a/charts/confluent/confluent-for-kubernetes/0.1033.22/templates/deployment.yaml b/charts/confluent/confluent-for-kubernetes/0.1033.22/templates/deployment.yaml new file mode 100644 index 0000000000..86a64d8669 --- /dev/null +++ b/charts/confluent/confluent-for-kubernetes/0.1033.22/templates/deployment.yaml @@ -0,0 +1,238 @@ +{{- $_ := required "Namespace is required" .Release.Namespace }} +{{- $_ := required "Name of operator is required." .Values.name }} +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: {{ include "confluent-operator.name" . }} + app.kubernetes.io/name: {{ include "confluent-operator.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/component: "confluent-operator" + helm.sh/chart: {{ include "confluent-operator.chart" . }} + version: {{ .Values.image.tag }} + name: {{ .Values.name }} + namespace: {{ .Release.Namespace }} +spec: + replicas: {{ .Values.replicas }} + selector: + matchLabels: + app.kubernetes.io/name: "confluent-operator" + app.kubernetes.io/instance: {{ .Release.Name }} + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 0 + type: RollingUpdate + template: + metadata: + annotations: + {{- range $key, $value := .Values.pod.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + labels: + app: "confluent-operator" + app.kubernetes.io/name: "confluent-operator" + app.kubernetes.io/instance: {{ .Release.Name }} + confluent-platform: "true" + version: {{ .Values.image.tag }} + {{- range $key, $value := .Values.pod.labels }} + {{ $key }}: {{ $value | quote }} + {{- end }} + spec: + {{- if not (empty $.Values.affinity) }} + affinity: +{{ toYaml .Values.affinity | trim | indent 8 }} + {{- end }} + {{- if not (empty $.Values.tolerations) }} + tolerations: +{{ toYaml .Values.tolerations | trim | indent 6 }} + {{- end }} + {{- if .Values.podSecurity.enabled }} + securityContext: +{{ toYaml .Values.podSecurity.securityContext | indent 8 }} + {{- end }} + containers: + - args: + - --debug={{.Values.debug}} + - --fipsmode={{.Values.fipsmode}} + - --kraftClusterIdRecovery={{.Values.kRaftEnabled}} + {{- if gt (int (.Values.replicas)) 1 }} + - --enable-leader-election + {{- end }} + {{- if .Values.namespaced }} + {{- if empty .Values.namespaceList }} + - --namespaces={{ .Release.Namespace }} + {{- else}} + {{- $ns := "" }} + {{- range $i, $v := .Values.namespaceList }} + {{- $ns = printf "%s,%s" $ns (trim $v) }} + {{- end }} + - --namespaces={{ substr 1 (len $ns) $ns }} + {{- end }} + {{- end }} + name: {{ .Values.name }} + image: {{ .Values.image.registry }}/{{ .Values.image.repository }}:{{.Values.image.tag }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + readinessProbe: + httpGet: + port: 8080 + path: /readyz + livenessProbe: + httpGet: + port: 8080 + path: /healthz + resources: +{{ toYaml .Values.resources | trim | indent 10 }} + env: + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: NODEIP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: DD_ENTITY_ID + valueFrom: + fieldRef: + fieldPath: metadata.uid + - name: DEPLOYMENT_NAME + value: {{ .Values.name }} + - name: CONFLUENT_SERVICE_ACCOUNT_NAME + value: {{ template "confluent-operator.service-account" . }} + {{- if .Values.numDay2Worker }} + - name: DEFAULT_DAY2_WORKER + value: "{{ .Values.numDay2Worker }}" + {{- end }} + {{- if .Values.managedCerts.enabled }} + {{- if and (empty .Values.managedCerts.caCertificate.secretRef) (empty .Values.managedCerts.caCertificate.directoryPathInContainer) }} + {{- $_ := required "secretRef or directoryPathInContainer must be configured when managedCerts is enabled" .Values.managedCerts.secretRef }} + {{- end }} + {{- if ge (.Values.managedCerts.renewBeforeInDays) (.Values.managedCerts.certDurationInDays) }} + {{- $_ := required "managedCerts.certDurationInDays for managed certs should be greater than managedCerts.renewBeforeInDays" "" }} + {{- end }} + {{- if .Values.managedCerts.certDurationInDays }} + - name: CONFLUENT_MANAGED_CERTS_DURATION_DAYS + value: "{{ .Values.managedCerts.certDurationInDays }}" + {{- end }} + {{- if .Values.managedCerts.renewBeforeInDays }} + - name: CONFLUENT_MANAGED_CERTS_RENEW_BEFORE_DAYS + value: "{{ .Values.managedCerts.renewBeforeInDays }}" + {{- end }} + {{- if .Values.managedCerts.sans }} + {{- if not (regexMatch "[ -~]" .Values.managedCerts.sans) }} + {{- $_ := required "invalid characters in managedCerts.sans. Only first 128 ASCII characters are allowed" "" }} + {{- end }} + - name: CONFLUENT_MANAGED_CERTS_SANS + value: "{{ .Values.managedCerts.sans }}" + {{- end }} + {{- if .Values.managedCerts.caCertificate.secretRef }} + - name: CONFLUENT_MANAGED_CERTS_SECRET_NAME + value: {{ .Values.managedCerts.caCertificate.secretRef }} + {{- end }} + {{- if .Values.managedCerts.caCertificate.directoryPathInContainer }} + - name: CONFLUENT_MANAGED_CERTS_DIRECTORY_PATH + value: {{ .Values.managedCerts.caCertificate.directoryPathInContainer }} + {{- end }} + {{- end }} + {{- if .Values.licenseSecretRef }} + - name: CONFLUENT_LICENSE_SECRET_NAME + value: {{ .Values.licenseSecretRef }} + {{- else if .Values.license.secretRef }} + - name: CONFLUENT_LICENSE_SECRET_NAME + value: {{ .Values.license.secretRef }} + {{- end }} + {{- if .Values.license.directoryPathInContainer }} + - name: CONFLUENT_LICENSE_DIRECTORY_PATH + value: {{ .Values.license.directoryPathInContainer }} + {{- end }} + {{- if or (.Values.telemetry.enabled) (.Values.telemetry.operator.enabled) }} + {{- if and (empty .Values.telemetry.secretRef) (empty .Values.telemetry.directoryPathInContainer) }} + {{- $_ := required "secretRef or directoryPathInContainer must be configured when telemetry is enabled" .Values.telemetry.secretRef }} + {{- end }} + - name: CP_TELEMETRY_ENABLED + value: {{ quote .Values.telemetry.enabled }} + - name: OPERATOR_TELEMETRY_ENABLED + value: {{ quote .Values.telemetry.operator.enabled }} + {{- if .Values.telemetry.secretRef }} + - name: CONFLUENT_TELEMETRY_SECRET_NAME + value: {{ .Values.telemetry.secretRef }} + {{- end }} + {{- if .Values.telemetry.directoryPathInContainer }} + - name: CONFLUENT_TELEMETRY_DIRECTORY_PATH + value: {{ .Values.telemetry.directoryPathInContainer }} + {{- end }} + {{- if .Values.telemetry.proxy.enabled }} + - name: CONFLUENT_TELEMETRY_PROXY_ENABLED + value: "true" + {{- end }} + {{- if .Values.telemetry.proxy.credentialRequired }} + - name: CONFLUENT_TELEMETRY_PROXY_CREDENTIAL_REQUIRED + value: "true" + {{- end }} + {{- end }} + {{- if .Values.webhooks.enabled }} + {{- if and (empty .Values.webhooks.tls.secretRef) (empty .Values.webhooks.tls.directoryPathInContainer) }} + {{- $_ := required "secretRef or directoryPathInContainer must be configured when webhooks are enabled" .Values.webhooks.tls.secretRef }} + {{- end }} + {{- if .Values.webhooks.tls.secretRef }} + - name: CONFLUENT_WEBHOOKS_SECRET_NAME + value: {{ .Values.webhooks.tls.secretRef }} + {{- end }} + {{- if .Values.webhooks.tls.directoryPathInContainer }} + - name: CONFLUENT_WEBHOOKS_DIRECTORY_PATH + value: {{ .Values.webhooks.tls.directoryPathInContainer }} + {{- end }} + - name: CONFLUENT_WEBHOOKS_PORT + value: {{ quote .Values.webhooks.port }} + {{- end }} + {{- if .Values.containerSecurity.enabled }} + securityContext: +{{ toYaml .Values.containerSecurity.securityContext | indent 10 }} + {{- end }} + {{- if or (not (empty .Values.mountedVolumes.volumeMounts)) (and (.Values.webhooks.enabled) (.Values.webhooks.tls.secretRef)) }} + volumeMounts: + {{- end }} + {{- if not (empty .Values.mountedVolumes.volumeMounts) }} + {{- range .Values.mountedVolumes.volumeMounts }} + {{- if and ($.Values.webhooks.enabled) (or (eq .mountPath "/mnt/sslcerts/webhook") (eq .name "webhook-certs")) }} + {{- $_ := fail "mount path \"/mnt/sslcerts/webhook\" and name \"webhook-certs\" are reserved for webhooks" }} + {{- end }} + - {{ toYaml . | indent 12 | trim }} + {{- end }} + {{- end }} + {{- if and (.Values.webhooks.enabled) (.Values.webhooks.tls.secretRef) }} + - mountPath: /mnt/sslcerts/webhook + name: webhook-certs + readOnly: true + {{- end }} + {{- if or (not (empty .Values.mountedVolumes.volumes)) (and (.Values.webhooks.enabled) (.Values.webhooks.tls.secretRef)) }} + volumes: + {{- end }} + {{- if not (empty .Values.mountedVolumes.volumes ) }} + {{- range .Values.mountedVolumes.volumes }} + {{- if and ($.Values.webhooks.enabled) (eq .name "webhook-certs") }} + {{- $_ := fail "name \"webhook-certs\" is reserved for webhooks" }} + {{- end }} + - {{ toYaml . | indent 10 | trim }} + {{- end }} + {{- end }} + {{- if and (.Values.webhooks.enabled) (.Values.webhooks.tls.secretRef) }} + - name: webhook-certs + secret: + defaultMode: 420 + secretName: {{ .Values.webhooks.tls.secretRef }} + {{- end }} + {{- if and .Values.imagePullSecretRef (not .Values.serviceAccount.create) }} + imagePullSecrets: + - name: {{ .Values.imagePullSecretRef }} + {{- end }} + serviceAccountName: {{ template "confluent-operator.service-account" . }} + {{- if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName | quote }} + {{- end }} + restartPolicy: Always + terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }} diff --git a/charts/confluent/confluent-for-kubernetes/0.1033.22/templates/licensing.yaml b/charts/confluent/confluent-for-kubernetes/0.1033.22/templates/licensing.yaml new file mode 100644 index 0000000000..a8ab26bcd9 --- /dev/null +++ b/charts/confluent/confluent-for-kubernetes/0.1033.22/templates/licensing.yaml @@ -0,0 +1,19 @@ +{{- if not .Values.licenseSecretRef }} +apiVersion: v1 +kind: Secret +metadata: + labels: + app: {{ include "confluent-operator.name" . }} + app.kubernetes.io/name: {{ include "confluent-operator.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/component: "confluent-operator" + helm.sh/chart: {{ include "confluent-operator.chart" . }} + namespace: {{ .Release.Namespace }} + name: confluent-operator-licensing +type: Opaque +data: + {{- if .Values.licenseKey }} + license.txt: {{ .Values.licenseKey | b64enc }} + {{- end }} +{{- end }} diff --git a/charts/confluent/confluent-for-kubernetes/0.1033.22/templates/service.yaml b/charts/confluent/confluent-for-kubernetes/0.1033.22/templates/service.yaml new file mode 100644 index 0000000000..2f9ecbc981 --- /dev/null +++ b/charts/confluent/confluent-for-kubernetes/0.1033.22/templates/service.yaml @@ -0,0 +1,28 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app: {{ include "confluent-operator.name" . }} + app.kubernetes.io/name: {{ include "confluent-operator.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/component: "confluent-operator" + helm.sh/chart: {{ include "confluent-operator.chart" . }} + name: confluent-operator + namespace: {{ .Release.Namespace }} +spec: + ports: + - name: http-metric + port: 7778 + protocol: TCP + targetPort: 7778 + {{- if (.Values.webhooks.enabled) }} + - name: webhook + port: {{ .Values.webhooks.port }} + protocol: TCP + targetPort: {{ .Values.webhooks.port }} + {{- end }} + selector: + app: "confluent-operator" + app.kubernetes.io/name: "confluent-operator" + type: ClusterIP diff --git a/charts/confluent/confluent-for-kubernetes/0.1033.22/templates/serviceaccount.yaml b/charts/confluent/confluent-for-kubernetes/0.1033.22/templates/serviceaccount.yaml new file mode 100644 index 0000000000..9ed5b692d4 --- /dev/null +++ b/charts/confluent/confluent-for-kubernetes/0.1033.22/templates/serviceaccount.yaml @@ -0,0 +1,18 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +{{- if .Values.imagePullSecretRef }} +imagePullSecrets: +- name: {{ .Values.imagePullSecretRef }} +{{- end }} +kind: ServiceAccount +metadata: + labels: + app: {{ include "confluent-operator.name" . }} + app.kubernetes.io/name: {{ include "confluent-operator.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/component: "confluent-operator" + helm.sh/chart: {{ include "confluent-operator.chart" . }} + name: {{ template "confluent-operator.service-account" . }} + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/charts/confluent/confluent-for-kubernetes/0.1033.22/templates/validatingwebhookconfiguration.yaml b/charts/confluent/confluent-for-kubernetes/0.1033.22/templates/validatingwebhookconfiguration.yaml new file mode 100644 index 0000000000..e7235f9fdb --- /dev/null +++ b/charts/confluent/confluent-for-kubernetes/0.1033.22/templates/validatingwebhookconfiguration.yaml @@ -0,0 +1,184 @@ +{{- if (.Values.webhooks.enabled) }} +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + labels: + app: {{ include "confluent-operator.name" . }} + app.kubernetes.io/name: {{ include "confluent-operator.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/component: "confluent-operator" + helm.sh/chart: {{ include "confluent-operator.chart" . }} + name: confluent-operator-{{ .Release.Namespace }}.webhook.platform.confluent.io +webhooks: +- admissionReviewVersions: + - v1beta1 + clientConfig: + service: + name: confluent-operator + namespace: {{ .Release.Namespace }} + path: /confluent-operator/validate + port: {{ .Values.webhooks.port }} + failurePolicy: Fail + name: cfk-resources.webhooks.platform.confluent.io + namespaceSelector: + matchExpressions: + - key: confluent-operator.webhooks.platform.confluent.io/disable + operator: NotIn + values: [ "true" ] + {{- if .Values.namespaced }} + - key: kubernetes.io/metadata.name + operator: In + values: + {{- if empty .Values.namespaceList }} + - {{ .Release.Namespace }} + {{- else }} + {{- range $i, $v := .Values.namespaceList }} + - {{ trim $v }} + {{- end }} + {{- end }} + {{- end }} + objectSelector: + matchExpressions: + - key: confluent-operator.webhooks.platform.confluent.io/disable + operator: NotIn + values: [ "true" ] + rules: + - apiGroups: + - platform.confluent.io + apiVersions: + - v1beta1 + operations: + - UPDATE + - DELETE + resources: + - zookeepers + - kafkas + - kraftcontrollers + - ksqldbs + - controlcenters + scope: Namespaced + sideEffects: None + timeoutSeconds: 10 +- admissionReviewVersions: + - v1beta1 + clientConfig: + service: + name: confluent-operator + namespace: {{ .Release.Namespace }} + path: /confluent-operator/validate + port: {{ .Values.webhooks.port }} + failurePolicy: Fail + name: core-resources.webhooks.platform.confluent.io + namespaceSelector: + matchExpressions: + - key: confluent-operator.webhooks.platform.confluent.io/disable + operator: NotIn + values: [ "true" ] + {{- if .Values.namespaced }} + - key: kubernetes.io/metadata.name + operator: In + values: + {{- if empty .Values.namespaceList }} + - {{ .Release.Namespace }} + {{- else }} + {{- range $i, $v := .Values.namespaceList }} + - {{ trim $v }} + {{- end }} + {{- end }} + {{- end }} + objectSelector: + matchLabels: + confluent-platform: "true" + rules: + - apiGroups: + - apps + apiVersions: + - v1 + operations: + - DELETE + resources: + - statefulsets + scope: Namespaced + sideEffects: None + timeoutSeconds: 10 +- admissionReviewVersions: + - v1beta1 + clientConfig: + service: + name: confluent-operator + namespace: {{ .Release.Namespace }} + path: /confluent-operator/validate + port: {{ .Values.webhooks.port }} + failurePolicy: Fail + name: kafka-pods.webhooks.platform.confluent.io + namespaceSelector: + matchExpressions: + - key: confluent-operator.webhooks.platform.confluent.io/disable + operator: NotIn + values: [ "true" ] + {{- if .Values.namespaced }} + - key: kubernetes.io/metadata.name + operator: In + values: + {{- if empty .Values.namespaceList }} + - {{ .Release.Namespace }} + {{- else }} + {{- range $i, $v := .Values.namespaceList }} + - {{ trim $v }} + {{- end }} + {{- end }} + {{- end }} + objectSelector: + matchLabels: + confluent-platform: "true" + platform.confluent.io/type: kafka + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - DELETE + resources: + - pods + scope: Namespaced + sideEffects: None + timeoutSeconds: 30 +- admissionReviewVersions: + - v1beta1 + clientConfig: + service: + name: confluent-operator + namespace: {{ .Release.Namespace }} + path: /confluent-operator/validate + port: {{ .Values.webhooks.port }} + failurePolicy: Fail + name: evictions.webhooks.platform.confluent.io + namespaceSelector: + matchExpressions: + {{- if .Values.namespaced }} + - key: kubernetes.io/metadata.name + operator: In + values: + {{- if empty .Values.namespaceList }} + - {{ .Release.Namespace }} + {{- else }} + {{- range $i, $v := .Values.namespaceList }} + - {{ trim $v }} + {{- end }} + {{- end }} + {{- end }} + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + resources: + - pods/eviction + scope: Namespaced + sideEffects: None + timeoutSeconds: 30 +{{- end }} diff --git a/charts/confluent/confluent-for-kubernetes/0.1033.22/values.yaml b/charts/confluent/confluent-for-kubernetes/0.1033.22/values.yaml new file mode 100644 index 0000000000..e0c5f2ab12 --- /dev/null +++ b/charts/confluent/confluent-for-kubernetes/0.1033.22/values.yaml @@ -0,0 +1,269 @@ +## Confluent operator name +## +name: confluent-operator +## +## license Key +## +licenseKey: "" +## +## Load license either from the secret or through directoryPath. +## This will take precedence over licenseKey field. +## +license: + ## + ## The license secret reference name is injected through + ## CONFLUENT_LICENSE_SECRET_NAME environment variable. + ## The expected key: license.txt. license.txt contains raw license data. + ## For backward compatibility, licenseSecretRef field takes precedence if configured. + secretRef: "" + ## The directoryPathInContainer value is injected through + ## CONFLUENT_LICENSE_DIRECTORY_PATH environment variable. + ## The expected key: license.txt. license.txt file must have value in pattern `license=`. + ## + ## This configuration takes precedence over license.secretRef or licenseSecretRef field. + ## + directoryPathInContainer: "" + +## +## AutoGenerated certificates configuration. +## We will continue using older model of reading CA from secret "ca-pair-sslcerts" unless +## managedCerts.enabled is set to true. +## +managedCerts: + ## + ## Denotes whether CFK managed certs are configured with helm values. If this is set to true + ## values below will be used for auto-generated certificates and will cause a cluster roll + ## first time after this is enabled. + ## + enabled: false + ## + ## CA certificate pair for AutoGenerated certificates in this CFK operator deployment. + ## + caCertificate: + ## + ## CA pair secret reference name is injected through + ## CONFLUENT_MANAGED_CERTS_SECRET_NAME environment variable. + ## The expected keys are tls.crt and tls.key for CA Certificate and CA Certificate Key + ## respectively. + ## + secretRef: "" + ## The directoryPathInContainer value for CA pair certificates are injected through + ## CONFLUENT_MANAGED_CERTS_DIRECTORY_PATH environment variable. + ## The expected files are tls.crt and tls.key for CA Certificate and CA Certificate Key + ## respectively. + ## + directoryPathInContainer: "" + ## + ## Validity for Auto-generated certificates is injected through + ## CONFLUENT_MANAGED_CERTS_DURATION_DAYS environment variable. + ## + certDurationInDays: 60 + ## + ## Renewal time for Auto-generated certificates is injected through + ## CONFLUENT_MANAGED_CERTS_RENEW_BEFORE_DAYS environment variable. + ## + renewBeforeInDays: 30 + ## + ## SANs to be added for all auto-generated certificates generated by this + ## CFK operator. This is injected through CONFLUENT_MANAGED_CERTS_SANS + ## environment variable. + ## Use this for adding wild card SANs. Modifying this will trigger regeneration of + ## certs for all CP clusters managed by the CFK operator. + ## + sans: "" + +### +## Image pull secret +imagePullSecretRef: confluent-registry +## Confluent Operator Image Information +## +image: + registry: docker.io + repository: confluentinc/confluent-operator + pullPolicy: IfNotPresent + tag: "0.1033.22" + +### +## Priority class for Confluent Operator pod +priorityClassName: "" +## Number of pods for Operator +## Enables leader election if more than one replica +replicas: 1 +## Confluent Operator Cluster Access +## If true, operator only creates roles/rolebinding for the release namespace +## Otherwise, it has cluster access with clusterrole/clusterrrolebinding +namespaced: true +### list of namespaces to watch by operator +### This field only takes in effect if `namespaced=true`. By default, it will only watch the release namespace +### Otherwise, it will watch specified namespaces. If watching only release namespace, do not specify this field +namespaceList: [] +## Confluent Operator Pod Resources +## +resources: + limits: + cpu: 500m + memory: 512Mi + requests: + cpu: 100m + memory: 256Mi +## Pod termination grace-period +## +terminationGracePeriodSeconds: 30 +## Enable debugging +## +debug: false +## Enable Fips Mode +## +fipsmode: false +## Set number of day2 workers +## +numDay2Worker: "" +## +## Configure affinity, +## More information here https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ +## +affinity: {} +## Example for nodeAffinity, configure as required. +##affinity: +## nodeAffinity: +## requiredDuringSchedulingIgnoredDuringExecution: +## nodeSelectorTerms: +## - matchExpressions: +## - key: "node-role.kubernetes.io/compute" +## operator: In +## values: +## - "true" + +## +## Configure tolerations +## https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +## +tolerations: [] +## +##tolerations: +##- key: "dedicated" +## operator: "Equal" +## value: "operator" +## effect: "NoSchedule" + +## Pod Security Context +## +podSecurity: + enabled: true + securityContext: + fsGroup: 1001 + runAsUser: 1001 + runAsNonRoot: true + +## Container Security Context +## Container security context overrides security context defined at pod level. +## For example following container security context would override the +## default PodSecurityContext defined above +## +## securityContext: +## runAsUser: 2001 +## runAsNonRoot: false +## +## Refer to this documentation on how configure security context for container +## https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-containerh +## +containerSecurity: + enabled: false + securityContext: {} + +## +## ServiceAccount +## If enabled it will create, otherwise it will +## not create +## +serviceAccount: + create: true + name: "" +## Enable Kubernetes RBAC +## When set to true, it will create a proper role/rolebinding or cluster/clusterrolebinding based on namespaced field. +## If a user doesn't have permission to create role/rolebinding then they can disable rbac field and +## create required resources out of band to be used by the Operator. In this case, follow the +## templates/clusterrole.yaml and templates/clusterrolebiding.yaml to create proper required resources. +rbac: true + +## Enable extra Kubernetes API groups in role/clusterrole resource +## When set to true, it will add apiGroups to role/clusterrole for OpenShift route resource +clusterRole: + openshift: true + +### +### Confluent Telemetry Report configuration +## The secretRef contains following data, +## telemetry.txt: |- +## api.key= +## api.secret= +## proxy.url= # only required if proxy is enabled +## proxy.username= # only required if proxy requires credential +## proxy.password= +## +telemetry: + operator: + enabled: false + enabled: false + proxy: + enabled: false + credentialRequired: false + secretRef: "" + ## To use directoryPathInContainer, need to make sure + ## you mount telemetry.txt in the path you provided here in each pod + directoryPathInContainer: "" + +## In case of KRaft, we need to preserve the KRaft ClusterID in PV annotation +## for disaster recovery case. Enabling this ensures we create proper ClusterRoles +## to be able to set this annotation in PersistentVolumes. +kRaftEnabled: false + +### +### Webhooks configuration +## To enable webhooks, it requires TLS certificates to set up webhook server, +## which used for secure communication between webhook server and kubernetes api server. +## Please provide the TLS keys and certificates with format as mentioned in this doc: +## https://docs.confluent.io/operator/current/co-network-encryption.html#provide-tls-keys-and-certificates-in-pem-format. +## The certificate must have the Subject Alternative Name (SAN) of the form: confluent-operator..svc +webhooks: + enabled: false + port: 8443 + tls: + secretRef: "" + directoryPathInContainer: "" + +## +## Pod annotations/labels configurations +## +pod: + annotations: + prometheus.io/path: "/metrics" + prometheus.io/port: "7778" + prometheus.io/scrape: "true" + labels: {} +# labels: +# key: "value" + +## +## Load license from the secret reference +## +Deprecated, use license.secretRef instead. +## +licenseSecretRef: "" + +## +## Volumes to mount on CFK operator +## Refer to the Kubernetes volume/volumeMounts format: https://kubernetes.io/docs/concepts/storage/volumes/ +## +## Example with a PVC. +## mountedVolumes: +## volumes: +## - name: custom-volume +## persistentVolumeClaim: +## claimName: pvc-test +## volumeMounts: +## - name: custom-volume +## mountPath: /mnt/ +## +mountedVolumes: + volumes: [] + volumeMounts: [] diff --git a/charts/crate/crate-operator/2.41.0/.helmignore b/charts/crate/crate-operator/2.41.0/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/crate/crate-operator/2.41.0/.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/crate/crate-operator/2.41.0/Chart.lock b/charts/crate/crate-operator/2.41.0/Chart.lock new file mode 100644 index 0000000000..bfd61e84a1 --- /dev/null +++ b/charts/crate/crate-operator/2.41.0/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: crate-operator-crds + repository: file://../crate-operator-crds + version: 2.41.0 +digest: sha256:b3ea92d9fa71a48c61b80c43847f80f85727e178676898033c94b102962efec4 +generated: "2024-08-26T11:55:11.319301487Z" diff --git a/charts/crate/crate-operator/2.41.0/Chart.yaml b/charts/crate/crate-operator/2.41.0/Chart.yaml new file mode 100644 index 0000000000..dc4dfbfff6 --- /dev/null +++ b/charts/crate/crate-operator/2.41.0/Chart.yaml @@ -0,0 +1,18 @@ +annotations: + catalog.cattle.io/certified: partner + catalog.cattle.io/display-name: CrateDB Operator + catalog.cattle.io/release-name: crate-operator +apiVersion: v2 +appVersion: 2.41.0 +dependencies: +- condition: crate-operator-crds.enabled + name: crate-operator-crds + repository: file://./charts/crate-operator-crds + version: 2.41.0 +description: Crate Operator - Helm chart for installing and upgrading Crate Operator. +icon: file://assets/icons/crate-operator.svg +maintainers: +- name: Crate.io +name: crate-operator +type: application +version: 2.41.0 diff --git a/charts/crate/crate-operator/2.41.0/README.md b/charts/crate/crate-operator/2.41.0/README.md new file mode 100644 index 0000000000..96e327220f --- /dev/null +++ b/charts/crate/crate-operator/2.41.0/README.md @@ -0,0 +1,61 @@ +# Crate Operator Helm Chart + +A Helm chart for installing and upgrading the [Crate Operator](https://github.com/crate/crate-operator). +The **CrateDB Kubernetes Operator** provides convenient way to run [CrateDB](https://github.com/crate/crate) +clusters inside Kubernetes. + +Helm must be installed to use the charts. Please refer to Helm's [documentation](https://helm.sh/docs/) to get started. + +## Prerequisites + +The Crate Operator requires the CrateDB [CRD](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/#customresourcedefinitions). +It can be installed separately by installing the [Helm Chart](../cratedb-crds/) or as a dependency of this Chart. + +If the CRD is already installed (via the `crate-operator-crds` Helm chart or manually), you need to pass `--set crate-operator-crds.enabled=false` when installing the Operator. + +If the RBAC resources are already installed, you need to pass `--set rbac.create=false` when installing the Operator. + +## Usage + +Once Helm is properly set up, install the chart. + +### Install from local folder + +``` +helm install crate-operator crate-operator +``` + +### Install from repo + +``` +helm repo add crate-operator https://crate.github.io/crate-operator +helm search repo crate-operator +helm install crate-operator crate-operator/crate-operator +``` + +#### Namespace + +The operator is installed in the namespace `crate-operator`. +The namespace needs either to be created first: + +```shell +kubectl create namespace crate-operator +``` + +or it will be created automatically by adding `--namespace=crate-operator --create-namespace` to the Helm command: + +```shell +helm upgrade --install --atomic crate-operator crate-operator \ + --namespace=crate-operator \ + --create-namespace +``` + +#### Configuration + +Please refer to the [configuration documentation](https://github.com/crate/crate-operator/blob/master/docs/source/configuration.rst) for further details. + +### Upgrading the Operator + +``` +helm upgrade --atomic crate-operator crate-operator +``` diff --git a/charts/crate/crate-operator/2.41.0/charts/crate-operator-crds/.helmignore b/charts/crate/crate-operator/2.41.0/charts/crate-operator-crds/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/crate/crate-operator/2.41.0/charts/crate-operator-crds/.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/crate/crate-operator/2.41.0/charts/crate-operator-crds/Chart.yaml b/charts/crate/crate-operator/2.41.0/charts/crate-operator-crds/Chart.yaml new file mode 100644 index 0000000000..d9df2912b1 --- /dev/null +++ b/charts/crate/crate-operator/2.41.0/charts/crate-operator-crds/Chart.yaml @@ -0,0 +1,9 @@ +apiVersion: v2 +appVersion: 2.41.0 +description: Crate Operator CRDs - Helm chart for installing and upgrading Custom + Resource Definitions (CRDs) for the Crate Operator. +maintainers: +- name: Crate.io +name: crate-operator-crds +type: application +version: 2.41.0 diff --git a/charts/crate/crate-operator/2.41.0/charts/crate-operator-crds/README.md b/charts/crate/crate-operator/2.41.0/charts/crate-operator-crds/README.md new file mode 100644 index 0000000000..29f503e4f7 --- /dev/null +++ b/charts/crate/crate-operator/2.41.0/charts/crate-operator-crds/README.md @@ -0,0 +1,30 @@ +# Crate Operator CRDs Helm Chart + +A Helm chart for installing and upgrading the CRDs for [Crate Operator](https://github.com/crate/crate-operator). +To be able to deploy the custom resource CrateDB to a Kubernetes cluster, the API needs to be extended with a Custom Resource Definition (CRD). + +Helm must be installed to use the charts. Please refer to Helm's [documentation](https://helm.sh/docs/) to get started. + +## Usage + +Once Helm is properly set up, install the chart. + +### Install from local folder + +``` +helm install crate-operator-crds crate-operator-crds +``` + +### Install from repo + +``` +helm repo add crate-operator https://crate.github.io/crate-operator +helm search repo crate-operator +helm install crate-operator-crds crate-operator/crate-operator-crds +``` + +### Upgrading the Operator + +``` +helm upgrade --atomic crate-operator-crds crate-operator-crds +``` diff --git a/charts/crate/crate-operator/2.41.0/charts/crate-operator-crds/templates/NOTES.txt b/charts/crate/crate-operator/2.41.0/charts/crate-operator-crds/templates/NOTES.txt new file mode 100644 index 0000000000..c5615c64c6 --- /dev/null +++ b/charts/crate/crate-operator/2.41.0/charts/crate-operator-crds/templates/NOTES.txt @@ -0,0 +1 @@ +Thank you for installing {{ .Chart.Name }}. diff --git a/charts/crate/crate-operator/2.41.0/charts/crate-operator-crds/templates/cratedbs-cloud-crate-io.yaml b/charts/crate/crate-operator/2.41.0/charts/crate-operator-crds/templates/cratedbs-cloud-crate-io.yaml new file mode 100644 index 0000000000..575073b9c3 --- /dev/null +++ b/charts/crate/crate-operator/2.41.0/charts/crate-operator-crds/templates/cratedbs-cloud-crate-io.yaml @@ -0,0 +1,691 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + name: cratedbs.cloud.crate.io +spec: + conversion: + strategy: None + group: cloud.crate.io + names: + kind: CrateDB + listKind: CrateDBList + plural: cratedbs + singular: cratedb + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The CrateDB Cluster name + jsonPath: .spec.cluster.name + name: ClusterName + type: string + - description: The CrateDB Cluster version + jsonPath: .spec.cluster.version + name: Version + type: string + - description: Number of data nodes in this cluster + jsonPath: .spec.nodes.data[?(@.name == "hot")].replicas + name: Nodes + type: number + - description: CPU Requests + jsonPath: .spec.nodes.data[?(@.name == "hot")].resources.requests.cpu + name: CPU_REQ + type: number + - description: CPU Limits + jsonPath: .spec.nodes.data[?(@.name == "hot")].resources.limits.cpu + name: CPU_LIM + type: number + # Only shown in wide mode (-o wide) + priority: 1 + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.crateDBStatus.health + name: Health + type: string + name: v1 + schema: + openAPIV3Schema: + properties: + spec: + properties: + backups: + properties: + aws: + properties: + accessKeyId: + properties: + secretKeyRef: + properties: + key: + description: The key within the Kubernetes Secret + that holds the AWS Access Key ID. + type: string + name: + description: Name of a Kubernetes Secret that contains + the AWS Access Key ID to be used for backups. + type: string + required: + - key + - name + type: object + required: + - secretKeyRef + type: object + basePath: + description: The base path within the backup under which the + snapshots will be placed. + type: string + bucket: + properties: + secretKeyRef: + properties: + key: + description: The key within the Kubernetes Secret + that holds the AWS S3 bucket name. + type: string + name: + description: Name of a Kubernetes Secret that contains + the AWS S3 bucket name to be used for backups. + type: string + required: + - key + - name + type: object + required: + - secretKeyRef + type: object + cron: + description: A crontab formatted string indicating when and + how often to perform backups. + pattern: ^(((\d+,)+\d+|(\d+(\/|-)\d+)|\d+|\*) ){4}(((\d+,)+\d+|(\d+(\/|-)\d+)|\d+|\*))$ + type: string + endpointUrl: + properties: + secretKeyRef: + properties: + key: + description: The key within the Kubernetes Secret + that holds the S3 endpoint. + type: string + name: + description: Name of a Kubernetes Secret that contains + the S3 endpoint-url to be used for backups. + type: string + required: + - key + - name + type: object + required: + - secretKeyRef + type: object + region: + properties: + secretKeyRef: + properties: + key: + description: The key within the Kubernetes Secret + that holds the name of the AWS region to use. + type: string + name: + description: Name of a Kubernetes Secret that contains + the AWS region to be used for backups. + type: string + required: + - key + - name + type: object + required: + - secretKeyRef + type: object + secretAccessKey: + properties: + secretKeyRef: + properties: + key: + description: The key within the Kubernetes Secret + that holds the AWS Secret Access Key. + type: string + name: + description: Name of a Kubernetes Secret that contains + the AWS Secret Access Key to be used for backups. + type: string + required: + - key + - name + type: object + required: + - secretKeyRef + type: object + required: + - accessKeyId + - bucket + - cron + - region + - secretAccessKey + type: object + type: object + cluster: + properties: + allowedCIDRs: + description: Whitelisted CIDRs + items: + type: string + type: array + externalDNS: + description: The external DNS name record that should point to + the CrateDB cluster. + type: string + imageRegistry: + description: Point to a Docker registry. For the offical image + it's 'crate', testing and nightly releases are under 'crate/crate'. + Or others under 'https://example.com/path/to/registry' + type: string + license: + properties: + secretKeyRef: + properties: + key: + description: The key within the Kubernetes Secret that + holds the CrateDB license. + type: string + name: + description: Name of a Kubernetes Secret that contains + a valid CrateDB license. + type: string + required: + - key + - name + type: object + description: Deprecated and no longer has any effect. + Only here for backwards-compatibility. + required: + - secretKeyRef + type: object + name: + description: Name of the cluster + pattern: ^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$ + type: string + restoreSnapshot: + description: Restore data from a snapshot. + properties: + accessKeyId: + properties: + secretKeyRef: + properties: + key: + description: The key within the Kubernetes Secret + that holds the Access Key ID. + type: string + name: + description: Name of a Kubernetes Secret that contains + the Access Key ID to be used for accessing the + backup of the source cluster. + type: string + required: + - key + - name + type: object + required: + - secretKeyRef + type: object + basePath: + properties: + secretKeyRef: + properties: + key: + description: The key within the Kubernetes Secret + that holds the base path of the repository. + type: string + name: + description: Name of a Kubernetes Secret that contains + the base path to be used. + type: string + required: + - key + - name + type: object + required: + - secretKeyRef + type: object + bucket: + properties: + secretKeyRef: + properties: + key: + description: The key within the Kubernetes Secret + that holds the snapshot's bucket name. + type: string + name: + description: Name of a Kubernetes Secret that contains + the snapshot's bucket name to be used for the restore. + type: string + required: + - key + - name + type: object + required: + - secretKeyRef + type: object + secretAccessKey: + properties: + secretKeyRef: + properties: + key: + description: The key within the Kubernetes Secret + that holds the Secret Access Key. + type: string + name: + description: Name of a Kubernetes Secret that contains + the Secret Access Key to be used for accessing the + backup of the source cluster.. + type: string + required: + - key + - name + type: object + required: + - secretKeyRef + type: object + snapshot: + description: The name of the snapshot to use. + type: string + type: + type: string + enum: ["all", "tables", "metadata", "partitions", "sections"] + tables: + description: The tables to restore from the backup. + Format '.'. + items: + type: string + type: array + sections: + description: Restore a single metadata group or only tables or views. + items: + type: string + enum: ["tables", "views", "users", "privileges", "analyzers", "udfs"] + type: array + partitions: + description: Restore certain table partitions by their column and value. + items: + properties: + table_ident: + type: string + columns: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + required: + - table_ident + - columns + type: object + type: array + required: + - snapshot + - bucket + - secretAccessKey + - basePath + - accessKeyId + type: object + settings: + description: Additional settings to apply to all nodes in the + cluster. + type: object + x-kubernetes-preserve-unknown-fields: true + service: + description: Additional configuration for k8s services. + properties: + annotations: + description: Additional annotations to add to the k8s load balancer service. + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + ssl: + properties: + keystore: + properties: + secretKeyRef: + properties: + key: + description: CrateDB SSL keystore + type: string + name: + description: Keystore name + type: string + required: + - key + - name + type: object + required: + - secretKeyRef + type: object + keystoreKeyPassword: + properties: + secretKeyRef: + properties: + key: + description: Keystore key password + type: string + name: + description: Keystore passwords + type: string + required: + - key + - name + type: object + required: + - secretKeyRef + type: object + keystorePassword: + properties: + secretKeyRef: + properties: + key: + description: Keystore password + type: string + name: + description: Keystore passwords + type: string + required: + - key + - name + type: object + required: + - secretKeyRef + type: object + required: + - keystore + - keystoreKeyPassword + - keystorePassword + type: object + version: + description: CrateDB version + type: string + required: + - imageRegistry + - name + - version + type: object + grandCentral: + properties: + backendImage: + description: The image of the grand central backend. + type: string + backendEnabled: + description: Flag indicating whether grand central backend is + deployed for this cluster. + type: boolean + jwkUrl: + description: The endpoint to retrieve the list of JWK public keys + used for verifying JWT tokens. + type: string + apiUrl: + description: The CrateDB Cloud API URL. + type: string + required: + - backendImage + - jwkUrl + - apiUrl + - backendEnabled + type: object + nodes: + properties: + data: + items: + properties: + annotations: + description: Additional annotations to put on the corresponding + pods. + type: object + x-kubernetes-preserve-unknown-fields: true + labels: + description: Additional labels to put on the corresponding + pods. + type: object + x-kubernetes-preserve-unknown-fields: true + name: + description: Uniquely identifying name of this type of node. + pattern: ^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?$ + type: string + replicas: + description: Number of CrateDB nodes of this type. + type: number + nodepool: + description: Type of nodepool where the cluster should run. + type: string + resources: + properties: + cpus: + description: Deprecated - please use requests/d. + type: number + disk: + properties: + count: + description: Number of disks + type: number + size: + description: Size of the disk. + type: string + storageClass: + description: The name of a Kubernetes StorageClass + type: string + required: + - count + - size + - storageClass + type: object + heapRatio: + description: Allocated heap size relative to memory + format: float + type: number + limits: + properties: + cpu: + description: Limited CPUs for each CrateDB container. + Supports the syntax documented in https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/. + type: number + memory: + description: Limited memory for each CrateDB container. + Supports the syntax documented in https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/. + type: string + type: object + memory: + description: Deprecated - please use requests/limits. + type: string + requests: + properties: + cpu: + description: Requested CPUs for each CrateDB container. + Supports the syntax documented in https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/. + type: number + memory: + description: Requested memory for each CrateDB container. + Supports the syntax documented in https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/. + type: string + type: object + required: + - disk + - heapRatio + type: object + settings: + description: Additional settings to apply to all nodes of + that type in the cluster. + type: object + x-kubernetes-preserve-unknown-fields: true + required: + - name + - replicas + - resources + type: object + minItems: 1 + type: array + master: + properties: + annotations: + description: Additional annotations to put on the corresponding + pods. + type: object + x-kubernetes-preserve-unknown-fields: true + labels: + description: Additional labels to put on the corresponding + pods. + type: object + x-kubernetes-preserve-unknown-fields: true + replicas: + description: Number of master nodes. Should be an odd number. + minimum: 3 + type: number + nodepool: + description: Type of nodepool where the cluster should run. + type: string + resources: + properties: + cpus: + description: Deprecated - please use requests/limits. + type: number + disk: + properties: + count: + description: Number of disks + type: number + size: + description: Size of the disk. + type: string + storageClass: + description: The name of a Kubernetes StorageClass + type: string + required: + - count + - size + - storageClass + type: object + heapRatio: + description: Allocated heap size relative to memory + format: float + type: number + limits: + properties: + cpu: + description: Limited CPUs for each CrateDB container. + Supports the syntax documented in https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/. + type: number + memory: + description: Limited memory for each CrateDB container. + Supports the syntax documented in https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/. + type: string + type: object + memory: + description: Deprecated - please use requests/limits. + type: string + requests: + properties: + cpu: + description: Requested CPUs for each CrateDB container. + Supports the syntax documented in https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/. + type: number + memory: + description: Requested memory for each CrateDB container. + Supports the syntax documented in https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/. + type: string + type: object + required: + - disk + - heapRatio + type: object + settings: + description: Additional settings to apply to all master nodes + in the cluster. + type: object + x-kubernetes-preserve-unknown-fields: true + required: + - replicas + - resources + type: object + required: + - data + type: object + ports: + properties: + exporter: + description: SQL exporter port number + maximum: 65535 + minimum: 1 + type: number + http: + description: HTTP port number + maximum: 65535 + minimum: 1 + type: number + jmx: + description: JMX port number + maximum: 65535 + minimum: 1 + type: number + postgres: + description: PostgreSQL port number + maximum: 65535 + minimum: 1 + type: number + prometheus: + description: Prometheus port number + maximum: 65535 + minimum: 1 + type: number + required: + - exporter + - http + - jmx + - postgres + - prometheus + type: object + users: + items: + properties: + name: + description: The username for a CrateDB cluster user. + type: string + password: + properties: + secretKeyRef: + properties: + key: + description: The key within the Kubernetes Secret that + holds the user's password. + type: string + name: + description: Name of a Kubernetes Secret that contains + the password for the user. + type: string + required: + - key + - name + type: object + required: + - secretKeyRef + type: object + required: + - name + - password + type: object + type: array + required: + - cluster + - nodes + type: object + status: + type: object + x-kubernetes-preserve-unknown-fields: true + required: + - spec + type: object + served: true + storage: true diff --git a/charts/crate/crate-operator/2.41.0/charts/crate-operator-crds/values.yaml b/charts/crate/crate-operator/2.41.0/charts/crate-operator-crds/values.yaml new file mode 100644 index 0000000000..45a6fce00b --- /dev/null +++ b/charts/crate/crate-operator/2.41.0/charts/crate-operator-crds/values.yaml @@ -0,0 +1,3 @@ +# Default values for crate-operator-crds. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. diff --git a/charts/crate/crate-operator/2.41.0/templates/NOTES.txt b/charts/crate/crate-operator/2.41.0/templates/NOTES.txt new file mode 100644 index 0000000000..c5615c64c6 --- /dev/null +++ b/charts/crate/crate-operator/2.41.0/templates/NOTES.txt @@ -0,0 +1 @@ +Thank you for installing {{ .Chart.Name }}. diff --git a/charts/crate/crate-operator/2.41.0/templates/_helpers.tpl b/charts/crate/crate-operator/2.41.0/templates/_helpers.tpl new file mode 100644 index 0000000000..136cc8076c --- /dev/null +++ b/charts/crate/crate-operator/2.41.0/templates/_helpers.tpl @@ -0,0 +1,63 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "crate-operator.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 "crate-operator.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 "crate-operator.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "crate-operator.labels" -}} +helm.sh/chart: {{ include "crate-operator.chart" . }} +{{ include "crate-operator.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Values.image.tag | default .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +app.kubernetes.io/instance: {{ .Release.Name }} +app.kubernetes.io/part-of: {{ .Values.partOf }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "crate-operator.selectorLabels" -}} +app.kubernetes.io/name: {{ include "crate-operator.name" . }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "crate-operator.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "crate-operator.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/charts/crate/crate-operator/2.41.0/templates/deployment.yaml b/charts/crate/crate-operator/2.41.0/templates/deployment.yaml new file mode 100644 index 0000000000..28a3ebe2f9 --- /dev/null +++ b/charts/crate/crate-operator/2.41.0/templates/deployment.yaml @@ -0,0 +1,59 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + {{- include "crate-operator.labels" . | nindent 4 }} + name: {{ include "crate-operator.fullname" . }} + namespace: {{ .Release.Namespace }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + {{- include "crate-operator.selectorLabels" . | nindent 6 }} + strategy: + type: Recreate + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "crate-operator.labels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "crate-operator.serviceAccountName" . }} + containers: + - name: {{ .Chart.Name }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + env: + {{- range $name, $value := .Values.envFromSecret }} + - name: {{ $name }} + valueFrom: + secretKeyRef: + name: {{ $value.name }} + key: {{ $value.key }} + {{- end }} + {{- range $name, $value := .Values.env }} + - name: {{ $name }} + value: "{{ $value }}" + {{- end }} + resources: + {{- toYaml .Values.resources | nindent 12 }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/charts/crate/crate-operator/2.41.0/templates/rbac.yaml b/charts/crate/crate-operator/2.41.0/templates/rbac.yaml new file mode 100644 index 0000000000..695834939b --- /dev/null +++ b/charts/crate/crate-operator/2.41.0/templates/rbac.yaml @@ -0,0 +1,87 @@ +{{- if .Values.rbac.create -}} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "crate-operator.labels" . | nindent 4 }} + name: {{ template "crate-operator.fullname" . }} +rules: +# Framework: posting the events about the handlers progress/errors +- apiGroups: + - "" + - events.k8s.io + resources: + - events + verbs: + - create +# Application: watching & handling for the custom resources +- apiGroups: + - cloud.crate.io + resources: + - cratedbs + verbs: + - get + - list + - watch + - patch +# Application: other resources it produces and manipulates +- apiGroups: + - "" + - apps + - batch + - policy + - networking.k8s.io + resources: + - configmaps + - cronjobs + - jobs + - deployments + - ingresses + - namespaces + - persistentvolumeclaims + - persistentvolumes + - pods + - secrets + - services + - statefulsets + - poddisruptionbudgets + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - "" + resources: + - pods/exec + verbs: + - "*" +# Required by kopf to scan for CRD Changes. +- apiGroups: + - apiextensions.k8s.io + resources: + - customresourcedefinitions + verbs: + - list + - watch + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + {{- include "crate-operator.labels" . | nindent 4 }} + name: {{ template "crate-operator.fullname" . }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "crate-operator.fullname" . }} +subjects: +- kind: ServiceAccount + name: {{ template "crate-operator.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end -}} diff --git a/charts/crate/crate-operator/2.41.0/templates/serviceaccount.yaml b/charts/crate/crate-operator/2.41.0/templates/serviceaccount.yaml new file mode 100644 index 0000000000..f79f3e3be8 --- /dev/null +++ b/charts/crate/crate-operator/2.41.0/templates/serviceaccount.yaml @@ -0,0 +1,18 @@ +{{- if .Values.serviceAccount.create -}} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "crate-operator.labels" . | nindent 4 }} + name: {{ include "crate-operator.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- with .Values.imagePullSecrets }} +imagePullSecrets: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} diff --git a/charts/crate/crate-operator/2.41.0/values.yaml b/charts/crate/crate-operator/2.41.0/values.yaml new file mode 100644 index 0000000000..02f7053f45 --- /dev/null +++ b/charts/crate/crate-operator/2.41.0/values.yaml @@ -0,0 +1,65 @@ +--- +# Default values for crate-operator. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# If the `crate-operator-crds` is already installed, its installation +# can be disabled by changing this value to `false`. +crate-operator-crds: + # Make this disabled if you don't want to install + # the CRD dependency automatically. + enabled: true + +replicaCount: 1 + +image: + repository: crate/crate-operator + pullPolicy: Always + # Overrides the image tag whose default is the chart appVersion. + # tag: latest + +imagePullSecrets: [] +nameOverride: "crate-operator" +fullnameOverride: "crate-operator" + +partOf: cratedb + +env: + CRATEDB_OPERATOR_BOOTSTRAP_TIMEOUT: "1800" + CRATEDB_OPERATOR_DEBUG_VOLUME_SIZE: "128GiB" + CRATEDB_OPERATOR_DEBUG_VOLUME_STORAGE_CLASS: "default" + CRATEDB_OPERATOR_JMX_EXPORTER_VERSION: "1.2.0" + CRATEDB_OPERATOR_LOG_LEVEL: "INFO" + CRATEDB_OPERATOR_ROLLING_RESTART_TIMEOUT: "3600" + CRATEDB_OPERATOR_SCALING_TIMEOUT: "3600" + +envFromSecret: {} + +serviceAccount: + # Specifies whether a service account should be created + create: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "crate-operator" + +rbac: + # Specifies whether RBAC resources should be created + create: true + +podAnnotations: {} + +resources: + limits: + cpu: 250m + memory: 128Mi + requests: + cpu: 250m + memory: 128Mi + +nodeSelector: {} + +tolerations: [] + +affinity: {} diff --git a/charts/speedscale/speedscale-operator/2.2.303/.helmignore b/charts/speedscale/speedscale-operator/2.2.303/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/speedscale/speedscale-operator/2.2.303/.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/speedscale/speedscale-operator/2.2.303/Chart.yaml b/charts/speedscale/speedscale-operator/2.2.303/Chart.yaml new file mode 100644 index 0000000000..a9dfbbb708 --- /dev/null +++ b/charts/speedscale/speedscale-operator/2.2.303/Chart.yaml @@ -0,0 +1,27 @@ +annotations: + catalog.cattle.io/certified: partner + catalog.cattle.io/display-name: Speedscale Operator + catalog.cattle.io/kube-version: '>= 1.17.0-0' + catalog.cattle.io/release-name: speedscale-operator +apiVersion: v1 +appVersion: 2.2.303 +description: Stress test your APIs with real world scenarios. Collect and replay + traffic without scripting. +home: https://speedscale.com +icon: file://assets/icons/speedscale-operator.png +keywords: +- speedscale +- test +- testing +- regression +- reliability +- load +- replay +- network +- traffic +kubeVersion: '>= 1.17.0-0' +maintainers: +- email: support@speedscale.com + name: Speedscale Support +name: speedscale-operator +version: 2.2.303 diff --git a/charts/speedscale/speedscale-operator/2.2.303/LICENSE b/charts/speedscale/speedscale-operator/2.2.303/LICENSE new file mode 100644 index 0000000000..b78723d62f --- /dev/null +++ b/charts/speedscale/speedscale-operator/2.2.303/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2021 Speedscale + + 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/speedscale/speedscale-operator/2.2.303/README.md b/charts/speedscale/speedscale-operator/2.2.303/README.md new file mode 100644 index 0000000000..97a522e895 --- /dev/null +++ b/charts/speedscale/speedscale-operator/2.2.303/README.md @@ -0,0 +1,108 @@ +# Speedscale Operator + +The [Speedscale](https://www.speedscale.com) Operator is a [Kubernetes operator](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/) +that watches for deployments to be applied to the cluster and takes action based on annotations. The operator +can inject a proxy to capture traffic into or out of applications, or setup an isolation test environment around +a deployment for testing. The operator itself is a deployment that will be always present on the cluster once +the helm chart is installed. + +## Prerequisites + +- Kubernetes 1.20+ +- Helm 3+ +- Appropriate [network and firewall configuration](https://docs.speedscale.com/reference/networking) for Speedscale cloud and webhook traffic + +## Get Repo Info + +```bash +helm repo add speedscale https://speedscale.github.io/operator-helm/ +helm repo update +``` + +_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + +## Install Chart + +An API key is required. Sign up for a [free Speedscale trial](https://speedscale.com/free-trial/) if you do not have one. + +```bash +helm install speedscale-operator speedscale/speedscale-operator \ + -n speedscale \ + --create-namespace \ + --set apiKey= \ + --set clusterName= +``` + +_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ + +### Pre-install job failure + +We use pre-install job to check provided API key and provision some of the required resources. + +If the job failed during the installation, you'll see the following error during install: + +``` +Error: INSTALLATION FAILED: failed pre-install: job failed: BackoffLimitExceeded +``` + +You can inspect the logs using this command: + +```bash +kubectl -n speedscale logs job/speedscale-operator-pre-install +``` + +After fixing the error, uninstall the helm release, delete the failed job +and try installing again: + +```bash +helm -n speedscale uninstall speedscale-operator +kubectl -n speedscale delete job speedscale-operator-pre-install +``` + +## Uninstall Chart + +```bash +helm -n speedscale uninstall speedscale-operator +``` + +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._ + +CRDs created by this chart are not removed by default and should be manually cleaned up: + +```bash +kubectl delete crd trafficreplays.speedscale.com +``` + +## Upgrading Chart + +```bash +helm repo update +helm -n speedscale upgrade speedscale-operator speedscale/speedscale-operator +``` + +Resources capturing traffic will need to be rolled to pick up the latest +Speedscale sidecar. Use the rollout restart command for each namespace and +resource type: + +```bash +kubectl -n rollout restart deployment +``` + +With Helm v3, CRDs created by this chart are not updated by default +and should be manually updated. +Consult also the [Helm Documentation on CRDs](https://helm.sh/docs/chart_best_practices/custom_resource_definitions). + +_See [helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) for command documentation._ + +### Upgrading an existing Release to a new version + +A major chart version change (like v1.2.3 -> v2.0.0) indicates that there is an +incompatible breaking change needing manual actions. + + +## Help + +Speedscale docs information available at [docs.speedscale.com](https://docs.speedscale.com) or join us +on the [Speedscale community Slack](https://join.slack.com/t/speedscalecommunity/shared_invite/zt-x5rcrzn4-XHG1QqcHNXIM~4yozRrz8A)! diff --git a/charts/speedscale/speedscale-operator/2.2.303/app-readme.md b/charts/speedscale/speedscale-operator/2.2.303/app-readme.md new file mode 100644 index 0000000000..97a522e895 --- /dev/null +++ b/charts/speedscale/speedscale-operator/2.2.303/app-readme.md @@ -0,0 +1,108 @@ +# Speedscale Operator + +The [Speedscale](https://www.speedscale.com) Operator is a [Kubernetes operator](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/) +that watches for deployments to be applied to the cluster and takes action based on annotations. The operator +can inject a proxy to capture traffic into or out of applications, or setup an isolation test environment around +a deployment for testing. The operator itself is a deployment that will be always present on the cluster once +the helm chart is installed. + +## Prerequisites + +- Kubernetes 1.20+ +- Helm 3+ +- Appropriate [network and firewall configuration](https://docs.speedscale.com/reference/networking) for Speedscale cloud and webhook traffic + +## Get Repo Info + +```bash +helm repo add speedscale https://speedscale.github.io/operator-helm/ +helm repo update +``` + +_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + +## Install Chart + +An API key is required. Sign up for a [free Speedscale trial](https://speedscale.com/free-trial/) if you do not have one. + +```bash +helm install speedscale-operator speedscale/speedscale-operator \ + -n speedscale \ + --create-namespace \ + --set apiKey= \ + --set clusterName= +``` + +_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ + +### Pre-install job failure + +We use pre-install job to check provided API key and provision some of the required resources. + +If the job failed during the installation, you'll see the following error during install: + +``` +Error: INSTALLATION FAILED: failed pre-install: job failed: BackoffLimitExceeded +``` + +You can inspect the logs using this command: + +```bash +kubectl -n speedscale logs job/speedscale-operator-pre-install +``` + +After fixing the error, uninstall the helm release, delete the failed job +and try installing again: + +```bash +helm -n speedscale uninstall speedscale-operator +kubectl -n speedscale delete job speedscale-operator-pre-install +``` + +## Uninstall Chart + +```bash +helm -n speedscale uninstall speedscale-operator +``` + +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._ + +CRDs created by this chart are not removed by default and should be manually cleaned up: + +```bash +kubectl delete crd trafficreplays.speedscale.com +``` + +## Upgrading Chart + +```bash +helm repo update +helm -n speedscale upgrade speedscale-operator speedscale/speedscale-operator +``` + +Resources capturing traffic will need to be rolled to pick up the latest +Speedscale sidecar. Use the rollout restart command for each namespace and +resource type: + +```bash +kubectl -n rollout restart deployment +``` + +With Helm v3, CRDs created by this chart are not updated by default +and should be manually updated. +Consult also the [Helm Documentation on CRDs](https://helm.sh/docs/chart_best_practices/custom_resource_definitions). + +_See [helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) for command documentation._ + +### Upgrading an existing Release to a new version + +A major chart version change (like v1.2.3 -> v2.0.0) indicates that there is an +incompatible breaking change needing manual actions. + + +## Help + +Speedscale docs information available at [docs.speedscale.com](https://docs.speedscale.com) or join us +on the [Speedscale community Slack](https://join.slack.com/t/speedscalecommunity/shared_invite/zt-x5rcrzn4-XHG1QqcHNXIM~4yozRrz8A)! diff --git a/charts/speedscale/speedscale-operator/2.2.303/questions.yaml b/charts/speedscale/speedscale-operator/2.2.303/questions.yaml new file mode 100644 index 0000000000..29aee38958 --- /dev/null +++ b/charts/speedscale/speedscale-operator/2.2.303/questions.yaml @@ -0,0 +1,9 @@ +questions: +- variable: apiKey + default: "fffffffffffffffffffffffffffffffffffffffffffff" + description: "An API key is required to connect to the Speedscale cloud." + required: true + type: string + label: API Key + group: Authentication + diff --git a/charts/speedscale/speedscale-operator/2.2.303/templates/NOTES.txt b/charts/speedscale/speedscale-operator/2.2.303/templates/NOTES.txt new file mode 100644 index 0000000000..cabb59b175 --- /dev/null +++ b/charts/speedscale/speedscale-operator/2.2.303/templates/NOTES.txt @@ -0,0 +1,12 @@ +Thank you for installing the Speedscale Operator! + +Next you'll need to add the Speedscale Proxy Sidecar to your deployments. +See https://docs.speedscale.com/setup/sidecar/install/ + +If upgrading use the rollout restart command for each namespace and resource +type to ensure Speedscale sidecars are updated: + + kubectl -n rollout restart deployment + +Once your deployment is running the sidecar your service will show up on +https://app.speedscale.com/. diff --git a/charts/speedscale/speedscale-operator/2.2.303/templates/admission.yaml b/charts/speedscale/speedscale-operator/2.2.303/templates/admission.yaml new file mode 100644 index 0000000000..9a2a943d34 --- /dev/null +++ b/charts/speedscale/speedscale-operator/2.2.303/templates/admission.yaml @@ -0,0 +1,199 @@ +{{- $cacrt := "" -}} +{{- $crt := "" -}} +{{- $key := "" -}} +{{- $s := (lookup "v1" "Secret" .Release.Namespace "speedscale-webhook-certs") -}} +{{- if $s -}} +{{- $cacrt = index $s.data "ca.crt" | default (index $s.data "tls.crt") | b64dec -}} +{{- $crt = index $s.data "tls.crt" | b64dec -}} +{{- $key = index $s.data "tls.key" | b64dec -}} +{{ else }} +{{- $altNames := list ( printf "speedscale-operator.%s" .Release.Namespace ) ( printf "speedscale-operator.%s.svc" .Release.Namespace ) -}} +{{- $ca := genCA "speedscale-operator" 3650 -}} +{{- $cert := genSignedCert "speedscale-operator" nil $altNames 3650 $ca -}} +{{- $cacrt = $ca.Cert -}} +{{- $crt = $cert.Cert -}} +{{- $key = $cert.Key -}} +{{- end -}} +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + creationTimestamp: null + name: speedscale-operator + annotations: + argocd.argoproj.io/hook: PreSync + {{- if .Values.globalAnnotations }} +{{ toYaml .Values.globalAnnotations | indent 4}} + {{- end }} +webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + caBundle: {{ $cacrt | b64enc }} + service: + name: speedscale-operator + namespace: {{ .Release.Namespace }} + path: /mutate + failurePolicy: Ignore + name: sidecar.speedscale.com + namespaceSelector: + matchExpressions: + - key: kubernetes.io/metadata.name + operator: "NotIn" + values: + - kube-system + - kube-node-lease + {{- if .Values.namespaceSelector }} + - key: kubernetes.io/metadata.name + operator: "In" + values: + {{- range .Values.namespaceSelector }} + - {{ . | quote }} + {{- end }} + {{- end }} + reinvocationPolicy: IfNeeded + rules: + - apiGroups: + - apps + - batch + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + - DELETE + resources: + - deployments + - statefulsets + - daemonsets + - jobs + - replicasets + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + - DELETE + resources: + - pods + sideEffects: None + timeoutSeconds: 10 +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + creationTimestamp: null + name: speedscale-operator-replay + annotations: + argocd.argoproj.io/hook: PreSync + {{- if .Values.globalAnnotations }} +{{ toYaml .Values.globalAnnotations | indent 4}} + {{- end }} +webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + caBundle: {{ $cacrt | b64enc }} + service: + name: speedscale-operator + namespace: {{ .Release.Namespace }} + path: /mutate-speedscale-com-v1-trafficreplay + failurePolicy: Fail + name: replay.speedscale.com + namespaceSelector: + matchExpressions: + - key: kubernetes.io/metadata.name + operator: "NotIn" + values: + - kube-system + - kube-node-lease + {{- if .Values.namespaceSelector }} + - key: kubernetes.io/metadata.name + operator: "In" + values: + {{- range .Values.namespaceSelector }} + - {{ . | quote }} + {{- end }} + {{- end }} + rules: + - apiGroups: + - speedscale.com + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - trafficreplays + sideEffects: None + timeoutSeconds: 10 +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + creationTimestamp: null + name: speedscale-operator-replay + annotations: + argocd.argoproj.io/hook: PreSync + {{- if .Values.globalAnnotations }} +{{ toYaml .Values.globalAnnotations | indent 4}} + {{- end }} +webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + caBundle: {{ $cacrt | b64enc }} + service: + name: speedscale-operator + namespace: {{ .Release.Namespace }} + path: /validate-speedscale-com-v1-trafficreplay + failurePolicy: Fail + name: replay.speedscale.com + namespaceSelector: + matchExpressions: + - key: kubernetes.io/metadata.name + operator: "NotIn" + values: + - kube-system + - kube-node-lease + {{- if .Values.namespaceSelector }} + - key: kubernetes.io/metadata.name + operator: "In" + values: + {{- range .Values.namespaceSelector }} + - {{ . | quote }} + {{- end }} + {{- end }} + rules: + - apiGroups: + - speedscale.com + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + - DELETE + resources: + - trafficreplays + sideEffects: None + timeoutSeconds: 10 +--- +apiVersion: v1 +kind: Secret +metadata: + annotations: + helm.sh/hook: pre-install + helm.sh/hook-delete-policy: before-hook-creation + {{- if .Values.globalAnnotations }} +{{ toYaml .Values.globalAnnotations | indent 4}} + {{- end }} + creationTimestamp: null + name: speedscale-webhook-certs + namespace: {{ .Release.Namespace }} +type: kubernetes.io/tls +data: + ca.crt: {{ $cacrt | b64enc }} + tls.crt: {{ $crt | b64enc }} + tls.key: {{ $key | b64enc }} diff --git a/charts/speedscale/speedscale-operator/2.2.303/templates/configmap.yaml b/charts/speedscale/speedscale-operator/2.2.303/templates/configmap.yaml new file mode 100644 index 0000000000..af735e2886 --- /dev/null +++ b/charts/speedscale/speedscale-operator/2.2.303/templates/configmap.yaml @@ -0,0 +1,41 @@ +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: speedscale-operator + namespace: {{ .Release.Namespace }} + annotations: + argocd.argoproj.io/hook: PreSync + {{- if .Values.globalAnnotations }} +{{ toYaml .Values.globalAnnotations | indent 4}} + {{- end }} +data: + CLUSTER_NAME: {{ .Values.clusterName }} + IMAGE_PULL_POLICY: {{ .Values.image.pullPolicy }} + IMAGE_PULL_SECRETS: "" + IMAGE_REGISTRY: {{ .Values.image.registry }} + IMAGE_TAG: {{ .Values.image.tag }} + INSTANCE_ID: '{{- $cm := (lookup "v1" "ConfigMap" .Release.Namespace "speedscale-operator") -}}{{ if $cm }}{{ $cm.data.INSTANCE_ID }}{{ else }}{{ ( printf "%s-%s" .Values.clusterName uuidv4 ) }}{{ end }}' + LOG_LEVEL: {{ .Values.logLevel }} + SPEEDSCALE_DLP_CONFIG: {{ .Values.dlp.config }} + SPEEDSCALE_FILTER_RULE: {{ .Values.filterRule }} + TELEMETRY_INTERVAL: 1s + WITH_DLP: {{ .Values.dlp.enabled | quote }} + WITH_INSPECTOR: {{ .Values.dashboardAccess | quote }} + API_KEY_SECRET_NAME: {{ .Values.apiKeySecret | quote }} + DEPLOY_DEMO: {{ .Values.deployDemo | quote }} + GLOBAL_ANNOTATIONS: {{ .Values.globalAnnotations | toJson | quote }} + GLOBAL_LABELS: {{ .Values.globalLabels | toJson | quote }} + {{- if .Values.http_proxy }} + HTTP_PROXY: {{ .Values.http_proxy }} + {{- end }} + {{- if .Values.https_proxy }} + HTTPS_PROXY: {{ .Values.https_proxy }} + {{- end }} + {{- if .Values.no_proxy }} + NO_PROXY: {{ .Values.no_proxy }} + {{- end }} + PRIVILEGED_SIDECARS: {{ .Values.privilegedSidecars | quote }} + DISABLE_SMARTDNS: {{ .Values.disableSidecarSmartReverseDNS | quote }} + SIDECAR_CONFIG: {{ .Values.sidecar | toJson | quote }} + FORWARDER_CONFIG: {{ .Values.forwarder | toJson | quote }} diff --git a/charts/speedscale/speedscale-operator/2.2.303/templates/crds/trafficreplays.yaml b/charts/speedscale/speedscale-operator/2.2.303/templates/crds/trafficreplays.yaml new file mode 100644 index 0000000000..5743c5a13c --- /dev/null +++ b/charts/speedscale/speedscale-operator/2.2.303/templates/crds/trafficreplays.yaml @@ -0,0 +1,515 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + creationTimestamp: null + name: trafficreplays.speedscale.com +spec: + group: speedscale.com + names: + kind: TrafficReplay + listKind: TrafficReplayList + plural: trafficreplays + shortNames: + - replay + singular: trafficreplay + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.active + name: Active + type: boolean + - jsonPath: .spec.mode + name: Mode + type: string + - jsonPath: .status.conditions[-1:].message + name: Status + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: TrafficReplay is the Schema for the trafficreplays 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: TrafficReplaySpec defines the desired state of TrafficReplay + properties: + buildTag: + description: |- + BuildTag links a unique tag, build hash, etc. to the generated + traffic replay report. That way you can connect the report results to the + version of the code that was tested. + type: string + cleanup: + description: |- + Cleanup is the name of cleanup mode used for this + TrafficReplay. + enum: + - inventory + - all + - none + type: string + collectLogs: + description: |- + CollectLogs enables or disables log collection from target + workload. Defaults to true. + DEPRECATED: use TestReport.ActualConfig.Cluster.CollectLogs + type: boolean + configChecksum: + description: |- + ConfigChecksum, managed my the operator, is the SHA1 checksum of the + configuration. + type: string + customURL: + description: CustomURL allows to specify custom URL to the SUT. + type: string + generatorLowData: + description: |- + GeneratorLowData forces the generator into a high + efficiency/low data output mode. This is ideal for high volume + performance tests. Defaults to false. + DEPRECATED + type: boolean + mode: + description: Mode is the name of replay mode used for this TrafficReplay. + enum: + - full-replay + - responder-only + - generator-only + type: string + needsReport: + description: Indicates whether a responder-only replay needs a report. + type: boolean + proxyMode: + description: |- + ProxyMode defines proxy operational mode used with injected sidecar. + DEPRECATED + type: string + responderLowData: + description: |- + ResponderLowData forces the responder into a high + efficiency/low data output mode. This is ideal for high volume + performance tests. Defaults to false. + DEPRECATED + type: boolean + secretRefs: + description: |- + SecretRefs hold the references to the secrets which contain + various secrets like (e.g. short-lived JWTs to be used by the generator + for authorization with HTTP calls). + items: + description: |- + LocalObjectReference contains enough information to locate the referenced + Kubernetes resource object. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + type: array + sidecar: + description: |- + Sidecar defines sidecar specific configuration. + DEPRECATED: use Workloads + properties: + inject: + description: 'DEPRECATED: do not use' + type: boolean + patch: + description: Patch is .yaml file patch for the Workload + format: byte + type: string + tls: + properties: + in: + description: In provides configuration for sidecar inbound + TLS. + properties: + private: + description: Private is the filename of the TLS inbound + private key. + type: string + public: + description: Public is the filename of the TLS inbound + public key. + type: string + secret: + description: Secret is a secret with the TLS keys to use + for inbound traffic. + type: string + type: object + mutual: + description: Mutual provides configuration for sidecar mutual + TLS. + properties: + private: + description: Private is the filename of the mutual TLS + private key. + type: string + public: + description: Public is the filename of the mutual TLS + public key. + type: string + secret: + description: Secret is a secret with the mutual TLS keys. + type: string + type: object + out: + description: |- + Out enables or disables TLS out on the + sidecar during replay. + type: boolean + type: object + type: object + snapshotID: + description: |- + SnapshotID is the id of the traffic snapshot for this + TrafficReplay. + type: string + testConfigID: + description: |- + TestConfigID is the id of the replay configuration to be used + by the generator and responder for the TrafficReplay. + type: string + timeout: + description: |- + Timeout is the time to wait for replay test to finish. Defaults + to value of the `TIMEOUT` setting of the operator. + type: string + ttlAfterReady: + description: |- + TTLAfterReady provides a TTL (time to live) mechanism to limit + the lifetime of TrafficReplay object that have finished the execution and + reached its final state (either complete or failed). + type: string + workloadRef: + description: |- + WorkloadRef is the reference to the target workload (SUT) for + TrafficReplay. The operations will be performed in the namespace of the + target object. + DEPRECATED: use Workloads + properties: + apiVersion: + description: API version of the referenced object. + type: string + kind: + description: Kind of the referenced object. Defaults to "Deployment". + type: string + name: + description: Name of the referenced object. + type: string + namespace: + description: Namespace of the referenced object. Defaults to the + TrafficReplay namespace. + type: string + required: + - name + type: object + workloads: + description: |- + Workloads define target workloads (SUT) for a TrafficReplay. Many + workloads may be provided, or none. Workloads may be modified and + restarted during replay to configure communication with a responder. + items: + description: |- + Workload represents a Kubernetes workload to be targeted during replay and + associated settings. + properties: + customURI: + description: CustomURI will be target of the traffic instead + of directly targeting workload + type: string + inTrafficKey: + description: 'DEPRECATED: use InTrafficKeys' + type: string + inTrafficKeys: + description: 'DEPRECATED: use Tests' + items: + type: string + type: array + mocks: + description: |- + Mocks are strings used to identify slices of outbound snapshot traffic to + mock for this workload and maps directly to a snapshot's `OutTraffic` + field. Snapshot egress traffic can be split across multiple slices where + each slice contains part of the traffic. A workload may specify multiple + keys and multiple workloads may specify the same key. + + + Only the traffic slices defined here will be mocked. A workload with no + keys defined will not mock any traffic. Pass '*' to mock all traffic. + + + Mock strings may only match part of the snapshot's `OutTraffic` key if the + string matches exactly one key. For example, the test string + `foo.example.com` would match the `OutTraffic` key of + my-service:foo.example.com:8080, as long as no other keys would match + `foo.example.com`. Multiple mocks must be specified for multiple keys + unless using '*'. + items: + type: string + type: array + outTrafficKeys: + description: 'DEPRECATED: use Mocks' + items: + type: string + type: array + ref: + description: |- + Ref is a reference to a cluster workload, like a deployment or a + statefulset. + properties: + apiVersion: + description: API version of the referenced object. + type: string + kind: + description: Kind of the referenced object. Defaults to + "Deployment". + type: string + name: + description: Name of the referenced object. + type: string + namespace: + description: Namespace of the referenced object. Defaults + to the TrafficReplay namespace. + type: string + required: + - name + type: object + routing: + description: Routing configures how workloads route egress traffic + to responders + enum: + - hostalias + - nat + type: string + sidecar: + description: |- + TODO: this is not implemented, come back and replace deprecated Sidecar with workload specific settings + Sidecar defines sidecar specific configuration. + properties: + inject: + description: 'DEPRECATED: do not use' + type: boolean + patch: + description: Patch is .yaml file patch for the Workload + format: byte + type: string + tls: + properties: + in: + description: In provides configuration for sidecar inbound + TLS. + properties: + private: + description: Private is the filename of the TLS + inbound private key. + type: string + public: + description: Public is the filename of the TLS inbound + public key. + type: string + secret: + description: Secret is a secret with the TLS keys + to use for inbound traffic. + type: string + type: object + mutual: + description: Mutual provides configuration for sidecar + mutual TLS. + properties: + private: + description: Private is the filename of the mutual + TLS private key. + type: string + public: + description: Public is the filename of the mutual + TLS public key. + type: string + secret: + description: Secret is a secret with the mutual + TLS keys. + type: string + type: object + out: + description: |- + Out enables or disables TLS out on the + sidecar during replay. + type: boolean + type: object + type: object + tests: + description: |- + Tests are strings used to identify slices of inbound snapshot traffic this + workload is targeting and maps directly to a snapshot's `InTraffic` field. + Snapshot ingress traffic can be split across multiple slices where each + slice contains part of the traffic. A key must only be specified once + across all workloads, but a workload may specify multiple keys. Pass '*' + to match all keys. + + + Test strings may only match part of the snapshot's `InTraffic` key if the + string matches exactly one key. For example, the test string + `foo.example.com` would match the `InTraffic` key of + my-service:foo.example.com:8080, as long as no other keys would match + `foo.example.com` + + + This field is optional in the spec to provide support for single-workload + and legacy replays, but must be specified for multi-workload replays in + order to provide deterministic replay configuration. + items: + type: string + type: array + type: object + type: array + required: + - snapshotID + - testConfigID + type: object + status: + default: + observedGeneration: -1 + description: TrafficReplayStatus defines the observed state of TrafficReplay + properties: + active: + description: Active indicates whether this traffic replay is currently + underway or not. + type: boolean + conditions: + 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 + finishedTime: + description: Information when the traffic replay has finished. + format: date-time + type: string + initializedTime: + description: Information when the test environment was successfully + prepared. + format: date-time + type: string + lastHeartbeatTime: + description: 'DEPRECATED: will not be set' + format: date-time + type: string + observedGeneration: + description: ObservedGeneration is the last observed generation. + format: int64 + type: integer + reconcileFailures: + description: |- + ReconcileFailures is the number of times the traffic replay controller + experienced an error during the reconciliation process. The traffic + replay will be deleted if too many errors occur. + format: int64 + type: integer + reportID: + description: The id of the traffic replay report created. + type: string + reportURL: + description: The url to the traffic replay report. + type: string + startedTime: + description: Information when the traffic replay has started. + format: date-time + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/charts/speedscale/speedscale-operator/2.2.303/templates/deployments.yaml b/charts/speedscale/speedscale-operator/2.2.303/templates/deployments.yaml new file mode 100644 index 0000000000..e5f3292579 --- /dev/null +++ b/charts/speedscale/speedscale-operator/2.2.303/templates/deployments.yaml @@ -0,0 +1,132 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + operator.speedscale.com/ignore: "true" + {{- if .Values.globalAnnotations }} +{{ toYaml .Values.globalAnnotations | indent 4}} + {{- end }} + labels: + app: speedscale-operator + controlplane.speedscale.com/component: operator + {{- if .Values.globalLabels }} +{{ toYaml .Values.globalLabels | indent 4}} + {{- end }} + name: speedscale-operator + namespace: {{ .Release.Namespace }} +spec: + replicas: 1 + selector: + matchLabels: + app: speedscale-operator + controlplane.speedscale.com/component: operator + strategy: + type: Recreate + template: + metadata: + annotations: + {{- if .Values.globalAnnotations }} +{{ toYaml .Values.globalAnnotations | indent 8}} + {{- end }} + labels: + app: speedscale-operator + controlplane.speedscale.com/component: operator + {{- if .Values.globalLabels }} +{{ toYaml .Values.globalLabels | indent 8}} + {{- end }} + spec: + containers: + - command: + - /operator + env: + - name: POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + envFrom: + - configMapRef: + name: speedscale-operator + # https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#container-v1-core + # 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. + - configMapRef: + name: speedscale-operator-override + optional: true + - secretRef: + name: '{{ ne .Values.apiKeySecret "" | ternary .Values.apiKeySecret "speedscale-apikey" }}' + optional: false + image: '{{ .Values.image.registry }}/operator:{{ .Values.image.tag }}' + imagePullPolicy: {{ .Values.image.pullPolicy }} + livenessProbe: + failureThreshold: 5 + httpGet: + path: /healthz + port: health-check + scheme: HTTP + initialDelaySeconds: 30 + periodSeconds: 30 + successThreshold: 1 + timeoutSeconds: 5 + name: operator + ports: + - containerPort: 443 + name: webhook-server + - containerPort: 8081 + name: health-check + readinessProbe: + failureThreshold: 10 + httpGet: + path: /readyz + port: health-check + scheme: HTTP + initialDelaySeconds: 5 + periodSeconds: 5 + successThreshold: 1 + timeoutSeconds: 5 + resources: {{- toYaml .Values.operator.resources | nindent 10 }} + securityContext: + allowPrivilegeEscalation: false + privileged: false + readOnlyRootFilesystem: true + runAsNonRoot: false + # Run as root to bind 443 https://github.com/kubernetes/kubernetes/issues/56374 + runAsUser: 0 + volumeMounts: + - mountPath: /tmp + name: tmp + - mountPath: /tmp/k8s-webhook-server/serving-certs + name: webhook-certs + readOnly: true + - mountPath: /etc/ssl/speedscale + name: speedscale-tls-out + readOnly: true + hostNetwork: {{ .Values.hostNetwork }} + securityContext: + runAsNonRoot: true + serviceAccountName: speedscale-operator + terminationGracePeriodSeconds: 10 + volumes: + - emptyDir: {} + name: tmp + - name: webhook-certs + secret: + secretName: speedscale-webhook-certs + - name: speedscale-tls-out + secret: + secretName: speedscale-certs + {{- if .Values.affinity }} + affinity: {{ toYaml .Values.affinity | nindent 8 }} + {{- end }} + {{- if .Values.tolerations }} + tolerations: {{ toYaml .Values.tolerations | nindent 8 }} + {{- end }} + {{- if .Values.nodeSelector }} + nodeSelector: {{ toYaml .Values.nodeSelector | nindent 8 }} + {{- end }} diff --git a/charts/speedscale/speedscale-operator/2.2.303/templates/hooks.yaml b/charts/speedscale/speedscale-operator/2.2.303/templates/hooks.yaml new file mode 100644 index 0000000000..3e8231f194 --- /dev/null +++ b/charts/speedscale/speedscale-operator/2.2.303/templates/hooks.yaml @@ -0,0 +1,73 @@ +--- +apiVersion: batch/v1 +kind: Job +metadata: + annotations: + helm.sh/hook: pre-install + helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded + helm.sh/hook-weight: "4" + {{- if .Values.globalAnnotations }} +{{ toYaml .Values.globalAnnotations | indent 4}} + {{- end }} + creationTimestamp: null + name: speedscale-operator-pre-install + namespace: {{ .Release.Namespace }} + labels: + {{- if .Values.globalLabels }} +{{ toYaml .Values.globalLabels | indent 4}} + {{- end }} +spec: + backoffLimit: 0 + ttlSecondsAfterFinished: 30 + template: + metadata: + annotations: + {{- if .Values.globalAnnotations }} +{{ toYaml .Values.globalAnnotations | indent 8}} + {{- end }} + creationTimestamp: null + labels: + {{- if .Values.globalLabels }} +{{ toYaml .Values.globalLabels | indent 8}} + {{- end }} + spec: + containers: + - args: + - |- + # ensure valid settings before the chart reports a successfull install + {{- if .Values.http_proxy }} + HTTP_PROXY={{ .Values.http_proxy | quote }} \ + {{- end }} + {{- if .Values.https_proxy }} + HTTPS_PROXY={{ .Values.https_proxy | quote }} \ + {{- end }} + {{- if .Values.no_proxy }} + NO_PROXY={{ .Values.no_proxy | quote }} \ + {{- end }} + speedctl init --overwrite --no-rcfile-update \ + --api-key $SPEEDSCALE_API_KEY \ + --app-url $SPEEDSCALE_APP_URL + + # in case we're in istio + curl -X POST http://127.0.0.1:15000/quitquitquit || true + command: + - sh + - -c + envFrom: + - secretRef: + name: '{{ ne .Values.apiKeySecret "" | ternary .Values.apiKeySecret "speedscale-apikey" }}' + optional: false + image: '{{ .Values.image.registry }}/speedscale-cli:{{ .Values.image.tag }}' + imagePullPolicy: {{ .Values.image.pullPolicy }} + name: speedscale-cli + resources: {} + restartPolicy: Never + {{- if .Values.affinity }} + affinity: {{ toYaml .Values.affinity | nindent 8 }} + {{- end }} + {{- if .Values.tolerations }} + tolerations: {{ toYaml .Values.tolerations | nindent 8 }} + {{- end }} + {{- if .Values.nodeSelector }} + nodeSelector: {{ toYaml .Values.nodeSelector | nindent 8 }} + {{- end }} diff --git a/charts/speedscale/speedscale-operator/2.2.303/templates/rbac.yaml b/charts/speedscale/speedscale-operator/2.2.303/templates/rbac.yaml new file mode 100644 index 0000000000..e1ea42d999 --- /dev/null +++ b/charts/speedscale/speedscale-operator/2.2.303/templates/rbac.yaml @@ -0,0 +1,244 @@ +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + name: speedscale-operator + {{- if .Values.globalAnnotations }} + annotations: {{ toYaml .Values.globalAnnotations | nindent 4 }} + {{- end }} +rules: +- apiGroups: + - apps + resources: + - deployments + - statefulsets + - daemonsets + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +- apiGroups: + - apps + resources: + - replicasets + verbs: + - delete + - deletecollection + - get + - list + - patch + - update + - watch +- apiGroups: + - batch + resources: + - jobs + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +- apiGroups: + - apiextensions.k8s.io + resources: + - customresourcedefinitions + verbs: + - get + - list +- apiGroups: + - admissionregistration.k8s.io + resources: + - mutatingwebhookconfigurations + - validatingwebhookconfigurations + verbs: + - get + - list +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterrolebindings + - clusterroles + verbs: + - get + - list +- apiGroups: + - "" + resources: + - namespaces + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - configmaps + - secrets + - pods + - services + - serviceaccounts + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +- apiGroups: + - "" + resources: + - pods/log + verbs: + - get + - list +- apiGroups: + - "" + resources: + - events + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - nodes + verbs: + - get + - list + - watch +- apiGroups: + - metrics.k8s.io + resources: + - pods + verbs: + - get + - list + - watch +- apiGroups: + - rbac.authorization.k8s.io + resources: + - rolebindings + - roles + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +- apiGroups: + - networking.istio.io + resources: + - envoyfilters + - sidecars + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +- apiGroups: + - security.istio.io + resources: + - peerauthentications + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +- apiGroups: + - speedscale.com + resources: + - trafficreplays + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +- apiGroups: + - speedscale.com + resources: + - trafficreplays/status + verbs: + - get + - update + - patch +- apiGroups: + - argoproj.io + resources: + - rollouts + verbs: + - get + - list + - patch + - update + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: speedscale-operator + {{- if .Values.globalAnnotations }} + annotations: {{ toYaml .Values.globalAnnotations | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: speedscale-operator +subjects: +- kind: ServiceAccount + name: speedscale-operator + namespace: {{ .Release.Namespace }} +--- +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + creationTimestamp: null + labels: + app: speedscale-operator + controlplane.speedscale.com/component: operator + name: speedscale-operator + namespace: {{ .Release.Namespace }} + {{- if .Values.globalAnnotations }} + annotations: {{ toYaml .Values.globalAnnotations | nindent 4 }} + {{- end }} diff --git a/charts/speedscale/speedscale-operator/2.2.303/templates/secrets.yaml b/charts/speedscale/speedscale-operator/2.2.303/templates/secrets.yaml new file mode 100644 index 0000000000..1fb6999e4c --- /dev/null +++ b/charts/speedscale/speedscale-operator/2.2.303/templates/secrets.yaml @@ -0,0 +1,18 @@ +--- +{{ if .Values.apiKey }} +apiVersion: v1 +kind: Secret +metadata: + name: speedscale-apikey + namespace: {{ .Release.Namespace }} + annotations: + helm.sh/hook: pre-install + helm.sh/hook-weight: "3" + {{- if .Values.globalAnnotations }} +{{ toYaml .Values.globalAnnotations | indent 4}} + {{- end }} +type: Opaque +data: + SPEEDSCALE_API_KEY: {{ .Values.apiKey | b64enc }} + SPEEDSCALE_APP_URL: {{ .Values.appUrl | b64enc }} +{{ end }} diff --git a/charts/speedscale/speedscale-operator/2.2.303/templates/services.yaml b/charts/speedscale/speedscale-operator/2.2.303/templates/services.yaml new file mode 100644 index 0000000000..f9da2c25c1 --- /dev/null +++ b/charts/speedscale/speedscale-operator/2.2.303/templates/services.yaml @@ -0,0 +1,22 @@ +--- +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + app: speedscale-operator + controlplane.speedscale.com/component: operator + name: speedscale-operator + namespace: {{ .Release.Namespace }} + {{- if .Values.globalAnnotations }} + annotations: {{ toYaml .Values.globalAnnotations | nindent 4 }} + {{- end }} +spec: + ports: + - port: 443 + protocol: TCP + selector: + app: speedscale-operator + controlplane.speedscale.com/component: operator +status: + loadBalancer: {} diff --git a/charts/speedscale/speedscale-operator/2.2.303/templates/tls.yaml b/charts/speedscale/speedscale-operator/2.2.303/templates/tls.yaml new file mode 100644 index 0000000000..4a24562884 --- /dev/null +++ b/charts/speedscale/speedscale-operator/2.2.303/templates/tls.yaml @@ -0,0 +1,183 @@ +{{- $crt := "" -}} +{{- $key := "" -}} +{{- $s := (lookup "v1" "Secret" .Release.Namespace "speedscale-certs") -}} +{{- if $s -}} +{{- $crt = index $s.data "tls.crt" | b64dec -}} +{{- $key = index $s.data "tls.key" | b64dec -}} +{{ else }} +{{- $cert := genCA "Speedscale" 3650 -}} +{{- $crt = $cert.Cert -}} +{{- $key = $cert.Key -}} +{{- end -}} +--- +apiVersion: batch/v1 +kind: Job +metadata: + annotations: + helm.sh/hook: pre-install + helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded + helm.sh/hook-weight: "5" + {{- if .Values.globalAnnotations }} +{{ toYaml .Values.globalAnnotations | indent 4}} + {{- end }} + creationTimestamp: null + name: speedscale-operator-create-jks + namespace: {{ .Release.Namespace }} + labels: + {{- if .Values.globalLabels }} +{{ toYaml .Values.globalLabels | indent 4}} + {{- end }} +spec: + backoffLimit: 0 + ttlSecondsAfterFinished: 30 + template: + metadata: + annotations: + {{- if .Values.globalAnnotations }} +{{ toYaml .Values.globalAnnotations | indent 8}} + {{- end }} + creationTimestamp: null + labels: + {{- if .Values.globalAnnotations }} +{{ toYaml .Values.globalAnnotations | indent 8}} + {{- end }} + spec: + containers: + - args: + - |- + keytool -keystore /usr/lib/jvm/jre/lib/security/cacerts -importcert -noprompt -trustcacerts -storepass changeit -alias speedscale -file /etc/ssl/speedscale/tls.crt + kubectl -n ${POD_NAMESPACE} delete secret speedscale-jks || true + kubectl -n ${POD_NAMESPACE} create secret generic speedscale-jks --from-file=cacerts.jks=/usr/lib/jvm/jre/lib/security/cacerts + + # in case we're in istio + curl -X POST http://127.0.0.1:15000/quitquitquit || true + command: + - sh + - -c + volumeMounts: + - mountPath: /etc/ssl/speedscale + name: speedscale-tls-out + readOnly: true + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + envFrom: + - secretRef: + name: '{{ ne .Values.apiKeySecret "" | ternary .Values.apiKeySecret "speedscale-apikey" }}' + optional: false + image: '{{ .Values.image.registry }}/amazoncorretto' + imagePullPolicy: {{ .Values.image.pullPolicy }} + name: create-jks + resources: {} + restartPolicy: Never + serviceAccountName: speedscale-operator-provisioning + volumes: + - name: speedscale-tls-out + secret: + secretName: speedscale-certs + {{- if .Values.affinity }} + affinity: {{ toYaml .Values.affinity | nindent 8 }} + {{- end }} + {{- if .Values.tolerations }} + tolerations: {{ toYaml .Values.tolerations | nindent 8 }} + {{- end }} + {{- if .Values.nodeSelector }} + nodeSelector: {{ toYaml .Values.nodeSelector | nindent 8 }} + {{- end }} +--- +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: + helm.sh/hook: pre-install + helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded + helm.sh/hook-weight: "1" + {{- if .Values.globalAnnotations }} +{{ toYaml .Values.globalAnnotations | indent 4}} + {{- end }} + creationTimestamp: null + labels: + app: speedscale-operator + controlplane.speedscale.com/component: operator + name: speedscale-operator-provisioning + namespace: {{ .Release.Namespace }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + annotations: + helm.sh/hook: pre-install + helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded + helm.sh/hook-weight: "2" + creationTimestamp: null + name: speedscale-operator-provisioning +rules: +- apiGroups: + - "" + resources: + - secrets + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +- apiGroups: + - admissionregistration.k8s.io + resources: + - mutatingwebhookconfigurations + - validatingwebhookconfigurations + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + annotations: + helm.sh/hook: pre-install + helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded + helm.sh/hook-weight: "3" + {{- if .Values.globalAnnotations }} +{{ toYaml .Values.globalAnnotations | indent 4}} + {{- end }} + creationTimestamp: null + name: speedscale-operator-provisioning +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: speedscale-operator-provisioning +subjects: +- kind: ServiceAccount + name: speedscale-operator-provisioning + namespace: {{ .Release.Namespace }} +--- +apiVersion: v1 +kind: Secret +metadata: + annotations: + helm.sh/hook: pre-install + helm.sh/hook-delete-policy: before-hook-creation + {{- if .Values.globalAnnotations }} +{{ toYaml .Values.globalAnnotations | indent 4}} + {{- end }} + creationTimestamp: null + name: speedscale-certs + namespace: {{ .Release.Namespace }} +type: kubernetes.io/tls +data: + tls.crt: {{ $crt | b64enc }} + tls.key: {{ $key | b64enc }} diff --git a/charts/speedscale/speedscale-operator/2.2.303/values.yaml b/charts/speedscale/speedscale-operator/2.2.303/values.yaml new file mode 100644 index 0000000000..b29d99cce1 --- /dev/null +++ b/charts/speedscale/speedscale-operator/2.2.303/values.yaml @@ -0,0 +1,133 @@ +# An API key is required to connect to the Speedscale cloud. +# If you need a key email support@speedscale.com. +apiKey: "" + +# A secret name can be referenced instead of the api key itself. +# The secret must be of the format: +# +# type: Opaque +# data: +# SPEEDSCALE_API_KEY: +# SPEEDSCALE_APP_URL: +apiKeySecret: "" + +# Speedscale domain to use. +appUrl: "app.speedscale.com" + +# The name of your cluster. +clusterName: "my-cluster" + +# Speedscale components image settings. +image: + registry: gcr.io/speedscale + tag: v2.2.303 + pullPolicy: Always + +# Log level for Speedscale components. +logLevel: "info" + +# Namespaces to be watched by Speedscale Operator as a list of names. +namespaceSelector: [] + +# Instructs operator to deploy resources necessary to interact with your cluster from the Speedscale dashboard. +dashboardAccess: true + +# Filter Rule to apply to the Speedscale Forwarder +filterRule: "standard" + +# Data Loss Prevention settings. +dlp: + # Instructs operator to enable data loss prevention features + enabled: false + + # Configuration for data loss prevention + config: "standard" + +# If the operator pod/webhooks need to be on the host network. +# This is only needed if the control plane cannot connect directly to a pod +# for eg. if Calico is used as EKS's default networking +# https://docs.tigera.io/calico/3.25/getting-started/kubernetes/managed-public-cloud/eks#install-eks-with-calico-networking +hostNetwork: false + +# A set of annotations to be applied to all Speedscale related deployments, +# services, jobs, pods, etc. +# +# Example: +# annotation.first: value +# annotation.second: value +globalAnnotations: {} + +# A set of labels to be applied to all Speedscale related deployments, +# services, jobs, pods, etc. +# +# Example: +# label1: value +# label2: value +globalLabels: {} + +# A full affinity object as detailed: https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity +affinity: {} + +# The list of tolerations as detailed: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/ +tolerations: [] + +# A nodeselector object as detailed: https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes/ +nodeSelector: {} + +# Deploy a demo app at startup. Set this to an empty string to not deploy. +# Valid values: ["java", ""] +deployDemo: "java" + +# Proxy connection settings if required by your network. These translate to standard proxy environment +# variables HTTP_PROXY, HTTPS_PROXY, and NO_PROXY +http_proxy: "" +https_proxy: "" +no_proxy: "" + +# control if sidecar init containers should run with privileged set +privilegedSidecars: false + +# control if the sidecar should enable/disable use of the smart dns lookup feature (requires NET_ADMIN) +disableSidecarSmartReverseDNS: false + +# Operator settings. These limits are recommended unless you have a cluster +# with a very large number of workloads (for eg. 10k+ deployments, replicasets, etc.). +operator: + resources: + limits: + cpu: 500m + memory: 512Mi + requests: + cpu: 100m + memory: 128Mi + +# Default sidecar settings. Example: +# sidecar: +# resources: +# limits: +# cpu: 500m +# memory: 512Mi +# ephemeral-storage: 100Mi +# requests: +# cpu: 10m +# memory: 32Mi +# ephemeral-storage: 100Mi +# ignore_src_hosts: example.com, example.org +# ignore_src_ips: 8.8.8.8, 1.1.1.1 +# ignore_dst_hosts: example.com, example.org +# ignore_dst_ips: 8.8.8.8, 1.1.1.1 +# insert_init_first: false +# tls_out: false +# reinitialize_iptables: false +sidecar: {} + +# Forwarder settings +# forwarder: +# resources: +# limits: +# cpu: 500m +# memory: 500M +# requests: +# cpu: 300m +# memory: 250M +forwarder: {} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/.helmignore b/charts/stackstate/stackstate-k8s-agent/1.0.95/.helmignore new file mode 100644 index 0000000000..15a5c12775 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/.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/ +linter_values.yaml +ci/ +installation/ +logo.svg diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/Chart.lock b/charts/stackstate/stackstate-k8s-agent/1.0.95/Chart.lock new file mode 100644 index 0000000000..a8df83f136 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: http-header-injector + repository: https://helm.stackstate.io + version: 0.0.11 +digest: sha256:ae5ad7c3176f89b71aabef7cd75f99394750f4fffb9905b86fb45c345595c24c +generated: "2024-05-30T13:30:45.346757+02:00" diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/Chart.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/Chart.yaml new file mode 100644 index 0000000000..e2d483e889 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/Chart.yaml @@ -0,0 +1,25 @@ +annotations: + catalog.cattle.io/certified: partner + catalog.cattle.io/display-name: StackState Agent + catalog.cattle.io/kube-version: '>=1.19.0-0' + catalog.cattle.io/release-name: stackstate-k8s-agent +apiVersion: v2 +appVersion: 3.0.0 +dependencies: +- alias: httpHeaderInjectorWebhook + name: http-header-injector + repository: file://./charts/http-header-injector + version: 0.0.11 +description: Helm chart for the StackState Agent. +home: https://github.com/StackVista/stackstate-agent +icon: file://assets/icons/stackstate-k8s-agent.svg +keywords: +- monitoring +- observability +- stackstate +kubeVersion: '>=1.19.0-0' +maintainers: +- email: ops@stackstate.com + name: Stackstate +name: stackstate-k8s-agent +version: 1.0.95 diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/README.md b/charts/stackstate/stackstate-k8s-agent/1.0.95/README.md new file mode 100644 index 0000000000..2776d5774f --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/README.md @@ -0,0 +1,263 @@ +# stackstate-k8s-agent + +Helm chart for the StackState Agent. + +Current chart version is `1.0.95` + +**Homepage:** + +## Requirements + +| Repository | Name | Version | +|------------|------|---------| +| https://helm.stackstate.io | httpHeaderInjectorWebhook(http-header-injector) | 0.0.11 | + +## Required Values + +In order to successfully install this chart, you **must** provide the following variables: + +* `stackstate.apiKey` +* `stackstate.cluster.name` +* `stackstate.url` + +The parameter `stackstate.cluster.name` is entered when installing the Cluster Agent StackPack. + +Install them on the command line on Helm with the following command: + +```shell +helm install \ +--set-string 'stackstate.apiKey'='' \ +--set-string 'stackstate.cluster.name'='' \ +--set-string 'stackstate.url'='' \ +stackstate/stackstate-k8s-agent +``` + +## Recommended Values + +It is also recommended that you set a value for `stackstate.cluster.authToken`. If it is not provided, a value will be generated for you, but the value will change each time an upgrade is performed. + +The command for **also** installing with a set token would be: + +```shell +helm install \ +--set-string 'stackstate.apiKey'='' \ +--set-string 'stackstate.cluster.name'='' \ +--set-string 'stackstate.cluster.authToken'='' \ +--set-string 'stackstate.url'='' \ +stackstate/stackstate-k8s-agent +``` + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| all.hardening.enabled | bool | `false` | An indication of whether the containers will be evaluated for hardening at runtime | +| all.image.registry | string | `"quay.io"` | The image registry to use. | +| checksAgent.affinity | object | `{}` | Affinity settings for pod assignment. | +| checksAgent.apm.enabled | bool | `true` | Enable / disable the agent APM module. | +| checksAgent.checksTagCardinality | string | `"orchestrator"` | | +| checksAgent.config | object | `{"override":[]}` | | +| checksAgent.config.override | list | `[]` | A list of objects containing three keys `name`, `path` and `data`, specifying filenames at specific paths which need to be (potentially) overridden using a mounted configmap | +| checksAgent.enabled | bool | `true` | Enable / disable runnning cluster checks in a separately deployed pod | +| checksAgent.image.pullPolicy | string | `"IfNotPresent"` | Default container image pull policy. | +| checksAgent.image.repository | string | `"stackstate/stackstate-k8s-agent"` | Base container image repository. | +| checksAgent.image.tag | string | `"10e27026"` | Default container image tag. | +| checksAgent.livenessProbe.enabled | bool | `true` | Enable use of livenessProbe check. | +| checksAgent.livenessProbe.failureThreshold | int | `3` | `failureThreshold` for the liveness probe. | +| checksAgent.livenessProbe.initialDelaySeconds | int | `15` | `initialDelaySeconds` for the liveness probe. | +| checksAgent.livenessProbe.periodSeconds | int | `15` | `periodSeconds` for the liveness probe. | +| checksAgent.livenessProbe.successThreshold | int | `1` | `successThreshold` for the liveness probe. | +| checksAgent.livenessProbe.timeoutSeconds | int | `5` | `timeoutSeconds` for the liveness probe. | +| checksAgent.logLevel | string | `"INFO"` | Logging level for clusterchecks agent processes. | +| checksAgent.networkTracing.enabled | bool | `true` | Enable / disable the agent network tracing module. | +| checksAgent.nodeSelector | object | `{}` | Node labels for pod assignment. | +| checksAgent.priorityClassName | string | `""` | Priority class for clusterchecks agent pods. | +| checksAgent.processAgent.enabled | bool | `true` | Enable / disable the agent process agent module. | +| checksAgent.readinessProbe.enabled | bool | `true` | Enable use of readinessProbe check. | +| checksAgent.readinessProbe.failureThreshold | int | `3` | `failureThreshold` for the readiness probe. | +| checksAgent.readinessProbe.initialDelaySeconds | int | `15` | `initialDelaySeconds` for the readiness probe. | +| checksAgent.readinessProbe.periodSeconds | int | `15` | `periodSeconds` for the readiness probe. | +| checksAgent.readinessProbe.successThreshold | int | `1` | `successThreshold` for the readiness probe. | +| checksAgent.readinessProbe.timeoutSeconds | int | `5` | `timeoutSeconds` for the readiness probe. | +| checksAgent.replicas | int | `1` | Number of clusterchecks agent pods to schedule | +| checksAgent.resources.limits.cpu | string | `"400m"` | CPU resource limits. | +| checksAgent.resources.limits.memory | string | `"600Mi"` | Memory resource limits. | +| checksAgent.resources.requests.cpu | string | `"20m"` | CPU resource requests. | +| checksAgent.resources.requests.memory | string | `"512Mi"` | Memory resource requests. | +| checksAgent.scc.enabled | bool | `false` | Enable / disable the installation of the SecurityContextConfiguration needed for installation on OpenShift | +| checksAgent.serviceaccount.annotations | object | `{}` | Annotations for the service account for the cluster checks pods | +| checksAgent.skipSslValidation | bool | `false` | Set to true if self signed certificates are used. | +| checksAgent.strategy | object | `{"type":"RollingUpdate"}` | The strategy for the Deployment object. | +| checksAgent.tolerations | list | `[]` | Toleration labels for pod assignment. | +| clusterAgent.affinity | object | `{}` | Affinity settings for pod assignment. | +| clusterAgent.collection.kubeStateMetrics.annotationsAsTags | object | `{}` | Extra annotations to collect from resources and to turn into StackState tag. | +| clusterAgent.collection.kubeStateMetrics.clusterCheck | bool | `false` | For large clusters where the Kubernetes State Metrics Check Core needs to be distributed on dedicated workers. | +| clusterAgent.collection.kubeStateMetrics.enabled | bool | `true` | Enable / disable the cluster agent kube-state-metrics collection. | +| clusterAgent.collection.kubeStateMetrics.labelsAsTags | object | `{}` | Extra labels to collect from resources and to turn into StackState tag. # It has the following structure: # labelsAsTags: # : # can be pod, deployment, node, etc. # : # where is the kubernetes label and is the StackState tag # : # : # : # # Warning: the label must match the transformation done by kube-state-metrics, # for example tags.stackstate/version becomes tags_stackstate_version. | +| clusterAgent.collection.kubernetesEvents | bool | `true` | Enable / disable the cluster agent events collection. | +| clusterAgent.collection.kubernetesMetrics | bool | `true` | Enable / disable the cluster agent metrics collection. | +| clusterAgent.collection.kubernetesResources.configmaps | bool | `true` | Enable / disable collection of ConfigMaps. | +| clusterAgent.collection.kubernetesResources.cronjobs | bool | `true` | Enable / disable collection of CronJobs. | +| clusterAgent.collection.kubernetesResources.daemonsets | bool | `true` | Enable / disable collection of DaemonSets. | +| clusterAgent.collection.kubernetesResources.deployments | bool | `true` | Enable / disable collection of Deployments. | +| clusterAgent.collection.kubernetesResources.endpoints | bool | `true` | Enable / disable collection of Endpoints. If endpoints are disabled then StackState won't be able to connect a Service to Pods that serving it | +| clusterAgent.collection.kubernetesResources.horizontalpodautoscalers | bool | `true` | Enable / disable collection of HorizontalPodAutoscalers. | +| clusterAgent.collection.kubernetesResources.ingresses | bool | `true` | Enable / disable collection of Ingresses. | +| clusterAgent.collection.kubernetesResources.jobs | bool | `true` | Enable / disable collection of Jobs. | +| clusterAgent.collection.kubernetesResources.limitranges | bool | `true` | Enable / disable collection of LimitRanges. | +| clusterAgent.collection.kubernetesResources.namespaces | bool | `true` | Enable / disable collection of Namespaces. | +| clusterAgent.collection.kubernetesResources.persistentvolumeclaims | bool | `true` | Enable / disable collection of PersistentVolumeClaims. Disabling these will not let StackState connect PersistentVolumes to pods they are attached to | +| clusterAgent.collection.kubernetesResources.persistentvolumes | bool | `true` | Enable / disable collection of PersistentVolumes. | +| clusterAgent.collection.kubernetesResources.poddisruptionbudgets | bool | `true` | Enable / disable collection of PodDisruptionBudgets. | +| clusterAgent.collection.kubernetesResources.replicasets | bool | `true` | Enable / disable collection of ReplicaSets. | +| clusterAgent.collection.kubernetesResources.replicationcontrollers | bool | `true` | Enable / disable collection of ReplicationControllers. | +| clusterAgent.collection.kubernetesResources.resourcequotas | bool | `true` | Enable / disable collection of ResourceQuotas. | +| clusterAgent.collection.kubernetesResources.secrets | bool | `true` | Enable / disable collection of Secrets. | +| clusterAgent.collection.kubernetesResources.statefulsets | bool | `true` | Enable / disable collection of StatefulSets. | +| clusterAgent.collection.kubernetesResources.storageclasses | bool | `true` | Enable / disable collection of StorageClasses. | +| clusterAgent.collection.kubernetesResources.volumeattachments | bool | `true` | Enable / disable collection of Volume Attachments. Used to bind Nodes to Persistent Volumes. | +| clusterAgent.collection.kubernetesTimeout | int | `10` | Default timeout (in seconds) when obtaining information from the Kubernetes API. | +| clusterAgent.collection.kubernetesTopology | bool | `true` | Enable / disable the cluster agent topology collection. | +| clusterAgent.config | object | `{"configMap":{"maxDataSize":null},"events":{"categories":{}},"override":[],"topology":{"collectionInterval":90}}` | | +| clusterAgent.config.configMap.maxDataSize | string | `nil` | Maximum amount of characters for the data property of a ConfigMap collected by the kubernetes topology check | +| clusterAgent.config.events.categories | object | `{}` | Custom mapping from Kubernetes event reason to StackState event category. Categories allowed: Alerts, Activities, Changes, Others | +| clusterAgent.config.override | list | `[]` | A list of objects containing three keys `name`, `path` and `data`, specifying filenames at specific paths which need to be (potentially) overridden using a mounted configmap | +| clusterAgent.config.topology.collectionInterval | int | `90` | Interval for running topology collection, in seconds | +| clusterAgent.enabled | bool | `true` | Enable / disable the cluster agent. | +| clusterAgent.image.pullPolicy | string | `"IfNotPresent"` | Default container image pull policy. | +| clusterAgent.image.repository | string | `"stackstate/stackstate-k8s-cluster-agent"` | Base container image repository. | +| clusterAgent.image.tag | string | `"10e27026"` | Default container image tag. | +| clusterAgent.livenessProbe.enabled | bool | `true` | Enable use of livenessProbe check. | +| clusterAgent.livenessProbe.failureThreshold | int | `3` | `failureThreshold` for the liveness probe. | +| clusterAgent.livenessProbe.initialDelaySeconds | int | `15` | `initialDelaySeconds` for the liveness probe. | +| clusterAgent.livenessProbe.periodSeconds | int | `15` | `periodSeconds` for the liveness probe. | +| clusterAgent.livenessProbe.successThreshold | int | `1` | `successThreshold` for the liveness probe. | +| clusterAgent.livenessProbe.timeoutSeconds | int | `5` | `timeoutSeconds` for the liveness probe. | +| clusterAgent.logLevel | string | `"INFO"` | Logging level for stackstate-k8s-agent processes. | +| clusterAgent.nodeSelector | object | `{}` | Node labels for pod assignment. | +| clusterAgent.priorityClassName | string | `""` | Priority class for stackstate-k8s-agent pods. | +| clusterAgent.readinessProbe.enabled | bool | `true` | Enable use of readinessProbe check. | +| clusterAgent.readinessProbe.failureThreshold | int | `3` | `failureThreshold` for the readiness probe. | +| clusterAgent.readinessProbe.initialDelaySeconds | int | `15` | `initialDelaySeconds` for the readiness probe. | +| clusterAgent.readinessProbe.periodSeconds | int | `15` | `periodSeconds` for the readiness probe. | +| clusterAgent.readinessProbe.successThreshold | int | `1` | `successThreshold` for the readiness probe. | +| clusterAgent.readinessProbe.timeoutSeconds | int | `5` | `timeoutSeconds` for the readiness probe. | +| clusterAgent.replicaCount | int | `1` | Number of replicas of the cluster agent to deploy. | +| clusterAgent.resources.limits.cpu | string | `"400m"` | CPU resource limits. | +| clusterAgent.resources.limits.memory | string | `"800Mi"` | Memory resource limits. | +| clusterAgent.resources.requests.cpu | string | `"70m"` | CPU resource requests. | +| clusterAgent.resources.requests.memory | string | `"512Mi"` | Memory resource requests. | +| clusterAgent.service.port | int | `5005` | Change the Cluster Agent service port | +| clusterAgent.service.targetPort | int | `5005` | Change the Cluster Agent service targetPort | +| clusterAgent.serviceaccount.annotations | object | `{}` | Annotations for the service account for the cluster agent pods | +| clusterAgent.skipSslValidation | bool | `false` | If true, ignores the server certificate being signed by an unknown authority. | +| clusterAgent.strategy | object | `{"type":"RollingUpdate"}` | The strategy for the Deployment object. | +| clusterAgent.tolerations | list | `[]` | Toleration labels for pod assignment. | +| fullnameOverride | string | `""` | Override the fullname of the chart. | +| global.extraAnnotations | object | `{}` | Extra annotations added ta all resources created by the helm chart | +| global.extraEnv.open | object | `{}` | Extra open environment variables to inject into pods. | +| global.extraEnv.secret | object | `{}` | Extra secret environment variables to inject into pods via a `Secret` object. | +| global.extraLabels | object | `{}` | Extra labels added ta all resources created by the helm chart | +| global.imagePullCredentials | object | `{}` | Globally define credentials for pulling images. | +| global.imagePullSecrets | list | `[]` | Secrets / credentials needed for container image registry. | +| global.proxy.url | string | `""` | Proxy for all traffic to stackstate | +| global.skipSslValidation | bool | `false` | Enable tls validation from client | +| httpHeaderInjectorWebhook.enabled | bool | `false` | Enable the webhook for injection http header injection sidecar proxy | +| logsAgent.affinity | object | `{}` | Affinity settings for pod assignment. | +| logsAgent.enabled | bool | `true` | Enable / disable k8s pod log collection | +| logsAgent.image.pullPolicy | string | `"IfNotPresent"` | Default container image pull policy. | +| logsAgent.image.repository | string | `"stackstate/promtail"` | Base container image repository. | +| logsAgent.image.tag | string | `"2.9.8-5b179aee"` | Default container image tag. | +| logsAgent.nodeSelector | object | `{}` | Node labels for pod assignment. | +| logsAgent.priorityClassName | string | `""` | Priority class for logsAgent pods. | +| logsAgent.resources.limits.cpu | string | `"1300m"` | CPU resource limits. | +| logsAgent.resources.limits.memory | string | `"192Mi"` | Memory resource limits. | +| logsAgent.resources.requests.cpu | string | `"20m"` | CPU resource requests. | +| logsAgent.resources.requests.memory | string | `"100Mi"` | Memory resource requests. | +| logsAgent.serviceaccount.annotations | object | `{}` | Annotations for the service account for the daemonset pods | +| logsAgent.skipSslValidation | bool | `false` | If true, ignores the server certificate being signed by an unknown authority. | +| logsAgent.tolerations | list | `[]` | Toleration labels for pod assignment. | +| logsAgent.updateStrategy | object | `{"rollingUpdate":{"maxUnavailable":100},"type":"RollingUpdate"}` | The update strategy for the DaemonSet object. | +| nameOverride | string | `""` | Override the name of the chart. | +| nodeAgent.affinity | object | `{}` | Affinity settings for pod assignment. | +| nodeAgent.apm.enabled | bool | `true` | Enable / disable the nodeAgent APM module. | +| nodeAgent.autoScalingEnabled | bool | `false` | Enable / disable autoscaling for the node agent pods. | +| nodeAgent.checksTagCardinality | string | `"orchestrator"` | low, orchestrator or high. Orchestrator level adds pod_name, high adds display_container_name | +| nodeAgent.config | object | `{"override":[]}` | | +| nodeAgent.config.override | list | `[]` | A list of objects containing three keys `name`, `path` and `data`, specifying filenames at specific paths which need to be (potentially) overridden using a mounted configmap | +| nodeAgent.containerRuntime.customSocketPath | string | `""` | If the container socket path does not match the default for CRI-O, Containerd or Docker, supply a custom socket path. | +| nodeAgent.containerRuntime.hostProc | string | `"/proc"` | | +| nodeAgent.containers.agent.env | object | `{}` | Additional environment variables for the agent container | +| nodeAgent.containers.agent.image.pullPolicy | string | `"IfNotPresent"` | Default container image pull policy. | +| nodeAgent.containers.agent.image.repository | string | `"stackstate/stackstate-k8s-agent"` | Base container image repository. | +| nodeAgent.containers.agent.image.tag | string | `"10e27026"` | Default container image tag. | +| nodeAgent.containers.agent.livenessProbe.enabled | bool | `true` | Enable use of livenessProbe check. | +| nodeAgent.containers.agent.livenessProbe.failureThreshold | int | `3` | `failureThreshold` for the liveness probe. | +| nodeAgent.containers.agent.livenessProbe.initialDelaySeconds | int | `15` | `initialDelaySeconds` for the liveness probe. | +| nodeAgent.containers.agent.livenessProbe.periodSeconds | int | `15` | `periodSeconds` for the liveness probe. | +| nodeAgent.containers.agent.livenessProbe.successThreshold | int | `1` | `successThreshold` for the liveness probe. | +| nodeAgent.containers.agent.livenessProbe.timeoutSeconds | int | `5` | `timeoutSeconds` for the liveness probe. | +| nodeAgent.containers.agent.logLevel | string | `nil` | Set logging verbosity, valid log levels are: trace, debug, info, warn, error, critical, and off # If not set, fall back to the value of agent.logLevel. | +| nodeAgent.containers.agent.processAgent.enabled | bool | `false` | Enable / disable the agent process agent module. - deprecated | +| nodeAgent.containers.agent.readinessProbe.enabled | bool | `true` | Enable use of readinessProbe check. | +| nodeAgent.containers.agent.readinessProbe.failureThreshold | int | `3` | `failureThreshold` for the readiness probe. | +| nodeAgent.containers.agent.readinessProbe.initialDelaySeconds | int | `15` | `initialDelaySeconds` for the readiness probe. | +| nodeAgent.containers.agent.readinessProbe.periodSeconds | int | `15` | `periodSeconds` for the readiness probe. | +| nodeAgent.containers.agent.readinessProbe.successThreshold | int | `1` | `successThreshold` for the readiness probe. | +| nodeAgent.containers.agent.readinessProbe.timeoutSeconds | int | `5` | `timeoutSeconds` for the readiness probe. | +| nodeAgent.containers.agent.resources.limits.cpu | string | `"270m"` | CPU resource limits. | +| nodeAgent.containers.agent.resources.limits.memory | string | `"420Mi"` | Memory resource limits. | +| nodeAgent.containers.agent.resources.requests.cpu | string | `"20m"` | CPU resource requests. | +| nodeAgent.containers.agent.resources.requests.memory | string | `"180Mi"` | Memory resource requests. | +| nodeAgent.containers.processAgent.enabled | bool | `true` | Enable / disable the process agent container. | +| nodeAgent.containers.processAgent.env | object | `{}` | Additional environment variables for the process-agent container | +| nodeAgent.containers.processAgent.image.pullPolicy | string | `"IfNotPresent"` | Process-agent container image pull policy. | +| nodeAgent.containers.processAgent.image.registry | string | `nil` | | +| nodeAgent.containers.processAgent.image.repository | string | `"stackstate/stackstate-k8s-process-agent"` | Process-agent container image repository. | +| nodeAgent.containers.processAgent.image.tag | string | `"cae7a4fa"` | Default process-agent container image tag. | +| nodeAgent.containers.processAgent.logLevel | string | `nil` | Set logging verbosity, valid log levels are: trace, debug, info, warn, error, critical, and off # If not set, fall back to the value of agent.logLevel. | +| nodeAgent.containers.processAgent.procVolumeReadOnly | bool | `true` | Configure whether /host/proc is read only for the process agent container | +| nodeAgent.containers.processAgent.resources.limits.cpu | string | `"125m"` | CPU resource limits. | +| nodeAgent.containers.processAgent.resources.limits.memory | string | `"400Mi"` | Memory resource limits. | +| nodeAgent.containers.processAgent.resources.requests.cpu | string | `"25m"` | CPU resource requests. | +| nodeAgent.containers.processAgent.resources.requests.memory | string | `"128Mi"` | Memory resource requests. | +| nodeAgent.httpTracing.enabled | bool | `true` | | +| nodeAgent.logLevel | string | `"INFO"` | Logging level for agent processes. | +| nodeAgent.networkTracing.enabled | bool | `true` | Enable / disable the nodeAgent network tracing module. | +| nodeAgent.nodeSelector | object | `{}` | Node labels for pod assignment. | +| nodeAgent.priorityClassName | string | `""` | Priority class for nodeAgent pods. | +| nodeAgent.protocolInspection.enabled | bool | `true` | Enable / disable the nodeAgent protocol inspection. | +| nodeAgent.scaling.autoscalerLimits.agent.maximum.cpu | string | `"200m"` | Maximum CPU resource limits for main agent. | +| nodeAgent.scaling.autoscalerLimits.agent.maximum.memory | string | `"450Mi"` | Maximum memory resource limits for main agent. | +| nodeAgent.scaling.autoscalerLimits.agent.minimum.cpu | string | `"20m"` | Minimum CPU resource limits for main agent. | +| nodeAgent.scaling.autoscalerLimits.agent.minimum.memory | string | `"180Mi"` | Minimum memory resource limits for main agent. | +| nodeAgent.scaling.autoscalerLimits.processAgent.maximum.cpu | string | `"200m"` | Maximum CPU resource limits for process agent. | +| nodeAgent.scaling.autoscalerLimits.processAgent.maximum.memory | string | `"500Mi"` | Maximum memory resource limits for process agent. | +| nodeAgent.scaling.autoscalerLimits.processAgent.minimum.cpu | string | `"25m"` | Minimum CPU resource limits for process agent. | +| nodeAgent.scaling.autoscalerLimits.processAgent.minimum.memory | string | `"100Mi"` | Minimum memory resource limits for process agent. | +| nodeAgent.scc.enabled | bool | `false` | Enable / disable the installation of the SecurityContextConfiguration needed for installation on OpenShift. | +| nodeAgent.service | object | `{"annotations":{},"loadBalancerSourceRanges":["10.0.0.0/8"],"type":"ClusterIP"}` | The Kubernetes service for the agent | +| nodeAgent.service.annotations | object | `{}` | Annotations for the service | +| nodeAgent.service.loadBalancerSourceRanges | list | `["10.0.0.0/8"]` | The IP4 CIDR allowed to reach LoadBalancer for the service. For LoadBalancer type of service only. | +| nodeAgent.service.type | string | `"ClusterIP"` | Type of Kubernetes service: ClusterIP, LoadBalancer, NodePort | +| nodeAgent.serviceaccount.annotations | object | `{}` | Annotations for the service account for the agent daemonset pods | +| nodeAgent.skipKubeletTLSVerify | bool | `false` | Set to true if you want to skip kubelet tls verification. | +| nodeAgent.skipSslValidation | bool | `false` | Set to true if self signed certificates are used. | +| nodeAgent.tolerations | list | `[]` | Toleration labels for pod assignment. | +| nodeAgent.updateStrategy | object | `{"rollingUpdate":{"maxUnavailable":100},"type":"RollingUpdate"}` | The update strategy for the DaemonSet object. | +| openShiftLogging.installSecret | bool | `false` | Install a secret for logging on openshift | +| processAgent.checkIntervals.connections | int | `30` | Override the default value of the connections check interval in seconds. | +| processAgent.checkIntervals.container | int | `28` | Override the default value of the container check interval in seconds. | +| processAgent.checkIntervals.process | int | `32` | Override the default value of the process check interval in seconds. | +| processAgent.softMemoryLimit.goMemLimit | string | `"340MiB"` | Soft-limit for golang heap allocation, for sanity, must be around 85% of nodeAgent.containers.processAgent.resources.limits.cpu. | +| processAgent.softMemoryLimit.httpObservationsBufferSize | int | `40000` | Sets a maximum for the number of http observations to keep in memory between check runs, to use 40k requires around ~400Mib of memory. | +| processAgent.softMemoryLimit.httpStatsBufferSize | int | `40000` | Sets a maximum for the number of http stats to keep in memory between check runs, to use 40k requires around ~400Mib of memory. | +| stackstate.apiKey | string | `nil` | **PROVIDE YOUR API KEY HERE** API key to be used by the StackState agent. | +| stackstate.cluster.authToken | string | `""` | Provide a token to enable secure communication between the agent and the cluster agent. | +| stackstate.cluster.name | string | `nil` | **PROVIDE KUBERNETES CLUSTER NAME HERE** Name of the Kubernetes cluster where the agent will be installed. | +| stackstate.customApiKeySecretKey | string | `"sts-api-key"` | Key in the secret containing the receiver API key. | +| stackstate.customClusterAuthTokenSecretKey | string | `"sts-cluster-auth-token"` | Key in the secret containing the cluster auth token. | +| stackstate.customSecretName | string | `""` | Name of the secret containing the receiver API key. | +| stackstate.manageOwnSecrets | bool | `false` | Set to true if you don't want this helm chart to create secrets for you. | +| stackstate.url | string | `nil` | **PROVIDE STACKSTATE URL HERE** URL of the StackState installation to receive data from the agent. | +| targetSystem | string | `"linux"` | Target OS for this deployment (possible values: linux) | diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/README.md.gotmpl b/charts/stackstate/stackstate-k8s-agent/1.0.95/README.md.gotmpl new file mode 100644 index 0000000000..7909e6f0d7 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/README.md.gotmpl @@ -0,0 +1,45 @@ +{{ template "chart.header" . }} +{{ template "chart.description" . }} + +Current chart version is `{{ template "chart.version" . }}` + +{{ template "chart.homepageLine" . }} + +{{ template "chart.requirementsSection" . }} + +## Required Values + +In order to successfully install this chart, you **must** provide the following variables: + +* `stackstate.apiKey` +* `stackstate.cluster.name` +* `stackstate.url` + +The parameter `stackstate.cluster.name` is entered when installing the Cluster Agent StackPack. + +Install them on the command line on Helm with the following command: + +```shell +helm install \ +--set-string 'stackstate.apiKey'='' \ +--set-string 'stackstate.cluster.name'='' \ +--set-string 'stackstate.url'='' \ +stackstate/stackstate-k8s-agent +``` + +## Recommended Values + +It is also recommended that you set a value for `stackstate.cluster.authToken`. If it is not provided, a value will be generated for you, but the value will change each time an upgrade is performed. + +The command for **also** installing with a set token would be: + +```shell +helm install \ +--set-string 'stackstate.apiKey'='' \ +--set-string 'stackstate.cluster.name'='' \ +--set-string 'stackstate.cluster.authToken'='' \ +--set-string 'stackstate.url'='' \ +stackstate/stackstate-k8s-agent +``` + +{{ template "chart.valuesSection" . }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/Releasing.md b/charts/stackstate/stackstate-k8s-agent/1.0.95/Releasing.md new file mode 100644 index 0000000000..bab6c2b944 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/Releasing.md @@ -0,0 +1,15 @@ +To make a new release of this helm chart, follow the following steps: + + +- Create a branch from master +- Set the latest tags for the docker images, based on the dev settings (while we do not promote to prod, the moment we promote to prod we should take those tags) from https://gitlab.com/stackvista/devops/agent-promoter/-/blob/master/config.yml. Set the value to the folowing keys: + * stackstate-k8s-cluster-agent: + * [clusterAgent.image.tag] + * stackstate-k8s-agent: + * [nodeAgent.containers.agent.image.tag] + * [checksAgent.image.tag] + * stackstate-k8s-process-agent: + * [nodeAgent.containers.processAgent.image.tag] +- Bump the version of the chart +- Merge the mr and hit the public release button on the ci pipeline +- Manually smoke-test (deploy) the newly released stackstate/stackstate-k8s-agent chart to make sure it runs diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/app-readme.md b/charts/stackstate/stackstate-k8s-agent/1.0.95/app-readme.md new file mode 100644 index 0000000000..8025fe1d36 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/app-readme.md @@ -0,0 +1,5 @@ +## Introduction + +StackState is a modern Application Troubleshooting and Observability solution designed for the rapid evolving engineering landscape. With specific enhancements for Kubernetes environments it empowers engineers, allowing them to remediate application issues independently in production. + +The StackState Agent auto-discovers your entire environment in minutes, assimilating topology, logs, metrics, and events and sends this of to the StackState server. By using StackState you're able to tracke all activity in your environment in real-time and over time. StackState provides instant understanding of the business impact of an issue, offering end-to-end chain observability and ensuring that you can quickly correlate any product or environmental changes to the overall health of your cloud-native implementation. diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/.helmignore b/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/.helmignore new file mode 100644 index 0000000000..69790771c9 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/.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 +.vscode/ +linter_values.yaml +ci/ +installation/ diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/Chart.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/Chart.yaml new file mode 100644 index 0000000000..ff28ae8dab --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/Chart.yaml @@ -0,0 +1,15 @@ +apiVersion: v2 +appVersion: 0.0.1 +description: 'Helm chart for deploying the http-header-injector sidecar, which automatically + injects x-request-id into http traffic going through the cluster for pods which + have the annotation `http-header-injector.stackstate.io/inject: enabled` is set. ' +home: https://github.com/StackVista/http-header-injector +icon: https://www.stackstate.com/wp-content/uploads/2019/02/152x152-favicon.png +keywords: +- monitoring +- stackstate +maintainers: +- email: ops@stackstate.com + name: Stackstate Lupulus Team +name: http-header-injector +version: 0.0.11 diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/README.md b/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/README.md new file mode 100644 index 0000000000..840ff52404 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/README.md @@ -0,0 +1,56 @@ +# http-header-injector + +![Version: 0.0.11](https://img.shields.io/badge/Version-0.0.11-informational?style=flat-square) ![AppVersion: 0.0.1](https://img.shields.io/badge/AppVersion-0.0.1-informational?style=flat-square) + +Helm chart for deploying the http-header-injector sidecar, which automatically injects x-request-id into http traffic +going through the cluster for pods which have the annotation `http-header-injector.stackstate.io/inject: enabled` is set. + +**Homepage:** + +## Maintainers + +| Name | Email | Url | +| ---- | ------ | --- | +| Stackstate Lupulus Team | | | + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| certificatePrehook | object | `{"image":{"pullPolicy":"IfNotPresent","registry":null,"repository":"stackstate/container-tools","tag":"1.4.0"},"resources":{"limits":{"cpu":"100m","memory":"200Mi"},"requests":{"cpu":"100m","memory":"200Mi"}}}` | Helm prehook to setup/remove a certificate for the sidecarInjector mutationwebhook | +| certificatePrehook.image.pullPolicy | string | `"IfNotPresent"` | Policy when pulling an image | +| certificatePrehook.image.registry | string | `nil` | Registry for the docker image. | +| certificatePrehook.image.tag | string | `"1.4.0"` | The tag for the docker image | +| debug | bool | `false` | Enable debugging. This will leave leave artifacts around like the prehook jobs for further inspection | +| enabled | bool | `true` | Enable/disable the mutationwebhook | +| global.extraAnnotations | object | `{}` | Extra annotations added ta all resources created by the helm chart | +| global.extraLabels | object | `{}` | Extra labels added ta all resources created by the helm chart | +| global.imagePullCredentials | object | `{}` | Globally define credentials for pulling images. | +| global.imagePullSecrets | list | `[]` | Globally add image pull secrets that are used. | +| global.imageRegistry | string | `nil` | Globally override the image registry that is used. Can be overridden by specific containers. Defaults to quay.io | +| images.pullSecretName | string | `nil` | | +| proxy | object | `{"image":{"pullPolicy":"IfNotPresent","registry":null,"repository":"stackstate/http-header-injector-proxy","tag":"sha-5ff79451"},"resources":{"limits":{"memory":"40Mi"},"requests":{"memory":"25Mi"}}}` | Proxy being injected into pods for rewriting http headers | +| proxy.image.pullPolicy | string | `"IfNotPresent"` | Policy when pulling an image | +| proxy.image.registry | string | `nil` | Registry for the docker image. | +| proxy.image.tag | string | `"sha-5ff79451"` | The tag for the docker image | +| proxy.resources.limits.memory | string | `"40Mi"` | Memory resource limits. | +| proxy.resources.requests.memory | string | `"25Mi"` | Memory resource requests. | +| proxyInit | object | `{"image":{"pullPolicy":"IfNotPresent","registry":null,"repository":"stackstate/http-header-injector-proxy-init","tag":"sha-5ff79451"}}` | InitContainer within pod which redirects traffic to the proxy container. | +| proxyInit.image.pullPolicy | string | `"IfNotPresent"` | Policy when pulling an image | +| proxyInit.image.registry | string | `nil` | Registry for the docker image | +| proxyInit.image.tag | string | `"sha-5ff79451"` | The tag for the docker image | +| sidecarInjector | object | `{"image":{"pullPolicy":"IfNotPresent","registry":null,"repository":"stackstate/generic-sidecar-injector","tag":"sha-9c852245"}}` | Service for injecting the proxy sidecar into pods | +| sidecarInjector.image.pullPolicy | string | `"IfNotPresent"` | Policy when pulling an image | +| sidecarInjector.image.registry | string | `nil` | Registry for the docker image. | +| sidecarInjector.image.tag | string | `"sha-9c852245"` | The tag for the docker image | +| webhook | object | `{"failurePolicy":"Ignore","tls":{"certManager":{"issuer":"","issuerKind":"ClusterIssuer","issuerNamespace":""},"mode":"generated","provided":{"caBundle":"","crt":"","key":""},"secret":{"name":""}}}` | MutationWebhook that will be installed to inject a sidecar into pods | +| webhook.failurePolicy | string | `"Ignore"` | How should the webhook fail? Best is to use Ignore, because there is a brief moment at initialization when the hook s there but the service not. Also, putting this to fail can cause the control plane be unresponsive. | +| webhook.tls.certManager.issuer | string | `""` | The issuer that is used for the webhook. Only used if you set webhook.tls.mode to "cert-manager". | +| webhook.tls.certManager.issuerKind | string | `"ClusterIssuer"` | The issuer kind that is used for the webhook, valid values are "Issuer" or "ClusterIssuer". Only used if you set webhook.tls.mode to "cert-manager". | +| webhook.tls.certManager.issuerNamespace | string | `""` | The namespace the cert-manager issuer is located in. If left empty defaults to the release's namespace that is used for the webhook. Only used if you set webhook.tls.mode to "cert-manager". | +| webhook.tls.mode | string | `"generated"` | The mode for the webhook. Can be "provided", "generated", "secret" or "cert-manager". If you want to use cert-manager, you need to install it first. NOTE: If you choose "generated", additional privileges are required to create the certificate and webhook at runtime. | +| webhook.tls.provided.caBundle | string | `""` | The caBundle that is used for the webhook. This is the certificate that is used to sign the webhook. Only used if you set webhook.tls.mode to "provided". | +| webhook.tls.provided.crt | string | `""` | The certificate that is used for the webhook. Only used if you set webhook.tls.mode to "provided". | +| webhook.tls.provided.key | string | `""` | The key that is used for the webhook. Only used if you set webhook.tls.mode to "provided". | +| webhook.tls.secret.name | string | `""` | The name of the secret containing the pre-provisioned certificate data that is used for the webhook. Only used if you set webhook.tls.mode to "secret". | + diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/Readme.md.gotpl b/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/Readme.md.gotpl new file mode 100644 index 0000000000..225032aa2a --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/Readme.md.gotpl @@ -0,0 +1,26 @@ +{{ template "chart.header" . }} +{{ template "chart.description" . }} + +Current chart version is `{{ template "chart.version" . }}` + +{{ template "chart.homepageLine" . }} + +{{ template "chart.requirementsSection" . }} + +## Required Values + +No values have to be included to install this chart. After installing this chart, it becomes possible to annotate pods with +the `http-header-injector.stackstate.io/inject: enabled` annotation to make sure the sidecar provided by this chart is +activated on a pod. + +## Recommended Values + +{{ template "chart.valuesSection" . -}} + +## Install + +Install from the command line on Helm with the following command: + +```shell +helm install stackstate/http-header-injector +``` diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/_defines.tpl b/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/_defines.tpl new file mode 100644 index 0000000000..ee6b7320ef --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/_defines.tpl @@ -0,0 +1,131 @@ +{{- define "http-header-injector.app.name" -}} +{{ .Release.Name }}-http-header-injector +{{- end -}} + +{{- define "http-header-injector.webhook-service.name" -}} +{{ .Release.Name }}-http-header-injector +{{- end -}} + +{{- define "http-header-injector.webhook-service.fqname" -}} +{{ .Release.Name }}-http-header-injector.{{ .Release.Namespace }}.svc +{{- end -}} + +{{- define "http-header-injector.cert-secret.name" -}} +{{- if eq .Values.webhook.tls.mode "secret" -}} +{{ .Values.webhook.tls.secret.name }} +{{- else -}} +{{ .Release.Name }}-http-injector-cert +{{- end -}} +{{- end -}} + +{{- define "http-header-injector.cert-clusterrole.name" -}} +{{ .Release.Name }}-http-injector-cert-cluster-role +{{- end -}} + +{{- define "http-header-injector.cert-serviceaccount.name" -}} +{{ .Release.Name }}-http-injector-cert-sa +{{- end -}} + +{{- define "http-header-injector.cert-config.name" -}} +{{ .Release.Name }}-cert-config +{{- end -}} + +{{- define "http-header-injector.mutatingwebhookconfiguration.name" -}} +{{ .Release.Name }}-http-header-injector-webhook.stackstate.io +{{- end -}} + +{{- define "http-header-injector.webhook-config.name" -}} +{{ .Release.Name }}-http-header-injector-config +{{- end -}} + +{{- define "http-header-injector.mutating-webhook.name" -}} +{{ .Release.Name }}-http-header-injector-webhook +{{- end -}} + +{{- define "http-header-injector.pull-secret.name" -}} +{{ include "http-header-injector.app.name" . }}-pull-secret +{{- end -}} + +{{/* If the issuer is located in a different namespace, it is possible to set that, else default to the release namespace */}} +{{- define "cert-manager.certificate.namespace" -}} +{{ .Values.webhook.tls.certManager.issuerNamespace | default .Release.Namespace }} +{{- end -}} + +{{- define "http-header-injector.image.registry.global" -}} + {{- if .Values.global }} + {{- .Values.global.imageRegistry | default "quay.io" -}} + {{- else -}} + quay.io + {{- end -}} +{{- end -}} + +{{- define "http-header-injector.image.registry" -}} + {{- if ((.ContainerConfig).image).registry -}} + {{- tpl .ContainerConfig.image.registry . -}} + {{- else -}} + {{- include "http-header-injector.image.registry.global" . }} + {{- end -}} +{{- end -}} + +{{- define "http-header-injector.image.pullSecrets" -}} + {{- $pullSecrets := list }} + {{- $pullSecrets = append $pullSecrets (include "http-header-injector.pull-secret.name" .) }} + {{- range .Values.global.imagePullSecrets -}} + {{- $pullSecrets = append $pullSecrets . -}} + {{- end -}} + {{- if (not (empty $pullSecrets)) -}} +imagePullSecrets: + {{- range $pullSecrets | uniq }} + - name: {{ . }} + {{- end }} + {{- end -}} +{{- end -}} + +{{- define "http-header-injector.cert-setup.container.main" }} +{{- $containerConfig := dict "ContainerConfig" .Values.certificatePrehook -}} +name: webhook-cert-setup +image: "{{ include "http-header-injector.image.registry" (merge $containerConfig .) }}/{{ .Values.certificatePrehook.image.repository }}:{{ .Values.certificatePrehook.image.tag }}" +imagePullPolicy: {{ .Values.certificatePrehook.image.pullPolicy }} +{{- with .Values.certificatePrehook.resources }} +resources: + {{- toYaml . | nindent 2 }} +{{- end }} +volumeMounts: + - name: "{{ include "http-header-injector.cert-config.name" . }}" + mountPath: /scripts + readOnly: true +command: ["/scripts/generate-cert.sh"] +{{- end }} + +{{- define "http-header-injector.cert-delete.container.main" }} +{{- $containerConfig := dict "ContainerConfig" .Values.certificatePrehook -}} +name: webhook-cert-delete +image: "{{ include "http-header-injector.image.registry" (merge $containerConfig .) }}/{{ .Values.certificatePrehook.image.repository }}:{{ .Values.certificatePrehook.image.tag }}" +imagePullPolicy: {{ .Values.certificatePrehook.image.pullPolicy }} +{{- with .Values.certificatePrehook.resources }} +resources: + {{- toYaml . | nindent 2 }} +{{- end }} +volumeMounts: + - name: "{{ include "http-header-injector.cert-config.name" . }}" + mountPath: /scripts +command: [ "/scripts/delete-cert.sh" ] +{{- end }} + +{{/* +Returns a YAML with extra annotations. +*/}} +{{- define "http-header-injector.global.extraAnnotations" -}} +{{- with .Values.global.extraAnnotations }} +{{- toYaml . }} +{{- end }} +{{- end -}} + +{{/* +Returns a YAML with extra labels. +*/}} +{{- define "http-header-injector.global.extraLabels" -}} +{{- with .Values.global.extraLabels }} +{{- toYaml . }} +{{- end }} +{{- end -}} \ No newline at end of file diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/cert-hook-clusterrolbinding.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/cert-hook-clusterrolbinding.yaml new file mode 100644 index 0000000000..fc0c012585 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/cert-hook-clusterrolbinding.yaml @@ -0,0 +1,24 @@ +{{- if eq .Values.webhook.tls.mode "generated" }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: "{{ include "http-header-injector.cert-serviceaccount.name" . }}" + labels: + app.kubernetes.io/component: http-header-injector-cert-hook + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "http-header-injector.app.name" . }} +{{ include "http-header-injector.global.extraLabels" . | indent 4 }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade,post-delete,post-upgrade + "helm.sh/hook-weight": "-3" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +{{ include "http-header-injector.global.extraAnnotations" . | indent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: "{{ include "http-header-injector.cert-clusterrole.name" . }}" +subjects: + - kind: ServiceAccount + name: "{{ include "http-header-injector.cert-serviceaccount.name" . }}" + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/cert-hook-clusterrole.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/cert-hook-clusterrole.yaml new file mode 100644 index 0000000000..afab838b3c --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/cert-hook-clusterrole.yaml @@ -0,0 +1,26 @@ +{{- if eq .Values.webhook.tls.mode "generated" }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: "{{ include "http-header-injector.cert-clusterrole.name" . }}" + labels: + app.kubernetes.io/component: http-header-injector-cert-hook + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "http-header-injector.app.name" . }} +{{ include "http-header-injector.global.extraLabels" . | indent 4 }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade,post-delete,post-upgrade + "helm.sh/hook-weight": "-4" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +{{ include "http-header-injector.global.extraAnnotations" . | indent 4 }} +rules: + - apiGroups: [ "admissionregistration.k8s.io" ] + resources: [ "mutatingwebhookconfigurations" ] + verbs: [ "get", "create", "patch","update","delete" ] + - apiGroups: [ "" ] + resources: [ "secrets" ] + verbs: [ "create", "get", "patch","update","delete" ] + - apiGroups: [ "apps" ] + resources: [ "deployments" ] + verbs: [ "get" ] +{{- end }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/cert-hook-config.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/cert-hook-config.yaml new file mode 100644 index 0000000000..a22bdf4fb9 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/cert-hook-config.yaml @@ -0,0 +1,158 @@ +{{- if eq .Values.webhook.tls.mode "generated" }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: "{{ include "http-header-injector.cert-config.name" . }}" + labels: + app.kubernetes.io/component: http-header-injector-cert-hook + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "http-header-injector.app.name" . }} +{{ include "http-header-injector.global.extraLabels" . | indent 4 }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade,post-delete,post-upgrade + "helm.sh/hook-weight": "-3" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +{{ include "http-header-injector.global.extraAnnotations" . | indent 4 }} +data: + generate-cert.sh: | + #!/bin/bash + + # We are going for a self-signed certificate here. We would like to use k8s CertificateSigningRequest, however, + # currently there are no out of the box signers that can sign a 'server auth' certificate, which is required for mutation webhooks. + set -ex + + SCRIPTDIR="${BASH_SOURCE%/*}" + + DIR=`mktemp -d` + + cd "$DIR" + + {{ if .Values.enabled }} + echo "Chart enabled, creating secret and webhook" + + openssl genrsa -out ca.key 2048 + + openssl req -x509 -new -nodes -key ca.key -subj "/CN={{ include "http-header-injector.webhook-service.fqname" . }}" -days 10000 -out ca.crt + + openssl genrsa -out tls.key 2048 + + openssl req -new -key tls.key -out tls.csr -config "$SCRIPTDIR/csr.conf" + + openssl x509 -req -in tls.csr -CA ca.crt -CAkey ca.key \ + -CAcreateserial -out tls.crt -days 10000 \ + -extensions v3_ext -extfile "$SCRIPTDIR/csr.conf" -sha256 + + # Create or update the secret + echo "Applying secret" + kubectl create secret tls "{{ include "http-header-injector.cert-secret.name" . }}" \ + -n "{{ .Release.Namespace }}" \ + --cert=./tls.crt \ + --key=./tls.key \ + --dry-run=client \ + -o yaml | kubectl apply -f - + + echo "Applying mutationwebhook" + caBundle=`base64 -w 0 ca.crt` + cat "$SCRIPTDIR/mutatingwebhookconfiguration.yaml" | sed "s/\\\$CA_BUNDLE/$caBundle/g" | kubectl apply -f - + {{ else }} + echo "Chart disabled, not creating secret and webhook" + {{ end }} + delete-cert.sh: | + #!/bin/bash + + set -x + + DIR="${BASH_SOURCE%/*}" + if [[ ! -d "$DIR" ]]; then DIR="$PWD"; fi + if [[ "$DIR" = "." ]]; then DIR="$PWD"; fi + + cd "$DIR" + + # Using detection of deployment hee to also make this work in post-delete. + if kubectl get deployments "{{ include "http-header-injector.app.name" . }}" -n "{{ .Release.Namespace }}"; then + echo "Chart enabled, not removing secret and mutationwebhook" + exit 0 + else + echo "Chart disabled, removing secret and mutationwebhook" + fi + + # Create or update the secret + echo "Deleting secret" + kubectl delete secret "{{ include "http-header-injector.cert-secret.name" . }}" -n "{{ .Release.Namespace }}" + + echo "Applying mutationwebhook" + kubectl delete MutatingWebhookConfiguration "{{ include "http-header-injector.mutating-webhook.name" . }}" -n "{{ .Release.Namespace }}" + + exit 0 + + csr.conf: | + [ req ] + default_bits = 2048 + prompt = no + default_md = sha256 + req_extensions = req_ext + distinguished_name = dn + + [ dn ] + C = NL + ST = Utrecht + L = Hilversum + O = StackState + OU = Dev + CN = {{ include "http-header-injector.webhook-service.fqname" . }} + + [ req_ext ] + subjectAltName = @alt_names + + [ alt_names ] + DNS.1 = {{ include "http-header-injector.webhook-service.fqname" . }} + + [ v3_ext ] + authorityKeyIdentifier=keyid,issuer:always + basicConstraints=CA:FALSE + keyUsage=keyEncipherment,dataEncipherment + extendedKeyUsage=serverAuth + subjectAltName=@alt_names + + mutatingwebhookconfiguration.yaml: | + apiVersion: admissionregistration.k8s.io/v1 + kind: MutatingWebhookConfiguration + metadata: + name: "{{ include "http-header-injector.mutating-webhook.name" . }}" + namespace: "{{ .Release.Namespace }}" + labels: +{{ include "http-header-injector.global.extraLabels" . | indent 8 }} + annotations: +{{ include "http-header-injector.global.extraAnnotations" . | indent 8 }} + webhooks: + - clientConfig: + caBundle: "$CA_BUNDLE" + service: + name: "{{ include "http-header-injector.webhook-service.name" . }}" + path: /mutate + namespace: {{ .Release.Namespace }} + port: 8443 + # Putting failure on ignore, not doing so can crash the entire control plane if something goes wrong with the service. + failurePolicy: "{{ .Values.webhook.failurePolicy }}" + name: "{{ include "http-header-injector.mutatingwebhookconfiguration.name" . }}" + namespaceSelector: + matchExpressions: + - key: kubernetes.io/metadata.name + operator: NotIn + values: + - kube-system + - cert-manager + - {{ .Release.Namespace }} + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + resources: + - pods + sideEffects: None + admissionReviewVersions: + - v1 +{{- end }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/cert-hook-job-delete.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/cert-hook-job-delete.yaml new file mode 100644 index 0000000000..6f72ce2478 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/cert-hook-job-delete.yaml @@ -0,0 +1,39 @@ +{{- if eq .Values.webhook.tls.mode "generated" }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ .Release.Name }}-header-injector-cert-delete + labels: + app.kubernetes.io/component: http-header-injector-cert-hook-delete + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "http-header-injector.app.name" . }} +{{ include "http-header-injector.global.extraLabels" . | indent 4 }} + annotations: + "helm.sh/hook": post-delete,post-upgrade + "helm.sh/hook-weight": "-2" + "helm.sh/hook-delete-policy": before-hook-creation{{- if not .Values.debug -}},hook-succeeded{{- end }} +{{ include "http-header-injector.global.extraAnnotations" . | indent 4 }} +spec: + template: + metadata: + labels: + app.kubernetes.io/component: http-header-injector-delete + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "http-header-injector.app.name" . }} +{{ include "http-header-injector.global.extraLabels" . | indent 8 }} + annotations: + checksum/config: {{ include (print $.Template.BasePath "/cert-hook-config.yaml") . | sha256sum }} +{{ include "http-header-injector.global.extraAnnotations" . | indent 8 }} + spec: + serviceAccountName: "{{ include "http-header-injector.cert-serviceaccount.name" . }}" + {{- include "http-header-injector.image.pullSecrets" . | nindent 6 }} + volumes: + - name: "{{ include "http-header-injector.cert-config.name" . }}" + configMap: + name: "{{ include "http-header-injector.cert-config.name" . }}" + defaultMode: 0777 + containers: + - {{ include "http-header-injector.cert-delete.container.main" . | nindent 8 }} + restartPolicy: Never + backoffLimit: 0 +{{- end }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/cert-hook-job-setup.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/cert-hook-job-setup.yaml new file mode 100644 index 0000000000..cc1c89631f --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/cert-hook-job-setup.yaml @@ -0,0 +1,39 @@ +{{- if eq .Values.webhook.tls.mode "generated" }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ .Release.Name }}-header-injector-cert-setup + labels: + app.kubernetes.io/component: http-header-injector-cert-hook-setup + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "http-header-injector.app.name" . }} +{{ include "http-header-injector.global.extraLabels" . | indent 4 }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-weight": "-2" + "helm.sh/hook-delete-policy": before-hook-creation{{- if not .Values.debug -}},hook-succeeded{{- end }} +{{ include "http-header-injector.global.extraAnnotations" . | indent 4 }} +spec: + template: + metadata: + labels: + app.kubernetes.io/component: http-header-injector-setup + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "http-header-injector.app.name" . }} +{{ include "http-header-injector.global.extraLabels" . | indent 8 }} + annotations: + checksum/config: {{ include (print $.Template.BasePath "/cert-hook-config.yaml") . | sha256sum }} +{{ include "http-header-injector.global.extraAnnotations" . | indent 8 }} + spec: + serviceAccountName: "{{ include "http-header-injector.cert-serviceaccount.name" . }}" + {{- include "http-header-injector.image.pullSecrets" . | nindent 6 }} + volumes: + - name: "{{ include "http-header-injector.cert-config.name" . }}" + configMap: + name: "{{ include "http-header-injector.cert-config.name" . }}" + defaultMode: 0777 + containers: + - {{ include "http-header-injector.cert-setup.container.main" . | nindent 8 }} + restartPolicy: Never + backoffLimit: 0 +{{- end }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/cert-hook-serviceaccount.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/cert-hook-serviceaccount.yaml new file mode 100644 index 0000000000..29b26df95b --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/cert-hook-serviceaccount.yaml @@ -0,0 +1,18 @@ +{{- if eq .Values.webhook.tls.mode "generated" }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: "{{ include "http-header-injector.cert-serviceaccount.name" . }}" + namespace: {{ .Release.Namespace }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade,post-delete,post-upgrade + "helm.sh/hook-weight": "-4" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +{{ include "http-header-injector.global.extraAnnotations" . | indent 4 }} + labels: + app.kubernetes.io/component: http-header-injector-cert-hook + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "http-header-injector.app.name" . }} + app: "{{ include "http-header-injector.app.name" . }}" +{{ include "http-header-injector.global.extraLabels" . | indent 4 }} +{{- end }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/pull-secret.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/pull-secret.yaml new file mode 100644 index 0000000000..80b4ee404b --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/pull-secret.yaml @@ -0,0 +1,32 @@ +{{- $defaultRegistry := .Values.global.imageRegistry }} +{{- $top := . }} +{{- $registryAuthMap := dict }} + +{{- range $registry, $credentials := .Values.global.imagePullCredentials }} + {{- $registryAuthDocument := dict -}} + {{- $_ := set $registryAuthDocument "username" $credentials.username }} + {{- $_ := set $registryAuthDocument "password" $credentials.password }} + {{- $authMessage := printf "%s:%s" $registryAuthDocument.username $registryAuthDocument.password | b64enc }} + {{- $_ := set $registryAuthDocument "auth" $authMessage }} + {{- if eq $registry "default" }} + {{- $registryAuthMap := set $registryAuthMap (include "http-header-injector.image.registry.global" $top) $registryAuthDocument }} + {{ else }} + {{- $registryAuthMap := set $registryAuthMap $registry $registryAuthDocument }} + {{- end }} +{{- end }} +{{- $dockerAuthsDocuments := dict "auths" $registryAuthMap }} + +apiVersion: v1 +kind: Secret +metadata: + labels: + app.kubernetes.io/component: http-header-injector + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "http-header-injector.app.name" . }} +{{ include "http-header-injector.global.extraLabels" . | indent 4 }} + annotations: +{{ include "http-header-injector.global.extraAnnotations" . | indent 4 }} + name: {{ include "http-header-injector.pull-secret.name" . }} +data: + .dockerconfigjson: {{ $dockerAuthsDocuments | toJson | b64enc | quote }} +type: kubernetes.io/dockerconfigjson \ No newline at end of file diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/webhook-cert-secret.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/webhook-cert-secret.yaml new file mode 100644 index 0000000000..f571ca86bb --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/webhook-cert-secret.yaml @@ -0,0 +1,18 @@ +{{- if eq .Values.webhook.tls.mode "provided" }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "http-header-injector.cert-secret.name" . }} + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/component: http-header-injector + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "http-header-injector.app.name" . }} +{{ include "http-header-injector.global.extraLabels" . | indent 4 }} + annotations: +{{ include "http-header-injector.global.extraAnnotations" . | indent 4 }} +type: kubernetes.io/tls +data: + tls.crt: {{ .Values.webhook.tls.provided.crt | b64enc }} + tls.key: {{ .Values.webhook.tls.provided.key | b64enc }} +{{- end }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/webhook-certificate.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/webhook-certificate.yaml new file mode 100644 index 0000000000..a68c7c5f62 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/webhook-certificate.yaml @@ -0,0 +1,23 @@ +{{- if eq .Values.webhook.tls.mode "cert-manager" }} +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: {{ include "http-header-injector.webhook-service.name" . }} + namespace: {{ include "cert-manager.certificate.namespace" . }} + labels: + app.kubernetes.io/component: http-header-injector + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "http-header-injector.app.name" . }} +{{ include "http-header-injector.global.extraLabels" . | indent 4 }} + annotations: +{{ include "http-header-injector.global.extraAnnotations" . | indent 4 }} +spec: + secretName: {{ include "http-header-injector.cert-secret.name" . }} + issuerRef: + name: {{ .Values.webhook.tls.certManager.issuer }} + kind: {{ .Values.webhook.tls.certManager.issuerKind }} + dnsNames: + - "{{ include "http-header-injector.webhook-service.name" . }}" + - "{{ include "http-header-injector.webhook-service.name" . }}.{{ .Release.Namespace }}" + - "{{ include "http-header-injector.webhook-service.name" . }}.{{ .Release.Namespace }}.svc" +{{- end }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/webhook-config.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/webhook-config.yaml new file mode 100644 index 0000000000..20b38ce963 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/webhook-config.yaml @@ -0,0 +1,128 @@ +{{- if .Values.enabled -}} +{{- $proxyContainerConfig := dict "ContainerConfig" .Values.proxy -}} +{{- $proxyInitContainerConfig := dict "ContainerConfig" .Values.proxyInit -}} +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/component: http-header-injector + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "http-header-injector.app.name" . }} +{{ include "http-header-injector.global.extraLabels" . | indent 4 }} + annotations: +{{ include "http-header-injector.global.extraAnnotations" . | indent 4 }} + name: {{ .Release.Name }}-http-header-injector-config +data: + sidecarconfig.yaml: | + initContainers: + - name: http-header-proxy-init + image: "{{ include "http-header-injector.image.registry" (merge $proxyInitContainerConfig .) }}/{{ .Values.proxyInit.image.repository }}:{{ .Values.proxyInit.image.tag }}" + imagePullPolicy: {{ .Values.proxyInit.image.pullPolicy }} + command: ["/init-iptables.sh"] + env: + - name: CHART_VERSION + value: "{{ .Chart.Version }}" + - name: PROXY_PORT + value: {% if index .Annotations "config.http-header-injector.stackstate.io/proxy-port" %}"{% index .Annotations "config.http-header-injector.stackstate.io/proxy-port" %}"{% else %}"7060"{% end %} + - name: PROXY_UID + value: {% if index .Annotations "config.http-header-injector.stackstate.io/proxy-uid" %}"{% index .Annotations "config.http-header-injector.stackstate.io/proxy-uid" %}"{% else %}"2103"{% end %} + - name: POD_HOST_NETWORK + value: {% .Spec.HostNetwork %} + {% if eq (index .Annotations "linkerd.io/inject") "enabled" %} + - name: LINKERD + value: true + # Reference: https://linkerd.io/2.13/reference/proxy-configuration/ + - name: LINKERD_PROXY_UID + value: {% if index .Annotations "config.linkerd.io/proxy-uid" %}"{% index .Annotations "config.linkerd.io/proxy-uid" %}"{% else %}"2102"{% end %} + # Due to https://github.com/linkerd/linkerd2/issues/10981 this is now not realy possible, still bringing in the code for future reference + - name: LINKERD_ADMIN_PORT + value: {% if index .Annotations "config.linkerd.io/admin-port" %}"{% index .Annotations "config.linkerd.io/admin-port" %}"{% else %}"4191"{% end %} + {% end %} + securityContext: + allowPrivilegeEscalation: false + capabilities: + add: + - NET_ADMIN + - NET_RAW + privileged: false + readOnlyRootFilesystem: true + runAsNonRoot: false + runAsUser: 0 + seccompProfile: + type: RuntimeDefault + volumeMounts: + # This is required for iptables to be able to run + - mountPath: /run + name: http-header-proxy-init-xtables-lock + + containers: + - name: http-header-proxy + image: "{{ include "http-header-injector.image.registry" (merge $proxyContainerConfig .) }}/{{ .Values.proxy.image.repository }}:{{ .Values.proxy.image.tag }}" + imagePullPolicy: {{ .Values.proxy.image.pullPolicy }} + env: + - name: CHART_VERSION + value: "{{ .Chart.Version }}" + - name: PORT + value: {% if index .Annotations "config.http-header-injector.stackstate.io/proxy-port" %}"{% index .Annotations "config.http-header-injector.stackstate.io/proxy-port" %}"{% else %}"7060"{% end %} + - name: DEBUG + value: {% if index .Annotations "config.http-header-injector.stackstate.io/debug" %}"{% index .Annotations "config.http-header-injector.stackstate.io/debug" %}"{% else %}"disabled"{% end %} + securityContext: + runAsUser: {% if index .Annotations "config.http-header-injector.stackstate.io/proxy-uid" %}{% index .Annotations "config.http-header-injector.stackstate.io/proxy-uid" %}{% else %}2103{% end %} + seccompProfile: + type: RuntimeDefault + {{- with .Values.proxy.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + - name: http-header-inject-debug + image: "{{ include "http-header-injector.image.registry" (merge $proxyContainerConfig .) }}/{{ .Values.proxyInit.image.repository }}:{{ .Values.proxyInit.image.tag }}" + imagePullPolicy: {{ .Values.proxyInit.image.pullPolicy }} + command: ["/bin/sh", "-c", "while echo \"Running\"; do sleep 1; done"] + securityContext: + allowPrivilegeEscalation: false + capabilities: + add: + - NET_ADMIN + - NET_RAW + privileged: false + readOnlyRootFilesystem: true + runAsNonRoot: false + runAsUser: 0 + seccompProfile: + type: RuntimeDefault + volumeMounts: + # This is required for iptables to be able to run + - mountPath: /run + name: http-header-proxy-init-xtables-lock + + volumes: + - emptyDir: {} + name: http-header-proxy-init-xtables-lock + + mutationconfig.yaml: | + mutationConfigs: + - name: "http-header-injector" + annotationNamespace: "http-header-injector.stackstate.io" + annotationTrigger: "inject" + annotationConfig: + volumeMounts: [] + initContainersBeforePodInitContainers: [ "http-header-proxy-init" ] + initContainers: [ "http-header-proxy-init" ] + containers: [ "http-header-proxy" ] + volumes: [ "http-header-proxy-init-xtables-lock" ] + volumeMounts: [ ] + # Namespaces are ignored by the mutatingwebhook + ignoreNamespaces: [ ] + - name: "http-header-injector-debug" + annotationNamespace: "http-header-injector-debug.stackstate.io" + annotationTrigger: "inject" + annotationConfig: + volumeMounts: [] + initContainersBeforePodInitContainers: [ ] + initContainers: [ ] + containers: [ "http-header-inject-debug" ] + volumes: [ "http-header-proxy-init-xtables-lock" ] + volumeMounts: [ ] + # Namespaces are ignored by the mutatingwebhook + ignoreNamespaces: [ ] + {{- end -}} \ No newline at end of file diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/webhook-deployment.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/webhook-deployment.yaml new file mode 100644 index 0000000000..8af6ff51a2 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/webhook-deployment.yaml @@ -0,0 +1,61 @@ +{{- if .Values.enabled -}} +{{- $containerConfig := dict "ContainerConfig" .Values.sidecarInjector -}} +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: http-header-injector + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "http-header-injector.app.name" . }} + app: "{{ include "http-header-injector.app.name" . }}" +{{ include "http-header-injector.global.extraLabels" . | indent 4 }} + annotations: +{{ include "http-header-injector.global.extraAnnotations" . | indent 4 }} + name: "{{ include "http-header-injector.app.name" . }}" +spec: + replicas: 1 + selector: + matchLabels: + app: "{{ include "http-header-injector.app.name" . }}" + template: + metadata: + labels: + app.kubernetes.io/component: http-header-injector + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "http-header-injector.app.name" . }} + app: "{{ include "http-header-injector.app.name" . }}" +{{ include "http-header-injector.global.extraLabels" . | indent 8 }} + annotations: + checksum/config: {{ include (print $.Template.BasePath "/webhook-config.yaml") . | sha256sum }} + # This is here to make sure the generic injector gets restarted and picks up a new secret that may have been generated upon upgrade. + revision: "{{ .Release.Revision }}" +{{ include "http-header-injector.global.extraAnnotations" . | indent 8 }} + name: "{{ include "http-header-injector.app.name" . }}" + spec: + {{- include "http-header-injector.image.pullSecrets" . | nindent 6 }} + volumes: + - name: "{{ include "http-header-injector.webhook-config.name" . }}" + configMap: + name: "{{ include "http-header-injector.webhook-config.name" . }}" + - name: "{{ include "http-header-injector.cert-secret.name" . }}" + secret: + secretName: "{{ include "http-header-injector.cert-secret.name" . }}" + containers: + - image: "{{ include "http-header-injector.image.registry" (merge $containerConfig .) }}/{{ .Values.sidecarInjector.image.repository }}:{{ .Values.sidecarInjector.image.tag }}" + imagePullPolicy: {{ .Values.sidecarInjector.image.pullPolicy }} + name: http-header-injector + volumeMounts: + - name: "{{ include "http-header-injector.webhook-config.name" . }}" + mountPath: /etc/webhook/config + readOnly: true + - name: "{{ include "http-header-injector.cert-secret.name" . }}" + mountPath: /etc/webhook/certs + readOnly: true + command: [ "/sidecarinjector" ] + args: + - --port=8443 + - --sidecar-config-file=/etc/webhook/config/sidecarconfig.yaml + - --mutation-config-file=/etc/webhook/config/mutationconfig.yaml + - --cert-file-path=/etc/webhook/certs/tls.crt + - --key-file-path=/etc/webhook/certs/tls.key +{{- end -}} \ No newline at end of file diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/webhook-mutatingwebhookconfiguration.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/webhook-mutatingwebhookconfiguration.yaml new file mode 100644 index 0000000000..de0acc1dff --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/webhook-mutatingwebhookconfiguration.yaml @@ -0,0 +1,54 @@ +{{- if not (eq .Values.webhook.tls.mode "generated") }} +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + name: "{{ include "http-header-injector.mutating-webhook.name" . }}" + namespace: "{{ .Release.Namespace }}" + labels: + app.kubernetes.io/component: http-header-injector + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "http-header-injector.app.name" . }} +{{ include "http-header-injector.global.extraLabels" . | indent 4 }} + annotations: + {{- if eq .Values.webhook.tls.mode "cert-manager" }} + cert-manager.io/inject-ca-from: {{ include "cert-manager.certificate.namespace" . }}/{{ include "http-header-injector.webhook-service.name" . }} + {{- else if eq .Values.webhook.tls.mode "secret" }} + cert-manager.io/inject-ca-from-secret: {{ .Release.Namespace }}/{{ .Values.webhook.tls.secret.name | required "'webhook.tls.secret.name' is required when webhook.tls.mode is 'secret'" }} + {{- end }} +{{ include "http-header-injector.global.extraAnnotations" . | indent 4 }} +webhooks: + - clientConfig: + {{- if eq .Values.webhook.tls.mode "provided" }} + caBundle: "{{ .Values.webhook.tls.provided.caBundle | b64enc }}" + {{- else if or (eq .Values.webhook.tls.mode "cert-manager") (eq .Values.webhook.tls.mode "secret") }} + caBundle: "" + {{- end }} + service: + name: "{{ include "http-header-injector.webhook-service.name" . }}" + path: /mutate + namespace: {{ .Release.Namespace }} + port: 8443 + # Putting failure on ignore, not doing so can crash the entire control plane if something goes wrong with the service. + failurePolicy: "{{ .Values.webhook.failurePolicy }}" + name: "{{ include "http-header-injector.mutatingwebhookconfiguration.name" . }}" + namespaceSelector: + matchExpressions: + - key: kubernetes.io/metadata.name + operator: NotIn + values: + - kube-system + - cert-manager + - {{ .Release.Namespace }} + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + resources: + - pods + sideEffects: None + admissionReviewVersions: + - v1 +{{- end }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/webhook-service.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/webhook-service.yaml new file mode 100644 index 0000000000..55abdb022c --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/templates/webhook-service.yaml @@ -0,0 +1,20 @@ +{{- if .Values.enabled -}} +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: http-header-injector + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "http-header-injector.app.name" . }} +{{ include "http-header-injector.global.extraLabels" . | indent 4 }} + annotations: +{{ include "http-header-injector.global.extraAnnotations" . | indent 4 }} + name: "{{ include "http-header-injector.webhook-service.name" . }}" +spec: + ports: + - port: 8443 + protocol: TCP + targetPort: 8443 + selector: + app: "{{ include "http-header-injector.app.name" . }}" +{{- end -}} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/values.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/values.yaml new file mode 100644 index 0000000000..a1b4be2fcc --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/charts/http-header-injector/values.yaml @@ -0,0 +1,110 @@ +# enabled -- Enable/disable the mutationwebhook +enabled: true + +# debug -- Enable debugging. This will leave leave artifacts around like the prehook jobs for further inspection +debug: false + +global: + # global.imageRegistry -- Globally override the image registry that is used. Can be overridden by specific containers. Defaults to quay.io + imageRegistry: null + # global.imagePullSecrets -- Globally add image pull secrets that are used. + imagePullSecrets: [] + # global.imagePullCredentials -- Globally define credentials for pulling images. + imagePullCredentials: {} + + # global.extraLabels -- Extra labels added ta all resources created by the helm chart + extraLabels: {} + # global.extraAnnotations -- Extra annotations added ta all resources created by the helm chart + extraAnnotations: {} + +images: + pullSecretName: + +# proxy -- Proxy being injected into pods for rewriting http headers +proxy: + image: + # proxy.image.registry -- Registry for the docker image. + registry: + # proxy.image.repository - Repository for the docker image + repository: "stackstate/http-header-injector-proxy" + # proxy.image.pullPolicy -- Policy when pulling an image + pullPolicy: IfNotPresent + # proxy.image.tag -- The tag for the docker image + tag: sha-5ff79451 + + # proxy.resource -- Resources for the proxy container + resources: + requests: + # proxy.resources.requests.memory -- Memory resource requests. + memory: "25Mi" + limits: + # proxy.resources.limits.memory -- Memory resource limits. + memory: "40Mi" + +# proxyInit -- InitContainer within pod which redirects traffic to the proxy container. +proxyInit: + image: + # proxyInit.image.registry -- Registry for the docker image + registry: + # proxyInit.image.repository - Repository for the docker image + repository: "stackstate/http-header-injector-proxy-init" + # proxyInit.image.pullPolicy -- Policy when pulling an image + pullPolicy: IfNotPresent + # proxyInit.image.tag -- The tag for the docker image + tag: sha-5ff79451 + +# sidecarInjector -- Service for injecting the proxy sidecar into pods +sidecarInjector: + image: + # sidecarInjector.image.registry -- Registry for the docker image. + registry: + # sidecarInjector.image.repository - Repository for the docker image + repository: "stackstate/generic-sidecar-injector" + # sidecarInjector.image.pullPolicy -- Policy when pulling an image + pullPolicy: IfNotPresent + # sidecarInjector.image.tag -- The tag for the docker image + tag: sha-9c852245 + +# certificatePrehook -- Helm prehook to setup/remove a certificate for the sidecarInjector mutationwebhook +certificatePrehook: + image: + # certificatePrehook.image.registry -- Registry for the docker image. + registry: + # certificatePrehook.image.repository - Repository for the docker image. + repository: stackstate/container-tools + # certificatePrehook.image.pullPolicy -- Policy when pulling an image + pullPolicy: IfNotPresent + # certificatePrehook.image.tag -- The tag for the docker image + tag: 1.4.0 + resources: + limits: + cpu: "100m" + memory: "200Mi" + requests: + cpu: "100m" + memory: "200Mi" + +# webhook -- MutationWebhook that will be installed to inject a sidecar into pods +webhook: + # webhook.failurePolicy -- How should the webhook fail? Best is to use Ignore, because there is a brief moment at initialization when the hook s there but the service not. Also, putting this to fail can cause the control plane be unresponsive. + failurePolicy: Ignore + tls: + # webhook.tls.mode -- The mode for the webhook. Can be "provided", "generated", "secret" or "cert-manager". If you want to use cert-manager, you need to install it first. NOTE: If you choose "generated", additional privileges are required to create the certificate and webhook at runtime. + mode: "generated" + provided: + # webhook.tls.provided.caBundle -- The caBundle that is used for the webhook. This is the certificate that is used to sign the webhook. Only used if you set webhook.tls.mode to "provided". + caBundle: "" + # webhook.tls.provided.crt -- The certificate that is used for the webhook. Only used if you set webhook.tls.mode to "provided". + crt: "" + # webhook.tls.provided.key -- The key that is used for the webhook. Only used if you set webhook.tls.mode to "provided". + key: "" + certManager: + # webhook.tls.certManager.issuer -- The issuer that is used for the webhook. Only used if you set webhook.tls.mode to "cert-manager". + issuer: "" + # webhook.tls.certManager.issuerKind -- The issuer kind that is used for the webhook, valid values are "Issuer" or "ClusterIssuer". Only used if you set webhook.tls.mode to "cert-manager". + issuerKind: "ClusterIssuer" + # webhook.tls.certManager.issuerNamespace -- The namespace the cert-manager issuer is located in. If left empty defaults to the release's namespace that is used for the webhook. Only used if you set webhook.tls.mode to "cert-manager". + issuerNamespace: "" + secret: + # webhook.tls.secret.name -- The name of the secret containing the pre-provisioned certificate data that is used for the webhook. Only used if you set webhook.tls.mode to "secret". + name: "" diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/questions.yml b/charts/stackstate/stackstate-k8s-agent/1.0.95/questions.yml new file mode 100644 index 0000000000..5d6e6a0112 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/questions.yml @@ -0,0 +1,184 @@ +questions: + - variable: stackstate.apiKey + label: "StackState API Key" + type: string + description: "The API key for StackState." + required: true + group: General + - variable: stackstate.url + label: "StackState URL" + type: string + description: "The URL where StackState is running." + required: true + group: General + - variable: stackstate.cluster.name + label: "StackState Cluster Name" + type: string + description: "The StackState Cluster Name given when installing the instance of the Kubernetes StackPack in StackState. This is used to identify the cluster in StackState." + required: true + group: General + - variable: all.registry.override + label: "Override Default Image Registry" + type: boolean + description: "Whether or not to override the default image registry." + default: false + group: "General" + show_subquestions_if: true + subquestions: + - variable: all.image.registry + label: "Docker Image Registry" + type: string + description: "The registry to pull the StackState Agent images from." + default: "quay.io" + - variable: global.imagePullCredentials.username + label: "Docker Image Pull Username" + type: string + description: "The username to use when pulling the StackState Agent images." + - variable: global.imagePullCredentials.password + label: "Docker Image Pull Password" + type: secret + description: "The password to use when pulling the StackState Agent images." + - variable: nodeAgent.containers.agent.resources.override + label: "Override Node Agent Resource Allocation" + type: boolean + description: "Whether or not to override the default resources." + default: "false" + group: "Node Agent" + show_subquestions_if: true + subquestions: + - variable: nodeAgent.containers.agent.resources.requests.cpu + label: "CPU Requests" + type: string + description: "The requested CPU for the Node Agent." + default: "20m" + - variable: nodeAgent.containers.agent.resources.requests.memory + label: "Memory Requests" + type: string + description: "The requested memory for the Node Agent." + default: "180Mi" + - variable: nodeAgent.containers.agent.resources.limits.cpu + label: "CPU Limit" + type: string + description: "The CPU limit for the Node Agent." + default: "270m" + - variable: nodeAgent.containers.agent.resources.limits.memory + label: "Memory Limit" + type: string + description: "The memory limit for the Node Agent." + default: "420Mi" + - variable: nodeAgent.containers.processAgent.enabled + label: "Enable Process Agent" + type: boolean + description: "Whether or not to enable the Process Agent." + default: "true" + group: "Process Agent" + - variable: nodeAgent.skipKubeletTLSVerify + label: "Skip Kubelet TLS Verify" + type: boolean + description: "Whether or not to skip TLS verification when connecting to the kubelet API." + default: "true" + group: "Process Agent" + - variable: nodeAgent.containers.processAgent.resources.override + label: "Override Process Agent Resource Allocation" + type: boolean + description: "Whether or not to override the default resources." + default: "false" + group: "Process Agent" + show_subquestions_if: true + subquestions: + - variable: nodeAgent.containers.processAgent.resources.requests.cpu + label: "CPU Requests" + type: string + description: "The requested CPU for the Process Agent." + default: "25m" + - variable: nodeAgent.containers.processAgent.resources.requests.memory + label: "Memory Requests" + type: string + description: "The requested memory for the Process Agent." + default: "128Mi" + - variable: nodeAgent.containers.processAgent.resources.limits.cpu + label: "CPU Limit" + type: string + description: "The CPU limit for the Process Agent." + default: "125m" + - variable: nodeAgent.containers.processAgent.resources.limits.memory + label: "Memory Limit" + type: string + description: "The memory limit for the Process Agent." + default: "400Mi" + - variable: clusterAgent.enabled + label: "Enable Cluster Agent" + type: boolean + description: "Whether or not to enable the Cluster Agent." + default: "true" + group: "Cluster Agent" + - variable: clusterAgent.collection.kubernetesResources.secrets + label: "Collect Secret Resources" + type: boolean + description: | + Whether or not to collect Kubernetes Secrets. + NOTE: StackState will not send the actual data of the secrets, only the metadata and a secure hash of the data. + default: "true" + group: "Cluster Agent" + - variable: clusterAgent.resources.override + label: "Override Cluster Agent Resource Allocation" + type: boolean + description: "Whether or not to override the default resources." + default: "false" + group: "Cluster Agent" + show_subquestions_if: true + subquestions: + - variable: clusterAgent.resources.requests.cpu + label: "CPU Requests" + type: string + description: "The requested CPU for the Cluster Agent." + default: "70m" + - variable: clusterAgent.resources.requests.memory + label: "Memory Requests" + type: string + description: "The requested memory for the Cluster Agent." + default: "512Mi" + - variable: clusterAgent.resources.limits.cpu + label: "CPU Limit" + type: string + description: "The CPU limit for the Cluster Agent." + default: "400m" + - variable: clusterAgent.resources.limits.memory + label: "Memory Limit" + type: string + description: "The memory limit for the Cluster Agent." + default: "800Mi" + - variable: logsAgent.enabled + label: "Enable Logs Agent" + type: boolean + description: "Whether or not to enable the Logs Agent." + default: "true" + group: "Logs Agent" + - variable: logsAgent.resources.override + label: "Override Logs Agent Resource Allocation" + type: boolean + description: "Whether or not to override the default resources." + default: "false" + group: "Logs Agent" + show_subquestions_if: true + subquestions: + - variable: logsAgent.resources.requests.cpu + label: "CPU Requests" + type: string + description: "The requested CPU for the Logs Agent." + default: "20m" + - variable: logsAgent.resources.requests.memory + label: "Memory Requests" + type: string + description: "The requested memory for the Logs Agent." + default: "100Mi" + - variable: logsAgent.resources.limits.cpu + label: "CPU Limit" + type: string + description: "The CPU limit for the Logs Agent." + default: "1300m" + - variable: logsAgent.resources.limits.memory + label: "Memory Limit" + type: string + description: "The memory limit for the Logs Agent." + default: "192Mi" diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/_cluster-agent-kube-state-metrics.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/_cluster-agent-kube-state-metrics.yaml new file mode 100644 index 0000000000..f99fbf6187 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/_cluster-agent-kube-state-metrics.yaml @@ -0,0 +1,62 @@ +{{- define "cluster-agent-kube-state-metrics" -}} +{{- $kubeRes := .Values.clusterAgent.collection.kubernetesResources }} +{{- if .Values.clusterAgent.collection.kubeStateMetrics.clusterCheck }} +cluster_check: true +{{- end }} +init_config: +instances: + - collectors: + - nodes + - pods + - services + {{- if $kubeRes.persistentvolumeclaims }} + - persistentvolumeclaims + {{- end }} + {{- if $kubeRes.persistentvolumes }} + - persistentvolumes + {{- end }} + {{- if $kubeRes.namespaces }} + - namespaces + {{- end }} + {{- if $kubeRes.endpoints }} + - endpoints + {{- end }} + {{- if $kubeRes.daemonsets }} + - daemonsets + {{- end }} + {{- if $kubeRes.deployments }} + - deployments + {{- end }} + {{- if $kubeRes.replicasets }} + - replicasets + {{- end }} + {{- if $kubeRes.statefulsets }} + - statefulsets + {{- end }} + {{- if $kubeRes.cronjobs }} + - cronjobs + {{- end }} + {{- if $kubeRes.jobs }} + - jobs + {{- end }} + {{- if $kubeRes.ingresses }} + - ingresses + {{- end }} + {{- if $kubeRes.secrets }} + - secrets + {{- end }} + - resourcequotas + - replicationcontrollers + - limitranges + - horizontalpodautoscalers + - poddisruptionbudgets + - storageclasses + - volumeattachments + {{- if .Values.clusterAgent.collection.kubeStateMetrics.clusterCheck }} + skip_leader_election: true + {{- end }} + labels_as_tags: + {{ .Values.clusterAgent.collection.kubeStateMetrics.labelsAsTags | toYaml | indent 8 }} + annotations_as_tags: + {{ .Values.clusterAgent.collection.kubeStateMetrics.annotationsAsTags | toYaml | indent 8 }} +{{- end -}} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/_container-agent.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/_container-agent.yaml new file mode 100644 index 0000000000..09f9591c63 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/_container-agent.yaml @@ -0,0 +1,191 @@ +{{- define "container-agent" -}} +- name: node-agent +{{- if .Values.all.hardening.enabled}} + lifecycle: + preStop: + exec: + command: [ "/bin/sh", "-c", "echo 'Giving slim.ai monitor time to submit data...'; sleep 120" ] +{{- end }} + image: "{{ include "stackstate-k8s-agent.imageRegistry" . }}/{{ .Values.nodeAgent.containers.agent.image.repository }}:{{ .Values.nodeAgent.containers.agent.image.tag }}" + imagePullPolicy: "{{ .Values.nodeAgent.containers.agent.image.pullPolicy }}" + env: + {{ include "stackstate-k8s-agent.apiKeyEnv" . | nindent 4 }} + - name: STS_KUBERNETES_KUBELET_HOST + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: KUBERNETES_HOSTNAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: STS_HOSTNAME + value: "$(KUBERNETES_HOSTNAME)-{{ .Values.stackstate.cluster.name}}" + - name: AGENT_VERSION + value: {{ .Values.nodeAgent.containers.agent.image.tag | quote }} + - name: HOST_PROC + value: "/host/proc" + - name: HOST_SYS + value: "/host/sys" + - name: KUBERNETES + value: "true" + - name: STS_APM_ENABLED + value: {{ .Values.nodeAgent.apm.enabled | quote }} + - name: STS_APM_URL + value: {{ include "stackstate-k8s-agent.stackstate.url" . }} + - name: STS_CLUSTER_AGENT_ENABLED + value: {{ .Values.clusterAgent.enabled | quote }} + {{- if .Values.clusterAgent.enabled }} + - name: STS_CLUSTER_AGENT_KUBERNETES_SERVICE_NAME + value: {{ .Release.Name }}-cluster-agent + {{ include "stackstate-k8s-agent.clusterAgentAuthTokenEnv" . | nindent 4 }} + {{- end }} + - name: STS_CLUSTER_NAME + value: {{ .Values.stackstate.cluster.name | quote }} + - name: STS_SKIP_VALIDATE_CLUSTERNAME + value: "true" + - name: STS_CHECKS_TAG_CARDINALITY + value: {{ .Values.nodeAgent.checksTagCardinality | quote }} + {{- if .Values.checksAgent.enabled }} + - name: STS_EXTRA_CONFIG_PROVIDERS + value: "endpointschecks" + {{- end }} + - name: STS_HEALTH_PORT + value: "5555" + - name: STS_LEADER_ELECTION + value: "false" + - name: LOG_LEVEL + value: {{ .Values.nodeAgent.containers.agent.logLevel | default .Values.nodeAgent.logLevel | quote }} + - name: STS_LOG_LEVEL + value: {{ .Values.nodeAgent.containers.agent.logLevel | default .Values.nodeAgent.logLevel | quote }} + - name: STS_NETWORK_TRACING_ENABLED + value: {{ .Values.nodeAgent.networkTracing.enabled | quote }} + - name: STS_PROTOCOL_INSPECTION_ENABLED + value: {{ .Values.nodeAgent.protocolInspection.enabled | quote }} + - name: STS_PROCESS_AGENT_ENABLED + value: {{ .Values.nodeAgent.containers.agent.processAgent.enabled | quote }} + - name: STS_CONTAINER_CHECK_INTERVAL + value: {{ .Values.processAgent.checkIntervals.container | quote }} + - name: STS_CONNECTION_CHECK_INTERVAL + value: {{ .Values.processAgent.checkIntervals.connections | quote }} + - name: STS_PROCESS_CHECK_INTERVAL + value: {{ .Values.processAgent.checkIntervals.process | quote }} + - name: STS_PROCESS_AGENT_URL + value: {{ include "stackstate-k8s-agent.stackstate.url" . }} + + - name: STS_SKIP_SSL_VALIDATION + value: {{ or .Values.global.skipSslValidation .Values.nodeAgent.skipSslValidation | quote }} + - name: STS_SKIP_KUBELET_TLS_VERIFY + value: {{ .Values.nodeAgent.skipKubeletTLSVerify | quote }} + - name: STS_STS_URL + value: {{ include "stackstate-k8s-agent.stackstate.url" . }} + {{- if .Values.nodeAgent.containerRuntime.customSocketPath }} + - name: STS_CRI_SOCKET_PATH + value: {{ .Values.nodeAgent.containerRuntime.customSocketPath }} + {{- end }} + {{- if .Values.global.proxy.url }} + - name: STS_PROXY_HTTPS + value: {{ .Values.global.proxy.url | quote }} + - name: STS_PROXY_HTTP + value: {{ .Values.global.proxy.url | quote }} + {{- end }} + {{- range $key, $value := .Values.global.extraEnv.open }} + - name: {{ $key }} + value: {{ $value | quote }} + {{- end }} + {{- range $key, $value := .Values.global.extraEnv.secret }} + - name: {{ $key }} + valueFrom: + secretKeyRef: + name: {{ include "stackstate-k8s-agent.fullname" . }} + key: {{ $key }} + {{- end }} + {{- range $key, $value := .Values.nodeAgent.containers.agent.env }} + - name: {{ $key }} + value: {{ $value | quote }} + {{- end }} + {{- if .Values.nodeAgent.containers.agent.livenessProbe.enabled }} + livenessProbe: + httpGet: + path: /health + port: healthport + failureThreshold: {{ .Values.nodeAgent.containers.agent.livenessProbe.failureThreshold }} + initialDelaySeconds: {{ .Values.nodeAgent.containers.agent.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.nodeAgent.containers.agent.livenessProbe.periodSeconds }} + successThreshold: {{ .Values.nodeAgent.containers.agent.livenessProbe.successThreshold }} + timeoutSeconds: {{ .Values.nodeAgent.containers.agent.livenessProbe.timeoutSeconds }} + {{- end }} + {{- if .Values.nodeAgent.containers.agent.readinessProbe.enabled }} + readinessProbe: + httpGet: + path: /health + port: healthport + failureThreshold: {{ .Values.nodeAgent.containers.agent.readinessProbe.failureThreshold }} + initialDelaySeconds: {{ .Values.nodeAgent.containers.agent.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.nodeAgent.containers.agent.readinessProbe.periodSeconds }} + successThreshold: {{ .Values.nodeAgent.containers.agent.readinessProbe.successThreshold }} + timeoutSeconds: {{ .Values.nodeAgent.containers.agent.readinessProbe.timeoutSeconds }} + {{- end }} + ports: + - containerPort: 8126 + name: traceport + protocol: TCP + - containerPort: 5555 + name: healthport + protocol: TCP + {{- with .Values.nodeAgent.containers.agent.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + {{- if .Values.nodeAgent.containerRuntime.customSocketPath }} + - name: customcrisocket + mountPath: {{ .Values.nodeAgent.containerRuntime.customSocketPath }} + readOnly: true + {{- end }} + - name: crisocket + mountPath: /var/run/crio/crio.sock + readOnly: true + - name: containerdsocket + mountPath: /var/run/containerd/containerd.sock + readOnly: true + - name: kubelet + mountPath: /var/lib/kubelet + readOnly: true + - name: nfs + mountPath: /var/lib/nfs + readOnly: true + - name: dockersocket + mountPath: /var/run/docker.sock + readOnly: true + - name: dockernetns + mountPath: /run/docker/netns + readOnly: true + - name: dockeroverlay2 + mountPath: /var/lib/docker/overlay2 + readOnly: true + - name: procdir + mountPath: /host/proc + readOnly: true + - name: cgroups + mountPath: /host/sys/fs/cgroup + readOnly: true + {{- if .Values.nodeAgent.config.override }} + {{- range .Values.nodeAgent.config.override }} + - name: config-override-volume + mountPath: {{ .path }}/{{ .name }} + subPath: {{ .path | replace "/" "_"}}_{{ .name }} + readOnly: true + {{- end }} + {{- end }} +{{- if .Values.all.hardening.enabled}} + securityContext: + privileged: true + runAsUser: 0 # root + capabilities: + add: [ "ALL" ] + readOnlyRootFilesystem: false +{{- else }} + securityContext: + privileged: false +{{- end }} +{{- end -}} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/_container-process-agent.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/_container-process-agent.yaml new file mode 100644 index 0000000000..893f11581a --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/_container-process-agent.yaml @@ -0,0 +1,160 @@ +{{- define "container-process-agent" -}} +- name: process-agent +{{ if .Values.nodeAgent.containers.processAgent.image.registry }} + image: "{{ .Values.nodeAgent.containers.processAgent.image.registry }}/{{ .Values.nodeAgent.containers.processAgent.image.repository }}:{{ .Values.nodeAgent.containers.processAgent.image.tag }}" +{{ else }} + image: "{{ include "stackstate-k8s-agent.imageRegistry" . }}/{{ .Values.nodeAgent.containers.processAgent.image.repository }}:{{ .Values.nodeAgent.containers.processAgent.image.tag }}" +{{- end }} + imagePullPolicy: "{{ .Values.nodeAgent.containers.processAgent.image.pullPolicy }}" + ports: + - containerPort: 6063 + env: + {{ include "stackstate-k8s-agent.apiKeyEnv" . | nindent 4 }} + - name: STS_KUBERNETES_KUBELET_HOST + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: KUBERNETES_HOSTNAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: STS_HOSTNAME + value: "$(KUBERNETES_HOSTNAME)-{{ .Values.stackstate.cluster.name}}" + - name: AGENT_VERSION + value: {{ .Values.nodeAgent.containers.processAgent.image.tag | quote }} + - name: STS_LOG_TO_CONSOLE + value: "true" + - name: HOST_PROC + value: "/host/proc" + - name: HOST_SYS + value: "/host/sys" + - name: HOST_ETC + value: "/host/etc" + - name: KUBERNETES + value: "true" + - name: STS_CLUSTER_AGENT_ENABLED + value: {{ .Values.clusterAgent.enabled | quote }} + {{- if .Values.clusterAgent.enabled }} + - name: STS_CLUSTER_AGENT_KUBERNETES_SERVICE_NAME + value: {{ .Release.Name }}-cluster-agent + {{ include "stackstate-k8s-agent.clusterAgentAuthTokenEnv" . | nindent 4 }} + {{- end }} + - name: STS_CLUSTER_NAME + value: {{ .Values.stackstate.cluster.name | quote }} + - name: STS_SKIP_VALIDATE_CLUSTERNAME + value: "true" + - name: LOG_LEVEL + value: {{ .Values.nodeAgent.containers.processAgent.logLevel | default .Values.nodeAgent.logLevel | quote }} + - name: STS_LOG_LEVEL + value: {{ .Values.nodeAgent.containers.processAgent.logLevel | default .Values.nodeAgent.logLevel | quote }} + - name: STS_NETWORK_TRACING_ENABLED + value: {{ .Values.nodeAgent.networkTracing.enabled | quote }} + - name: STS_PROTOCOL_INSPECTION_ENABLED + value: {{ .Values.nodeAgent.protocolInspection.enabled | quote }} + - name: STS_PROCESS_AGENT_ENABLED + value: {{ .Values.nodeAgent.containers.processAgent.enabled | quote }} + - name: STS_CONTAINER_CHECK_INTERVAL + value: {{ .Values.processAgent.checkIntervals.container | quote }} + - name: STS_CONNECTION_CHECK_INTERVAL + value: {{ .Values.processAgent.checkIntervals.connections | quote }} + - name: STS_PROCESS_CHECK_INTERVAL + value: {{ .Values.processAgent.checkIntervals.process | quote }} + - name: GOMEMLIMIT + value: {{ .Values.processAgent.softMemoryLimit.goMemLimit | quote }} + - name: STS_HTTP_STATS_BUFFER_SIZE + value: {{ .Values.processAgent.softMemoryLimit.httpStatsBufferSize | quote }} + - name: STS_HTTP_OBSERVATIONS_BUFFER_SIZE + value: {{ .Values.processAgent.softMemoryLimit.httpObservationsBufferSize | quote }} + - name: STS_PROCESS_AGENT_URL + value: {{ include "stackstate-k8s-agent.stackstate.url" . }} + - name: STS_SKIP_SSL_VALIDATION + value: {{ or .Values.global.skipSslValidation .Values.nodeAgent.skipSslValidation | quote }} + - name: STS_SKIP_KUBELET_TLS_VERIFY + value: {{ .Values.nodeAgent.skipKubeletTLSVerify | quote }} + - name: STS_STS_URL + value: {{ include "stackstate-k8s-agent.stackstate.url" . }} + - name: STS_HTTP_TRACING_ENABLED + value: {{ .Values.nodeAgent.httpTracing.enabled | quote }} + {{- if .Values.nodeAgent.containerRuntime.customSocketPath }} + - name: STS_CRI_SOCKET_PATH + value: {{ .Values.nodeAgent.containerRuntime.customSocketPath }} + {{- end }} + {{- if .Values.global.proxy.url }} + - name: STS_PROXY_HTTPS + value: {{ .Values.global.proxy.url | quote }} + - name: STS_PROXY_HTTP + value: {{ .Values.global.proxy.url | quote }} + {{- end }} + {{- range $key, $value := .Values.global.extraEnv.open }} + - name: {{ $key }} + value: {{ $value | quote }} + {{- end }} + {{- range $key, $value := .Values.global.extraEnv.secret }} + - name: {{ $key }} + valueFrom: + secretKeyRef: + name: {{ include "stackstate-k8s-agent.fullname" . }} + key: {{ $key }} + {{- end }} + {{- range $key, $value := .Values.nodeAgent.containers.processAgent.env }} + - name: {{ $key }} + value: {{ $value | quote }} + {{- end }} + {{- with .Values.nodeAgent.containers.processAgent.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + {{- if .Values.nodeAgent.containerRuntime.customSocketPath }} + - name: customcrisocket + mountPath: {{ .Values.nodeAgent.containerRuntime.customSocketPath }} + readOnly: true + {{- end }} + - name: crisocket + mountPath: /var/run/crio/crio.sock + readOnly: true + - name: containerdsocket + mountPath: /var/run/containerd/containerd.sock + readOnly: true + - name: sys-kernel-debug + mountPath: /sys/kernel/debug + # Having sys-kernel-debug as read only breaks specific monitors from receiving metrics + # readOnly: true + - name: dockersocket + mountPath: /var/run/docker.sock + readOnly: true + # The agent needs access to /etc to figure out what os it is running on. + - name: etcdir + mountPath: /host/etc + readOnly: true + - name: procdir + mountPath: /host/proc + # We have an agent option STS_DISABLE_BPF_JIT_HARDEN that write to /proc. this is a debug setting but if we want to use + # it, we have the option to make /proc writable. + readOnly: {{ .Values.nodeAgent.containers.processAgent.procVolumeReadOnly }} + - name: passwd + mountPath: /etc/passwd + readOnly: true + - name: cgroups + mountPath: /host/sys/fs/cgroup + readOnly: true + {{- if .Values.nodeAgent.config.override }} + {{- range .Values.nodeAgent.config.override }} + - name: config-override-volume + mountPath: {{ .path }}/{{ .name }} + subPath: {{ .path | replace "/" "_"}}_{{ .name }} + readOnly: true + {{- end }} + {{- end }} +{{- if .Values.all.hardening.enabled}} + securityContext: + privileged: true + runAsUser: 0 # root + capabilities: + add: [ "ALL" ] + readOnlyRootFilesystem: false +{{- else }} + securityContext: + privileged: true +{{- end }} +{{- end -}} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/_helpers.tpl b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/_helpers.tpl new file mode 100644 index 0000000000..3c51bc3087 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/_helpers.tpl @@ -0,0 +1,219 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "stackstate-k8s-agent.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 "stackstate-k8s-agent.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 "stackstate-k8s-agent.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Common labels +*/}} +{{- define "stackstate-k8s-agent.labels" -}} +app.kubernetes.io/name: {{ include "stackstate-k8s-agent.name" . }} +helm.sh/chart: {{ include "stackstate-k8s-agent.chart" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end -}} + +{{/* +Cluster agent checksum annotations +*/}} +{{- define "stackstate-k8s-agent.checksum-configs" }} +checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }} +{{- end }} + +{{/* +StackState URL function +*/}} +{{- define "stackstate-k8s-agent.stackstate.url" -}} +{{ tpl .Values.stackstate.url . | quote }} +{{- end }} + +{{- define "stackstate-k8s-agent.configmap.override.checksum" -}} +{{- if .Values.clusterAgent.config.override }} +checksum/override-configmap: {{ include (print $.Template.BasePath "/cluster-agent-configmap.yaml") . | sha256sum }} +{{- end }} +{{- end }} + +{{- define "stackstate-k8s-agent.nodeAgent.configmap.override.checksum" -}} +{{- if .Values.nodeAgent.config.override }} +checksum/override-configmap: {{ include (print $.Template.BasePath "/node-agent-configmap.yaml") . | sha256sum }} +{{- end }} +{{- end }} + +{{- define "stackstate-k8s-agent.logsAgent.configmap.override.checksum" -}} +checksum/override-configmap: {{ include (print $.Template.BasePath "/logs-agent-configmap.yaml") . | sha256sum }} +{{- end }} + +{{- define "stackstate-k8s-agent.checksAgent.configmap.override.checksum" -}} +{{- if .Values.checksAgent.config.override }} +checksum/override-configmap: {{ include (print $.Template.BasePath "/checks-agent-configmap.yaml") . | sha256sum }} +{{- end }} +{{- end }} + + +{{/* +Return the image registry +*/}} +{{- define "stackstate-k8s-agent.imageRegistry" -}} + {{- if .Values.global }} + {{- .Values.global.imageRegistry | default .Values.all.image.registry -}} + {{- else -}} + {{- .Values.all.image.registry -}} + {{- end -}} +{{- end -}} + +{{/* +Renders a value that contains a template. +Usage: +{{ include "stackstate-k8s-agent.tplvalue.render" ( dict "value" .Values.path.to.the.Value "context" $) }} +*/}} +{{- define "stackstate-k8s-agent.tplvalue.render" -}} + {{- if typeIs "string" .value }} + {{- tpl .value .context }} + {{- else }} + {{- tpl (.value | toYaml) .context }} + {{- end }} +{{- end -}} + +{{- define "stackstate-k8s-agent.pull-secret.name" -}} +{{ include "stackstate-k8s-agent.fullname" . }}-pull-secret +{{- end -}} + +{{/* +Return the proper Docker Image Registry Secret Names evaluating values as templates +{{ include "stackstate-k8s-agent.image.pullSecrets" ( dict "images" (list .Values.path.to.the.image1, .Values.path.to.the.image2) "context" $) }} +*/}} +{{- define "stackstate-k8s-agent.image.pullSecrets" -}} + {{- $pullSecrets := list }} + {{- $context := .context }} + {{- if $context.Values.global }} + {{- range $context.Values.global.imagePullSecrets -}} + {{/* Is plain array of strings, compatible with all bitnami charts */}} + {{- $pullSecrets = append $pullSecrets (include "stackstate-k8s-agent.tplvalue.render" (dict "value" . "context" $context)) -}} + {{- end -}} + {{- end -}} + {{- range $context.Values.imagePullSecrets -}} + {{- $pullSecrets = append $pullSecrets (include "stackstate-k8s-agent.tplvalue.render" (dict "value" .name "context" $context)) -}} + {{- end -}} + {{- range .images -}} + {{- if .pullSecretName -}} + {{- $pullSecrets = append $pullSecrets (include "stackstate-k8s-agent.tplvalue.render" (dict "value" .pullSecretName "context" $context)) -}} + {{- end -}} + {{- end -}} + {{- $pullSecrets = append $pullSecrets (include "stackstate-k8s-agent.pull-secret.name" $context) -}} + {{- if (not (empty $pullSecrets)) -}} +imagePullSecrets: + {{- range $pullSecrets | uniq }} + - name: {{ . }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Check whether the kubernetes-state-metrics configuration is overridden. If so, return 'true' else return nothing (which is false). +{{ include "stackstate-k8s-agent.kube-state-metrics.overridden" $ }} +*/}} +{{- define "stackstate-k8s-agent.kube-state-metrics.overridden" -}} +{{- if .Values.clusterAgent.config.override }} + {{- range $i, $val := .Values.clusterAgent.config.override }} + {{- if and (eq $val.name "conf.yaml") (eq $val.path "/etc/stackstate-agent/conf.d/kubernetes_state.d") }} +true + {{- end }} + {{- end }} +{{- end }} +{{- end -}} + +{{- define "stackstate-k8s-agent.nodeAgent.kube-state-metrics.overridden" -}} +{{- if .Values.nodeAgent.config.override }} + {{- range $i, $val := .Values.nodeAgent.config.override }} + {{- if and (eq $val.name "auto_conf.yaml") (eq $val.path "/etc/stackstate-agent/conf.d/kubernetes_state.d") }} +true + {{- end }} + {{- end }} +{{- end }} +{{- end -}} + +{{/* +Return the appropriate os label +*/}} +{{- define "label.os" -}} +{{- if semverCompare "^1.14-0" .Capabilities.KubeVersion.GitVersion -}} +kubernetes.io/os +{{- else -}} +beta.kubernetes.io/os +{{- end -}} +{{- end -}} + +{{/* +Returns a YAML with extra annotations +*/}} +{{- define "stackstate-k8s-agent.global.extraAnnotations" -}} +{{- with .Values.global.extraAnnotations }} +{{- toYaml . }} +{{- end }} +{{- end -}} + +{{/* +Returns a YAML with extra labels +*/}} +{{- define "stackstate-k8s-agent.global.extraLabels" -}} +{{- with .Values.global.extraLabels }} +{{- toYaml . }} +{{- end }} +{{- end -}} + +{{- define "stackstate-k8s-agent.apiKeyEnv" -}} +- name: STS_API_KEY + valueFrom: + secretKeyRef: +{{- if not .Values.stackstate.manageOwnSecrets }} + name: {{ include "stackstate-k8s-agent.fullname" . }} + key: sts-api-key +{{- else }} + name: {{ .Values.stackstate.customSecretName | quote }} + key: {{ .Values.stackstate.customApiKeySecretKey | quote }} +{{- end }} +{{- end -}} + +{{- define "stackstate-k8s-agent.clusterAgentAuthTokenEnv" -}} +- name: STS_CLUSTER_AGENT_AUTH_TOKEN + valueFrom: + secretKeyRef: +{{- if not .Values.stackstate.manageOwnSecrets }} + name: {{ include "stackstate-k8s-agent.fullname" . }} + key: sts-cluster-auth-token +{{- else }} + name: {{ .Values.stackstate.customSecretName | quote }} + key: {{ .Values.stackstate.customClusterAuthTokenSecretKey | quote }} +{{- end }} +{{- end -}} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/checks-agent-clusterrolebinding.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/checks-agent-clusterrolebinding.yaml new file mode 100644 index 0000000000..4fd0eadbcd --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/checks-agent-clusterrolebinding.yaml @@ -0,0 +1,21 @@ +{{- if .Values.checksAgent.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ .Release.Name }}-checks-agent + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: checks-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ .Release.Name }}-node-agent +subjects: +- apiGroup: "" + kind: ServiceAccount + name: {{ .Release.Name }}-checks-agent + namespace: {{ .Release.Namespace }} +{{- end -}} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/checks-agent-configmap.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/checks-agent-configmap.yaml new file mode 100644 index 0000000000..54a1abf2fe --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/checks-agent-configmap.yaml @@ -0,0 +1,17 @@ +{{- if and .Values.checksAgent.enabled .Values.checksAgent.config.override }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-checks-agent + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: checks-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +data: +{{- range .Values.checksAgent.config.override }} + {{ .path | replace "/" "_"}}_{{ .name }}: | +{{ .data | indent 4 -}} +{{- end -}} +{{- end -}} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/checks-agent-deployment.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/checks-agent-deployment.yaml new file mode 100644 index 0000000000..37a0b1a1db --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/checks-agent-deployment.yaml @@ -0,0 +1,185 @@ +{{- if .Values.checksAgent.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-checks-agent + namespace: {{ .Release.Namespace }} + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: checks-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +spec: + selector: + matchLabels: + app.kubernetes.io/component: checks-agent + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "stackstate-k8s-agent.name" . }} + replicas: {{ .Values.checksAgent.replicas }} +{{- with .Values.checksAgent.strategy }} + strategy: + {{- toYaml . | nindent 4 }} +{{- end }} + template: + metadata: + annotations: + {{- include "stackstate-k8s-agent.checksum-configs" . | nindent 8 }} + {{- include "stackstate-k8s-agent.nodeAgent.configmap.override.checksum" . | nindent 8 }} +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 8 }} + labels: + app.kubernetes.io/component: checks-agent + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "stackstate-k8s-agent.name" . }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 8 }} + spec: + {{- include "stackstate-k8s-agent.image.pullSecrets" (dict "images" (list .Values.checksAgent.image .Values.all.image) "context" $) | nindent 6 }} + {{- if .Values.all.hardening.enabled}} + terminationGracePeriodSeconds: 240 + {{- end }} + containers: + - name: {{ .Chart.Name }} + image: "{{ include "stackstate-k8s-agent.imageRegistry" . }}/{{ .Values.checksAgent.image.repository }}:{{ .Values.checksAgent.image.tag }}" + imagePullPolicy: "{{ .Values.checksAgent.image.pullPolicy }}" + {{- if .Values.all.hardening.enabled}} + lifecycle: + preStop: + exec: + command: [ "/bin/sh", "-c", "echo 'Giving slim.ai monitor time to submit data...'; sleep 120" ] + {{- end }} + env: + {{ include "stackstate-k8s-agent.apiKeyEnv" . | nindent 10 }} + - name: KUBERNETES_HOSTNAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: STS_HOSTNAME + value: "$(KUBERNETES_HOSTNAME)-{{ .Values.stackstate.cluster.name}}" + - name: AGENT_VERSION + value: {{ .Values.checksAgent.image.tag | quote }} + - name: LOG_LEVEL + value: {{ .Values.checksAgent.logLevel | quote }} + - name: STS_APM_ENABLED + value: "false" + - name: STS_CLUSTER_AGENT_ENABLED + value: {{ .Values.clusterAgent.enabled | quote }} + {{- if .Values.clusterAgent.enabled }} + - name: STS_CLUSTER_AGENT_KUBERNETES_SERVICE_NAME + value: {{ .Release.Name }}-cluster-agent + {{ include "stackstate-k8s-agent.clusterAgentAuthTokenEnv" . | nindent 10 }} + {{- end }} + - name: STS_CLUSTER_NAME + value: {{ .Values.stackstate.cluster.name | quote }} + - name: STS_SKIP_VALIDATE_CLUSTERNAME + value: "true" + - name: STS_CHECKS_TAG_CARDINALITY + value: {{ .Values.checksAgent.checksTagCardinality | quote }} + - name: STS_EXTRA_CONFIG_PROVIDERS + value: "clusterchecks" + - name: STS_HEALTH_PORT + value: "5555" + - name: STS_LEADER_ELECTION + value: "false" + - name: STS_LOG_LEVEL + value: {{ .Values.checksAgent.logLevel | quote }} + - name: STS_NETWORK_TRACING_ENABLED + value: "false" + - name: STS_PROCESS_AGENT_ENABLED + value: "false" + - name: STS_SKIP_SSL_VALIDATION + value: {{ or .Values.global.skipSslValidation .Values.checksAgent.skipSslValidation | quote }} + - name: STS_STS_URL + value: {{ include "stackstate-k8s-agent.stackstate.url" . }} + {{- if .Values.global.proxy.url }} + - name: STS_PROXY_HTTPS + value: {{ .Values.global.proxy.url | quote }} + - name: STS_PROXY_HTTP + value: {{ .Values.global.proxy.url | quote }} + {{- end }} + {{- range $key, $value := .Values.global.extraEnv.open }} + - name: {{ $key }} + value: {{ $value | quote }} + {{- end }} + {{- range $key, $value := .Values.global.extraEnv.secret }} + - name: {{ $key }} + valueFrom: + secretKeyRef: + name: {{ include "stackstate-k8s-agent.fullname" . }} + key: {{ $key }} + {{- end }} + livenessProbe: + httpGet: + path: /health + port: healthport + failureThreshold: {{ .Values.checksAgent.livenessProbe.failureThreshold }} + initialDelaySeconds: {{ .Values.checksAgent.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.checksAgent.livenessProbe.periodSeconds }} + successThreshold: {{ .Values.checksAgent.livenessProbe.successThreshold }} + timeoutSeconds: {{ .Values.checksAgent.livenessProbe.timeoutSeconds }} + readinessProbe: + httpGet: + path: /health + port: healthport + failureThreshold: {{ .Values.checksAgent.readinessProbe.failureThreshold }} + initialDelaySeconds: {{ .Values.checksAgent.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.checksAgent.readinessProbe.periodSeconds }} + successThreshold: {{ .Values.checksAgent.readinessProbe.successThreshold }} + timeoutSeconds: {{ .Values.checksAgent.readinessProbe.timeoutSeconds }} + ports: + - containerPort: 5555 + name: healthport + protocol: TCP + {{- if .Values.all.hardening.enabled}} + securityContext: + privileged: true + runAsUser: 0 # root + capabilities: + add: [ "ALL" ] + readOnlyRootFilesystem: false + {{- else }} + securityContext: + privileged: false + {{- end }} + {{- with .Values.checksAgent.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + - name: confd-empty-volume + mountPath: /etc/stackstate-agent/conf.d +# setting as readOnly: false because we need the ability to write data on /etc/stackstate-agent/conf.d as we enable checks to run. + readOnly: false + {{- if .Values.checksAgent.config.override }} + {{- range .Values.checksAgent.config.override }} + - name: config-override-volume + mountPath: {{ .path }}/{{ .name }} + subPath: {{ .path | replace "/" "_"}}_{{ .name }} + readOnly: true + {{- end }} + {{- end }} + {{- if .Values.checksAgent.priorityClassName }} + priorityClassName: {{ .Values.checksAgent.priorityClassName }} + {{- end }} + serviceAccountName: {{ .Release.Name }}-checks-agent + nodeSelector: + {{ template "label.os" . }}: {{ .Values.targetSystem }} + {{- with .Values.checksAgent.nodeSelector }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.checksAgent.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.checksAgent.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: confd-empty-volume + emptyDir: {} + {{- if .Values.checksAgent.config.override }} + - name: config-override-volume + configMap: + name: {{ .Release.Name }}-checks-agent + {{- end }} +{{- end -}} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/checks-agent-poddisruptionbudget.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/checks-agent-poddisruptionbudget.yaml new file mode 100644 index 0000000000..19d3924ea3 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/checks-agent-poddisruptionbudget.yaml @@ -0,0 +1,23 @@ +{{- if .Values.checksAgent.enabled }} +{{- if .Capabilities.APIVersions.Has "policy/v1/PodDisruptionBudget" }} +apiVersion: policy/v1 +{{- else }} +apiVersion: policy/v1beta1 +{{- end }} +kind: PodDisruptionBudget +metadata: + name: {{ .Release.Name }}-checks-agent + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: checks-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +spec: + maxUnavailable: 1 + selector: + matchLabels: + app.kubernetes.io/component: checks-agent + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "stackstate-k8s-agent.name" . }} +{{- end -}} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/checks-agent-serviceaccount.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/checks-agent-serviceaccount.yaml new file mode 100644 index 0000000000..a90a43589d --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/checks-agent-serviceaccount.yaml @@ -0,0 +1,16 @@ +{{- if .Values.checksAgent.enabled }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Release.Name }}-checks-agent + namespace: {{ .Release.Namespace }} + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: checks-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +{{- with .Values.checksAgent.serviceaccount.annotations }} + {{- toYaml . | nindent 4 }} +{{- end }} +{{- end -}} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/cluster-agent-clusterrole.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/cluster-agent-clusterrole.yaml new file mode 100644 index 0000000000..021a43ebdf --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/cluster-agent-clusterrole.yaml @@ -0,0 +1,152 @@ +{{- $kubeRes := .Values.clusterAgent.collection.kubernetesResources }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "stackstate-k8s-agent.fullname" . }} + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: cluster-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +rules: +- apiGroups: + - "" + resources: + - events + - nodes + - pods + - services + {{- if $kubeRes.namespaces }} + - namespaces + {{- end }} + {{- if .Values.clusterAgent.collection.kubernetesMetrics }} + - componentstatuses + {{- end }} + {{- if $kubeRes.configmaps }} + - configmaps + {{- end }} + {{- if $kubeRes.endpoints }} + - endpoints + {{- end }} + {{- if $kubeRes.persistentvolumeclaims }} + - persistentvolumeclaims + {{- end }} + {{- if $kubeRes.persistentvolumes }} + - persistentvolumes + {{- end }} + {{- if $kubeRes.secrets }} + - secrets + {{- end }} + {{- if $kubeRes.resourcequotas }} + - resourcequotas + {{- end }} + verbs: + - get + - list + - watch +{{- if or $kubeRes.daemonsets $kubeRes.deployments $kubeRes.replicasets $kubeRes.statefulsets }} +- apiGroups: + - "apps" + resources: + {{- if $kubeRes.daemonsets }} + - daemonsets + {{- end }} + {{- if $kubeRes.deployments }} + - deployments + {{- end }} + {{- if $kubeRes.replicasets }} + - replicasets + {{- end }} + {{- if $kubeRes.statefulsets }} + - statefulsets + {{- end }} + verbs: + - get + - list + - watch +{{- end}} +{{- if $kubeRes.ingresses }} +- apiGroups: + - "extensions" + - "networking.k8s.io" + resources: + - ingresses + verbs: + - get + - list + - watch +{{- end}} +{{- if or $kubeRes.cronjobs $kubeRes.jobs }} +- apiGroups: + - "batch" + resources: + {{- if $kubeRes.cronjobs }} + - cronjobs + {{- end }} + {{- if $kubeRes.jobs }} + - jobs + {{- end }} + verbs: + - get + - list + - watch +{{- end}} +- nonResourceURLs: + - "/healthz" + - "/version" + verbs: + - get +- apiGroups: + - "storage.k8s.io" + resources: + {{- if $kubeRes.volumeattachments }} + - volumeattachments + {{- end }} + {{- if $kubeRes.storageclasses }} + - storageclasses + {{- end }} + verbs: + - get + - list + - watch +- apiGroups: + - "policy" + resources: + {{- if $kubeRes.poddisruptionbudgets }} + - poddisruptionbudgets + {{- end }} + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + {{- if $kubeRes.replicationcontrollers }} + - replicationcontrollers + {{- end }} + verbs: + - get + - list + - watch +- apiGroups: + - "autoscaling" + resources: + {{- if $kubeRes.horizontalpodautoscalers }} + - horizontalpodautoscalers + {{- end }} + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + {{- if $kubeRes.limitranges }} + - limitranges + {{- end }} + verbs: + - get + - list + - watch diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/cluster-agent-clusterrolebinding.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/cluster-agent-clusterrolebinding.yaml new file mode 100644 index 0000000000..207613dd9e --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/cluster-agent-clusterrolebinding.yaml @@ -0,0 +1,19 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "stackstate-k8s-agent.fullname" . }} + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: cluster-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "stackstate-k8s-agent.fullname" . }} +subjects: +- apiGroup: "" + kind: ServiceAccount + name: {{ include "stackstate-k8s-agent.fullname" . }} + namespace: {{ .Release.Namespace }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/cluster-agent-configmap.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/cluster-agent-configmap.yaml new file mode 100644 index 0000000000..37d10217f8 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/cluster-agent-configmap.yaml @@ -0,0 +1,31 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-cluster-agent + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: cluster-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +data: + kubernetes_api_events_conf: | + init_config: + instances: + - collect_events: {{ .Values.clusterAgent.collection.kubernetesEvents }} + event_categories:{{ .Values.clusterAgent.config.events.categories | toYaml | nindent 10 }} + kubernetes_api_topology_conf: | + init_config: + instances: + - collection_interval: {{ .Values.clusterAgent.config.topology.collectionInterval }} + resources:{{ .Values.clusterAgent.collection.kubernetesResources | toYaml | nindent 10 }} + {{- if .Values.clusterAgent.collection.kubeStateMetrics.enabled }} + kube_state_metrics_core_conf: | + {{- include "cluster-agent-kube-state-metrics" . | nindent 6 }} + {{- end }} +{{- if .Values.clusterAgent.config.override }} +{{- range .Values.clusterAgent.config.override }} + {{ .path | replace "/" "_"}}_{{ .name }}: | +{{ .data | indent 4 -}} +{{- end -}} +{{- end -}} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/cluster-agent-deployment.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/cluster-agent-deployment.yaml new file mode 100644 index 0000000000..51025a6703 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/cluster-agent-deployment.yaml @@ -0,0 +1,169 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-cluster-agent + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: cluster-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +spec: + replicas: {{ .Values.clusterAgent.replicaCount }} + selector: + matchLabels: + app.kubernetes.io/component: cluster-agent + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "stackstate-k8s-agent.name" . }} +{{- with .Values.clusterAgent.strategy }} + strategy: + {{- toYaml . | nindent 4 }} +{{- end }} + template: + metadata: + annotations: + {{- include "stackstate-k8s-agent.checksum-configs" . | nindent 8 }} + {{- include "stackstate-k8s-agent.configmap.override.checksum" . | nindent 8 }} +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 8 }} + labels: + app.kubernetes.io/component: cluster-agent + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "stackstate-k8s-agent.name" . }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 8 }} + spec: + {{- include "stackstate-k8s-agent.image.pullSecrets" (dict "images" (list .Values.clusterAgent.image .Values.all.image) "context" $) | nindent 6 }} + {{- if .Values.clusterAgent.priorityClassName }} + priorityClassName: {{ .Values.clusterAgent.priorityClassName }} + {{- end }} + serviceAccountName: {{ include "stackstate-k8s-agent.fullname" . }} + {{- if .Values.all.hardening.enabled}} + terminationGracePeriodSeconds: 240 + {{- end }} + containers: + - name: cluster-agent + image: "{{ include "stackstate-k8s-agent.imageRegistry" . }}/{{ .Values.clusterAgent.image.repository }}:{{ .Values.clusterAgent.image.tag }}" + imagePullPolicy: "{{ .Values.clusterAgent.image.pullPolicy }}" + {{- if .Values.all.hardening.enabled}} + lifecycle: + preStop: + exec: + command: [ "/bin/sh", "-c", "echo 'Giving slim.ai monitor time to submit data...'; sleep 120" ] + {{- end }} + env: + {{ include "stackstate-k8s-agent.apiKeyEnv" . | nindent 10 }} + {{ include "stackstate-k8s-agent.clusterAgentAuthTokenEnv" . | nindent 10 }} + - name: KUBERNETES_HOSTNAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: STS_HOSTNAME + value: "$(KUBERNETES_HOSTNAME)-{{ .Values.stackstate.cluster.name}}" + - name: LOG_LEVEL + value: {{ .Values.clusterAgent.logLevel | quote }} + {{- if .Values.checksAgent.enabled }} + - name: STS_CLUSTER_CHECKS_ENABLED + value: "true" + - name: STS_EXTRA_CONFIG_PROVIDERS + value: "kube_endpoints kube_services" + - name: STS_EXTRA_LISTENERS + value: "kube_endpoints kube_services" + {{- end }} + - name: STS_CLUSTER_NAME + value: {{.Values.stackstate.cluster.name | quote }} + - name: STS_SKIP_VALIDATE_CLUSTERNAME + value: "true" + - name: STS_SKIP_SSL_VALIDATION + value: {{ or .Values.global.skipSslValidation .Values.clusterAgent.skipSslValidation | quote }} + - name: STS_COLLECT_KUBERNETES_METRICS + value: {{ .Values.clusterAgent.collection.kubernetesMetrics | quote }} + - name: STS_COLLECT_KUBERNETES_TIMEOUT + value: {{ .Values.clusterAgent.collection.kubernetesTimeout | quote }} + - name: STS_COLLECT_KUBERNETES_TOPOLOGY + value: {{ .Values.clusterAgent.collection.kubernetesTopology | quote }} + - name: STS_LEADER_ELECTION + value: "true" + - name: STS_LOG_LEVEL + value: {{ .Values.clusterAgent.logLevel | quote }} + - name: STS_CLUSTER_AGENT_CMD_PORT + value: {{ .Values.clusterAgent.service.targetPort | quote }} + - name: STS_STS_URL + value: {{ include "stackstate-k8s-agent.stackstate.url" . }} + {{- if .Values.clusterAgent.config.configMap.maxDataSize }} + - name: STS_CONFIGMAP_MAX_DATASIZE + value: {{ .Values.clusterAgent.config.configMap.maxDataSize | quote }} + {{- end}} + {{- if .Values.global.proxy.url }} + - name: STS_PROXY_HTTPS + value: {{ .Values.global.proxy.url | quote }} + - name: STS_PROXY_HTTP + value: {{ .Values.global.proxy.url | quote }} + {{- end }} + {{- range $key, $value := .Values.global.extraEnv.open }} + - name: {{ $key }} + value: {{ $value | quote }} + {{- end }} + {{- range $key, $value := .Values.global.extraEnv.secret }} + - name: {{ $key }} + valueFrom: + secretKeyRef: + name: {{ include "stackstate-k8s-agent.fullname" . }} + key: {{ $key }} + {{- end }} + {{- if .Values.all.hardening.enabled}} + securityContext: + privileged: true + runAsUser: 0 # root + capabilities: + add: [ "ALL" ] + readOnlyRootFilesystem: false + {{- else }} + securityContext: + privileged: false + {{- end }} + {{- with .Values.clusterAgent.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + - name: logs + mountPath: /var/log/stackstate-agent + - name: config-override-volume + mountPath: /etc/stackstate-agent/conf.d/kubernetes_api_events.d/conf.yaml + subPath: kubernetes_api_events_conf + - name: config-override-volume + mountPath: /etc/stackstate-agent/conf.d/kubernetes_api_topology.d/conf.yaml + subPath: kubernetes_api_topology_conf + readOnly: true + {{- if .Values.clusterAgent.collection.kubeStateMetrics.enabled }} + - name: config-override-volume + mountPath: /etc/stackstate-agent/conf.d/kubernetes_state_core.d/conf.yaml + subPath: kube_state_metrics_core_conf + readOnly: true + {{- end }} + {{- if .Values.clusterAgent.config.override }} + {{- range .Values.clusterAgent.config.override }} + - name: config-override-volume + mountPath: {{ .path }}/{{ .name }} + subPath: {{ .path | replace "/" "_"}}_{{ .name }} + readOnly: true + {{- end }} + {{- end }} + nodeSelector: + {{ template "label.os" . }}: {{ .Values.targetSystem }} + {{- with .Values.clusterAgent.nodeSelector }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.clusterAgent.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.clusterAgent.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: logs + emptyDir: {} + - name: config-override-volume + configMap: + name: {{ .Release.Name }}-cluster-agent diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/cluster-agent-poddisruptionbudget.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/cluster-agent-poddisruptionbudget.yaml new file mode 100644 index 0000000000..64a265b7db --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/cluster-agent-poddisruptionbudget.yaml @@ -0,0 +1,21 @@ +{{- if .Capabilities.APIVersions.Has "policy/v1/PodDisruptionBudget" }} +apiVersion: policy/v1 +{{- else }} +apiVersion: policy/v1beta1 +{{- end }} +kind: PodDisruptionBudget +metadata: + name: {{ include "stackstate-k8s-agent.fullname" . }} + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: cluster-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +spec: + maxUnavailable: 1 + selector: + matchLabels: + app.kubernetes.io/component: cluster-agent + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "stackstate-k8s-agent.name" . }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/cluster-agent-role.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/cluster-agent-role.yaml new file mode 100644 index 0000000000..eabc5bde36 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/cluster-agent-role.yaml @@ -0,0 +1,21 @@ +{{- $kubeRes := .Values.clusterAgent.collection.kubernetesResources }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "stackstate-k8s-agent.fullname" . }} + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: cluster-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +rules: +- apiGroups: + - "" + resources: + - configmaps + verbs: + - create + - get + - patch + - update diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/cluster-agent-rolebinding.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/cluster-agent-rolebinding.yaml new file mode 100644 index 0000000000..adabad45e0 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/cluster-agent-rolebinding.yaml @@ -0,0 +1,18 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "stackstate-k8s-agent.fullname" . }} + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: cluster-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ include "stackstate-k8s-agent.fullname" . }} +subjects: +- apiGroup: "" + kind: ServiceAccount + name: {{ include "stackstate-k8s-agent.fullname" . }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/cluster-agent-service.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/cluster-agent-service.yaml new file mode 100644 index 0000000000..8b687e8f76 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/cluster-agent-service.yaml @@ -0,0 +1,21 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }}-cluster-agent + namespace: {{ .Release.Namespace }} + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: cluster-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +spec: + ports: + - name: clusteragent + port: {{int .Values.clusterAgent.service.port }} + protocol: TCP + targetPort: {{int .Values.clusterAgent.service.targetPort }} + selector: + app.kubernetes.io/component: cluster-agent + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "stackstate-k8s-agent.name" . }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/cluster-agent-serviceaccount.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/cluster-agent-serviceaccount.yaml new file mode 100644 index 0000000000..6cbc89699e --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/cluster-agent-serviceaccount.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "stackstate-k8s-agent.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: cluster-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +{{- with .Values.clusterAgent.serviceaccount.annotations }} + {{- toYaml . | nindent 4 }} +{{- end }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/logs-agent-clusterrole.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/logs-agent-clusterrole.yaml new file mode 100644 index 0000000000..da6cd59dd5 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/logs-agent-clusterrole.yaml @@ -0,0 +1,23 @@ +{{- if .Values.logsAgent.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ .Release.Name }}-logs-agent + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: logs-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +rules: +- apiGroups: # Kubelet connectivity + - "" + resources: + - nodes + - services + - pods + verbs: + - get + - watch + - list +{{- end -}} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/logs-agent-clusterrolebinding.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/logs-agent-clusterrolebinding.yaml new file mode 100644 index 0000000000..1f6e7cfcff --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/logs-agent-clusterrolebinding.yaml @@ -0,0 +1,21 @@ +{{- if .Values.logsAgent.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ .Release.Name }}-logs-agent + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: logs-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ .Release.Name }}-logs-agent +subjects: +- apiGroup: "" + kind: ServiceAccount + name: {{ .Release.Name }}-logs-agent + namespace: {{ .Release.Namespace }} +{{- end -}} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/logs-agent-configmap.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/logs-agent-configmap.yaml new file mode 100644 index 0000000000..ff9440a4b7 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/logs-agent-configmap.yaml @@ -0,0 +1,63 @@ +{{- if .Values.logsAgent.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-logs-agent + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: logs-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +data: + promtail.yaml: | + server: + http_listen_port: 9080 + grpc_listen_port: 0 + + clients: + - url: {{ tpl .Values.stackstate.url . }}/logs/k8s?api_key=${STS_API_KEY} + external_labels: + sts_cluster_name: {{ .Values.stackstate.cluster.name | quote }} + {{- if .Values.global.proxy.url }} + proxy_url: {{ .Values.global.proxy.url | quote }} + {{- end }} + tls_config: + insecure_skip_verify: {{ or .Values.global.skipSslValidation .Values.logsAgent.skipSslValidation }} + + + positions: + filename: /tmp/positions.yaml + target_config: + sync_period: 10s + scrape_configs: + - job_name: pod-logs + kubernetes_sd_configs: + - role: pod + pipeline_stages: + - docker: {} + - cri: {} + relabel_configs: + - action: replace + source_labels: + - __meta_kubernetes_pod_name + target_label: pod_name + - action: replace + source_labels: + - __meta_kubernetes_pod_uid + target_label: pod_uid + - action: replace + source_labels: + - __meta_kubernetes_pod_container_name + target_label: container_name + # The __path__ is required by the promtail client + - replacement: /var/log/pods/*$1/*.log + separator: / + source_labels: + - __meta_kubernetes_pod_uid + - __meta_kubernetes_pod_container_name + target_label: __path__ + # Drop all remaining labels, we do not need those + - action: drop + regex: __meta_(.*) +{{- end -}} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/logs-agent-daemonset.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/logs-agent-daemonset.yaml new file mode 100644 index 0000000000..23cfce31f0 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/logs-agent-daemonset.yaml @@ -0,0 +1,91 @@ +{{- if .Values.logsAgent.enabled }} +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ .Release.Name }}-logs-agent + namespace: {{ .Release.Namespace }} + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: logs-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +spec: + selector: + matchLabels: + app.kubernetes.io/component: logs-agent + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "stackstate-k8s-agent.name" . }} +{{- with .Values.logsAgent.updateStrategy }} + updateStrategy: + {{- toYaml . | nindent 4 }} +{{- end }} + template: + metadata: + annotations: + {{- include "stackstate-k8s-agent.checksum-configs" . | nindent 8 }} + {{- include "stackstate-k8s-agent.logsAgent.configmap.override.checksum" . | nindent 8 }} +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 8 }} + labels: + app.kubernetes.io/component: logs-agent + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "stackstate-k8s-agent.name" . }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 8 }} + spec: + {{- include "stackstate-k8s-agent.image.pullSecrets" (dict "images" (list .Values.logsAgent.image .Values.all.image) "context" $) | nindent 6 }} + containers: + - name: logs-agent + image: "{{ include "stackstate-k8s-agent.imageRegistry" . }}/{{ .Values.logsAgent.image.repository }}:{{ .Values.logsAgent.image.tag }}" + args: + - -config.expand-env=true + - -config.file=/etc/promtail/promtail.yaml + imagePullPolicy: "{{ .Values.logsAgent.image.pullPolicy }}" + env: + {{ include "stackstate-k8s-agent.apiKeyEnv" . | nindent 10 }} + - name: "HOSTNAME" # needed when using kubernetes_sd_configs + valueFrom: + fieldRef: + fieldPath: "spec.nodeName" + securityContext: + privileged: false + {{- with .Values.logsAgent.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + - name: logs + mountPath: /var/log + readOnly: true + - name: logs-agent-config + mountPath: /etc/promtail + readOnly: true + - name: varlibdockercontainers + mountPath: /var/lib/docker/containers + readOnly: true + {{- if .Values.logsAgent.priorityClassName }} + priorityClassName: {{ .Values.logsAgent.priorityClassName }} + {{- end }} + serviceAccountName: {{ .Release.Name }}-logs-agent + {{- with .Values.logsAgent.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.logsAgent.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.logsAgent.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: logs + hostPath: + path: /var/log + - name: varlibdockercontainers + hostPath: + path: /var/lib/docker/containers + - name: logs-agent-config + configMap: + name: {{ .Release.Name }}-logs-agent +{{- end -}} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/logs-agent-serviceaccount.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/logs-agent-serviceaccount.yaml new file mode 100644 index 0000000000..91cfdb137d --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/logs-agent-serviceaccount.yaml @@ -0,0 +1,16 @@ +{{- if .Values.logsAgent.enabled }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Release.Name }}-logs-agent + namespace: {{ .Release.Namespace }} + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: logs-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +{{- with .Values.logsAgent.serviceaccount.annotations }} + {{- toYaml . | nindent 4 }} +{{- end }} +{{- end -}} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/node-agent-clusterrole.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/node-agent-clusterrole.yaml new file mode 100644 index 0000000000..1ded16cc29 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/node-agent-clusterrole.yaml @@ -0,0 +1,21 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ .Release.Name }}-node-agent + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: node-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +rules: +- apiGroups: # Kubelet connectivity + - "" + resources: + - nodes/metrics + - nodes/proxy + - nodes/spec + - endpoints + verbs: + - get + - list diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/node-agent-clusterrolebinding.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/node-agent-clusterrolebinding.yaml new file mode 100644 index 0000000000..b3f033ebbf --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/node-agent-clusterrolebinding.yaml @@ -0,0 +1,19 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ .Release.Name }}-node-agent + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: node-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ .Release.Name }}-node-agent +subjects: +- apiGroup: "" + kind: ServiceAccount + name: {{ .Release.Name }}-node-agent + namespace: {{ .Release.Namespace }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/node-agent-configmap.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/node-agent-configmap.yaml new file mode 100644 index 0000000000..8f6b2ed3ac --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/node-agent-configmap.yaml @@ -0,0 +1,17 @@ +{{- if .Values.nodeAgent.config.override }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-node-agent + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: node-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +data: +{{- range .Values.nodeAgent.config.override }} + {{ .path | replace "/" "_"}}_{{ .name }}: | +{{ .data | indent 4 -}} +{{- end -}} +{{- end -}} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/node-agent-daemonset.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/node-agent-daemonset.yaml new file mode 100644 index 0000000000..4c8dbdd5a9 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/node-agent-daemonset.yaml @@ -0,0 +1,110 @@ +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ .Release.Name }}-node-agent + namespace: {{ .Release.Namespace }} + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: node-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +spec: + selector: + matchLabels: + app.kubernetes.io/component: node-agent + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "stackstate-k8s-agent.name" . }} +{{- with .Values.nodeAgent.updateStrategy }} + updateStrategy: + {{- toYaml . | nindent 4 }} +{{- end }} + template: + metadata: + annotations: + {{- include "stackstate-k8s-agent.checksum-configs" . | nindent 8 }} + {{- include "stackstate-k8s-agent.nodeAgent.configmap.override.checksum" . | nindent 8 }} +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 8 }} + labels: + app.kubernetes.io/component: node-agent + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "stackstate-k8s-agent.name" . }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 8 }} + spec: + {{- include "stackstate-k8s-agent.image.pullSecrets" (dict "images" (list .Values.nodeAgent.containers.agent.image .Values.all.image) "context" $) | nindent 6 }} + {{- if .Values.all.hardening.enabled}} + terminationGracePeriodSeconds: 240 + {{- end }} + containers: + {{- include "container-agent" . | nindent 6 }} + {{- if .Values.nodeAgent.containers.processAgent.enabled }} + {{- include "container-process-agent" . | nindent 6 }} + {{- end }} + dnsPolicy: ClusterFirstWithHostNet + hostNetwork: true + hostPID: true + {{- if .Values.nodeAgent.priorityClassName }} + priorityClassName: {{ .Values.nodeAgent.priorityClassName }} + {{- end }} + serviceAccountName: {{ .Release.Name }}-node-agent + nodeSelector: + {{ template "label.os" . }}: {{ .Values.targetSystem }} + {{- with .Values.nodeAgent.nodeSelector }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodeAgent.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodeAgent.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + {{- if .Values.nodeAgent.containerRuntime.customSocketPath }} + - hostPath: + path: {{ .Values.nodeAgent.containerRuntime.customSocketPath }} + name: customcrisocket + {{- end }} + - hostPath: + path: /var/lib/kubelet + name: kubelet + - hostPath: + path: /var/lib/nfs + name: nfs + - hostPath: + path: /var/lib/docker/overlay2 + name: dockeroverlay2 + - hostPath: + path: /run/docker/netns + name: dockernetns + - hostPath: + path: /var/run/crio/crio.sock + name: crisocket + - hostPath: + path: /var/run/containerd/containerd.sock + name: containerdsocket + - hostPath: + path: /sys/kernel/debug + name: sys-kernel-debug + - hostPath: + path: /var/run/docker.sock + name: dockersocket + - hostPath: + path: {{ .Values.nodeAgent.containerRuntime.hostProc }} + name: procdir + - hostPath: + path: /etc + name: etcdir + - hostPath: + path: /etc/passwd + name: passwd + - hostPath: + path: /sys/fs/cgroup + name: cgroups + {{- if .Values.nodeAgent.config.override }} + - name: config-override-volume + configMap: + name: {{ .Release.Name }}-node-agent + {{- end }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/node-agent-podautoscaler.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/node-agent-podautoscaler.yaml new file mode 100644 index 0000000000..38298d4147 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/node-agent-podautoscaler.yaml @@ -0,0 +1,39 @@ +--- +{{- if .Values.nodeAgent.autoScalingEnabled }} +apiVersion: "autoscaling.k8s.io/v1" +kind: VerticalPodAutoscaler +metadata: + name: {{ .Release.Name }}-node-agent-vpa + namespace: {{ .Release.Namespace }} + labels: +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +spec: + targetRef: + apiVersion: "apps/v1" + kind: DaemonSet + name: {{ .Release.Name }}-node-agent + resourcePolicy: + containerPolicies: + - containerName: 'node-agent' + minAllowed: + cpu: {{ .Values.nodeAgent.scaling.autoscalerLimits.agent.minimum.cpu }} + memory: {{ .Values.nodeAgent.scaling.autoscalerLimits.agent.minimum.memory }} + maxAllowed: + cpu: {{ .Values.nodeAgent.scaling.autoscalerLimits.agent.maximum.cpu }} + memory: {{ .Values.nodeAgent.scaling.autoscalerLimits.agent.maximum.memory }} + controlledResources: ["cpu", "memory"] + controlledValues: RequestsAndLimits + - containerName: 'process-agent' + minAllowed: + cpu: {{ .Values.nodeAgent.scaling.autoscalerLimits.processAgent.minimum.cpu }} + memory: {{ .Values.nodeAgent.scaling.autoscalerLimits.processAgent.minimum.memory }} + maxAllowed: + cpu: {{ .Values.nodeAgent.scaling.autoscalerLimits.processAgent.maximum.cpu }} + memory: {{ .Values.nodeAgent.scaling.autoscalerLimits.processAgent.maximum.memory }} + controlledResources: ["cpu", "memory"] + controlledValues: RequestsAndLimits + updatePolicy: + updateMode: "Auto" +{{- end }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/node-agent-scc.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/node-agent-scc.yaml new file mode 100644 index 0000000000..a09da78c17 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/node-agent-scc.yaml @@ -0,0 +1,60 @@ +{{- if .Values.nodeAgent.scc.enabled }} +allowHostDirVolumePlugin: true +# was true +allowHostIPC: true +# was true +allowHostNetwork: true +# Allow host PID for dogstatsd origin detection +allowHostPID: true +# Allow host ports for dsd / trace / logs intake +allowHostPorts: true +allowPrivilegeEscalation: true +# was true +allowPrivilegedContainer: true +# was - '*' +allowedCapabilities: [] +allowedUnsafeSysctls: +- '*' +apiVersion: security.openshift.io/v1 +defaultAddCapabilities: null +fsGroup: +# was RunAsAny + type: MustRunAs +groups: [] +kind: SecurityContextConstraints +metadata: + name: {{ .Release.Name }}-node-agent + namespace: {{ .Release.Namespace }} + labels: +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +priority: null +readOnlyRootFilesystem: false +requiredDropCapabilities: null +# was RunAsAny +runAsUser: + type: MustRunAsRange +# Use the `spc_t` selinux type to access the +# docker socket + proc and cgroup stats +seLinuxContext: + type: RunAsAny + seLinuxOptions: + user: "system_u" + role: "system_r" + type: "spc_t" + level: "s0" +# was - '*' +seccompProfiles: [] +supplementalGroups: + type: RunAsAny +users: +- system:serviceaccount:{{ .Release.Namespace }}:{{ .Release.Name }}-node-agent +# Allow hostPath for docker / process metrics +volumes: + - configMap + - downwardAPI + - emptyDir + - hostPath + - secret +{{- end }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/node-agent-service.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/node-agent-service.yaml new file mode 100644 index 0000000000..0b6cd6ec03 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/node-agent-service.yaml @@ -0,0 +1,28 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }}-node-agent + namespace: {{ .Release.Namespace }} + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: node-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +{{- with .Values.nodeAgent.service.annotations }} + {{- toYaml . | nindent 4 }} +{{- end }} +spec: + type: {{ .Values.nodeAgent.service.type }} +{{- if eq .Values.nodeAgent.service.type "LoadBalancer" }} + loadBalancerSourceRanges: {{ toYaml .Values.nodeAgent.service.loadBalancerSourceRanges | nindent 4}} +{{- end }} + ports: + - name: traceport + port: 8126 + protocol: TCP + targetPort: 8126 + selector: + app.kubernetes.io/component: node-agent + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/name: {{ include "stackstate-k8s-agent.name" . }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/node-agent-serviceaccount.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/node-agent-serviceaccount.yaml new file mode 100644 index 0000000000..803d184ef7 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/node-agent-serviceaccount.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Release.Name }}-node-agent + namespace: {{ .Release.Namespace }} + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + app.kubernetes.io/component: node-agent + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +{{- with .Values.nodeAgent.serviceaccount.annotations }} + {{- toYaml . | nindent 4 }} +{{- end }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/openshift-logging-secret.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/openshift-logging-secret.yaml new file mode 100644 index 0000000000..ed0707f1fa --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/openshift-logging-secret.yaml @@ -0,0 +1,22 @@ +{{- if not .Values.stackstate.manageOwnSecrets }} +{{- if .Values.openShiftLogging.installSecret }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "stackstate-k8s-agent.fullname" . }}-logging-secret + namespace: openshift-logging + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +type: Opaque +data: + username: {{ "apikey" | b64enc | quote }} +{{- if .Values.global.receiverApiKey }} + password: {{ .Values.global.receiverApiKey | b64enc | quote }} +{{- else }} + password: {{ .Values.stackstate.apiKey | b64enc | quote }} +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/pull-secret.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/pull-secret.yaml new file mode 100644 index 0000000000..9169416657 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/pull-secret.yaml @@ -0,0 +1,39 @@ +{{- $defaultRegistry := .Values.global.imageRegistry }} +{{- $top := . }} +{{- $registryAuthMap := dict }} + +{{- range $registry, $credentials := .Values.global.imagePullCredentials }} + {{- $registryAuthDocument := dict -}} + {{- $_ := set $registryAuthDocument "username" $credentials.username }} + {{- $_ := set $registryAuthDocument "password" $credentials.password }} + {{- $authMessage := printf "%s:%s" $registryAuthDocument.username $registryAuthDocument.password | b64enc }} + {{- $_ := set $registryAuthDocument "auth" $authMessage }} + {{- if eq $registry "default" }} + {{- $registryAuthMap := set $registryAuthMap (include "stackstate-k8s-agent.imageRegistry" $top) $registryAuthDocument }} + {{ else }} + {{- $registryAuthMap := set $registryAuthMap $registry $registryAuthDocument }} + {{- end }} +{{- end }} + +{{- if .Values.all.image.pullSecretUsername }} + {{- $registryAuthDocument := dict -}} + {{- $_ := set $registryAuthDocument "username" .Values.all.image.pullSecretUsername }} + {{- $_ := set $registryAuthDocument "password" .Values.all.image.pullSecretPassword }} + {{- $authMessage := printf "%s:%s" $registryAuthDocument.username $registryAuthDocument.password | b64enc }} + {{- $_ := set $registryAuthDocument "auth" $authMessage }} + {{- $registryAuthMap := set $registryAuthMap (include "stackstate-k8s-agent.imageRegistry" $top) $registryAuthDocument }} +{{- end }} + +{{- $dockerAuthsDocuments := dict "auths" $registryAuthMap }} + +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "stackstate-k8s-agent.pull-secret.name" . }} + labels: +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +data: + .dockerconfigjson: {{ $dockerAuthsDocuments | toJson | b64enc | quote }} +type: kubernetes.io/dockerconfigjson diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/secret.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/secret.yaml new file mode 100644 index 0000000000..5e0f5f74cd --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/templates/secret.yaml @@ -0,0 +1,27 @@ +{{- if not .Values.stackstate.manageOwnSecrets }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "stackstate-k8s-agent.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: +{{ include "stackstate-k8s-agent.labels" . | indent 4 }} +{{ include "stackstate-k8s-agent.global.extraLabels" . | indent 4 }} + annotations: +{{ include "stackstate-k8s-agent.global.extraAnnotations" . | indent 4 }} +type: Opaque +data: +{{- if .Values.global.receiverApiKey }} + sts-api-key: {{ .Values.global.receiverApiKey | b64enc | quote }} +{{- else }} + sts-api-key: {{ .Values.stackstate.apiKey | b64enc | quote }} +{{- end }} +{{- if .Values.stackstate.cluster.authToken }} + sts-cluster-auth-token: {{ .Values.stackstate.cluster.authToken | b64enc | quote }} +{{- else }} + sts-cluster-auth-token: {{ randAlphaNum 32 | b64enc | quote }} +{{- end }} +{{- range $key, $value := .Values.global.extraEnv.secret }} + {{ $key }}: {{ $value | b64enc | quote }} +{{- end }} +{{- end }} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/test/clusteragent_resources_test.go b/charts/stackstate/stackstate-k8s-agent/1.0.95/test/clusteragent_resources_test.go new file mode 100644 index 0000000000..25875e871a --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/test/clusteragent_resources_test.go @@ -0,0 +1,145 @@ +package test + +import ( + "regexp" + "strings" + "testing" + + v1 "k8s.io/api/rbac/v1" + + "github.com/stretchr/testify/assert" + "gitlab.com/StackVista/DevOps/helm-charts/helmtestutil" +) + +var requiredRules = []string{ + "events+get,list,watch", + "nodes+get,list,watch", + "pods+get,list,watch", + "services+get,list,watch", + "configmaps+create,get,patch,update", +} + +var optionalRules = []string{ + "namespaces+get,list,watch", + "componentstatuses+get,list,watch", + "configmaps+list,watch", // get is already required + "endpoints+get,list,watch", + "persistentvolumeclaims+get,list,watch", + "persistentvolumes+get,list,watch", + "secrets+get,list,watch", + "apps/daemonsets+get,list,watch", + "apps/deployments+get,list,watch", + "apps/replicasets+get,list,watch", + "apps/statefulsets+get,list,watch", + "extensions/ingresses+get,list,watch", + "batch/cronjobs+get,list,watch", + "batch/jobs+get,list,watch", +} + +var roleDescriptionRegexp = regexp.MustCompile(`^((?P\w+)/)?(?P\w+)\+(?P[\w,]+)`) + +type Rule struct { + Group string + ResourceName string + Verb string +} + +func assertRuleExistence(t *testing.T, rules []v1.PolicyRule, roleDescription string, shouldBePresent bool) { + match := roleDescriptionRegexp.FindStringSubmatch(roleDescription) + assert.NotNil(t, match) + + var roleRules []Rule + for _, rule := range rules { + for _, group := range rule.APIGroups { + for _, resource := range rule.Resources { + for _, verb := range rule.Verbs { + roleRules = append(roleRules, Rule{group, resource, verb}) + } + } + } + } + + resGroup := match[roleDescriptionRegexp.SubexpIndex("group")] + resName := match[roleDescriptionRegexp.SubexpIndex("name")] + verbs := strings.Split(match[roleDescriptionRegexp.SubexpIndex("verbs")], ",") + + for _, verb := range verbs { + requiredRule := Rule{resGroup, resName, verb} + found := false + for _, rule := range roleRules { + if rule == requiredRule { + found = true + break + } + } + if shouldBePresent { + assert.Truef(t, found, "Rule %v has not been found", requiredRule) + } else { + assert.Falsef(t, found, "Rule %v should not be present", requiredRule) + } + } +} + +func TestAllResourcesAreEnabled(t *testing.T) { + output := helmtestutil.RenderHelmTemplate(t, "stackstate-k8s-agent", "values/minimal.yaml") + resources := helmtestutil.NewKubernetesResources(t, output) + + assert.Contains(t, resources.ClusterRoles, "stackstate-k8s-agent") + assert.Contains(t, resources.Roles, "stackstate-k8s-agent") + rules := resources.ClusterRoles["stackstate-k8s-agent"].Rules + rules = append(rules, resources.Roles["stackstate-k8s-agent"].Rules...) + + for _, requiredRole := range requiredRules { + assertRuleExistence(t, rules, requiredRole, true) + } + // be default, everything is enabled, so all the optional roles should be present as well + for _, optionalRule := range optionalRules { + assertRuleExistence(t, rules, optionalRule, true) + } +} + +func TestMostOfResourcesAreDisabled(t *testing.T) { + output := helmtestutil.RenderHelmTemplate(t, "stackstate-k8s-agent", "values/minimal.yaml", "values/disable-all-resource.yaml") + resources := helmtestutil.NewKubernetesResources(t, output) + + assert.Contains(t, resources.ClusterRoles, "stackstate-k8s-agent") + assert.Contains(t, resources.Roles, "stackstate-k8s-agent") + rules := resources.ClusterRoles["stackstate-k8s-agent"].Rules + rules = append(rules, resources.Roles["stackstate-k8s-agent"].Rules...) + + for _, requiredRole := range requiredRules { + assertRuleExistence(t, rules, requiredRole, true) + } + + // we expect all optional resources to be removed from ClusterRole with the given values + for _, optionalRule := range optionalRules { + assertRuleExistence(t, rules, optionalRule, false) + } +} + +func TestNoClusterWideModificationRights(t *testing.T) { + output := helmtestutil.RenderHelmTemplate(t, "stackstate-k8s-agent", "values/minimal.yaml", "values/http-header-injector.yaml") + resources := helmtestutil.NewKubernetesResources(t, output) + assert.Contains(t, resources.ClusterRoles, "stackstate-k8s-agent") + illegalVerbs := []string{"create", "patch", "update", "delete"} + + for _, clusterRole := range resources.ClusterRoles { + for _, rule := range clusterRole.Rules { + for _, verb := range rule.Verbs { + assert.NotContains(t, illegalVerbs, verb, "ClusterRole %s should not have %s verb for %s resource", clusterRole.Name, verb, rule.Resources) + } + } + } +} + +func TestServicePortChange(t *testing.T) { + output := helmtestutil.RenderHelmTemplate(t, "stackstate-k8s-agent", "values/minimal.yaml", "values/clustercheck_service_port_override.yaml") + resources := helmtestutil.NewKubernetesResources(t, output) + + cluster_agent_service := resources.Services["stackstate-k8s-agent-cluster-agent"] + + port := cluster_agent_service.Spec.Ports[0] + assert.Equal(t, port.Name, "clusteragent") + assert.Equal(t, port.Port, int32(8008)) + assert.Equal(t, port.TargetPort.IntVal, int32(9009)) +} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/test/clustername_test.go b/charts/stackstate/stackstate-k8s-agent/1.0.95/test/clustername_test.go new file mode 100644 index 0000000000..55090b9956 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/test/clustername_test.go @@ -0,0 +1,54 @@ +package test + +import ( + "testing" + + "github.com/gruntwork-io/terratest/modules/helm" + "github.com/stretchr/testify/assert" + + "gitlab.com/StackVista/DevOps/helm-charts/helmtestutil" +) + +func TestHelmBasicRender(t *testing.T) { + output := helmtestutil.RenderHelmTemplate(t, "stackstate-k8s-agent", "values/minimal.yaml") + + // Parse all resources into their corresponding types for validation and further inspection + helmtestutil.NewKubernetesResources(t, output) +} + +func TestClusterNameValidation(t *testing.T) { + testCases := []struct { + Name string + ClusterName string + IsValid bool + }{ + {"not allowed end with special character [.]", "name.", false}, + {"not allowed end with special character [-]", "name.", false}, + {"not allowed start with special character [-]", "-name", false}, + {"not allowed start with special character [.]", ".name", false}, + {"upper case is not allowed", "Euwest1-prod.cool-company.com", false}, + {"upper case is not allowed", "euwest1-PROD.cool-company.com", false}, + {"upper case is not allowed", "euwest1-prod.cool-company.coM", false}, + {"dots and dashes are allowed in the middle", "euwest1-prod.cool-company.com", true}, + {"underscore is not allowed", "why_7", false}, + } + + for _, testCase := range testCases { + t.Run(testCase.Name, func(t *testing.T) { + output, err := helmtestutil.RenderHelmTemplateOpts( + t, "cluster-agent", + &helm.Options{ + ValuesFiles: []string{"values/minimal.yaml"}, + SetStrValues: map[string]string{ + "stackstate.cluster.name": testCase.ClusterName, + }, + }) + if testCase.IsValid { + assert.Nil(t, err) + } else { + assert.NotNil(t, err) + assert.Contains(t, output, "stackstate.cluster.name: Does not match pattern") + } + }) + } +} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/test/values/clustercheck_ksm_custom_url.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/test/values/clustercheck_ksm_custom_url.yaml new file mode 100644 index 0000000000..57b973eed9 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/test/values/clustercheck_ksm_custom_url.yaml @@ -0,0 +1,7 @@ +checksAgent: + enabled: true + kubeStateMetrics: + url: http://my-custom-ksm-url.monitoring.svc.local:8080/metrics +dependencies: + kubeStateMetrics: + enabled: true diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/test/values/clustercheck_ksm_no_override.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/test/values/clustercheck_ksm_no_override.yaml new file mode 100644 index 0000000000..b6c817d473 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/test/values/clustercheck_ksm_no_override.yaml @@ -0,0 +1,5 @@ +checksAgent: + enabled: true +dependencies: + kubeStateMetrics: + enabled: true diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/test/values/clustercheck_ksm_override.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/test/values/clustercheck_ksm_override.yaml new file mode 100644 index 0000000000..9ca201345a --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/test/values/clustercheck_ksm_override.yaml @@ -0,0 +1,26 @@ +checksAgent: + enabled: true +dependencies: + kubeStateMetrics: + enabled: true +agent: + config: + override: +# agent.config.override -- Disables kubernetes_state check on regular agent pods. + - name: auto_conf.yaml + path: /etc/stackstate-agent/conf.d/kubernetes_state.d + data: | +clusterAgent: + config: + override: +# clusterAgent.config.override -- Defines kubernetes_state check for clusterchecks agents. Auto-discovery +# with ad_identifiers does not work here. Use a specific URL instead. + - name: conf.yaml + path: /etc/stackstate-agent/conf.d/kubernetes_state.d + data: | + cluster_check: true + + init_config: + + instances: + - kube_state_url: http://YOUR_KUBE_STATE_METRICS_SERVICE_NAME:8080/metrics diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/test/values/clustercheck_no_ksm_custom_url.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/test/values/clustercheck_no_ksm_custom_url.yaml new file mode 100644 index 0000000000..a62691878c --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/test/values/clustercheck_no_ksm_custom_url.yaml @@ -0,0 +1,7 @@ +checksAgent: + enabled: true + kubeStateMetrics: + url: http://my-custom-ksm-url.monitoring.svc.local:8080/metrics +dependencies: + kubeStateMetrics: + enabled: false diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/test/values/clustercheck_service_port_override.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/test/values/clustercheck_service_port_override.yaml new file mode 100644 index 0000000000..c01a98fcb4 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/test/values/clustercheck_service_port_override.yaml @@ -0,0 +1,4 @@ +clusterAgent: + service: + port: 8008 + targetPort: 9009 diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/test/values/disable-all-resource.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/test/values/disable-all-resource.yaml new file mode 100644 index 0000000000..cd33e843ea --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/test/values/disable-all-resource.yaml @@ -0,0 +1,17 @@ +clusterAgent: + collection: + kubernetesMetrics: false + kubernetesResources: + namespaces: false + configmaps: false + endpoints: false + persistentvolumes: false + persistentvolumeclaims: false + secrets: false + daemonsets: false + deployments: false + replicasets: false + statefulsets: false + ingresses: false + cronjobs: false + jobs: false diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/test/values/http-header-injector.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/test/values/http-header-injector.yaml new file mode 100644 index 0000000000..c9392ce2dd --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/test/values/http-header-injector.yaml @@ -0,0 +1,8 @@ +httpHeaderInjectorWebhook: + webhook: + tls: + mode: "provided" + provided: + caBundle: insert-ca-here + crt: insert-cert-here + key: insert-key-here diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/test/values/minimal.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/test/values/minimal.yaml new file mode 100644 index 0000000000..b310c9a093 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/test/values/minimal.yaml @@ -0,0 +1,7 @@ +stackstate: + apiKey: foobar + cluster: + name: some-k8s-cluster + token: some-token + + url: https://stackstate:7000/receiver diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/values.schema.json b/charts/stackstate/stackstate-k8s-agent/1.0.95/values.schema.json new file mode 100644 index 0000000000..57d36a9f34 --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/values.schema.json @@ -0,0 +1,78 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "https://stackstate.io/example.json", + "type": "object", + "default": {}, + "title": "StackState Agent Helm chart values", + "required": [ + "stackstate", + "clusterAgent" + ], + "properties": { + "stackstate": { + "type": "object", + "required": [ + "cluster", + "url" + ], + "properties": { + "apiKey": { + "type": "string" + }, + "cluster": { + "type": "object", + "required": ["name"], + "properties": { + "name": { + "type": "string", + "pattern": "^[a-z0-9]([a-z0-9\\-\\.]*[a-z0-9])$" + }, + "authToken": { + "type": "string" + } + } + }, + "url": { + "type": "string" + } + } + }, + "clusterAgent": { + "type": "object", + "required": [ + "config" + ], + "properties": { + "config": { + "type": "object", + "required": [ + "events" + ], + "properties": { + "events": { + "type": "object", + "properties": { + "categories": { + "type": "object", + "patternProperties": { + ".*": { + "type": [ + "string" + ], + "enum": [ + "Alerts", + "Activities", + "Changes", + "Others" + ] + } + } + } + } + } + } + } + } + } + } +} diff --git a/charts/stackstate/stackstate-k8s-agent/1.0.95/values.yaml b/charts/stackstate/stackstate-k8s-agent/1.0.95/values.yaml new file mode 100644 index 0000000000..50112c361f --- /dev/null +++ b/charts/stackstate/stackstate-k8s-agent/1.0.95/values.yaml @@ -0,0 +1,616 @@ +##################### +# General variables # +##################### + +global: + extraEnv: + # global.extraEnv.open -- Extra open environment variables to inject into pods. + open: {} + # global.extraEnv.secret -- Extra secret environment variables to inject into pods via a `Secret` object. + secret: {} + # global.imagePullSecrets -- Secrets / credentials needed for container image registry. + imagePullSecrets: [] + # global.imagePullCredentials -- Globally define credentials for pulling images. + imagePullCredentials: {} + proxy: + # global.proxy.url -- Proxy for all traffic to stackstate + url: "" + # global.skipSslValidation -- Enable tls validation from client + skipSslValidation: false + + # global.extraLabels -- Extra labels added ta all resources created by the helm chart + extraLabels: {} + # global.extraAnnotations -- Extra annotations added ta all resources created by the helm chart + extraAnnotations: {} + +# nameOverride -- Override the name of the chart. +nameOverride: "" +# fullnameOverride -- Override the fullname of the chart. +fullnameOverride: "" + +# targetSystem -- Target OS for this deployment (possible values: linux) +targetSystem: "linux" + +all: + image: + # all.image.registry -- The image registry to use. + registry: "quay.io" + hardening: + # all.hardening.enabled -- An indication of whether the containers will be evaluated for hardening at runtime + enabled: false + +nodeAgent: + # nodeAgent.autoScalingEnabled -- Enable / disable autoscaling for the node agent pods. + autoScalingEnabled: false + containerRuntime: + # nodeAgent.containerRuntime.customSocketPath -- If the container socket path does not match the default for CRI-O, Containerd or Docker, supply a custom socket path. + customSocketPath: "" + # nodeAgent.containerRuntime.customHostProc -- If the container is launched from a place where /proc is mounted differently, /proc can be changed + hostProc: /proc + + scc: + # nodeAgent.scc.enabled -- Enable / disable the installation of the SecurityContextConfiguration needed for installation on OpenShift. + enabled: false + apm: + # nodeAgent.apm.enabled -- Enable / disable the nodeAgent APM module. + enabled: true + networkTracing: + # nodeAgent.networkTracing.enabled -- Enable / disable the nodeAgent network tracing module. + enabled: true + protocolInspection: + # nodeAgent.protocolInspection.enabled -- Enable / disable the nodeAgent protocol inspection. + enabled: true + httpTracing: + enabled: true + # nodeAgent.skipSslValidation -- Set to true if self signed certificates are used. + skipSslValidation: false + # nodeAgent.skipKubeletTLSVerify -- Set to true if you want to skip kubelet tls verification. + skipKubeletTLSVerify: false + + # nodeAgent.checksTagCardinality -- low, orchestrator or high. Orchestrator level adds pod_name, high adds display_container_name + checksTagCardinality: orchestrator + + # nodeAgent.config -- + config: + # nodeAgent.config.override -- A list of objects containing three keys `name`, `path` and `data`, specifying filenames at specific paths which need to be (potentially) overridden using a mounted configmap + override: [] + + # nodeAgent.priorityClassName -- Priority class for nodeAgent pods. + priorityClassName: "" + + scaling: + autoscalerLimits: + agent: + minimum: + # nodeAgent.scaling.autoscalerLimits.agent.minimum.cpu -- Minimum CPU resource limits for main agent. + cpu: "20m" + # nodeAgent.scaling.autoscalerLimits.agent.minimum.memory -- Minimum memory resource limits for main agent. + memory: "180Mi" + maximum: + # nodeAgent.scaling.autoscalerLimits.agent.maximum.cpu -- Maximum CPU resource limits for main agent. + cpu: "200m" + # nodeAgent.scaling.autoscalerLimits.agent.maximum.memory -- Maximum memory resource limits for main agent. + memory: "450Mi" + processAgent: + minimum: + # nodeAgent.scaling.autoscalerLimits.processAgent.minimum.cpu -- Minimum CPU resource limits for process agent. + cpu: "25m" + # nodeAgent.scaling.autoscalerLimits.processAgent.minimum.memory -- Minimum memory resource limits for process agent. + memory: "100Mi" + maximum: + # nodeAgent.scaling.autoscalerLimits.processAgent.maximum.cpu -- Maximum CPU resource limits for process agent. + cpu: "200m" + # nodeAgent.scaling.autoscalerLimits.processAgent.maximum.memory -- Maximum memory resource limits for process agent. + memory: "500Mi" + + containers: + agent: + image: + # nodeAgent.containers.agent.image.repository -- Base container image repository. + repository: stackstate/stackstate-k8s-agent + # nodeAgent.containers.agent.image.tag -- Default container image tag. + tag: "10e27026" + # nodeAgent.containers.agent.image.pullPolicy -- Default container image pull policy. + pullPolicy: IfNotPresent + processAgent: + # nodeAgent.containers.agent.processAgent.enabled -- Enable / disable the agent process agent module. - deprecated + enabled: false + # nodeAgent.containers.agent.env -- Additional environment variables for the agent container + env: {} + # nodeAgent.containers.agent.logLevel -- Set logging verbosity, valid log levels are: trace, debug, info, warn, error, critical, and off + ## If not set, fall back to the value of agent.logLevel. + logLevel: # INFO + + resources: + limits: + # nodeAgent.containers.agent.resources.limits.cpu -- CPU resource limits. + cpu: "270m" + # nodeAgent.containers.agent.resources.limits.memory -- Memory resource limits. + memory: "420Mi" + requests: + # nodeAgent.containers.agent.resources.requests.cpu -- CPU resource requests. + cpu: "20m" + # nodeAgent.containers.agent.resources.requests.memory -- Memory resource requests. + memory: "180Mi" + livenessProbe: + # nodeAgent.containers.agent.livenessProbe.enabled -- Enable use of livenessProbe check. + enabled: true + # nodeAgent.containers.agent.livenessProbe.failureThreshold -- `failureThreshold` for the liveness probe. + failureThreshold: 3 + # nodeAgent.containers.agent.livenessProbe.initialDelaySeconds -- `initialDelaySeconds` for the liveness probe. + initialDelaySeconds: 15 + # nodeAgent.containers.agent.livenessProbe.periodSeconds -- `periodSeconds` for the liveness probe. + periodSeconds: 15 + # nodeAgent.containers.agent.livenessProbe.successThreshold -- `successThreshold` for the liveness probe. + successThreshold: 1 + # nodeAgent.containers.agent.livenessProbe.timeoutSeconds -- `timeoutSeconds` for the liveness probe. + timeoutSeconds: 5 + readinessProbe: + # nodeAgent.containers.agent.readinessProbe.enabled -- Enable use of readinessProbe check. + enabled: true + # nodeAgent.containers.agent.readinessProbe.failureThreshold -- `failureThreshold` for the readiness probe. + failureThreshold: 3 + # nodeAgent.containers.agent.readinessProbe.initialDelaySeconds -- `initialDelaySeconds` for the readiness probe. + initialDelaySeconds: 15 + # nodeAgent.containers.agent.readinessProbe.periodSeconds -- `periodSeconds` for the readiness probe. + periodSeconds: 15 + # nodeAgent.containers.agent.readinessProbe.successThreshold -- `successThreshold` for the readiness probe. + successThreshold: 1 + # nodeAgent.containers.agent.readinessProbe.timeoutSeconds -- `timeoutSeconds` for the readiness probe. + timeoutSeconds: 5 + + processAgent: + # nodeAgent.containers.processAgent.enabled -- Enable / disable the process agent container. + enabled: true + image: + # Override to pull the image from an alternate registry + registry: + # nodeAgent.containers.processAgent.image.repository -- Process-agent container image repository. + repository: stackstate/stackstate-k8s-process-agent + # nodeAgent.containers.processAgent.image.tag -- Default process-agent container image tag. + tag: "cae7a4fa" + # nodeAgent.containers.processAgent.image.pullPolicy -- Process-agent container image pull policy. + pullPolicy: IfNotPresent + # nodeAgent.containers.processAgent.env -- Additional environment variables for the process-agent container + env: {} + # nodeAgent.containers.processAgent.logLevel -- Set logging verbosity, valid log levels are: trace, debug, info, warn, error, critical, and off + ## If not set, fall back to the value of agent.logLevel. + logLevel: # INFO + + # nodeAgent.containers.processAgent.procVolumeReadOnly -- Configure whether /host/proc is read only for the process agent container + procVolumeReadOnly: true + + resources: + limits: + # nodeAgent.containers.processAgent.resources.limits.cpu -- CPU resource limits. + cpu: "125m" + # nodeAgent.containers.processAgent.resources.limits.memory -- Memory resource limits. + memory: "400Mi" + requests: + # nodeAgent.containers.processAgent.resources.requests.cpu -- CPU resource requests. + cpu: "25m" + # nodeAgent.containers.processAgent.resources.requests.memory -- Memory resource requests. + memory: "128Mi" + # nodeAgent.service -- The Kubernetes service for the agent + service: + # nodeAgent.service.type -- Type of Kubernetes service: ClusterIP, LoadBalancer, NodePort + type: ClusterIP + # nodeAgent.service.annotations -- Annotations for the service + annotations: {} + # nodeAgent.service.loadBalancerSourceRanges -- The IP4 CIDR allowed to reach LoadBalancer for the service. For LoadBalancer type of service only. + loadBalancerSourceRanges: ["10.0.0.0/8"] + + # nodeAgent.logLevel -- Logging level for agent processes. + logLevel: INFO + + # nodeAgent.updateStrategy -- The update strategy for the DaemonSet object. + updateStrategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 100 + + # nodeAgent.nodeSelector -- Node labels for pod assignment. + nodeSelector: {} + + # nodeAgent.tolerations -- Toleration labels for pod assignment. + tolerations: [] + + # nodeAgent.affinity -- Affinity settings for pod assignment. + affinity: {} + + serviceaccount: + # nodeAgent.serviceaccount.annotations -- Annotations for the service account for the agent daemonset pods + annotations: {} + +processAgent: + softMemoryLimit: + # processAgent.softMemoryLimit.goMemLimit -- Soft-limit for golang heap allocation, for sanity, must be around 85% of nodeAgent.containers.processAgent.resources.limits.cpu. + goMemLimit: 340MiB + # processAgent.softMemoryLimit.httpStatsBufferSize -- Sets a maximum for the number of http stats to keep in memory between check runs, to use 40k requires around ~400Mib of memory. + httpStatsBufferSize: 40000 + # processAgent.softMemoryLimit.httpObservationsBufferSize -- Sets a maximum for the number of http observations to keep in memory between check runs, to use 40k requires around ~400Mib of memory. + httpObservationsBufferSize: 40000 + + checkIntervals: + # processAgent.checkIntervals.container -- Override the default value of the container check interval in seconds. + container: 28 + # processAgent.checkIntervals.connections -- Override the default value of the connections check interval in seconds. + connections: 30 + # processAgent.checkIntervals.process -- Override the default value of the process check interval in seconds. + process: 32 + +clusterAgent: + collection: + # clusterAgent.collection.kubernetesEvents -- Enable / disable the cluster agent events collection. + kubernetesEvents: true + # clusterAgent.collection.kubernetesMetrics -- Enable / disable the cluster agent metrics collection. + kubernetesMetrics: true + # clusterAgent.collection.kubernetesTimeout -- Default timeout (in seconds) when obtaining information from the Kubernetes API. + kubernetesTimeout: 10 + # clusterAgent.collection.kubernetesTopology -- Enable / disable the cluster agent topology collection. + kubernetesTopology: true + kubeStateMetrics: + # clusterAgent.collection.kubeStateMetrics.enabled -- Enable / disable the cluster agent kube-state-metrics collection. + enabled: true + # clusterAgent.collection.kubeStateMetrics.clusterCheck -- For large clusters where the Kubernetes State Metrics Check Core needs to be distributed on dedicated workers. + clusterCheck: false + # clusterAgent.collection.kubeStateMetrics.labelsAsTags -- Extra labels to collect from resources and to turn into StackState tag. + ## It has the following structure: + ## labelsAsTags: + ## : # can be pod, deployment, node, etc. + ## : # where is the kubernetes label and is the StackState tag + ## : + ## : + ## : + ## + ## Warning: the label must match the transformation done by kube-state-metrics, + ## for example tags.stackstate/version becomes tags_stackstate_version. + labelsAsTags: {} + # pod: + # app: app + # node: + # zone: zone + # team: team + + # clusterAgent.collection.kubeStateMetrics.annotationsAsTags -- Extra annotations to collect from resources and to turn into StackState tag. + + ## It has the following structure: + ## annotationsAsTags: + ## : # can be pod, deployment, node, etc. + ## : # where is the kubernetes annotation and is the StackState tag + ## : + ## : + ## : + ## + ## Warning: the annotation must match the transformation done by kube-state-metrics, + ## for example tags.stackstate/version becomes tags_stackstate_version. + annotationsAsTags: {} + kubernetesResources: + # clusterAgent.collection.kubernetesResources.limitranges -- Enable / disable collection of LimitRanges. + limitranges: true + # clusterAgent.collection.kubernetesResources.horizontalpodautoscalers -- Enable / disable collection of HorizontalPodAutoscalers. + horizontalpodautoscalers: true + # clusterAgent.collection.kubernetesResources.replicationcontrollers -- Enable / disable collection of ReplicationControllers. + replicationcontrollers: true + # clusterAgent.collection.kubernetesResources.poddisruptionbudgets -- Enable / disable collection of PodDisruptionBudgets. + poddisruptionbudgets: true + # clusterAgent.collection.kubernetesResources.storageclasses -- Enable / disable collection of StorageClasses. + storageclasses: true + # clusterAgent.collection.kubernetesResources.volumeattachments -- Enable / disable collection of Volume Attachments. Used to bind Nodes to Persistent Volumes. + volumeattachments: true + # clusterAgent.collection.kubernetesResources.namespaces -- Enable / disable collection of Namespaces. + namespaces: true + # clusterAgent.collection.kubernetesResources.configmaps -- Enable / disable collection of ConfigMaps. + configmaps: true + # clusterAgent.collection.kubernetesResources.endpoints -- Enable / disable collection of Endpoints. If endpoints are disabled then StackState won't be able to connect a Service to Pods that serving it + endpoints: true + # clusterAgent.collection.kubernetesResources.persistentvolumes -- Enable / disable collection of PersistentVolumes. + persistentvolumes: true + # clusterAgent.collection.kubernetesResources.persistentvolumeclaims -- Enable / disable collection of PersistentVolumeClaims. Disabling these will not let StackState connect PersistentVolumes to pods they are attached to + persistentvolumeclaims: true + # clusterAgent.collection.kubernetesResources.secrets -- Enable / disable collection of Secrets. + secrets: true + # clusterAgent.collection.kubernetesResources.daemonsets -- Enable / disable collection of DaemonSets. + daemonsets: true + # clusterAgent.collection.kubernetesResources.deployments -- Enable / disable collection of Deployments. + deployments: true + # clusterAgent.collection.kubernetesResources.replicasets -- Enable / disable collection of ReplicaSets. + replicasets: true + # clusterAgent.collection.kubernetesResources.statefulsets -- Enable / disable collection of StatefulSets. + statefulsets: true + # clusterAgent.collection.kubernetesResources.ingresses -- Enable / disable collection of Ingresses. + ingresses: true + # clusterAgent.collection.kubernetesResources.cronjobs -- Enable / disable collection of CronJobs. + cronjobs: true + # clusterAgent.collection.kubernetesResources.jobs -- Enable / disable collection of Jobs. + jobs: true + # clusterAgent.collection.kubernetesResources.resourcequotas -- Enable / disable collection of ResourceQuotas. + resourcequotas: true + + # clusterAgent.config -- + config: + events: + # clusterAgent.config.events.categories -- Custom mapping from Kubernetes event reason to StackState event category. Categories allowed: Alerts, Activities, Changes, Others + categories: {} + topology: + # clusterAgent.config.topology.collectionInterval -- Interval for running topology collection, in seconds + collectionInterval: 90 + configMap: + # clusterAgent.config.configMap.maxDataSize -- Maximum amount of characters for the data property of a ConfigMap collected by the kubernetes topology check + maxDataSize: + # clusterAgent.config.override -- A list of objects containing three keys `name`, `path` and `data`, specifying filenames at specific paths which need to be (potentially) overridden using a mounted configmap + override: [] + + service: + # clusterAgent.service.port -- Change the Cluster Agent service port + port: 5005 + # clusterAgent.service.targetPort -- Change the Cluster Agent service targetPort + targetPort: 5005 + + # clusterAgent.enabled -- Enable / disable the cluster agent. + enabled: true + + # clusterAgent.skipSslValidation -- If true, ignores the server certificate being signed by an unknown authority. + skipSslValidation: false + + image: + # clusterAgent.image.repository -- Base container image repository. + repository: stackstate/stackstate-k8s-cluster-agent + # clusterAgent.image.tag -- Default container image tag. + tag: "10e27026" + # clusterAgent.image.pullPolicy -- Default container image pull policy. + pullPolicy: IfNotPresent + + livenessProbe: + # clusterAgent.livenessProbe.enabled -- Enable use of livenessProbe check. + enabled: true + # clusterAgent.livenessProbe.failureThreshold -- `failureThreshold` for the liveness probe. + failureThreshold: 3 + # clusterAgent.livenessProbe.initialDelaySeconds -- `initialDelaySeconds` for the liveness probe. + initialDelaySeconds: 15 + # clusterAgent.livenessProbe.periodSeconds -- `periodSeconds` for the liveness probe. + periodSeconds: 15 + # clusterAgent.livenessProbe.successThreshold -- `successThreshold` for the liveness probe. + successThreshold: 1 + # clusterAgent.livenessProbe.timeoutSeconds -- `timeoutSeconds` for the liveness probe. + timeoutSeconds: 5 + + # clusterAgent.logLevel -- Logging level for stackstate-k8s-agent processes. + logLevel: INFO + + # clusterAgent.priorityClassName -- Priority class for stackstate-k8s-agent pods. + priorityClassName: "" + + readinessProbe: + # clusterAgent.readinessProbe.enabled -- Enable use of readinessProbe check. + enabled: true + # clusterAgent.readinessProbe.failureThreshold -- `failureThreshold` for the readiness probe. + failureThreshold: 3 + # clusterAgent.readinessProbe.initialDelaySeconds -- `initialDelaySeconds` for the readiness probe. + initialDelaySeconds: 15 + # clusterAgent.readinessProbe.periodSeconds -- `periodSeconds` for the readiness probe. + periodSeconds: 15 + # clusterAgent.readinessProbe.successThreshold -- `successThreshold` for the readiness probe. + successThreshold: 1 + # clusterAgent.readinessProbe.timeoutSeconds -- `timeoutSeconds` for the readiness probe. + timeoutSeconds: 5 + + # clusterAgent.replicaCount -- Number of replicas of the cluster agent to deploy. + replicaCount: 1 + + serviceaccount: + # clusterAgent.serviceaccount.annotations -- Annotations for the service account for the cluster agent pods + annotations: {} + + # clusterAgent.strategy -- The strategy for the Deployment object. + strategy: + type: RollingUpdate + # rollingUpdate: + # maxUnavailable: 1 + + resources: + limits: + # clusterAgent.resources.limits.cpu -- CPU resource limits. + cpu: "400m" + # clusterAgent.resources.limits.memory -- Memory resource limits. + memory: "800Mi" + requests: + # clusterAgent.resources.requests.cpu -- CPU resource requests. + cpu: "70m" + # clusterAgent.resources.requests.memory -- Memory resource requests. + memory: "512Mi" + + # clusterAgent.nodeSelector -- Node labels for pod assignment. + nodeSelector: {} + + # clusterAgent.tolerations -- Toleration labels for pod assignment. + tolerations: [] + + # clusterAgent.affinity -- Affinity settings for pod assignment. + affinity: {} + +openShiftLogging: + # openShiftLogging.installSecret -- Install a secret for logging on openshift + installSecret: false + +logsAgent: + # logsAgent.enabled -- Enable / disable k8s pod log collection + enabled: true + + # logsAgent.skipSslValidation -- If true, ignores the server certificate being signed by an unknown authority. + skipSslValidation: false + + # logsAgent.priorityClassName -- Priority class for logsAgent pods. + priorityClassName: "" + + image: + # logsAgent.image.repository -- Base container image repository. + repository: stackstate/promtail + # logsAgent.image.tag -- Default container image tag. + tag: 2.9.8-5b179aee + # logsAgent.image.pullPolicy -- Default container image pull policy. + pullPolicy: IfNotPresent + + resources: + limits: + # logsAgent.resources.limits.cpu -- CPU resource limits. + cpu: "1300m" + # logsAgent.resources.limits.memory -- Memory resource limits. + memory: "192Mi" + requests: + # logsAgent.resources.requests.cpu -- CPU resource requests. + cpu: "20m" + # logsAgent.resources.requests.memory -- Memory resource requests. + memory: "100Mi" + + # logsAgent.updateStrategy -- The update strategy for the DaemonSet object. + updateStrategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 100 + + # logsAgent.nodeSelector -- Node labels for pod assignment. + nodeSelector: {} + + # logsAgent.tolerations -- Toleration labels for pod assignment. + tolerations: [] + + # logsAgent.affinity -- Affinity settings for pod assignment. + affinity: {} + + serviceaccount: + # logsAgent.serviceaccount.annotations -- Annotations for the service account for the daemonset pods + annotations: {} + +checksAgent: + # checksAgent.enabled -- Enable / disable runnning cluster checks in a separately deployed pod + enabled: true + scc: + # checksAgent.scc.enabled -- Enable / disable the installation of the SecurityContextConfiguration needed for installation on OpenShift + enabled: false + apm: + # checksAgent.apm.enabled -- Enable / disable the agent APM module. + enabled: true + networkTracing: + # checksAgent.networkTracing.enabled -- Enable / disable the agent network tracing module. + enabled: true + processAgent: + # checksAgent.processAgent.enabled -- Enable / disable the agent process agent module. + enabled: true + # checksAgent.skipSslValidation -- Set to true if self signed certificates are used. + skipSslValidation: false + + # nodeAgent.checksTagCardinality -- low, orchestrator or high. Orchestrator level adds pod_name, high adds display_container_name + checksTagCardinality: orchestrator + + # checksAgent.config -- + config: + # checksAgent.config.override -- A list of objects containing three keys `name`, `path` and `data`, specifying filenames at specific paths which need to be (potentially) overridden using a mounted configmap + override: [] + + image: + # checksAgent.image.repository -- Base container image repository. + repository: stackstate/stackstate-k8s-agent + # checksAgent.image.tag -- Default container image tag. + tag: "10e27026" + # checksAgent.image.pullPolicy -- Default container image pull policy. + pullPolicy: IfNotPresent + + livenessProbe: + # checksAgent.livenessProbe.enabled -- Enable use of livenessProbe check. + enabled: true + # checksAgent.livenessProbe.failureThreshold -- `failureThreshold` for the liveness probe. + failureThreshold: 3 + # checksAgent.livenessProbe.initialDelaySeconds -- `initialDelaySeconds` for the liveness probe. + initialDelaySeconds: 15 + # checksAgent.livenessProbe.periodSeconds -- `periodSeconds` for the liveness probe. + periodSeconds: 15 + # checksAgent.livenessProbe.successThreshold -- `successThreshold` for the liveness probe. + successThreshold: 1 + # checksAgent.livenessProbe.timeoutSeconds -- `timeoutSeconds` for the liveness probe. + timeoutSeconds: 5 + + # checksAgent.logLevel -- Logging level for clusterchecks agent processes. + logLevel: INFO + + # checksAgent.priorityClassName -- Priority class for clusterchecks agent pods. + priorityClassName: "" + + readinessProbe: + # checksAgent.readinessProbe.enabled -- Enable use of readinessProbe check. + enabled: true + # checksAgent.readinessProbe.failureThreshold -- `failureThreshold` for the readiness probe. + failureThreshold: 3 + # checksAgent.readinessProbe.initialDelaySeconds -- `initialDelaySeconds` for the readiness probe. + initialDelaySeconds: 15 + # checksAgent.readinessProbe.periodSeconds -- `periodSeconds` for the readiness probe. + periodSeconds: 15 + # checksAgent.readinessProbe.successThreshold -- `successThreshold` for the readiness probe. + successThreshold: 1 + # checksAgent.readinessProbe.timeoutSeconds -- `timeoutSeconds` for the readiness probe. + timeoutSeconds: 5 + + # checksAgent.replicas -- Number of clusterchecks agent pods to schedule + replicas: 1 + + resources: + limits: + # checksAgent.resources.limits.cpu -- CPU resource limits. + cpu: "400m" + # checksAgent.resources.limits.memory -- Memory resource limits. + memory: "600Mi" + requests: + # checksAgent.resources.requests.cpu -- CPU resource requests. + cpu: "20m" + # checksAgent.resources.requests.memory -- Memory resource requests. + memory: "512Mi" + + serviceaccount: + # checksAgent.serviceaccount.annotations -- Annotations for the service account for the cluster checks pods + annotations: {} + + # checksAgent.strategy -- The strategy for the Deployment object. + strategy: + type: RollingUpdate + # rollingUpdate: + # maxUnavailable: 1 + + # checksAgent.nodeSelector -- Node labels for pod assignment. + nodeSelector: {} + + # checksAgent.tolerations -- Toleration labels for pod assignment. + tolerations: [] + + # checksAgent.affinity -- Affinity settings for pod assignment. + affinity: {} + +################################## +# http-header-injector variables # +################################## + +httpHeaderInjectorWebhook: + # httpHeaderInjectorWebhook.enabled -- Enable the webhook for injection http header injection sidecar proxy + enabled: false + +######################## +# StackState variables # +######################## + +stackstate: + # stackstate.manageOwnSecrets -- Set to true if you don't want this helm chart to create secrets for you. + manageOwnSecrets: false + # stackstate.customSecretName -- Name of the secret containing the receiver API key. + customSecretName: "" + # stackstate.customApiKeySecretKey -- Key in the secret containing the receiver API key. + customApiKeySecretKey: "sts-api-key" + # stackstate.customClusterAuthTokenSecretKey -- Key in the secret containing the cluster auth token. + customClusterAuthTokenSecretKey: "sts-cluster-auth-token" + # stackstate.apiKey -- (string) **PROVIDE YOUR API KEY HERE** API key to be used by the StackState agent. + apiKey: + cluster: + # stackstate.cluster.name -- (string) **PROVIDE KUBERNETES CLUSTER NAME HERE** Name of the Kubernetes cluster where the agent will be installed. + name: + # stackstate.cluster.authToken -- Provide a token to enable secure communication between the agent and the cluster agent. + authToken: "" + # stackstate.url -- (string) **PROVIDE STACKSTATE URL HERE** URL of the StackState installation to receive data from the agent. + url: diff --git a/index.yaml b/index.yaml index e2bdc0b092..345a4fa90a 100644 --- a/index.yaml +++ b/index.yaml @@ -5006,6 +5006,28 @@ entries: - assets/cloudcasa/cloudcasa-3.4.1.tgz version: 3.4.1 cockroachdb: + - annotations: + catalog.cattle.io/certified: partner + catalog.cattle.io/display-name: CockroachDB + catalog.cattle.io/kube-version: '>=1.8-0' + catalog.cattle.io/release-name: cockroachdb + apiVersion: v1 + appVersion: 24.2.0 + created: "2024-08-27T00:49:41.602925253Z" + description: CockroachDB is a scalable, survivable, strongly-consistent SQL database. + digest: da43944821ba55e30c474d995a81e7e986a84fa0ba457a18db6899cd3de18ce5 + home: https://www.cockroachlabs.com + icon: file://assets/icons/cockroachdb.png + kubeVersion: '>=1.8-0' + maintainers: + - email: helm-charts@cockroachlabs.com + name: cockroachlabs + name: cockroachdb + sources: + - https://github.com/cockroachdb/cockroach + urls: + - assets/cockroach-labs/cockroachdb-14.0.0.tgz + version: 14.0.0 - annotations: catalog.cattle.io/certified: partner catalog.cattle.io/display-name: CockroachDB @@ -5736,6 +5758,33 @@ entries: - assets/mongodb/community-operator-0.8.1.tgz version: 0.8.1 confluent-for-kubernetes: + - annotations: + catalog.cattle.io/certified: partner + catalog.cattle.io/display-name: Confluent for Kubernetes + catalog.cattle.io/kube-version: '>=1.15-0' + catalog.cattle.io/release-name: confluent-for-kubernetes + apiVersion: v1 + appVersion: 2.9.2 + created: "2024-08-27T00:49:41.646296631Z" + description: A Helm chart to deploy Confluent for Kubernetes + digest: 0080bf38adc574676506f7655725b28b533d64a997e34bd4bcf22fd8bfd32598 + home: https://www.confluent.io/ + icon: file://assets/icons/confluent-for-kubernetes.png + keywords: + - Confluent + - Confluent Operator + - Confluent Platform + - CFK + kubeVersion: '>=1.15-0' + maintainers: + - email: operator@confluent.io + name: Confluent Operator + name: confluent-for-kubernetes + sources: + - https://docs.confluent.io/current/index.html + urls: + - assets/confluent/confluent-for-kubernetes-0.1033.22.tgz + version: 0.1033.22 - annotations: catalog.cattle.io/certified: partner catalog.cattle.io/display-name: Confluent for Kubernetes @@ -7490,6 +7539,28 @@ entries: - assets/kubecost/cost-analyzer-1.103.3.tgz version: 1.103.3 crate-operator: + - annotations: + catalog.cattle.io/certified: partner + catalog.cattle.io/display-name: CrateDB Operator + catalog.cattle.io/release-name: crate-operator + apiVersion: v2 + appVersion: 2.41.0 + created: "2024-08-27T00:49:41.759613378Z" + dependencies: + - condition: crate-operator-crds.enabled + name: crate-operator-crds + repository: file://./charts/crate-operator-crds + version: 2.41.0 + description: Crate Operator - Helm chart for installing and upgrading Crate Operator. + digest: eec3722e8176506d27dc4b7f21128b924cd2bf809b796f25f525a5692135566d + icon: file://assets/icons/crate-operator.svg + maintainers: + - name: Crate.io + name: crate-operator + type: application + urls: + - assets/crate/crate-operator-2.41.0.tgz + version: 2.41.0 - annotations: catalog.cattle.io/certified: partner catalog.cattle.io/display-name: CrateDB Operator @@ -34233,6 +34304,37 @@ entries: - assets/btp/sextant-2.2.21.tgz version: 2.2.21 speedscale-operator: + - annotations: + catalog.cattle.io/certified: partner + catalog.cattle.io/display-name: Speedscale Operator + catalog.cattle.io/kube-version: '>= 1.17.0-0' + catalog.cattle.io/release-name: speedscale-operator + apiVersion: v1 + appVersion: 2.2.303 + created: "2024-08-27T00:49:45.582969956Z" + description: Stress test your APIs with real world scenarios. Collect and replay + traffic without scripting. + digest: ef375b276988268d3544af7657c4f10eadc4b56686aef548559236e2b0b61b10 + home: https://speedscale.com + icon: file://assets/icons/speedscale-operator.png + keywords: + - speedscale + - test + - testing + - regression + - reliability + - load + - replay + - network + - traffic + kubeVersion: '>= 1.17.0-0' + maintainers: + - email: support@speedscale.com + name: Speedscale Support + name: speedscale-operator + urls: + - assets/speedscale/speedscale-operator-2.2.303.tgz + version: 2.2.303 - annotations: catalog.cattle.io/certified: partner catalog.cattle.io/display-name: Speedscale Operator @@ -36714,6 +36816,35 @@ entries: - assets/speedscale/speedscale-operator-1.3.10.tgz version: 1.3.10 stackstate-k8s-agent: + - annotations: + catalog.cattle.io/certified: partner + catalog.cattle.io/display-name: StackState Agent + catalog.cattle.io/kube-version: '>=1.19.0-0' + catalog.cattle.io/release-name: stackstate-k8s-agent + apiVersion: v2 + appVersion: 3.0.0 + created: "2024-08-27T00:49:45.633810569Z" + dependencies: + - alias: httpHeaderInjectorWebhook + name: http-header-injector + repository: file://./charts/http-header-injector + version: 0.0.11 + description: Helm chart for the StackState Agent. + digest: 8c34a357ce6cbfddcaf9afb2567611450b9821a20d7fe3c2b8cb03a98009e704 + home: https://github.com/StackVista/stackstate-agent + icon: file://assets/icons/stackstate-k8s-agent.svg + keywords: + - monitoring + - observability + - stackstate + kubeVersion: '>=1.19.0-0' + maintainers: + - email: ops@stackstate.com + name: Stackstate + name: stackstate-k8s-agent + urls: + - assets/stackstate/stackstate-k8s-agent-1.0.95.tgz + version: 1.0.95 - annotations: catalog.cattle.io/certified: partner catalog.cattle.io/display-name: StackState Agent @@ -40419,4 +40550,4 @@ entries: urls: - assets/netfoundry/ziti-host-1.5.1.tgz version: 1.5.1 -generated: "2024-08-25T00:53:05.298779498Z" +generated: "2024-08-27T00:49:41.244956912Z"