From bbe16ac3c46aa4b4cfa650096538f45cc6be844d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 30 Aug 2024 00:54:54 +0000 Subject: [PATCH] Added chart versions: airlock/microgateway: - 4.3.2 airlock/microgateway-cni: - 4.3.2 kong/kong: - 2.41.0 linkerd/linkerd-control-plane: - 2024.8.3 linkerd/linkerd-crds: - 2024.8.3 redpanda/redpanda: - 5.9.2 --- assets/airlock/microgateway-4.3.2.tgz | Bin 0 -> 61772 bytes assets/airlock/microgateway-cni-4.3.2.tgz | Bin 0 -> 10968 bytes assets/kong/kong-2.41.0.tgz | Bin 0 -> 160982 bytes .../linkerd-control-plane-2024.8.2.tgz | Bin 31371 -> 31363 bytes .../linkerd-control-plane-2024.8.3.tgz | Bin 0 -> 31373 bytes assets/linkerd/linkerd-crds-2024.8.3.tgz | Bin 0 -> 112983 bytes assets/redpanda/redpanda-5.9.2.tgz | Bin 0 -> 549641 bytes .../microgateway-cni/4.3.2/.helmignore | 27 + .../airlock/microgateway-cni/4.3.2/Chart.yaml | 43 + .../airlock/microgateway-cni/4.3.2/README.md | 137 + .../microgateway-cni/4.3.2/gke-values.yaml | 4 + .../4.3.2/openshift-values.yaml | 15 + .../microgateway-cni/4.3.2/questions.yml | 18 + .../4.3.2/templates/NOTES.txt | 15 + .../4.3.2/templates/_helpers.tpl | 101 + .../4.3.2/templates/clusterrole.yaml | 22 + .../4.3.2/templates/clusterrolebinding.yaml | 20 + .../4.3.2/templates/configmap.yaml | 22 + .../4.3.2/templates/daemonset.yaml | 136 + .../network-attachment-definition.yaml | 13 + .../4.3.2/templates/scc-role.yaml | 22 + .../4.3.2/templates/scc-rolebinding.yaml | 20 + .../4.3.2/templates/serviceaccount.yaml | 13 + .../4.3.2/templates/tests/rbac.yaml | 64 + .../4.3.2/templates/tests/test-install.yaml | 103 + .../microgateway-cni/4.3.2/values.schema.json | 225 + .../microgateway-cni/4.3.2/values.yaml | 85 + charts/airlock/microgateway/4.3.2/.helmignore | 28 + charts/airlock/microgateway/4.3.2/Chart.yaml | 44 + charts/airlock/microgateway/4.3.2/README.md | 180 + .../airlock/microgateway/4.3.2/app-readme.md | 28 + ...cesscontrols.microgateway.airlock.com.yaml | 124 + ...ntsecurities.microgateway.airlock.com.yaml | 139 + .../denyrules.microgateway.airlock.com.yaml | 1804 ++ ...nvoyclusters.microgateway.airlock.com.yaml | 58 + ...nfigurations.microgateway.airlock.com.yaml | 185 + ...yhttpfilters.microgateway.airlock.com.yaml | 58 + .../graphqls.microgateway.airlock.com.yaml | 88 + ...aderrewrites.microgateway.airlock.com.yaml | 759 + ...propagations.microgateway.airlock.com.yaml | 108 + .../crds/limits.microgateway.airlock.com.yaml | 651 + ...idcproviders.microgateway.airlock.com.yaml | 305 + ...lyingparties.microgateway.airlock.com.yaml | 224 + .../openapis.microgateway.airlock.com.yaml | 167 + .../parsers.microgateway.airlock.com.yaml | 358 + ...disproviders.microgateway.airlock.com.yaml | 159 + ...ionhandlings.microgateway.airlock.com.yaml | 77 + ...ecargateways.microgateway.airlock.com.yaml | 758 + .../telemetries.microgateway.airlock.com.yaml | 96 + .../4.3.2/dashboards/blockLogs.json | 510 + .../4.3.2/dashboards/blockMetrics.json | 758 + .../4.3.2/dashboards/license.json | 521 + .../4.3.2/dashboards/overview.json | 1138 + .../microgateway/4.3.2/templates/NOTES.txt | 47 + .../microgateway/4.3.2/templates/_helpers.tpl | 153 + .../templates/operator/_operator_helpers.tpl | 42 + .../4.3.2/templates/operator/_rbac.gen.tpl | 237 + .../templates/operator/_webhooks.gen.tpl | 339 + .../4.3.2/templates/operator/configmap.yaml | 394 + .../operator/dashboard-configmap.yaml | 28 + .../4.3.2/templates/operator/deployment.yaml | 143 + .../templates/operator/manager-role.yaml | 33 + .../operator/manager-rolebinding.yaml | 45 + .../templates/operator/metrics-service.yaml | 47 + .../templates/operator/mutating-webhook.yaml | 28 + .../4.3.2/templates/operator/podmonitor.yaml | 27 + .../4.3.2/templates/operator/role.yaml | 45 + .../4.3.2/templates/operator/rolebinding.yaml | 20 + .../templates/operator/selfsigned-issuer.yaml | 13 + .../templates/operator/serviceaccount.yaml | 13 + .../templates/operator/servicemonitor.yaml | 60 + .../operator/serving-certificate.yaml | 19 + .../operator/validating-webhook.yaml | 28 + .../templates/operator/webhook-service.yaml | 23 + .../4.3.2/templates/operator/xds-service.yaml | 24 + .../4.3.2/templates/tests/rbac.yaml | 143 + .../4.3.2/templates/tests/service.yaml | 23 + .../4.3.2/templates/tests/statefulset.yaml | 56 + .../4.3.2/templates/tests/test-install.yaml | 227 + .../microgateway/4.3.2/values.schema.json | 540 + charts/airlock/microgateway/4.3.2/values.yaml | 213 + charts/kong/kong/2.41.0/CHANGELOG.md | 1932 ++ charts/kong/kong/2.41.0/Chart.lock | 6 + charts/kong/kong/2.41.0/Chart.yaml | 21 + charts/kong/kong/2.41.0/FAQs.md | 139 + charts/kong/kong/2.41.0/README.md | 1240 + charts/kong/kong/2.41.0/UPGRADE.md | 807 + charts/kong/kong/2.41.0/app-readme.md | 7 + .../kong/2.41.0/charts/postgresql/.helmignore | 21 + .../kong/2.41.0/charts/postgresql/Chart.lock | 6 + .../kong/2.41.0/charts/postgresql/Chart.yaml | 30 + .../kong/2.41.0/charts/postgresql/README.md | 683 + .../postgresql/charts/common/.helmignore | 22 + .../postgresql/charts/common/Chart.yaml | 23 + .../charts/postgresql/charts/common/README.md | 350 + .../charts/common/templates/_affinities.tpl | 102 + .../charts/common/templates/_capabilities.tpl | 154 + .../charts/common/templates/_errors.tpl | 23 + .../charts/common/templates/_images.tpl | 76 + .../charts/common/templates/_ingress.tpl | 68 + .../charts/common/templates/_labels.tpl | 18 + .../charts/common/templates/_names.tpl | 70 + .../charts/common/templates/_secrets.tpl | 140 + .../charts/common/templates/_storage.tpl | 23 + .../charts/common/templates/_tplvalues.tpl | 13 + .../charts/common/templates/_utils.tpl | 62 + .../charts/common/templates/_warnings.tpl | 14 + .../templates/validations/_cassandra.tpl | 72 + .../common/templates/validations/_mariadb.tpl | 103 + .../common/templates/validations/_mongodb.tpl | 108 + .../common/templates/validations/_mysql.tpl | 103 + .../templates/validations/_postgresql.tpl | 129 + .../common/templates/validations/_redis.tpl | 76 + .../templates/validations/_validations.tpl | 46 + .../postgresql/charts/common/values.yaml | 5 + .../charts/postgresql/templates/NOTES.txt | 89 + .../charts/postgresql/templates/_helpers.tpl | 399 + .../postgresql/templates/extra-list.yaml | 4 + .../templates/networkpolicy-egress.yaml | 32 + .../templates/primary/configmap.yaml | 24 + .../templates/primary/extended-configmap.yaml | 18 + .../primary/initialization-configmap.yaml | 15 + .../templates/primary/metrics-configmap.yaml | 16 + .../templates/primary/metrics-svc.yaml | 31 + .../templates/primary/networkpolicy.yaml | 57 + .../templates/primary/servicemonitor.yaml | 48 + .../templates/primary/statefulset.yaml | 634 + .../templates/primary/svc-headless.yaml | 31 + .../postgresql/templates/primary/svc.yaml | 51 + .../postgresql/templates/prometheusrule.yaml | 22 + .../charts/postgresql/templates/psp.yaml | 41 + .../templates/read/extended-configmap.yaml | 18 + .../templates/read/metrics-configmap.yaml | 16 + .../templates/read/metrics-svc.yaml | 31 + .../templates/read/networkpolicy.yaml | 36 + .../templates/read/servicemonitor.yaml | 48 + .../templates/read/statefulset.yaml | 531 + .../templates/read/svc-headless.yaml | 33 + .../charts/postgresql/templates/read/svc.yaml | 53 + .../charts/postgresql/templates/role.yaml | 31 + .../postgresql/templates/rolebinding.yaml | 22 + .../charts/postgresql/templates/secrets.yaml | 29 + .../postgresql/templates/serviceaccount.yaml | 19 + .../postgresql/templates/tls-secrets.yaml | 27 + .../charts/postgresql/values.schema.json | 156 + .../kong/2.41.0/charts/postgresql/values.yaml | 1399 + .../crds/custom-resource-definitions.yaml | 2974 ++ charts/kong/kong/2.41.0/questions.yml | 33 + charts/kong/kong/2.41.0/templates/NOTES.txt | 48 + .../kong/kong/2.41.0/templates/_helpers.tpl | 1844 ++ .../2.41.0/templates/admission-webhook.yaml | 256 + .../kong/2.41.0/templates/certificate.yaml | 89 + .../kong/2.41.0/templates/config-dbless.yaml | 17 + .../templates/controller-rbac-resources.yaml | 170 + .../custom-resource-definitions.yaml | 34 + .../kong/2.41.0/templates/deployment.yaml | 313 + .../kong/2.41.0/templates/extraManifests.yaml | 4 + charts/kong/kong/2.41.0/templates/hpa.yaml | 26 + .../kong/2.41.0/templates/ingress-class.yaml | 33 + .../templates/migrations-post-upgrade.yaml | 97 + .../templates/migrations-pre-upgrade.yaml | 99 + .../kong/2.41.0/templates/migrations.yaml | 108 + charts/kong/kong/2.41.0/templates/pdb.yaml | 26 + charts/kong/kong/2.41.0/templates/psp.yaml | 53 + .../2.41.0/templates/secret-sa-token.yaml | 14 + .../2.41.0/templates/service-account.yaml | 15 + .../2.41.0/templates/service-kong-admin.yaml | 113 + .../service-kong-cluster-telemetry.yaml | 17 + .../templates/service-kong-cluster.yaml | 17 + .../templates/service-kong-manager.yaml | 17 + .../templates/service-kong-portal-api.yaml | 19 + .../2.41.0/templates/service-kong-portal.yaml | 19 + .../2.41.0/templates/service-kong-proxy.yaml | 16 + .../templates/service-kong-udp-proxy.yaml | 15 + .../kong/2.41.0/templates/servicemonitor.yaml | 57 + .../templates/wait-for-postgres-script.yaml | 15 + charts/kong/kong/2.41.0/values.yaml | 1264 + .../linkerd-control-plane/2024.8.2/Chart.yaml | 1 - .../2024.8.3/.helmignore | 22 + .../linkerd-control-plane/2024.8.3/Chart.lock | 6 + .../linkerd-control-plane/2024.8.3/Chart.yaml | 29 + .../linkerd-control-plane/2024.8.3/README.md | 312 + .../2024.8.3/README.md.gotmpl | 133 + .../2024.8.3/app-readme.md | 14 + .../2024.8.3/charts/partials/.helmignore | 21 + .../2024.8.3/charts/partials/Chart.yaml | 5 + .../2024.8.3/charts/partials/README.md | 9 + .../2024.8.3/charts/partials/README.md.gotmpl | 14 + .../charts/partials/templates/NOTES.txt | 0 .../charts/partials/templates/_affinity.tpl | 38 + .../partials/templates/_capabilities.tpl | 16 + .../charts/partials/templates/_debug.tpl | 15 + .../charts/partials/templates/_helpers.tpl | 14 + .../charts/partials/templates/_metadata.tpl | 17 + .../partials/templates/_network-validator.tpl | 45 + .../partials/templates/_nodeselector.tpl | 4 + .../partials/templates/_proxy-config-ann.tpl | 18 + .../charts/partials/templates/_proxy-init.tpl | 98 + .../charts/partials/templates/_proxy.tpl | 267 + .../partials/templates/_pull-secrets.tpl | 6 + .../charts/partials/templates/_resources.tpl | 28 + .../partials/templates/_tolerations.tpl | 4 + .../charts/partials/templates/_trace.tpl | 5 + .../charts/partials/templates/_validate.tpl | 19 + .../charts/partials/templates/_volumes.tpl | 20 + .../2024.8.3/charts/partials/values.yaml | 0 .../2024.8.3/questions.yaml | 19 + .../2024.8.3/templates/NOTES.txt | 19 + .../2024.8.3/templates/config-rbac.yaml | 16 + .../2024.8.3/templates/config.yaml | 39 + .../2024.8.3/templates/destination-rbac.yaml | 327 + .../2024.8.3/templates/destination.yaml | 417 + .../2024.8.3/templates/heartbeat-rbac.yaml | 78 + .../2024.8.3/templates/heartbeat.yaml | 94 + .../2024.8.3/templates/identity-rbac.yaml | 49 + .../2024.8.3/templates/identity.yaml | 267 + .../2024.8.3/templates/namespace.yaml | 18 + .../2024.8.3/templates/podmonitor.yaml | 128 + .../templates/proxy-injector-rbac.yaml | 120 + .../2024.8.3/templates/proxy-injector.yaml | 216 + .../2024.8.3/templates/psp.yaml | 119 + .../2024.8.3/values-ha.yaml | 63 + .../2024.8.3/values.yaml | 638 + .../linkerd/linkerd-crds/2024.8.3/.helmignore | 22 + .../linkerd/linkerd-crds/2024.8.3/Chart.lock | 6 + .../linkerd/linkerd-crds/2024.8.3/Chart.yaml | 26 + .../linkerd/linkerd-crds/2024.8.3/README.md | 71 + .../linkerd-crds/2024.8.3/README.md.gotmpl | 59 + .../linkerd-crds/2024.8.3/app-readme.md | 9 + .../2024.8.3/charts/partials/.helmignore | 21 + .../2024.8.3/charts/partials/Chart.yaml | 5 + .../2024.8.3/charts/partials/README.md | 9 + .../2024.8.3/charts/partials/README.md.gotmpl | 14 + .../charts/partials/templates/NOTES.txt | 0 .../charts/partials/templates/_affinity.tpl | 38 + .../partials/templates/_capabilities.tpl | 16 + .../charts/partials/templates/_debug.tpl | 15 + .../charts/partials/templates/_helpers.tpl | 14 + .../charts/partials/templates/_metadata.tpl | 17 + .../partials/templates/_network-validator.tpl | 45 + .../partials/templates/_nodeselector.tpl | 4 + .../partials/templates/_proxy-config-ann.tpl | 18 + .../charts/partials/templates/_proxy-init.tpl | 98 + .../charts/partials/templates/_proxy.tpl | 267 + .../partials/templates/_pull-secrets.tpl | 6 + .../charts/partials/templates/_resources.tpl | 28 + .../partials/templates/_tolerations.tpl | 4 + .../charts/partials/templates/_trace.tpl | 5 + .../charts/partials/templates/_validate.tpl | 19 + .../charts/partials/templates/_volumes.tpl | 20 + .../2024.8.3/charts/partials/values.yaml | 0 .../linkerd-crds/2024.8.3/templates/NOTES.txt | 6 + .../gateway.networking.k8s.io_grpcroutes.yaml | 1507 + .../gateway.networking.k8s.io_httproutes.yaml | 3881 +++ .../policy/authorization-policy.yaml | 99 + .../2024.8.3/templates/policy/httproute.yaml | 5328 ++++ .../policy/meshtls-authentication.yaml | 87 + .../policy/network-authentication.yaml | 53 + .../policy/server-authorization.yaml | 266 + .../2024.8.3/templates/policy/server.yaml | 319 + .../2024.8.3/templates/serviceprofile.yaml | 274 + .../templates/workload/external-workload.yaml | 303 + .../linkerd/linkerd-crds/2024.8.3/values.yaml | 1 + charts/redpanda/redpanda/5.9.2/.helmignore | 28 + charts/redpanda/redpanda/5.9.2/Chart.lock | 9 + charts/redpanda/redpanda/5.9.2/Chart.yaml | 40 + charts/redpanda/redpanda/5.9.2/LICENSE | 201 + charts/redpanda/redpanda/5.9.2/README.md | 1300 + .../5.9.2/charts/connectors/.helmignore | 24 + .../5.9.2/charts/connectors/Chart.yaml | 25 + .../redpanda/5.9.2/charts/connectors/LICENSE | 201 + .../5.9.2/charts/connectors/README.md | 574 + .../5.9.2/charts/connectors/chart_test.go | 144 + .../connectors/ci/01-default-values.yaml | 34 + .../connectors/ci/02-broker-tls-values.yaml | 28 + .../5.9.2/charts/connectors/deployment.go | 394 + .../5.9.2/charts/connectors/helpers.go | 101 + .../5.9.2/charts/connectors/podmonitor.go | 56 + .../5.9.2/charts/connectors/service.go | 74 + .../5.9.2/charts/connectors/serviceaccount.go | 44 + .../connectors/templates/_deployment.go.tpl | 136 + .../connectors/templates/_helpers.go.tpl | 131 + .../charts/connectors/templates/_helpers.tpl | 79 + .../connectors/templates/_pod-monitor.go.tpl | 18 + .../connectors/templates/_service.go.tpl | 20 + .../templates/_serviceaccount.go.tpl | 18 + .../charts/connectors/templates/_shims.tpl | 289 + .../connectors/templates/_values.go.tpl | 15 + .../connectors/templates/deployment.yaml | 17 + .../connectors/templates/pod-monitor.yaml | 17 + .../charts/connectors/templates/service.yaml | 17 + .../connectors/templates/serviceaccount.yaml | 17 + .../templates/tests/01-mm2-values.yaml | 176 + .../testdata/template-cases-generated.txtar | 13778 +++++++++ .../testdata/template-cases.golden.txtar | 10301 +++++++ .../connectors/testdata/template-cases.txtar | 31 + .../5.9.2/charts/connectors/values.go | 212 + .../5.9.2/charts/connectors/values.yaml | 311 + .../charts/connectors/values_partial.gen.go | 188 + .../redpanda/5.9.2/charts/console/.helmignore | 24 + .../redpanda/5.9.2/charts/console/Chart.yaml | 23 + .../redpanda/5.9.2/charts/console/README.md | 353 + .../5.9.2/charts/console/chart_test.go | 158 + .../5.9.2/charts/console/configmap.go | 61 + .../5.9.2/charts/console/deployment.go | 535 + .../console/examples/console-enterprise.yaml | 94 + .../redpanda/5.9.2/charts/console/helpers.go | 84 + .../redpanda/5.9.2/charts/console/hpa.go | 82 + .../redpanda/5.9.2/charts/console/ingress.go | 88 + .../redpanda/5.9.2/charts/console/notes.go | 67 + .../redpanda/5.9.2/charts/console/secret.go | 84 + .../redpanda/5.9.2/charts/console/service.go | 60 + .../5.9.2/charts/console/serviceaccount.go | 60 + .../5.9.2/charts/console/templates/NOTES.txt | 20 + .../console/templates/_configmap.go.tpl | 25 + .../console/templates/_deployment.go.tpl | 133 + .../charts/console/templates/_helpers.go.tpl | 82 + .../charts/console/templates/_helpers.tpl | 25 + .../charts/console/templates/_hpa.go.tpl | 25 + .../charts/console/templates/_ingress.go.tpl | 46 + .../charts/console/templates/_notes.go.tpl | 40 + .../charts/console/templates/_secret.go.tpl | 22 + .../charts/console/templates/_service.go.tpl | 20 + .../console/templates/_serviceaccount.go.tpl | 39 + .../5.9.2/charts/console/templates/_shims.tpl | 289 + .../charts/console/templates/configmap.yaml | 17 + .../charts/console/templates/deployment.yaml | 17 + .../5.9.2/charts/console/templates/hpa.yaml | 17 + .../charts/console/templates/ingress.yaml | 17 + .../charts/console/templates/secret.yaml | 17 + .../charts/console/templates/service.yaml | 17 + .../console/templates/serviceaccount.yaml | 17 + .../templates/tests/test-connection.yaml | 22 + .../testdata/template-cases-generated.txtar | 22208 ++++++++++++++ .../testdata/template-cases.golden.txtar | 24705 ++++++++++++++++ .../console/testdata/template-cases.txtar | 136 + .../redpanda/5.9.2/charts/console/values.go | 215 + .../5.9.2/charts/console/values.schema.json | 323 + .../redpanda/5.9.2/charts/console/values.yaml | 279 + .../charts/console/values_partial.gen.go | 206 + .../redpanda/5.9.2/templates/NOTES.txt | 26 + .../5.9.2/templates/_cert-issuers.go.tpl | 57 + .../redpanda/5.9.2/templates/_certs.go.tpl | 71 + .../5.9.2/templates/_configmap.go.tpl | 517 + .../redpanda/5.9.2/templates/_console.go.tpl | 60 + .../5.9.2/templates/_example-commands.tpl | 58 + .../redpanda/5.9.2/templates/_helpers.go.tpl | 535 + .../redpanda/5.9.2/templates/_helpers.tpl | 368 + .../redpanda/5.9.2/templates/_memory.go.tpl | 63 + .../redpanda/5.9.2/templates/_notes.go.tpl | 167 + .../templates/_poddisruptionbudget.go.tpl | 21 + .../_post-install-upgrade-job.go.tpl | 233 + .../redpanda/5.9.2/templates/_secrets.go.tpl | 385 + .../5.9.2/templates/_service.internal.go.tpl | 38 + .../templates/_service.loadbalancer.go.tpl | 101 + .../5.9.2/templates/_service.nodeport.go.tpl | 80 + .../5.9.2/templates/_serviceaccount.go.tpl | 18 + .../5.9.2/templates/_servicemonitor.go.tpl | 26 + .../redpanda/5.9.2/templates/_shims.tpl | 289 + .../5.9.2/templates/_statefulset.go.tpl | 677 + .../redpanda/5.9.2/templates/_values.go.tpl | 1258 + .../5.9.2/templates/cert-issuers.yaml | 18 + .../redpanda/5.9.2/templates/certs.yaml | 17 + .../redpanda/5.9.2/templates/configmap.yaml | 17 + .../templates/connectors/connectors.yaml | 108 + .../console/configmap-and-deployment.yaml | 231 + .../5.9.2/templates/poddisruptionbudget.yaml | 17 + .../templates/post-install-upgrade-job.yaml | 17 + .../5.9.2/templates/post-upgrade.yaml | 17 + .../5.9.2/templates/post_upgrade_job.yaml | 90 + .../redpanda/5.9.2/templates/rbac.go.tpl | 116 + .../redpanda/5.9.2/templates/rbac.yaml | 20 + .../redpanda/5.9.2/templates/secrets.yaml | 17 + .../5.9.2/templates/service.internal.yaml | 17 + .../5.9.2/templates/service.loadbalancer.yaml | 17 + .../5.9.2/templates/service.nodeport.yaml | 17 + .../5.9.2/templates/serviceaccount.yaml | 17 + .../5.9.2/templates/servicemonitor.yaml | 17 + .../redpanda/5.9.2/templates/statefulset.yaml | 21 + .../templates/tests/test-api-status.yaml | 52 + .../templates/tests/test-auditLogging.yaml | 91 + .../tests/test-connector-via-console.yaml | 165 + .../5.9.2/templates/tests/test-console.yaml | 49 + .../test-internal-external-tls-secrets.yaml | 122 + .../tests/test-kafka-internal-tls-status.yaml | 62 + .../templates/tests/test-kafka-nodelete.yaml | 104 + .../tests/test-kafka-produce-consume.yaml | 87 + .../tests/test-kafka-sasl-status.yaml | 79 + .../tests/test-license-with-console.yaml | 61 + .../tests/test-lifecycle-scripts.yaml | 66 + .../tests/test-loadbalancer-tls.yaml | 173 + .../templates/tests/test-nodeport-tls.yaml | 173 + .../test-pandaproxy-internal-tls-status.yaml | 81 + .../tests/test-pandaproxy-status.yaml | 72 + .../tests/test-prometheus-targets.yaml | 84 + .../templates/tests/test-rack-awareness.yaml | 61 + .../tests/test-rpk-debug-bundle.yaml | 104 + .../templates/tests/test-sasl-updated.yaml | 71 + .../redpanda/5.9.2/values.schema.json | 5494 ++++ charts/redpanda/redpanda/5.9.2/values.yaml | 1321 + index.yaml | 230 +- 401 files changed, 143140 insertions(+), 3 deletions(-) create mode 100644 assets/airlock/microgateway-4.3.2.tgz create mode 100644 assets/airlock/microgateway-cni-4.3.2.tgz create mode 100644 assets/kong/kong-2.41.0.tgz create mode 100644 assets/linkerd/linkerd-control-plane-2024.8.3.tgz create mode 100644 assets/linkerd/linkerd-crds-2024.8.3.tgz create mode 100644 assets/redpanda/redpanda-5.9.2.tgz create mode 100644 charts/airlock/microgateway-cni/4.3.2/.helmignore create mode 100644 charts/airlock/microgateway-cni/4.3.2/Chart.yaml create mode 100644 charts/airlock/microgateway-cni/4.3.2/README.md create mode 100644 charts/airlock/microgateway-cni/4.3.2/gke-values.yaml create mode 100644 charts/airlock/microgateway-cni/4.3.2/openshift-values.yaml create mode 100644 charts/airlock/microgateway-cni/4.3.2/questions.yml create mode 100644 charts/airlock/microgateway-cni/4.3.2/templates/NOTES.txt create mode 100644 charts/airlock/microgateway-cni/4.3.2/templates/_helpers.tpl create mode 100644 charts/airlock/microgateway-cni/4.3.2/templates/clusterrole.yaml create mode 100644 charts/airlock/microgateway-cni/4.3.2/templates/clusterrolebinding.yaml create mode 100644 charts/airlock/microgateway-cni/4.3.2/templates/configmap.yaml create mode 100644 charts/airlock/microgateway-cni/4.3.2/templates/daemonset.yaml create mode 100644 charts/airlock/microgateway-cni/4.3.2/templates/network-attachment-definition.yaml create mode 100644 charts/airlock/microgateway-cni/4.3.2/templates/scc-role.yaml create mode 100644 charts/airlock/microgateway-cni/4.3.2/templates/scc-rolebinding.yaml create mode 100644 charts/airlock/microgateway-cni/4.3.2/templates/serviceaccount.yaml create mode 100644 charts/airlock/microgateway-cni/4.3.2/templates/tests/rbac.yaml create mode 100644 charts/airlock/microgateway-cni/4.3.2/templates/tests/test-install.yaml create mode 100644 charts/airlock/microgateway-cni/4.3.2/values.schema.json create mode 100644 charts/airlock/microgateway-cni/4.3.2/values.yaml create mode 100644 charts/airlock/microgateway/4.3.2/.helmignore create mode 100644 charts/airlock/microgateway/4.3.2/Chart.yaml create mode 100644 charts/airlock/microgateway/4.3.2/README.md create mode 100644 charts/airlock/microgateway/4.3.2/app-readme.md create mode 100644 charts/airlock/microgateway/4.3.2/crds/accesscontrols.microgateway.airlock.com.yaml create mode 100644 charts/airlock/microgateway/4.3.2/crds/contentsecurities.microgateway.airlock.com.yaml create mode 100644 charts/airlock/microgateway/4.3.2/crds/denyrules.microgateway.airlock.com.yaml create mode 100644 charts/airlock/microgateway/4.3.2/crds/envoyclusters.microgateway.airlock.com.yaml create mode 100644 charts/airlock/microgateway/4.3.2/crds/envoyconfigurations.microgateway.airlock.com.yaml create mode 100644 charts/airlock/microgateway/4.3.2/crds/envoyhttpfilters.microgateway.airlock.com.yaml create mode 100644 charts/airlock/microgateway/4.3.2/crds/graphqls.microgateway.airlock.com.yaml create mode 100644 charts/airlock/microgateway/4.3.2/crds/headerrewrites.microgateway.airlock.com.yaml create mode 100644 charts/airlock/microgateway/4.3.2/crds/identitypropagations.microgateway.airlock.com.yaml create mode 100644 charts/airlock/microgateway/4.3.2/crds/limits.microgateway.airlock.com.yaml create mode 100644 charts/airlock/microgateway/4.3.2/crds/oidcproviders.microgateway.airlock.com.yaml create mode 100644 charts/airlock/microgateway/4.3.2/crds/oidcrelyingparties.microgateway.airlock.com.yaml create mode 100644 charts/airlock/microgateway/4.3.2/crds/openapis.microgateway.airlock.com.yaml create mode 100644 charts/airlock/microgateway/4.3.2/crds/parsers.microgateway.airlock.com.yaml create mode 100644 charts/airlock/microgateway/4.3.2/crds/redisproviders.microgateway.airlock.com.yaml create mode 100644 charts/airlock/microgateway/4.3.2/crds/sessionhandlings.microgateway.airlock.com.yaml create mode 100644 charts/airlock/microgateway/4.3.2/crds/sidecargateways.microgateway.airlock.com.yaml create mode 100644 charts/airlock/microgateway/4.3.2/crds/telemetries.microgateway.airlock.com.yaml create mode 100644 charts/airlock/microgateway/4.3.2/dashboards/blockLogs.json create mode 100644 charts/airlock/microgateway/4.3.2/dashboards/blockMetrics.json create mode 100644 charts/airlock/microgateway/4.3.2/dashboards/license.json create mode 100644 charts/airlock/microgateway/4.3.2/dashboards/overview.json create mode 100644 charts/airlock/microgateway/4.3.2/templates/NOTES.txt create mode 100644 charts/airlock/microgateway/4.3.2/templates/_helpers.tpl create mode 100644 charts/airlock/microgateway/4.3.2/templates/operator/_operator_helpers.tpl create mode 100644 charts/airlock/microgateway/4.3.2/templates/operator/_rbac.gen.tpl create mode 100644 charts/airlock/microgateway/4.3.2/templates/operator/_webhooks.gen.tpl create mode 100644 charts/airlock/microgateway/4.3.2/templates/operator/configmap.yaml create mode 100644 charts/airlock/microgateway/4.3.2/templates/operator/dashboard-configmap.yaml create mode 100644 charts/airlock/microgateway/4.3.2/templates/operator/deployment.yaml create mode 100644 charts/airlock/microgateway/4.3.2/templates/operator/manager-role.yaml create mode 100644 charts/airlock/microgateway/4.3.2/templates/operator/manager-rolebinding.yaml create mode 100644 charts/airlock/microgateway/4.3.2/templates/operator/metrics-service.yaml create mode 100644 charts/airlock/microgateway/4.3.2/templates/operator/mutating-webhook.yaml create mode 100644 charts/airlock/microgateway/4.3.2/templates/operator/podmonitor.yaml create mode 100644 charts/airlock/microgateway/4.3.2/templates/operator/role.yaml create mode 100644 charts/airlock/microgateway/4.3.2/templates/operator/rolebinding.yaml create mode 100644 charts/airlock/microgateway/4.3.2/templates/operator/selfsigned-issuer.yaml create mode 100644 charts/airlock/microgateway/4.3.2/templates/operator/serviceaccount.yaml create mode 100644 charts/airlock/microgateway/4.3.2/templates/operator/servicemonitor.yaml create mode 100644 charts/airlock/microgateway/4.3.2/templates/operator/serving-certificate.yaml create mode 100644 charts/airlock/microgateway/4.3.2/templates/operator/validating-webhook.yaml create mode 100644 charts/airlock/microgateway/4.3.2/templates/operator/webhook-service.yaml create mode 100644 charts/airlock/microgateway/4.3.2/templates/operator/xds-service.yaml create mode 100644 charts/airlock/microgateway/4.3.2/templates/tests/rbac.yaml create mode 100644 charts/airlock/microgateway/4.3.2/templates/tests/service.yaml create mode 100644 charts/airlock/microgateway/4.3.2/templates/tests/statefulset.yaml create mode 100644 charts/airlock/microgateway/4.3.2/templates/tests/test-install.yaml create mode 100644 charts/airlock/microgateway/4.3.2/values.schema.json create mode 100644 charts/airlock/microgateway/4.3.2/values.yaml create mode 100644 charts/kong/kong/2.41.0/CHANGELOG.md create mode 100644 charts/kong/kong/2.41.0/Chart.lock create mode 100644 charts/kong/kong/2.41.0/Chart.yaml create mode 100644 charts/kong/kong/2.41.0/FAQs.md create mode 100644 charts/kong/kong/2.41.0/README.md create mode 100644 charts/kong/kong/2.41.0/UPGRADE.md create mode 100644 charts/kong/kong/2.41.0/app-readme.md create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/.helmignore create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/Chart.lock create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/Chart.yaml create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/README.md create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/charts/common/.helmignore create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/charts/common/Chart.yaml create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/charts/common/README.md create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_affinities.tpl create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_capabilities.tpl create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_errors.tpl create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_images.tpl create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_ingress.tpl create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_labels.tpl create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_names.tpl create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_secrets.tpl create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_storage.tpl create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_tplvalues.tpl create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_utils.tpl create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_warnings.tpl create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/validations/_cassandra.tpl create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/validations/_mariadb.tpl create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/validations/_mongodb.tpl create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/validations/_mysql.tpl create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/validations/_postgresql.tpl create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/validations/_redis.tpl create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/validations/_validations.tpl create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/charts/common/values.yaml create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/templates/NOTES.txt create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/templates/_helpers.tpl create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/templates/extra-list.yaml create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/templates/networkpolicy-egress.yaml create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/templates/primary/configmap.yaml create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/templates/primary/extended-configmap.yaml create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/templates/primary/initialization-configmap.yaml create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/templates/primary/metrics-configmap.yaml create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/templates/primary/metrics-svc.yaml create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/templates/primary/networkpolicy.yaml create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/templates/primary/servicemonitor.yaml create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/templates/primary/statefulset.yaml create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/templates/primary/svc-headless.yaml create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/templates/primary/svc.yaml create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/templates/prometheusrule.yaml create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/templates/psp.yaml create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/templates/read/extended-configmap.yaml create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/templates/read/metrics-configmap.yaml create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/templates/read/metrics-svc.yaml create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/templates/read/networkpolicy.yaml create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/templates/read/servicemonitor.yaml create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/templates/read/statefulset.yaml create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/templates/read/svc-headless.yaml create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/templates/read/svc.yaml create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/templates/role.yaml create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/templates/rolebinding.yaml create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/templates/secrets.yaml create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/templates/serviceaccount.yaml create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/templates/tls-secrets.yaml create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/values.schema.json create mode 100644 charts/kong/kong/2.41.0/charts/postgresql/values.yaml create mode 100644 charts/kong/kong/2.41.0/crds/custom-resource-definitions.yaml create mode 100644 charts/kong/kong/2.41.0/questions.yml create mode 100644 charts/kong/kong/2.41.0/templates/NOTES.txt create mode 100644 charts/kong/kong/2.41.0/templates/_helpers.tpl create mode 100644 charts/kong/kong/2.41.0/templates/admission-webhook.yaml create mode 100644 charts/kong/kong/2.41.0/templates/certificate.yaml create mode 100644 charts/kong/kong/2.41.0/templates/config-dbless.yaml create mode 100644 charts/kong/kong/2.41.0/templates/controller-rbac-resources.yaml create mode 100644 charts/kong/kong/2.41.0/templates/custom-resource-definitions.yaml create mode 100644 charts/kong/kong/2.41.0/templates/deployment.yaml create mode 100644 charts/kong/kong/2.41.0/templates/extraManifests.yaml create mode 100644 charts/kong/kong/2.41.0/templates/hpa.yaml create mode 100644 charts/kong/kong/2.41.0/templates/ingress-class.yaml create mode 100644 charts/kong/kong/2.41.0/templates/migrations-post-upgrade.yaml create mode 100644 charts/kong/kong/2.41.0/templates/migrations-pre-upgrade.yaml create mode 100644 charts/kong/kong/2.41.0/templates/migrations.yaml create mode 100644 charts/kong/kong/2.41.0/templates/pdb.yaml create mode 100644 charts/kong/kong/2.41.0/templates/psp.yaml create mode 100644 charts/kong/kong/2.41.0/templates/secret-sa-token.yaml create mode 100644 charts/kong/kong/2.41.0/templates/service-account.yaml create mode 100644 charts/kong/kong/2.41.0/templates/service-kong-admin.yaml create mode 100644 charts/kong/kong/2.41.0/templates/service-kong-cluster-telemetry.yaml create mode 100644 charts/kong/kong/2.41.0/templates/service-kong-cluster.yaml create mode 100644 charts/kong/kong/2.41.0/templates/service-kong-manager.yaml create mode 100644 charts/kong/kong/2.41.0/templates/service-kong-portal-api.yaml create mode 100644 charts/kong/kong/2.41.0/templates/service-kong-portal.yaml create mode 100644 charts/kong/kong/2.41.0/templates/service-kong-proxy.yaml create mode 100644 charts/kong/kong/2.41.0/templates/service-kong-udp-proxy.yaml create mode 100644 charts/kong/kong/2.41.0/templates/servicemonitor.yaml create mode 100644 charts/kong/kong/2.41.0/templates/wait-for-postgres-script.yaml create mode 100644 charts/kong/kong/2.41.0/values.yaml create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/.helmignore create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/Chart.lock create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/Chart.yaml create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/README.md create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/README.md.gotmpl create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/app-readme.md create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/.helmignore create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/Chart.yaml create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/README.md create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/README.md.gotmpl create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/NOTES.txt create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_affinity.tpl create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_capabilities.tpl create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_debug.tpl create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_helpers.tpl create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_metadata.tpl create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_network-validator.tpl create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_nodeselector.tpl create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_proxy-config-ann.tpl create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_proxy-init.tpl create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_proxy.tpl create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_pull-secrets.tpl create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_resources.tpl create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_tolerations.tpl create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_trace.tpl create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_validate.tpl create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_volumes.tpl create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/values.yaml create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/questions.yaml create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/templates/NOTES.txt create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/templates/config-rbac.yaml create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/templates/config.yaml create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/templates/destination-rbac.yaml create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/templates/destination.yaml create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/templates/heartbeat-rbac.yaml create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/templates/heartbeat.yaml create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/templates/identity-rbac.yaml create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/templates/identity.yaml create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/templates/namespace.yaml create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/templates/podmonitor.yaml create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/templates/proxy-injector-rbac.yaml create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/templates/proxy-injector.yaml create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/templates/psp.yaml create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/values-ha.yaml create mode 100644 charts/linkerd/linkerd-control-plane/2024.8.3/values.yaml create mode 100644 charts/linkerd/linkerd-crds/2024.8.3/.helmignore create mode 100644 charts/linkerd/linkerd-crds/2024.8.3/Chart.lock create mode 100644 charts/linkerd/linkerd-crds/2024.8.3/Chart.yaml create mode 100644 charts/linkerd/linkerd-crds/2024.8.3/README.md create mode 100644 charts/linkerd/linkerd-crds/2024.8.3/README.md.gotmpl create mode 100644 charts/linkerd/linkerd-crds/2024.8.3/app-readme.md create mode 100644 charts/linkerd/linkerd-crds/2024.8.3/charts/partials/.helmignore create mode 100644 charts/linkerd/linkerd-crds/2024.8.3/charts/partials/Chart.yaml create mode 100644 charts/linkerd/linkerd-crds/2024.8.3/charts/partials/README.md create mode 100644 charts/linkerd/linkerd-crds/2024.8.3/charts/partials/README.md.gotmpl create mode 100644 charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/NOTES.txt create mode 100644 charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_affinity.tpl create mode 100644 charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_capabilities.tpl create mode 100644 charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_debug.tpl create mode 100644 charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_helpers.tpl create mode 100644 charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_metadata.tpl create mode 100644 charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_network-validator.tpl create mode 100644 charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_nodeselector.tpl create mode 100644 charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_proxy-config-ann.tpl create mode 100644 charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_proxy-init.tpl create mode 100644 charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_proxy.tpl create mode 100644 charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_pull-secrets.tpl create mode 100644 charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_resources.tpl create mode 100644 charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_tolerations.tpl create mode 100644 charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_trace.tpl create mode 100644 charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_validate.tpl create mode 100644 charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_volumes.tpl create mode 100644 charts/linkerd/linkerd-crds/2024.8.3/charts/partials/values.yaml create mode 100644 charts/linkerd/linkerd-crds/2024.8.3/templates/NOTES.txt create mode 100644 charts/linkerd/linkerd-crds/2024.8.3/templates/gateway.networking.k8s.io_grpcroutes.yaml create mode 100644 charts/linkerd/linkerd-crds/2024.8.3/templates/gateway.networking.k8s.io_httproutes.yaml create mode 100644 charts/linkerd/linkerd-crds/2024.8.3/templates/policy/authorization-policy.yaml create mode 100644 charts/linkerd/linkerd-crds/2024.8.3/templates/policy/httproute.yaml create mode 100644 charts/linkerd/linkerd-crds/2024.8.3/templates/policy/meshtls-authentication.yaml create mode 100644 charts/linkerd/linkerd-crds/2024.8.3/templates/policy/network-authentication.yaml create mode 100644 charts/linkerd/linkerd-crds/2024.8.3/templates/policy/server-authorization.yaml create mode 100644 charts/linkerd/linkerd-crds/2024.8.3/templates/policy/server.yaml create mode 100644 charts/linkerd/linkerd-crds/2024.8.3/templates/serviceprofile.yaml create mode 100644 charts/linkerd/linkerd-crds/2024.8.3/templates/workload/external-workload.yaml create mode 100644 charts/linkerd/linkerd-crds/2024.8.3/values.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/.helmignore create mode 100644 charts/redpanda/redpanda/5.9.2/Chart.lock create mode 100644 charts/redpanda/redpanda/5.9.2/Chart.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/LICENSE create mode 100644 charts/redpanda/redpanda/5.9.2/README.md create mode 100644 charts/redpanda/redpanda/5.9.2/charts/connectors/.helmignore create mode 100644 charts/redpanda/redpanda/5.9.2/charts/connectors/Chart.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/charts/connectors/LICENSE create mode 100644 charts/redpanda/redpanda/5.9.2/charts/connectors/README.md create mode 100644 charts/redpanda/redpanda/5.9.2/charts/connectors/chart_test.go create mode 100644 charts/redpanda/redpanda/5.9.2/charts/connectors/ci/01-default-values.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/charts/connectors/ci/02-broker-tls-values.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/charts/connectors/deployment.go create mode 100644 charts/redpanda/redpanda/5.9.2/charts/connectors/helpers.go create mode 100644 charts/redpanda/redpanda/5.9.2/charts/connectors/podmonitor.go create mode 100644 charts/redpanda/redpanda/5.9.2/charts/connectors/service.go create mode 100644 charts/redpanda/redpanda/5.9.2/charts/connectors/serviceaccount.go create mode 100644 charts/redpanda/redpanda/5.9.2/charts/connectors/templates/_deployment.go.tpl create mode 100644 charts/redpanda/redpanda/5.9.2/charts/connectors/templates/_helpers.go.tpl create mode 100644 charts/redpanda/redpanda/5.9.2/charts/connectors/templates/_helpers.tpl create mode 100644 charts/redpanda/redpanda/5.9.2/charts/connectors/templates/_pod-monitor.go.tpl create mode 100644 charts/redpanda/redpanda/5.9.2/charts/connectors/templates/_service.go.tpl create mode 100644 charts/redpanda/redpanda/5.9.2/charts/connectors/templates/_serviceaccount.go.tpl create mode 100644 charts/redpanda/redpanda/5.9.2/charts/connectors/templates/_shims.tpl create mode 100644 charts/redpanda/redpanda/5.9.2/charts/connectors/templates/_values.go.tpl create mode 100644 charts/redpanda/redpanda/5.9.2/charts/connectors/templates/deployment.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/charts/connectors/templates/pod-monitor.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/charts/connectors/templates/service.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/charts/connectors/templates/serviceaccount.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/charts/connectors/templates/tests/01-mm2-values.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/charts/connectors/testdata/template-cases-generated.txtar create mode 100644 charts/redpanda/redpanda/5.9.2/charts/connectors/testdata/template-cases.golden.txtar create mode 100644 charts/redpanda/redpanda/5.9.2/charts/connectors/testdata/template-cases.txtar create mode 100644 charts/redpanda/redpanda/5.9.2/charts/connectors/values.go create mode 100644 charts/redpanda/redpanda/5.9.2/charts/connectors/values.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/charts/connectors/values_partial.gen.go create mode 100644 charts/redpanda/redpanda/5.9.2/charts/console/.helmignore create mode 100644 charts/redpanda/redpanda/5.9.2/charts/console/Chart.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/charts/console/README.md create mode 100644 charts/redpanda/redpanda/5.9.2/charts/console/chart_test.go create mode 100644 charts/redpanda/redpanda/5.9.2/charts/console/configmap.go create mode 100644 charts/redpanda/redpanda/5.9.2/charts/console/deployment.go create mode 100644 charts/redpanda/redpanda/5.9.2/charts/console/examples/console-enterprise.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/charts/console/helpers.go create mode 100644 charts/redpanda/redpanda/5.9.2/charts/console/hpa.go create mode 100644 charts/redpanda/redpanda/5.9.2/charts/console/ingress.go create mode 100644 charts/redpanda/redpanda/5.9.2/charts/console/notes.go create mode 100644 charts/redpanda/redpanda/5.9.2/charts/console/secret.go create mode 100644 charts/redpanda/redpanda/5.9.2/charts/console/service.go create mode 100644 charts/redpanda/redpanda/5.9.2/charts/console/serviceaccount.go create mode 100644 charts/redpanda/redpanda/5.9.2/charts/console/templates/NOTES.txt create mode 100644 charts/redpanda/redpanda/5.9.2/charts/console/templates/_configmap.go.tpl create mode 100644 charts/redpanda/redpanda/5.9.2/charts/console/templates/_deployment.go.tpl create mode 100644 charts/redpanda/redpanda/5.9.2/charts/console/templates/_helpers.go.tpl create mode 100644 charts/redpanda/redpanda/5.9.2/charts/console/templates/_helpers.tpl create mode 100644 charts/redpanda/redpanda/5.9.2/charts/console/templates/_hpa.go.tpl create mode 100644 charts/redpanda/redpanda/5.9.2/charts/console/templates/_ingress.go.tpl create mode 100644 charts/redpanda/redpanda/5.9.2/charts/console/templates/_notes.go.tpl create mode 100644 charts/redpanda/redpanda/5.9.2/charts/console/templates/_secret.go.tpl create mode 100644 charts/redpanda/redpanda/5.9.2/charts/console/templates/_service.go.tpl create mode 100644 charts/redpanda/redpanda/5.9.2/charts/console/templates/_serviceaccount.go.tpl create mode 100644 charts/redpanda/redpanda/5.9.2/charts/console/templates/_shims.tpl create mode 100644 charts/redpanda/redpanda/5.9.2/charts/console/templates/configmap.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/charts/console/templates/deployment.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/charts/console/templates/hpa.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/charts/console/templates/ingress.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/charts/console/templates/secret.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/charts/console/templates/service.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/charts/console/templates/serviceaccount.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/charts/console/templates/tests/test-connection.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/charts/console/testdata/template-cases-generated.txtar create mode 100644 charts/redpanda/redpanda/5.9.2/charts/console/testdata/template-cases.golden.txtar create mode 100644 charts/redpanda/redpanda/5.9.2/charts/console/testdata/template-cases.txtar create mode 100644 charts/redpanda/redpanda/5.9.2/charts/console/values.go create mode 100644 charts/redpanda/redpanda/5.9.2/charts/console/values.schema.json create mode 100644 charts/redpanda/redpanda/5.9.2/charts/console/values.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/charts/console/values_partial.gen.go create mode 100644 charts/redpanda/redpanda/5.9.2/templates/NOTES.txt create mode 100644 charts/redpanda/redpanda/5.9.2/templates/_cert-issuers.go.tpl create mode 100644 charts/redpanda/redpanda/5.9.2/templates/_certs.go.tpl create mode 100644 charts/redpanda/redpanda/5.9.2/templates/_configmap.go.tpl create mode 100644 charts/redpanda/redpanda/5.9.2/templates/_console.go.tpl create mode 100644 charts/redpanda/redpanda/5.9.2/templates/_example-commands.tpl create mode 100644 charts/redpanda/redpanda/5.9.2/templates/_helpers.go.tpl create mode 100644 charts/redpanda/redpanda/5.9.2/templates/_helpers.tpl create mode 100644 charts/redpanda/redpanda/5.9.2/templates/_memory.go.tpl create mode 100644 charts/redpanda/redpanda/5.9.2/templates/_notes.go.tpl create mode 100644 charts/redpanda/redpanda/5.9.2/templates/_poddisruptionbudget.go.tpl create mode 100644 charts/redpanda/redpanda/5.9.2/templates/_post-install-upgrade-job.go.tpl create mode 100644 charts/redpanda/redpanda/5.9.2/templates/_secrets.go.tpl create mode 100644 charts/redpanda/redpanda/5.9.2/templates/_service.internal.go.tpl create mode 100644 charts/redpanda/redpanda/5.9.2/templates/_service.loadbalancer.go.tpl create mode 100644 charts/redpanda/redpanda/5.9.2/templates/_service.nodeport.go.tpl create mode 100644 charts/redpanda/redpanda/5.9.2/templates/_serviceaccount.go.tpl create mode 100644 charts/redpanda/redpanda/5.9.2/templates/_servicemonitor.go.tpl create mode 100644 charts/redpanda/redpanda/5.9.2/templates/_shims.tpl create mode 100644 charts/redpanda/redpanda/5.9.2/templates/_statefulset.go.tpl create mode 100644 charts/redpanda/redpanda/5.9.2/templates/_values.go.tpl create mode 100644 charts/redpanda/redpanda/5.9.2/templates/cert-issuers.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/templates/certs.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/templates/configmap.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/templates/connectors/connectors.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/templates/console/configmap-and-deployment.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/templates/poddisruptionbudget.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/templates/post-install-upgrade-job.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/templates/post-upgrade.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/templates/post_upgrade_job.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/templates/rbac.go.tpl create mode 100644 charts/redpanda/redpanda/5.9.2/templates/rbac.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/templates/secrets.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/templates/service.internal.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/templates/service.loadbalancer.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/templates/service.nodeport.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/templates/serviceaccount.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/templates/servicemonitor.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/templates/statefulset.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/templates/tests/test-api-status.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/templates/tests/test-auditLogging.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/templates/tests/test-connector-via-console.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/templates/tests/test-console.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/templates/tests/test-internal-external-tls-secrets.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/templates/tests/test-kafka-internal-tls-status.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/templates/tests/test-kafka-nodelete.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/templates/tests/test-kafka-produce-consume.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/templates/tests/test-kafka-sasl-status.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/templates/tests/test-license-with-console.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/templates/tests/test-lifecycle-scripts.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/templates/tests/test-loadbalancer-tls.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/templates/tests/test-nodeport-tls.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/templates/tests/test-pandaproxy-internal-tls-status.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/templates/tests/test-pandaproxy-status.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/templates/tests/test-prometheus-targets.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/templates/tests/test-rack-awareness.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/templates/tests/test-rpk-debug-bundle.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/templates/tests/test-sasl-updated.yaml create mode 100644 charts/redpanda/redpanda/5.9.2/values.schema.json create mode 100644 charts/redpanda/redpanda/5.9.2/values.yaml diff --git a/assets/airlock/microgateway-4.3.2.tgz b/assets/airlock/microgateway-4.3.2.tgz new file mode 100644 index 0000000000000000000000000000000000000000..e8fa2199905853bd768f883ea35164956aebb2c9 GIT binary patch literal 61772 zcmV)nK%KuIiwG0|00000|0w_~VMtOiV@ORlOnEsqVl!4SWK%V1T2nbTPgYhoO;>Dc zVQyr3R8em|NM&qo0POv1f7>>)IF6skdKI%uy0&vH>Sp<(v+l0fNxMFqi%;yf-}6s% z9Eb!Z)D*!2pd2;H|F!=^Ny_K1gH|7z_r3nZaN%m=c%KF%tL&&D*CF#Dp_P z)8Ieu^67Lso&CK%^?#?+DgNK<@9q6ZcW-}xuh;Dl1_%Gq>Glsgd;bBQJH?{riMc@R zKRUN=tJt~U$%Dd>3M2>(`LF?im>@oK#Uvg%gtlEI@R+js5IA;YM#Q{aCLk^jIUd4` zv&*Wl;WZz^#|8jE3qmx-LpUKUpzbxi$S@x~rEWaMp+-g(2Z&iPgozLlAGX^bb-9Cd zRmY{%c8+)VoPK+GBhS%@SHX?~Gl)?RXF(aL#~4j02c`q(6QqpAp)$%1j_~q_J$B4CPK_Ai+P00 zPPOVWsjPM#k8o>-87DLx!q&IPU8gs2I<3xDWpRcBj5s!}ObgJZIN=VBaL6ab7qY?v zbWlWov<=UC4HQMmpLTgkumBT;0Ni%Em3d zZ*FdK)W%_sqZ-7O?f4|X!*&~Sjst4P_O}czHby5yh!jy1=nyIGZ(9dY_%~_b1OS3b5+DV!b3nQDI2pq z-+XBq`!zo~89GBjjQO1#0E_j1uRrMa3i^MqyVrZr|M&4cf>sMof`Hy|pfk)E@vI1y zvl9e`m}8Kt5hD+%56vvgG#xdGU+J272+d|=MUaSt9|wVcM}1(}%zdXJ-&ccujz&1( z5(M%*^;)K#X%tZ zM`R)HG)STF5Z=6PJjz%F)A?&WCS0)jzwulbdWojE(QuUp0Z?uJG{ItmnQV$*lSq+| zqmYO>xD)JN!_9=a6Nng|;ZSfjLP%lKj-xR{3C$;|nj|40aD$i&%;1KI3D8)0NMNtp zR5^Y9lsgKc%Lz8kA~IF|Hw{A^;`b4DC5#cCpc$b|sWQTOj5&C*8gQknXMG5%02B*4 zMS{2}2nyR;k7KRYGDf=La zX!P5u?8p#&6mZ<2Mgb;-e;H3lm}!nwDupZaLbh$o!c%2yNNZJsHswxf9Eu_IETD@B zyV6kO`MPl=DGppPX%U+!VS|bUU5S)V`VGshWC&Ztn%rFB$$d#=N3dO(om))0hi7g^+sq z0teWY{j2SGDhH)_rp(g{OD>WGLnH(uxMCCa7BfjD1zPb2EY$j4ro57O*j3mhqu(a;XgjaQWgj~#b!NU;_l~qJTnA4a+h_PpkvG3$?!@E~E z;Y(ZP9Z&}EE=V{IaOR~kg!H(|h6BO{Owk-@7|gBQ0vh79b=bzv*x7}5H%PdX1ely1 zO{39UIgQTeT;OT*?YkX~-dPAP;>j2k@XVn!rJk81R*PovNSO!!8l%86Lk>VvI!hTY z`ND;FFXBLunx=QPF-fOUfQ6w8^)q7t)0hj{c*N+8c-XTBXpt`ObkipxygLbk%=B(n!^ZjMGrubG!B8Z8cYL}8P*q)fM^t`MURJtY+S;Y`ag6@fK&58t;Wpy z*I=c{F;%##$(m~+zi!$Ex%^TZBg8j3*&!EpG!{zYASSHDvVFA+I!Scol7I*#6uk}I z7S9{SOS>?N1#m&s3fc^qS(sTqi7=ZI&XqLZCJuIX;Z&DMSts)%;h;O4O?>e*N+(-s zHr*YEmaH2op!}FAZHeC_DSh}ZaGY^VU&kZNLM*VdYdz}nw&Wcg3ErkNsnGCE`-ZY> z5{_GPtXp*S3w8x>D}LeaM+u9yB=#*c?^_&;mg3}=>4G#`%%s#@XAI%QK+L+i^PY0a z;yG(v192C>@Tsxf zNRez)lt6$u+~6RP|F6Jq5FwJWyNcFJqLk2x&eZU-5ppXGA8Flc^FayGbdIO)3`27- zX>9S@T2S!g(6x47$!1zY8_An?d6WV*{d++}Vgv!ty;;~ZRH&XVS!9o<`lT^)Q*^bH zB>}r=MV3JewCu}Tc4nt(2+hBxE5F2>&@!LDZ8mT?CLtcK>MVJtihm|oNfG!ujuPFE zdvueaerM42_j+Ex)9oL2`=idlKNxiTqtW3$_V!V~*Ew=W{Z6OvcSob1e=s`ed46y2 z2%*8=o_8xZ$)UH`I~W{!M@L6^f3$yueRPEVE_Qv-J>2u$u7Bw7`&}0u_ImE2*Yo<= zKlJ@B?)L|yBlqYI-6X56{TB`Qmv9FRDi-$L-r+KDK&j4N$NBhaXO ztx_~fMaYSVU8E(7{%L2>22$#rdO1-LC4Udiwt20DN~1w+DLv>#p$NeCn)qLpLCO+{OXg^Pq~YoYq8K(K^G zK?b^G=6HD4b|;90;}|iot=n5w^4(78d0lt!aL?Zx9bvTJ>mK6XsC(2K`1_;Ip*Ps` zy#Ao)9w6lJ5Bf(32cywwgz>1?#iKs%9(mrae8abG`woO2*XG*E7;BHtN_=>sD}k!@ znN(*@8|!FL)3+9qApRtZ)Z05e@b@}LM{aNbpx^Cyc;x$d;0;{lcJ~iGj6Kia?;Q3# zp+!lMwt}exU(UdDGZMWNP;~`XgK$VVYEPEaDa)%C!!h$E+w!mrxJwn{pjXPe9P+``YGDX76g z`MwJ(JMRlG7#bmVG3SWQjTc3(|1vIPKmiTMdJkMoFkxo>X@Cg|dX1YPrFJzK!>$PC zKs+1@;?Gq}m7OtgGF_1f_#{y7&Z%lx?Z$i9lgy~rg@K2e9hsyi*fqbE36~ShCF2M| z!ZBBVVToPpHnJ$&(J5^r0E~4JYftH>Q~$etU%{{`4U0@`@V6lzs;@bY6VyrI8b7(g z<4V_U);DW_XX(kXYQs~IEkU#W|KTicPmS&nnpM)qHk$xfCg1`ZXpT}7CBT9w4JK?+ zoK6heAcnL9wX{fz6v*+T?80Y4!IGyd+f{jUTmj}ta>@%VRTp0YuqqByU4B*Y z&*^w|*a00c1N;b1O>mF_Q``zL{8OoQRgjK40{}OO1CL!PL;W~#8js+0>h?5BO9@XT zd56@*4_R7Y<9QO!qt_~i8J&hm)o6AjF{&TR`9X!N;-pBKy0nmJ`N4zAdCagc>pW_EScPFoTd;khAiO|P6_89+!sd{e$E#4!kW9U=Ae(w$j9tuq&A=N` z8ekNrhJ$rZeM*{0CF^;%vD6J_aW00jR^g8rL-Q1UBJi|;c}-92`)U}a@UA@EyZNtE z5B)<1I!#8&+C3;v^J! zj9HExk{DzfPn$#NRCYffZdwFg&DlTX>r}#3EVCLo<$|e(k`F>$4P0T~Re&tXg3Y0o zgBI@+>>VPSm`-)vV>q$0ayB^cPO!-Y+STEcmnTpyQx^81ZpPcFyGd{KW{}C^XunA%5lOTKljnO&8BdFt+EJnSI@bgk5QJt=`WPk*iqkPCJU; z+m3ebsH1C1k_8<$zY=b#=CRZ!D%(0GqrQIiP-imMTlAHNc~LIr%-GC2sM5Txw+a@U z?X}i-y>zNEXiFqtd7W*-yl$~hyqjfLcCoO&jcoRsHWl85>6b?QERx?9Ko`*|`Ch9T zV5xS1^8AK{S_0PA6i}Ggl}*-b4XD-}P}Cl=V~Aui}9ITc}~Z7*~A7Ml?+!6 zl^4;bwnz74gOwbERV&Jby*F1bDhT5?YSjd9++ruSngAB==3N^HbcBKheQQ{JRE;to z6&u&P*$=rjuHKu@uSLyYrOkKqzO*x3Fm|k&Tv0XI7OgX-tBlUFJ&|LAhN1F83abK{ zX`6;6q|2}sxT&UziVg3)k2$|Nd{!`pH`y6BA@Fx#6J|XcsMcC4`pmP{bPW1Bs6i+lVSn$_k^B<6gb<|_BinkT^xnwKPIHj=&g?IoV! z{AzY>`Cw>O-KE{iAubHi=8`4vNxTLB70>$K`F?JJ?h7o&<~5#|4eorBsbsVYU>BO@ z3UH;hzG$DV%HFMr1-S(@9iz7xR+;XmKsEJO!lc5oUua9MXmeNZyk$WNK%M-c*5&c2x|_746N}Sld{avevClO;LbyyOqo5>T)&-UPZr)(jr@Y!&bfy z%34vMW6m4{)W<_6tXWci34~@f{1UY{Yov;t3tGCJK6-xKfn2Vja@QD?|%r9JtuL`c$5WQI4^GT<~TJa*xT&vEtSc3>1}yiabX4Z#umP^9_k5qC$8i?MO7zC7;Hdb zx!`Sl`kfxL_-dcr`45}Rj<;XFx_oxwi1*?y+E{Y`$KIf~Uq1iwkpKH$p34aeuVGGO zb*d^&B3*f)%V{)BZY&(~nBl@9>xf|`1UOL%#hA*H=#wD8-mvimPB9a$7brwy%zz{r ztM$P^d+x-Qg{HbtlK(1uf~`Hl!L;3YQj@Xz<(bOB7I2!v2bxPAoo%jgTSua%1E!S34@Ls9BsilNwtAUDirAFgBlh}-eIw68ON&F;#vCFF0xqSElBy@w= z!`0{89a-I+iD`lZpFT+rd;L^hp`q?(QTbQB`)Rw4BGPu5$Lsj=IU4ahxot)=X5+($ z77!ntAN6@X*|1YQBP1!(_zAI)gyW&2jJXxVIO#H$=4YBo<0 z6I&d%WcS-!;1Q-ATXXPYX~n=+RWA4~r*S#K4EvN}odZ-swaGrGD2%ghdP$0ajGU8m z2ZbJt6qMY>GlXlrh7EP0iYo$>?V@$P>U}2WymVXNo>M7=6sxuW&ai*{4Tn~XV>ZLA z#fgWZ)$%EGam%Hl9}rjYM&ry^0$vJaN!&DvZ54r%-l-)1=Gq5_gSnKVoK7)NHOZ&g zouH6#o6seb_cA|Tg{yfig?1HAE(%p%QieI#AJqW_7|m^lgA`F^IqKmqar?1gG2U|C zDgJWwJ!U7#1wuROwdG43dX>L3GfJQFHG4TZzReU$5^5HrMU(QGI+E_&6U4!Jtn6}81^gbnvA~A$WgoV7fvA+EX*vv(&=T8pRhfjlTi@_4SvW#W6f>l5 zag#(HpH0B|WjClyLa)!Sb77Hu&_(`O;S1>Q9aRe>K5D zgc)~4bo;A-7Tf>b-eAx#*#GH~)nc2Uf+RtgzAR)O#d4osF7m0n5D_5Hr7yFJp$bDqAukmaSE=Mi>y8WxX$ zhAPz-ejf$IB?5Tt`{ccxaos%y1i3;oXyZxS%v9yft+P_JFQt_hMR6eP%vH%av|Hn7dLdzs%D^^L2K?zQv@d8-G60B_boK;y3AYXf#_|??4c^>Wf z`LVRsevMIJ^7KZLV!sm8_V@3TY00$2w7r8I)1LV`t!Q&88QaL*JRo%Pkr9TN+f19u zm07FuijCrER@phl5D&}KwcqW0=h|NPzVfD5fgMu1lxUIiu?C*hX@fTO0~9 z#ZR>;ERhJ#)g=*n8)OJC>?JK${1YECtV%c#eu1Ym%wWaAwby@~zJ6+;oSSXM)c0eB z((o9zxrSa|P3Js3riOFQu+?bt^S8&6FOsh>&@Yt9l~L{`3Cl0f)pGFDr&jJ|3Op;w z*KVi-A3wsns3FhmR^ZpEbtWtyi@eV)L(XmdtGQKSncK~dezRhLc5>#_<7DK2%#7}0 z=!=-e$%AJo9AkJKAu-v7$5$YsJ8Dum-v@N0BTU;*)UC43l0EnsMMUBA*w(>91A~vs z*C(akjx)sqc}O5-ER=z`%u_%DO0VMxnkXXpy}+T0PIImgwe0UUp{einvZ-mGCh;Fl zXf_oxJ7wsEzp~e44v)3SsPgeBEXuB$_7gbsl>=67Of0(8Qh95XD{_Kn+Nok90y3BP z*eR-JebFnF#r0T;qe|xy@nM4azwullolrM9$XKeBrF4di#&WQ-5F8CajzEp-t%toK z`)5$vDZ9#w4QQcuN~e*u^2<{r3k_;uRTI0+7sc{M+Sh%m8mQv?x_6TOGT3O7VI<|H zo=X)V7A&~d7ij5l*t!gl@%tA_Sibwe?as$H-PY0DpS>qLKRfk*ZU24P+TQ;AFn#s$ zXYa`y)cWnD_5W+VebZ?j+25-0&(5lacb@F*{9V@g&+Y7o|5QM7Z&b<0@4(rB47rV= zj98cU{#}XoZRJZ&R!7n@U#bCCSL?+pi_~MQsEZ-H$d|%IV4hi+Y{pvE`4hCD`JWiG zdB%KE&g0>+b|SZOmUSkiv`T$l{lxft9s@f_V%miX`s(&+T-rbu8Cf5{!Ye zv(Tkcfm?m)Me^YrDpZc!LpvfHypOV;X6%mWOud$dL#M8 zwzC7(69Iujr9n;_OL_J961&!Q|G@Ip0Tu<66Ft1ih>Y zycD^-FUvTjmefgF;sr;GQ|UR$+}^f{Pp7uEHTqZd2szarE}h7JDa@+DECWjzY^XfJ zj0OQ_wZ7Hj)|JWH11NX%Z|Q>N^=X*RF7&d_tzJ{!F&W(pn^4Q*Ys&M+*;(3Dn03Tu zoZhz4ruora4^oZSv2Zh>O@go10APaG74ZX%Jj}FX%amGo3{17>3X*cd$yRc%tpD52 zR=qOOY#(zkO&%D&<2-qs?a-GN$oKp#)&FdSTxX2KTSNjZ(f|8{V*dADr#skt(Es=G zDF4*S50|gLfA;d(>yyi8PvN_>=g;8jD|q?p5}rLhyVRbhf-;h9k-6g+SRCLLr*b0o z9SP*Mtf;4L3s6M9XEct?ofs{ByIXqYlXgm&@lnl(RP>-xUM`)iL9&y5(J5$|5vNjA%HFel+SLhOEp zERAr8B65!{Mu_oyB`?Ds;a^}_O>UwI3cY}Y_4pk@8#Ka{XdNbQpd9_ zf2_Oqw*Y=J^%EC>XIu)e@r>XbvpJnivRStQ;06ST;xu#rukl&ht2DJIdLaTWgLtNf zTA~kOs~FIz4<>#3v}MXhNKA&%Rz1M2S+^BYuL0^rR?M)y68k$uf`&!Kl#Qt8ER;4R zoKbx@b>?Pmj6EzHP^+e7<(QXZkS>1ZgCdfrT!wn`(NrjYK7IY{% z(}xuqF)6)_74MbTF)2a-Ut8_coSx|W) zLuvHynypGcxH5zNLHQu-id%^Xk_vyM@y}A>Pc!scm*}dapRMypVt}H1_|L@zsjGD@ zK1i$m;aDN>eE!pLgK>Ya$_1wQA8GV68vuWrQ7><Tg!fT7M)SDAD6j!wD6eLaVYv zMb$qNPt_kcFT0tanIKIBaMD>`}j}A1ep!&`8te{ zt@lS`hSH|~pNAuKSi#DSpo{;Z#y<_L_|uHK4((WZV?mYvBaL|)+VZCv@?3Dusw1DP z^haWVQmE0Nh7a-qH>)y2zSbX!6Urf2WmfolgMBKVW${1BQ45v7WwSOG$N%*E{ry4l z{LkLr{zLrFeLU&>8A=g#O+s%7T0p%(QN!kS877l__2aFDgS(oO8aatoC$Jh|4!P>N zr;b;y)@YC%QT+%Z2|XMN*wYYevaDt9$<*ag`XX)KreCWDYo@!Ul)gvvYDB5vf}!Y2 z_x;MwFEy8j@KHg31ph?5kSKIlX_F90C@}LSO=t)aWdgcKolZy9QzfiyLY~Jk&xk5c z-D@naO7GL6(Cr;K9jD`TGaqFeS1PH)Fw>Mb57CskS0$0?dffCaZ9yeeLcx`fg*&+t zWQu7lhS2Tsq=e>15|LAvhLSA@%ST4X=E{xVV~P&e2%D2<9d= zTw44QoHKRM44%nm;U)F3&TUU;m<1GhHuw4arx&0Tyn`33{OSzkEHd~(^F2@Xwi zcUk9xil1Pdrw~H|Uny_al}WG8^L?G7_g8{mA&2o?Pt{<0r*flfgT849v{md*q5CY<>Ui zvKpA8MjZqrZIgxZRW6f*v9^>wRKd$v6%#$%Nj)F!B$PEAg-mf?EuQkQ@wCshD5v=A zY}*z`n<~S$^f^UmZ<*+<5uUK70R4Ovy(2*iMPXVTh4fh>Qeh3T3bzogu#tF$wL~l| z6|<0t+IoU56}bATVhls>N`oM@#Cjh6*eb&-SsWNLGNiRA86UTrRrPXH_Ad zK1;>9eHMy!`{?;~WnylIu%*uR@pi;#VavR-VgAYh4-(9im+LO;vIn||(IZP-}W zqWxX9axpR{vkpsnQ46$-%hzY8msd|;UL+sn`s506PR8LBha%gzRn|&4^dd?^QBW$u z=&JIIUYzLpopS1(UqJi9nQIeoU{@R{q_ zpy+_QD5z{Er)B&7gM%EAy{lw|7pjO7H^h+<)tVoSW;-_^UR5cX_1JBt26FK2jXhUZ z{Z=sls>(2<0IxBQP(Wst(nR^mW+)g!f4@^DOB3!MWVkzV7id1o0?y9&Vma=JAlpX$ zEMJe*mF-B1|6s=8GT`>2gglX^QyN~0K>1?i=OT&ZrwB2r(aR=Sz^_b_@pM2E-^u0k zi&^)oUtJ5mU#pfqY)3+9Eb?47St>sD<-WQL$}I|3fG=9kf$$}BG+ zr{4)Q&N){F8XFF6jueARvNbbJsMMfCX#V`Ovz?ZZf4%uX=k0&)>@=&PAtBHbaG4^@ z;c2ITc2d=WHD#8Av=?2}z%idI;KUqXp&+<2saZ8q(~SeWF<|`|mfnfLo$BY=&KY(E$-Ym?wGG8{;ylAdCFUlxn+Rn5qXUx;&OX{fMr*;$B zJ`!Q%3Npi2)u4tj=vcv#ZpfxM6^Ug-Op>yW-OY_j;9Zf>r%Q>lP*~UoGGs~HQnSf1 z(JRh{{7b<_krWTwt_bM3(58H&uUt>DP^O1@30ohU|B#cJ3p9&w;9lJbNE62H^xjB3FS*X!-4!GXzn&CBV!WELOuzw{9jF%Ve^}@EJ{M$ z9DeiY({9s`Lq&V}=`YPspLUySr%TqDQZJTuHA^;kn;sH~V`1MonT|F;?KUGuUCgVFtZ(+_2EMjZlGJ%mv=f*QpR4yg4j62jLnt_ zm}p5eq?x|Y*dxXG0)53&7Q_f~+#+7)-Q(?lo?JY;I(xd4D=0^_-(Nj{_T#hX2JVao@f5$HabhyH7DetQ7ufu-L|l*#X*gZ&LV$n!T`+Ab}Rh+A+; zW;TdzKfM}E-Gcc8$7~3Xw=bTZ{_y(j@_$cXy}W$(|1Ph7ID4w^&@V;N8MT%~fmnd0 zu#lQCy8Yr!Wa>|oW$_A)aVS>S))&t%F3w)PygK>**~`mnrJXObs_r)EoJed|*Wi-F zGKxg9+Fo--6`#`}rumklhKb2_e&KeJv8F!CL0hbh>gzpdsD&t`8fuA}kUUW@s;jRp zY<_#(b$SQ-GE@1>>9#sea85Iq);j-=N7!I(FMQrf=6XKLEh?arxn?V=A>8Pq;3luB zmc8ZhOKFF}0`2fX)6Epp;CG^saA$uYNpve)crk zLoBJMaSviI>5!WLkI+g6V0FSBEz5X zOxZC&I7l**aO`Zsx1bh^0<$Rzl~Y2l5VI}4CjwHhv`@@WPp2hJk--~d6H<|2^mF(c zbAgypk--u50Qmwlz#)&B4j4uPCX|bpnj0hlk8m^!u%~VzMe61@B*-Yh)h(aCJWK8v zCLGi~?}4mN^Xmifc7S@{SXm3wz4i85G zoo9Ea%-Oh9m+6&3a^3%>k&i=YwoTdgVsBjPel7~Pg+Nyp(kc9`&R7V0rFBWOk#;|! zwRHmN;mg8a>9~-F8PL?}i)T2OL~>PvQQ#q|E7WUOjTvBj}s5^+F+c$o27OI_3Jf zd>pk(v}Q+DtA;T{J_=F#MdiuPTzoBo=&L`oEwny;(i%r!l>QNZjj6zuBEIqz?W$<` zH1IG>Pv+hwVpW*boCIE=R`x1jTdqp3z*pC)Yd>9%Pb`ogNVLr&OV-+c?0iQ8%$@IX z=4SGgPVF+dogFArqV}@=ip$8C%Kya7+dKilV)@^#kpG?i!NG(4zmF#?EKwBkb|NvK zCL@1`Spfdf$NzbRl>?Ar6~n-*jdSz$RNYHmjagDw-&u4a7!r7F95~$kRf(KnWV#T? zqUm07Nx~ZBF5h5YS}R+bGPDcOgp<@NxJYdIxD)JN^LT1DI&$2mg(5t5>;lU9C*t@V zi3v38vX(S=6k>dWdV_r)PgCIza2=1ZD}uu1<0b;Dm8|cEP&~qx4B9m2;ss`7TpqrN zdRg|WWxNbN%hxd#3N1ff?qJH48mnf{h?=YK;kG@nQwMbTq9%G~*Ce~OCjYiuXUA18 zmW%^pmaU{kS2k)VgS3eZLP+id;5l~-Mv*PRP1=(zWMToXjRj> z^D@Ooi+gW%yKhVP`D)tBZ};6;@2d#4qTRLe* z7PE?onwrR+gA&yD9^V*Z;!<6=R(ENw>MhP?!>s~gHXZE+gWX+iufVo>T-8n6u}XFA!T&0(5C+l^{OQY`@a`AbM*e?n8 z#G1KKk{)_q?V7zRR4mmV5tTj%JfJdl^|;xzT(rD@lZtogfp7n%Uh={2OX_7e$e5aOrSY zkoF_QA^CM@15UU@7I>Utf%2AY__=ptSKem)GK}!p?w7ByTlf$$^GAKw(f=b7dL$g* zb^K4i(=FzI@AVJ%9`yfxJYS#w|EK1%2Qy%~^rrzf8yEKKj0MDQ*f`>>t@Zgy%VTvl zzv^4dU~rN1HZ(R_^DJ~&tP*1Ibz4ApI|=>-hR|kH;ns5?N7;L1^~cq$UK3~dVC6kL zHP2G}PoEgEX*f1=0WI_Y4EFYm{-6EMgZ+0ePi3&Q5n2`6XK|9$G?($03i4az8aFIl zj96MDz<0H%FDtKCiTt{&ki#TUq6H{Q63yvE>=~t#O*S3nLlcVO1^F<+JBkV1TNtCi zDcc1qIrg7``_dDIwRh^Z34gB0F@&aIu}Zo0)iZ59+g4|ikBU(>_s6`O4Z@d}^7YSB z{U6IQ4##${Z4(1v>Hbe|uc-eI2K@*9e;-dS{@>nU%J7(|F!QSA=?lXVKWTO!NFADY^q6)m>*2ixb9>idJYzDjCd@c0NLKRLUG~sPQPQbdotNzFt#t zt$%E}rbTt?;@SI%={TiKT*Wn>40VIQWH7uz!m;C0 zhAB76ON^~>p47kHv1_IBG;Uwl@~)m#-f}cwerR-oAFaEIV%oG|G}SS^8Yq*fA(1> z{|9@8^S{fe&ga(l1Q#I|H#M4O;DG1is`+~Y+6|@KTBt# zY%K8)`;akClkJlrqm88c6qD zD=}9?_jO=hPhNG0K_!xf)^&5g6IHT`{NFV0%RbBGe{Zi}wEqwGAL767<@t>A|1$(~ z{i)Qz7Yb>qB=mhpaXmz(+|#p6{&O7ooQy;4wFu`i-oy>GME-XM2gUuLUbp|?|GAeZ zmxi{mi;+n4Gd1#eDacD~^@kSa*4ZL^eW7|igb!bbU|T-_m4rrGLT_dQE}Q=c-J<`u zJLo*vfA{j#*?)P>TxSUuLwBq#a2rXnAhP?5ONbQ$Xbi#7eFW0nft9r4{J+&6(31Jz zAMBUnKL-!-ANTVtng6%i{kh1&_+w;|Tp`5oceVp`&-ox11wVYy;SbH#1MHf+nLvoA z6!VuLfKQFmjn}Q}9UvV|xL{Yv>{qD*udy0d66W&}YH#85LKa5-?Mht?e07z1 zZSDhJo&ODXy3?=1VE$S{I7dQY7Uoj5$OoxK`w%=vqf)r-mzuQ3r|>X$f6sGw!wBR* z`$W9P_$%F9UdjG5afZYvuFX@mP8-Yo|NXt<`meXwdszS7%d?XI=QJJsyLAHPVpzZU z>h80PYcJ%gH)eBp;h`2AZ(m0WhtJ$Q0^^vwwVi;vC};p^mt2w)H|GT0#Ld5g^Y63e z1N+hw>??nk$$yjL@m425mdO8Jr(e4Nr?>au|G$@K{qr9`CLHl_0_5QY$SNm5W<`#9 zI0N!<2IS%SDxPKfKWkEbru+}xUZ<4*bMO%VbwAIY9>h1y@^!oT{&e{tcxKI(j*xY? z*&8&<*GpuNQJ9N1KHItaFFg(Zw9hj6Z?8SsRQCVJD)RrJbpG$4_i+B>UYHuefTs5N%&Q9Y=Ffue|4!bvZ+zXjE6_GQ)~^;$@CfduyBfMYXR z@~_(5MM_THArp;|dyPYHeeQ{ByI0w@hDW2&5Xj`_8sH&0B#{ zn_Vr2e~mF0w*#g35D5*l;Fb?W<~aJQb9&*hR885su<`nxw+-~ul1m}}?Aoe!U%Yvj zH$&VxZfhMS-dvA=HY>dDs7t0*% z)rUpCBz@F~-FiuKha@WGqSt-P962c^oX>8NsMlZR;f@ua#qvL0U*1LsERp|v-M!-d zf1Uo`!Grw2k7q6UkD`cYP6`_CxWH8h{%<|KH&O(D8j*J2szWJOeLN!^lkmMV+oOQE zh!3H&%2CAiM(3`_=k7-6Zpdp+R9cB^sFs;U3gu#KfPCb7bk=p;kT`DW`id}E+)#GS zhxX$7c4eG~8xjL0D4dVnEQ4=ak8nX~8umVfrjG)iDY)+7-~I64B?H`UnjU7)h~5P+ zB>?Som5)n9fk=p1?szPjqA?zVJ7$iDXKiPFB?SPClB5g5^+PT6xj9OwEEdj;ia6$e2SB~A75ivid zp}_A&9?Rt;#4s0(xI&In4p4rWy1jhhQ7%$R4a|8Q1Q+TcTqZ`T_+^;mor*}I!+bND z+oSAYHCy0m6B>XwO6Vj$@_b?i2q#ALi;}}m~XKFSZx3I_Vzo)^M9R(^WXRM zZ07$tr{0~J{D!}Ne97^!&XEC;?9RK!ailV zr9P?sK$RiZ*d9_DA|}pF*_U{x&Ufd{5$j?}nlpAub3{alrlc)L$rZs+vcV~e(1-*? z5X_x_$0Ka`(RqP>QG1Kd;!-43rSy2zsQNoo@=2x?mrkcB^pf3sy9wKJ&5w@_YkUZ3 z;kaS#wg98>Dvq{y;6tKau{)tQHF^5?qeqY6R2GLgQlw0GQqrP^l4kQ4S}igT<>-Y} zw0s(e-mx_4p%vCnxndMY?J8mI8(k_QRp8@Cd+*4yu3xw)z~IrF5Vme()o+!FrD7=- z(^l0m1Fe=IQ%qxVyx&O|E=#v*vuU+vd&Ii%dIk zk%y^cOom&TN?&8wTNHlbG>nj#v=DE}-^W`Y9F6^_t-PlZrS$T-Hj<$#Z%bq-b7$V+JD}QLk!p8Dw*p)_Pl#LGVt^%X z-E=~wf+=Qs+p{1^BI<1Q59Tf%5jb1V+;ph;!at7Y)9TK~$P%LVRnh2LEg4t`GE zt1UXij1dpF#5}^sDh(4J6SuMqKTdVrhs^LbQ!&>ZLUYz_?qg60Yyq9yJD zo9PHXf}sD+X;_}#`M=*bs=j>M%CP}7AO9nzyUN}N>cCt0 z>tEq7t6M{NFc(TTzDKQP$Nvk+@#F1n@}J$E9r+NiG-@3k6!i3Tw7%0t(et#9}i5Dp;~5FsYynnz4jNIZT^eBr zE-B#m*o_5-tqBgM%B0)cRdsBDhPfv)X4nG~s!yt@${Pk-OX$3%vL9$>QFRk!x45-9 ze-59(Y0Q{3IFhiCpTlqX&tdjcQu?v}^>g^>(WBV>UH&m6H0IKXv@7bb$Dy3MQNAor-AbHRnhq9PM3c2vYVBxS zM=EA%NNl}hkR?sm1=^anZA{yowr$(CZQHhO+jjS~ZQJJUdEW0v+#mPPj;xBzI8~=I zbFY=T_exKK5aTgFHhpxh67DSDmtkxysFQ(pc{eV`>9P{R?(}61wddH+GMG~BvsST7 zvU_n11!DVb=~@r!Q?)}jMiTG#n*gjqzV+9YipAHQ&5UHZ=AYT5&DVDBu|K27=3C(M zFD{-+3BjUt%hB|DreAHXWl^hol)n86)sQ*Snh{B0b@FwBUwmW@v;cT$#DHU76Xbc1 zpYc|6+i@L*s&MpA8U$O(&flfyrw04(G;8;qX6JNUXpMRu4HN~V-G#G->8cI7^yb2_ zB6++JgIs9QQgH8#u$C{^nv2G%sR3~xI>o!|vemK_W^%ey-LUKF79qhi6huW z+MCtmNj&M|N8YNR*gSgo?runBNm6jE(BteSXXJ#xHg>aW}VCCLYs< zmQ9}H(MXjs7MtfNU0mIYa~0uM4XZ;*{E$f!Fl{u^AWynXD(A6~x0;wRTy9`O1qMoT zo{W9^zcZMDR^3^_!Eifhjy7U|dGkJg>!aGgEFT`W9jd0dqc^)}N!Pn42YPf?Vf$8L z^vEj5>pGmQ>%t##E@XV-sj?)`o2`JA$vE#TtUYi%W%i|Ye>QFE|RA$Ma$EeSNBOvh-5WS-C z9wxLV1GB{!4s6BCZM>_C++P1|pWnEiXJ{XX+*~Y9*tp{$gKR&rs{?q>pJ#e@`)!>& z?&ORHEDtxRGwvxM!>iCHLKawu_MFD%oK{r`PE=LIH8ZX2(f)B>q_HIB0!(O2a=bqP z(V3Tf)cmMn?CVqH;JB`jB0m0Re}5nP@bTEZ68O08;*9Ct&??r%cE2bZh1Nq(=vCkY z8toD`n9Ld`Y|SJyLMwB??nLG1f}`UFUPBwjvEE=0OtOOA2@tMGD&!hAESY&~D9XH>mhk92tov z^YtAiazm&uZkxsBHH;-aSgME*6XJ^A}3Tm*7R1#VDJX^<8Vq0xoVMD-Ft``Gm2D+D}fo;--ncd4&Gev zM;Bs@&GI`?#5O)ykc{%?-~)OZ17%Hd15i3Z)eBkiPe(J>P##vIjmI-mQb{K za30~Q(@|!6fDwDfG+Y3XB~j}guuJaaWF9}41v`6h^_R1b5ccoESdn3cD@AEz2rd4| zpWvB>Hm^f?@ zSkp++(IBheBu3YJE`;xJkzQLt1-BBlhHSiF1FcnoThR_qi>9MR(=Np#QKTsKKi)K^ zYCupv3_RNs@2bD7o_(ju>5XfM8zN~U__{wZ9CZLtXp1ISRhC?DbMS9gWop(il53Pn zsvQ-?vp1|acDp*dM0kbqTA0qX02AMr#IlgjVc9#iJL@7Xp>{#ZK&d!DJxDt zyhMp5$8)uxaK0||=dc4YSirX78&2WgfAS_5lgrUE$4lR>`$1geS z3ExEV-;O1)&}0dRB2=er+!aZbD46w3FOCXB%ZPFQs_gP7U-wuzWNXolK3$|&ob^5+ z@LT&?3+U_PyS}Mi#<*ZZqK9$L=CnJI^etJ4GP03Zh7@(3!h$*cp6x^ImeKSFy16q7 z66^^bN`JZJbOTaP9N)duSLubpwfkM`rvrv>b$oPGyn{1^lE@V_0kQPykC2RANHY(L z3AK2aXrD*I#i+OW8ZB(4;|d4sr0R^a5mzMJD7qvH?e2K zXz%wNda)^NDj8a<(kK~W0X4w(3j16kh5`9Perg*Mksc}k2C{RbGdLh2Hw(59Ke*Wn zgS_l{`ohk-603xwBWql=sK7jDzij}@v)N-Ak$R}VZuaJvW8&w%c$DfNr^#04c394e z>lXR@Htn&XNu)#MaXDk~CjQPO-w9i*E;5;j>yzf`dvGfAv7L5xj^Z2Xg5wh}cq`ci zTfuEg>0QyaJMpsA*%V`2lx>c^u9>(YzXh0W3XLZz@j?ujcx!Z&zr?hz;`JLz%_$9i zS+e7QmdwkNc4&?emNfGS_wA_`U7xQu!EeO`hFHZ1uwsw^QdMqVVU1Zq?ct?HOudL)oUK6l&4U4pm_Z1`6t| zv$b0!LEA`quyLAO0p zA=4}Zh-=`}D88=eTx0HXGifmNtuW{hU~@%YhX-hyFm$)hJKcvOll9~G-A2k5rB)#| zcEK#i&Y5AoQH(%$qwCLwS<$sNJ53WLNkb({HKal6v)duPS9#wwEF)?PIUMURn^&x$ za=0`#7$wUQ&rr5O{>;+*R+UqSA<57yjt)CZ#ZnoW0~tioq>Ln$(U$ki;l$`CHy)RN z%MMjRkjY%8&^H1K1$G{W&8(#lnlG6nd!q^6p2$Hm_ze&GKq6U`^b|`}od?aAKp-xd zlRjEj5P4qI8-%MmMY-fmSFrh$hEY_iE&`v&bY+M38|Batls{@LgG@)OT0?Wv&D;h2 zLfX54z?lwfe#VZ}N}ewir6k zz!LV|f;Xc~U8ca8s2J+k6Q4_;Hl4GYVG%MNiC2Wu_B=rD{tmdDtv-=aZ!# z-AG_^I)@2kjOf=|^uWfzmp^suTx;H+;DqA95MmHC5ErCK%YXn=Ze!cDmpxeYa9g`f`;Rd-LdA#d+0>*2-hs z#UyPZFNT6~M4i!N4#Uu|WP;LnLQ$FF7=bapzY=(V){2VBU6YV4$Mf9CCora}fBQ5o zz}D{EbX5Zm4&=q6`oZ3K`28ka$7s$P-)X|lej`(Wovr4Vl*;!Qnk?}PQDgT*osmVO zMxdKoF&dbp-amsJk4?5LjC@5#YV$6(C{W>Rr-8hKF)4Oi5RC_?>ts5|qPLvJc5r=%gAIbP-!#DpOA4 zo6>X-1SPxylaYQlPT6FvLT$lps3K6o#AlK^1>UXJ0;5s05(*2y#3qLm6Ile4Wgy1Q z*VXrRGqZk<10CI2P(awpv&PfU&ED^g*3o^8d*x=m%=7U4SselE!Sy_I?&fuY_vVfE z{2nkH=TX@DvZq7Z)z>}E3sy`|-oKCUYc)`}#s=A}wQvpH{-yo*+@<|_=eZs&xDG;q%IL;T}#HjO*|9B@O}8%KH7=6b_j7D&YtI%!=#rqcTi& zzQ3Tz@xp|{-lUJ%P#da5Ima=gO;*|8i#x<>4i&(p-BA1ADlcxOLBzZrXR(o%7m^6n zz(P2I^XB7obR9aHPQk^nEMm#n^5b7qOq5Wm!uE?u0r~wvV$58ZZl8n2a>X8c9v*t` zd72r_9Q=Y^XiSNXsxpavZu0a#CkEv@KisFXOV_AE!kOMmW}qpqJem5wP(_hv)((v1 zIZ%mT`F#+3;xI6r%#e-9G*)Ir;Wmx>$$T^ zeB_^pRz?gp;2vppWg~@=ej$BojIs)J^Ng2FbFl~c0x$^gaitXs(c*OJ#KE)QVd>b% z!rkErX)2*;NYe3%WRME#+$~qVaM+Y`g8V$8b|>Z@z8y#xLwvt4;*X*hF=uWaI0yK; zfr%c<&II?`#)egYIYRqYDgv~5LO!~C{}uY|^Dg0Gzkt>Ze1hYwaqty3omqEycm2E0 z^CM-`7w5C%*1g`>h0A@jIgN1U#C}z*Fv`W+-+GM)3;XQxRqE3k^Yb!2EbM2FKN2ee zSKiC#IM~jxAABvxI4^{79j%PL_3Si_%dC$?rrNv|`CG-)*bv>&R$MmH zzo4B;jxZ?${^4jTsgTI|fj|oPh#~`qBYQDR|G9AVQ$vsvCfFeH$2|8%1yDXt9KGTw zw1l_5W@YkGNLw2VHxeu4K({%;FYNdLW_0sa>9799AuB2zc0~XauWLff;6^eBNSH*e z-^A;cGrr6j*sS-D%7CcjRmOD0nprmMzY3$M`X7gL!WtzuNQV!kXm-o`?wpCLLEGO7 z)gjFr9*2dh@Am$PXhob?vEEUm;zMETCd0G!P|(>kX&7qJm+#Xw{7xJqn1MgQPSBJi z7TX{F3E4jZ@%%MWLVko`4VzI@rk?nb8_ukBOdFYh=r+m3MECk}6x3|qfSB|mRYMH& z%LX^U>=x;KK8plR(cQzEUP}>?xNuHrwdViTni8vs4EALZ>upR~$i|cTJt)F179Fzq z3Wn2vJ~u-QI6Z2ONKq8qC(0&2e<9~~;&%O9-F~fOXBcY3!0VjE7&qLn&8%zU$S;ip zx=WY>B8Z>oj}P6ovl+n(PjtG|@v(KE=PhB3`(tuQ%eE1DV^qTfIkWSSR4JLZ6Hb<5m@EEN>-B)k+MJlojU`=PG z#ZqLgmtx9=w0ZY2Ieqo<>_y|UmGo`gEv6CyH8P$*+36okm-M#C3Mp%-J4APTI# zch^`4J0+T)(w4vuJ|rtwfFLKg;TT|5zB@3af|)p+nC}_@_Nj4jJa~G7d)tf-5$TQr z+v*jvcKMzeSh@fB;VXXyzQFgta#_$FKeqbhY#bZ6+16a$+hWkXqi}LU8(zAK7}k`M@{Zxk3D2n`wnc9)pd)0%ZRAuN}BR|pN{OwwwW*z z=pPb?B%h~+W$N&YN_ietBn4=aiW50I04Nb#mJ zh^bN-D|FwahA7c84|1xR*`GyVwe2-AG0C&-?*9zW!4ZD3PDntIwEthkRNul{WWJ!To3gqf7@oTG4Tu05SJA^RZW2<|MRHU8k+4p_VBPeaS99+u=vFDR z*D^*+{qx79%@S!WD~ZzH!@g@bb(XcfhkaOE-;6y51Xn?L4$4I%skI^|eOw(q+uU=( zqs{o;<#pXb-+oYpZ&FtFBJ7RG$qO4_`DF#*5&*N<8n*^emu&DdDX5IVd3r&uQUP;t zp3cSXhBhG>d&u{5KvKbxzgN|K>}9)E}k1`{$W?mE#|r&RWiNOh}d_b1X@(`{dt z*luQ~t?B)duj;@wTN<;*fdfTPMoC|;sWo%}TF`4LH*x~1TzcxoF%>4KMV}0!+WIE} zqCi!4c%4E*I3vLh$_N&@MNUw?oG}km*W`>#dXWCdW;2Za%Rc!@S+7H zj&xdNn3H0+x3gW^+s0yRnv<%0qd&iMBaxBVi9ti7QiLP~N=P<0dbNOG*tiXROtBzQ z+0y}UGGGox9W|QFn#5&NL}rj}crh!h5cc-_${76~H5)!!9QmSM z>CZPLhc{ih)YLfAPJG$$!iog6Gc1@;jn^XI)i(0ftqWO8W4(&oXW#EWc}j=z|hfMS9Ix~QpflTz|Y>#h~{)-)=2sNF{q0~oqw zV~AnZik1$(7@ka+pB7B*W>fKw*9rLH1HZU!PG?_t4q92I)Eg5;N|}$u911outucN4 z^4Uld2n@$QfTFC*7avOQk}1%d*{i}~;6cR*pyRIEvYD5*oSv_M3$WFas~$RBbFG>2 z&RM4D+(JeLOWi$|l9I!ZjSMe5o4FLj2CE=xlRhe%3sgpus~#&e43uW_W80VFCqp8K zZTEiHfJOW{Uz*StEI8(TFXwcVbN6+xMj7WEmFqLJF+7WToCJE9oX99+?YsDu4IDd*c3Mr*Nq zh~IvpF{9D1NsWSYh-z3FOW_hn_6oX3W<)(X1KK(6XsxY|tkA;$Imhb)xsM)ae`YJlko zLclheqqVeR0hAfFfXS%Trjn3#(J^00ogjXC&3y(q9|{#|vtHQprQRga(jYC;pxq|e zD(W;TPtd9?Ic9Qa#BT%ITxbe9A-H5hW%@4onIY5!%=LVGApvX0->OtBJH z;+*dlhxY&+z|)yVk{HKB_|iMaU3Aktfuw}oyZcw+tY1pQ)~{x<_CN^jd2(aD)R;+E zNv{b6J`4wRYF~z?NYcSqI+4Dp8c>mT*_HW^2c{75+?cR;DT#ql0toGX;~k7L6C)9A zbkV^9#H|i=pyYBkP%T3iMh6tt`cmh>c=SwXXI1)R4UJoBs)TD+2vNyx z%J=@tB3HgC(+w<(_wf*S*KTH9Ze_Q1_S07s`#o~in?k$Oah=$OjCz*mGqG>T4FsxePOzawKO`#;+uLbLJZ-f#&RhC3Z|c?(ZU@qngpvIF)Y+{T*k^ zUdsJ7A5xmH3LpZ5G&9r#WAf1ryUi_&Xp0RRZ7cH{nNrY;NoiE*WkF%-7^dX+O!mTo zzlt^d2)EME799NDFNmBt4X9>FbtBOkXp(JBhSAf}78rxwFEIAQ=!fG)zE*4$Om9DA zOzZEsPqZ{Y;}=}NTxy@qe+Hd|B;8ew;-M9H%07ZUeRhH0jyg|1$@)DZ zbEj>60`4rX7%}rjiy=}iJR)Xzid_SdkdIQ%jWR>6P+)=2(8W>%=%vI;8IVqvYy!af zj9kQe!NZ;=YIn#KNx7l<(j0mY6qJ=>#=Y9|NzP@Dc8eJXM`cl8KyR(!XEg>T3pE!R zF;tOc4TORAe7Yb41aI`XZ2`QXWjjyS9?6+_ePA=I3TPGE{_kCD4MQS;-s5UFb>6J7X9?MpDJy87kJ7naK{>*N?x0#`4R zFKwTy5E7x>EcP$Wl!by!75!iqwc~rFVKq=0X?pNQ`6H5nJ1j7)VUNQ;0JehZ7LB+yS7%HkHsCq_%!KX7)1OLGVRPOA8xxp*a|^V<=UzoA2`fCP~> zW0p-?m*?|0^fM5bES^St9UPA$^9ZrymDy>U9xC@o*p~&{T|k8!B?oMocgs6N4kr!{ zHQP~M|BNdTBxB-?^LssMU7$x%t6#H3YK$&OrVM^smWRZ1>co9@%4=)Vj2&9kWEWF2 zPU+~TE8E0m*NnH+0uGMk5pY=6E6z{9`<6y%Xjcb0h>A9~ULg#Io|g4rY32rBMP+|b z{QO3g8oXOcb``q$7;M$x)gPh{-mo#|XO2@_=GdBU#I@xUdD9q@W7$@La*LEh#=M<1 zo8+6COSIXX<{?flnaizAF^t;)!w~KI15x})x;;@=NiOPi(B&>8X3-PGFr3A&BP`~K zQCFP>w5AGVw>~t)el{%@9R1kh5RI5#rX0U$YYLJ4of*QA^*i`&M{(;fOV=ntrKBY( zGacZ8BkD*Zlo~4^p41&u3!kzgGSmqnbi5TjBhxTm3!u!%oy=ntXFj`2GKkQbBh*^# zz12yk;W76wjm&Vk6r+ybW!ADAL27{)3@vF_elh`|N~bhsGjcXX=Jdr@{n#d8UBvN; zRqT!Q&|8JVBQx};1*X#0 z|3{(#qyp1jCM*pa8cy4Ds3p*xL||Yd#x2_#e=$R*Zz1Jwf|$#`6My~Z3G1bJ9_puL zO}K3#-3>mBnY5NfNIZXHAN~VkjoEqQht_5?ZKIyje;!1kZ zUG_aB=tTT0by;&>_Bj$-f#X%8r6!Bs6ZAg7A1 zovam{1Gzc=+!9%q@uqhFDLuB|Hi|4qH4=E%N}sIN`P&=x$dG!W^o^{E==?Fw%Dh*R z%1{K^5*+#PjoyDajRb!>0xrXySA)hlV*dq=pE#wf*eqxXTv|n*3XHzl-v&BMrs&$I zX%W}n+$jY!=3wUBcL!N!Q({@oY+Z z>*8Qa+UU-h)W-SFxCF?pAtA-8HzNz0E12UQm)8S8O9Gd7Jr-;Rmltgm*c2|8%h&tP zV)kEYIjV%q*SZj9H^2#KCK`o7Cgk053q3tX)x*|sN}cpN>b))Jnp1HrSC+s=*0vC4 z6}6L3@6&hz3%Qf84-0wx00wd^cLxUY*B$6D+I3$RGW0zrBR?ejMfW*`G?##ml)DJx zz*0;-*kcY~ZNa&;^_j0fLX+LV`NOgH@2{vRn!=^PEL$2U5H^mgMGC!GI2%}91R5bM z?3LS*?garX?5+g@X`QouSU8=tdAwUEJ4RSH!XeTq`sbny+B z@ETD5!~pyIZV1_0-YAW(>@o)Ul*CtAt=(Tkk3x}k5;k-2fEEr2uLTXLbxTFEEB^k- zyYTlQ!5H38B|J0M#feEp2ZYwyBi^eya|k56s6n81oljIZK6h*%hG%w;xgUKLeg0BEe|<`M`Yie^8EyHR`vR)E_2jvfcxOzMEHhG| zc#%}p1f3piprPqz@4E~%$gztw5h2ME@o?%JU~_G0qf@KvM2j|dN>)(d%5|T zJG>mY&JxGd!s&4$^Ra)sdN^Ci>%V$3Ak^N2*FfA6B%i?ve(`z2Qq|S zD`YxBud722t!s=uczheN>A&fN=Nh&lin-+)ZXv{jo&^(la7K~1b4IaIA)i;juWG5F zn!)`0Jl|YF$5a4;3C+>l2c^}7i&%~p(08L}EepnKh!!iU39nklG7^vg_2@6}13Hia z+?N=zJ7u8;N~dOumHSorGi|NBPn`b*l4pEPd~JPYWPL8R_}P(BwG9r^%}C zwZ)`aD8$AJi>{NkhnI28 zJ4ZG7Ykg<3`(~Tgs`B|MgsRKZXa!Y;a-jZUeRrn$VDa50S!igymWo0-*hsF8fodW= zNl(r3WvLm^*huwX#pYUVjOL*#k^V~Pi9L5C)nw(L#m`5p6k!`V^gVL&Wl`{@!nG?2*N{OTQ?LS2gOf^qSR((m0YS zkkEs{3#Lj`+0}8#n>0B7I=PD6(KT&n@j`4pPwZ8z0g-Meww=hrklwe6yXUw}1Kdn$pJRIK%ph+KO_ zza8;elH}Um8U_wOOoZpA>Pfl>H>pl_KOyhvIK=J!!y~B9-6;@vBP~T5JfiUm5V?} zg*4Lv?aLD+aU#yC6k(eNYuS-qu$E8`611L3(OwU9gILI>5FoTMZB>Bk0ga$AdwWl}jinvtSuEGoddNzVw$ z8msUA9I)2Xc%|_o@*97@Nx0?i^+qp!WJ_ZBk7&G7ceRdoiVb3RpuUCG{sD^_&!QaMr`Hc9QtF$d0J%(^6H8wiM*xG+C+DbS zTi4PyL^5ljxfZSTT_^tyfZC{ZdFY~&U`}daSrl=2q5&Sh^qX%Ssl746sGy$8+;Sg~ z*nm^4D1Z<;sR?7P7a6MzUq_d^vG9_6z)0bR?1mjA}!km5i(u?F{@yw&HN6~56k$pXisOGTSzPMPdQ~$inA<-9{ zua9`V!TyK6SObrelucqmiIwhWPReI*I7I8*FNT2AIvBdE+S*UJQ*Xi?%A(g=4?k~{ z>n{aBUAg%B!JTUm<1H=6F%z+7z@2ye;HrVQx7zNQ7j2xC!lsk|E`EG2ccsmL&PqX5 zCwJypp!eK{$aR`+CE%37jc!vCSMmpD&ErauUFbSoV#uWL)}tkS8cZYV7MKCc+`H}cs_WNoP6uqC!#T3oXOH8FY*>O`b{ z6lvLgbyNm1IeiJcTlN=8A3$|A2xCd6BDA40D~U>zgImBdGkEC*c7j{@_oK2l|HFi5 z6*vJbS(ZE)rYCTzXrl%sSa+#o2E{4I{43sr91LKANyB2qoyD$Mtl$2eu39}9 zk2{M2Dsb8p2YnS_HMpIqqX8;Ea1^X2i^A}D=-G`fyQJEg2j?$lD`?5?v%~wETVSV9 z9{*PUjwn_=t!qU8+f-=_nQMf93t8fr26CrRp9V7I0X3v{GoXzeoukdjE^d4E9QjUO zg+~F4Ab{IR`%nMKs|cyaZBHH(P=V9pa-@z8ss5=Br^TTZs>jf^?Qmnb<_c1+l-a-Q z!k`u4U}N&2g{d9TcJJ4bwWmw*9v`*qg$3Wfd$CBgpD?ftM?t_LF%lhL2b`^K^@fKi zQu8?JG&Du2d(_l7p;c#(mf5*x@AmNGTD7bS#@V^%SOW~}jfw7B_1X+|q!nd{$F=k$ zi0KR(Tiv<@Gw=ZAu=w=jTvN@LUmF3|FAL2vlblAj3iM7Tf(!)PO6_6(R zGV%Mn6+Nk-ivS?~vA-+W8M3wkVS{YR976j)H0!GOgJun$H%gn@Q|S|Hj^T_0Z?&!314t(e8Ehn*{Jw9~%X_0a5p^z2}0*E%qv_2Ej&7B;9U z=^`~AK7!Z?@KPM=CSRRLM>+59m+%qcubnc!H>yL1A(v!`On`Cz!QRyR4Q--^@DV%1 zIMZI3HRtJr8l(p_J2zr59+vdti`RL`g&ReCg0&10&*V2CH-$-do6;@hhJPdqAgYnx zb7u-*3%d5FGyl8%$5V{~a*DR_bZF!MKLm04>*a?N{{It1J{;Fo+-!DAMU)V?+bUwn zL^dthNeoB61bdDoheao2vcVg1Mf>YH4~3R5WVLQ}X7EUitTF)+aYVuR><^_hAl!pQ zx29TfX@;vv#6Qcn$YMoqu@-&Lri!kSBLm!D0X=Ld`#g%KRVLFTzg2UavTg7pdPjb{ zhI^hHAp8&HMGMghj3ufw7y17c95ULGp<v{P`R`d> zALwzrw1(n4wT9M}#v7MB&o3#U8i(&c8!suKr%e4p2ViY)_*JSx0?&qY={!@h764&a ze-R;}fheC%-R>OlcjYeR^xYis(jDr$-m51AN}{fTmhzkiz~Mc8-L?0)+!TM;_q2Q) zn|wcpz~#S$z`b{Lc!cbpOzrMYe`UbIV#X(!nYpoqi+{ySpKyQNu3s-o|FiiYcs-xm zXTv}CsvdFVXOY34?07g&{pZBQ0YiMSX}z%y3@P7&8t9Yi%k}q3GQjOc8Bj<0;mt#p zZq{q1oZIBU=Tj#dunHK^Sxp&;x37kvnbf0nxq(E0zK;jLZ*SvAFN}vIIN0O* z{RVSw(C*Oie1Vy81CL$8nb!c-1uip4L)#UTGbIZokjhJthfl!d7u2f`RLFoS6#Dq1 zE)@iVS;Pv7kU-0l)4h6m-F0@&4UF$kh+6m02q!s)l1-4^t7c~)x9`Qo2ldVej&xr@;n)CH;0hTP zJrY2k-uJQ2Bz$1X`m%dybjT;9LJ^(%pi44@Z*@mb7c+H~58R}O@fRkDf}iUUl;o`U z3mm)54dgl^Q`U5p!BAV(CW*RXs-D=r(mdH_qGDUNGz4O%E}AGrKbZBmIh*)C(5%LF z{;&(VvtF`U6rhrBc%H8`_?OI+vo-&d2#`K8gCaLl0r}=&3n0;Me}{=JEIQ)$FLLru zxnE^EmJ=T1AiP-f0HOt5n3SY1g8&{vu}l7~2rDFyYRu*$?wZN@#t@jBg`U7hWtS4=N7M17I&29vtW!<;^Ww_e zOP`r{f_{fN==|4#^eFUsFi`ccww;T5rEEbbrd*F>J1xoQ=%c*7)Cu)z6n!|q_S~t))_Gq) z@C?JJ4kN^ZgbgwB%#W1r^;P#*ef~FI=a$#u<97&t&G%1S7I1;Det~%%Z(T2oMrPKa9kQpK}x5U#~L0 zGayjDKxvbgPbE4&Rqw*hw_=yFIS2uhDPj~Rmc`@zi2jD@_O`c=v-F_|8G5JXa*en$ z=tN<+rjYmoUaP4%o9R5CZxte3xQ}Far6yi-fAdQbSW6qpU_cS$wcTr}R!8j3`T69j zv<=NYVRlUKz3HB6jYLSPaY2;9II{R;UMVO320^Rv+-e*C2rpj+&-B8(oly;$rc*tC zyJ2dHius$!bRx+w!_sDdS=u7gJroiv8eolc%>L@MYMP?9ljN%EF4cQSJ^|>{Ri8;X zqCd0fF)G*>2rm2u9Ry&1gO?r1PzxoHSpfgBeE5oiK9yj^jk_%i%KvlP9nxu2W__yt z;8YRlJsjKokA!5 z9G}~vFj=`@rEqXPFF=}ND2lZ?cM#o+EZPU2nPVxa{>Oo#yI9Ca>=w*z`l@e#H`Ti| z(-KnGl(G_%#IeOh#&_IBFtuh<9n1K{8#~&BV@Xw@#bYZj04ENm%&@okvH|LnQbQHk z3zg%$CMD65zCP_Ee-_vB#u~|)n)HML$=vsVsqboL2Y%#TLXg(Eas15K0}4mrp?Asn zi`#FbkfE3bAqEk^e$r-wQtxnSuM>q7F#J6cj%dxw5RLQsjbX-$ci2)I+*K~ib&w?1 zikAJk*T>Qutu*gzQhh(SdqWGXZo1Y2mCd#0&=spVjqhE@9Qz&gubaoyy2(Ou_QdzQ4&5Lf4zP@#E4SEh-UncguE1QBR~i<^6* zX6v%=cuXEA?KXlbEHXm4tDlCEmK=YF}XZr2@%<*J<|(xF*wT?eAfZq`jy=T3g# zuIGZdHG*$K@MUStH(IMA)wHl8hd_up;$KDKPeMY!C)aAXC_VZCy<(Rz{YPw8>4Cw~ zv_7YEVb>550QbA7u$v9A6SH=q6P*;uc6`@Zhk zxc~Zwm(nt>>o);+zx)*a8 zwg|u5%RYTHtRc0ybH58d8>{jMY$O}SCidqrkLehnn)x*`f^{?!cyv~4rkHiK?tDbC zF916TOXhWqDZ}C@Sqh3aT%Yi_zXHlHw-!@b)0^`cB0bD0hIlySA@+03k@ zr-Iw4hWgng`4bw0!H=cmIk$b{PvaSbg|OLmJgw>yK*oS8adY}K_{5Z~d^Ag=@Xe(t zcrCpVpMx!jh7Dj7^wz)&P*fH+ZZs4Mpn$<3JcO(qWon-)z7&CS&~JTYFv1NRIpjwo z;l$nj>~p|n%;|e(JRmd|@G`Kb10dB|~rHd|(@Ya?{p^SmkreCubP+80U^l(UxmkI;wGRcjm-*REj80|)?yvH21 zK!4VJo?v0MaTPClXmu{VPA_@j_%f{jeQ2--psu9LwwcQ^^nh_VG)w-&Zbd2qC^);mP9nIMXvT{{dS zR%t>j&s>l~dKq+o#(Uw-&NYtYD$smeataC!;eJk(V)ouDPwbzyJw(o8X(tg=s#Igi zRcgaLO?2_W)ZrTaR`5a+U8`2pvAO&QNTb=^v{fmlHe2&6h9kBxxqUKu7ZECR)xyMD z7Rrp;%(p*w@U$(WaM73u8nLq@OWg zh*8|?f@GCKpH(Y$J41jK?Eo5G^o8ZLus5H_+yjf_WZ9&F2}L;{Pi{UTDIG?m$&k5X z!kpG-(JIYUQ1EjRTzLz-0Z4n@0VI;qeHCTAUY9g|m zZ>>%Y7TkaY>;%O7!N7p2+m|BN*FVfr7o17d%XLsR!y#qG6ZqK$=F+?>tc(JGEYuFqCl#~)Sym@%aSpPke&LE zuKxBZhd}Det&8@nxyOtu+u%WIe7oS8jj2*dOBw@vb{HaCNfzTO+$P|bAioX~M`IZ6 zjoQFJSL!Dg2p(ZyYvc>kZr~lov`SJH#s?uJ`$do#yoot2SeO7iWPk|%ob-KCM85ul z>xg}lq-GAHv}?puJx~B3&!9jZ&A6#qzvx@UojN4-f{O@2GNF>0PJ@%i%k1O-+mlTs zD-$65NmSGvM|@LS2RI9x9FQ$b4yI64DrOX@F6Qz*aGRqR+cO6Se{e$>obU=yH*MPJ z4Udj`Hm4W45na!qH1ijEJpFbm-kF3`UTm+4>9VUJXETn#8CQb-q=o8!dZr zrC))0LlPJlvB5;?fH3}4L2>b9P#&oQdbe%1t=*v<%bpR!rNy)|Q*uZP+>0+`|r!iXVao^~JvP(hoY`Z~ZSem*Q9 z_qETh8=mH&`6yKsVx_sM7#broA)-H;&MkFb%%s`)!U$)GM(o*qiTtp;9qjs$O zTZ?;H37&hIN->IS|LF=L>2l|OxI1VM>rdi8ZwVuvZOpOm4w69^qGSWFCvK1%ax?FL zHc>fU3uWX3-JVp>imYKNMsM))1F)Qy>}C|-A|gyrt8OzxA*;Vm0)XvIFW#tI9+mMH zvP}iKQ5We(`-6@T0;~mkxDLV*F6l4r%gr98=gReS3%6sM7@Eh|Z#O|pKCEVLuHR3g zu3c;!g!)ixWZ9}Bf)|=YLwyLWY-~U!4lCB$t~*`aGSU!VF6L$791fXCG5-&1?-(Rm zv_NYXyKLKbb=kIU+qSxFTU|D~Y}>YNtILyp?|U;bh(W~UkIb|4#L4`XC-+|KTWh!d z39C-S|ML>!Y5??J-tzmgCfB>SIqVwWr`JwJD+*vYvBRnNNw@HcC`$YDJ#Bk;n;Pz& zJ2!ALxW5)2P0cHh3rg5ae)d}ALXvhzTLwx58a6&+ z`^k}j?MhIVjn`4m#V^V9I>XyBwoeI5PFfI~QYboVuag$h)i)ylj8*r(p5nfA+!|Dz zbkt9Cq+g^wgJ2K|auPN23x zlUBp{6zMaW&~J$$&+?w&fs-$NW^%J^$qN|yJzsqG*NM`L_SwBocszZPQUVJdGFXfw zJ&RGzswx>7(!5L@E7u@Vyhe-w6qRB=3T$TAgedWa_>5F}CT=OrJMC?tEC1ux8Kqr` z2GPjK#c1vM);;o4@c^@r)KtQE%}dBepzR{sN7*JK181xAK6y~aVhaiaxG*~lN)nCh zAMcuTSFIgmK)X>4atf0QKq#pAes|!1b4d_M*anb69JfrRU1$C5 zN_pD&Tl!kk)YHffQ|oarpgaJxp3X_J2PHB03tc7&4;jtr%cWl-NWzTSI}9yRNLb9M zimMfjE+?)`%x@&Jpdx{kDcXVYxIB0vF62)x5+bY|k%;O+xRvf(Ta>hawo6e52SQx) z(){vM5ZXRqu3k~^HOPI8!+qZ(+9;dA2>XXPD$)ys15fTbjfUp-jBwB{buzIUl(po4 zz228%e#dz!cV~{A^4LwzTa-PJe)!&LN5204?lN})y{jrE;KNuya2De1JGgUZ(&6w- z7kmxvTl+*1zoS_b7$uMZMC4Vw=Y z)5Q&?$0$rZP+Jmy0p3S)#PbxnM5=?a#SHWQcefZqxd;#U6$*8`hr&Vye4U)An*8XW z!Qxt0lAxY)*aegGLo1hL@`Xe+nY>OYQ;jl{0~=@%DUiYNOXW-%BuOybMu$7sy093+ zk-pE45??yLq@zF$F1&R`=FUFcUxfYl*!n_IpW;#!sti0%*ciLfa!{GGU;~3zza83E z8yN-6kEPu?CDx>G3{4V8$1nVf1?v{gXKJ>)dKL^jyk55LTE5x?(h{ktePHWl-0Xso zpz{<0O@)m|JsC2XGv%0R=;RO5*SQF{qDDx`jmOQLu)2hAvE{ThyKS1a%C56iv;)Vn)I6A>x(YD)3XOOrVyZ1KC zx9W_~Z1%;MJ^R(C7+vS=c z9}DTK?_~GjK!VNix9*kbNb@m`N|Jd)`&k(4>jBJ0JtpPX{w4DLSdz~@>2IDf3it{cKLdCj|LyJl{;u!W?0)<9)c3VLpIeM?1-H!+y;2dI(GI5np6Ba@(rSSEq-wtgWx@ z%CGC6K*StE2{o_>t-tN13IZ3+0?c~#5@@`oVwIbV%%01G0A$72&uUCy3Oj#t7vDJ+ z%Q;Rk>51}|ETYlQ$e6~frDp*?6=UAnYV70cMERlSkF9#-f6^o4Kk4zUdkh3*6dG1f z`w$C=Cr@Y)nm2xgQDE;U(Bt1TzDH=eNMUj}n*T_TEL$(V^4W<*s8)JAjFS8Y5`M?f zGl=rLRb@J5RGgW4;FbjagCAwkTbF&5xk82VcLtGWjNfcANSxU4ejc8ho(in6^zg=1 z_|1z!AxarBsFbj(j^?^0W~k^Irry?|esVy-M%)A@ zqi$1HE|!tp#Mn7QLNDWy1b}d56@yVc;8986Qp!>ua1*r)&cTl);hXfKQcy}Lg}NC; zd)NOIVK}<=XQZpIc>7Ws5~&d!8AGmA@9=fuq6N)LY41SwG>sA3F8eL9_(gC7F6fvAr!z^k5K@(8e z3hRRloj<28?c9THheKu6ghRIl_mXgNN)BejN~itfPqS~&Q(wzjAaB7YF*@4NubZW6 z7hDlybM@$7zTBnLdLAe&1pJoHh)LQ8(Wk5PqSFkEo%N!pPJR8$^F2DL(T10FH+gfG z6Y>OX+97Yw`dQZ@Mypo8wG~RIaG50#X6qGxil)P}&NW3dK7zi1YW2T& zIgKH<7Tz`|wsa0`(IBPibYVid^TaTzcN5QK?_hMy>L*o~+(G}DMf7TVJr?wo08t;T z?+{og!*k%5e9KsmL8ivt^ND z!BgJ@WoR)*h5AKgsOG0O*SJFFWXMzblo5__)bkD`%xY`qP>W2= z^G;V9gZ_0-1)vtU`{O>P<(m)8w*9juWP@OG|6Q)R(CAQ=pMKS~u+zqFY|5{ZX?wdI zPPK{Iotdf~hO%-no%!eNw$V9VNo41ci!fb@6tc-S0{yTO@6YPxc^F$DIw{~!O`@nt zF!#FX@fF&Y7Ys5IXkcOoR3f`fLXzvUA5w;0k)KEaDqd&Ro=(d(Q*~@uoUQ7%2CXn^ z(FS2nd_tXOGVY06q=iTkl}ck18f(HfB?UXPEEfkp6gOlTM@4H^A=pePFfUOXSC=+7hitODt1lzb()jY06Zo49tO%KaDVO!^;P^=p-?4yEg`S z2HRSPi`&a5FY_mRUug2~=zGqrQmN^#%^bMp1F!vsw!BtBo-J1P@pG9^FnSt0SOS;vuz50^ zNN@UNc-f@W2cq~F_I=^XUOR+F-dQ~%dz4IT~6>#(qY?%EY6vnz7 zlZCqB5kX_z()r1T+zM)d_$I!i_ndgOf_BBtMF3k{sxWnNi>{&DLBXeqg@}|4D(xxxi zR2~2&bz-%~z3mRDGYqP=J_(ixy30A#lr0#!=mpnYP{wt+6I>AeBlnH0*{LX^*<4|0 z3KLmd94$?Dx@%4M5>;C0G1Wi;&8Ye&c6X}wm-oZ;_Lo|u_Lo-w7>@rjrcPpa^E6Il zcS9S+>FBfp-Ci{<bNL*R?(ZR^umt!SJ!ubnP??sIF?Kc03Os)b8U z0Ya}itaKV$RWm~AHTxWm(s>X!J?J!${K$>^q~c;yA$%{T>~OpIrNr)&s@|u`Mj;nN zvI^xtET85VuQ;_lGKJ|(4N}TFp{0OQ0a`< zQ}??}-8%`q!?m;j0PB`uG#%vSVZ8iGn!tbXsa7qMz51P73ILnkuBjKW=Gl?osOg`L zCbwX`1cG32S@M!7(}Vpn5Y{G$w;Qi3!0ae!P`r(cAV|YYz{m3?Ir~Yl_ut zl5ZREmc;k>*6@a*_T3x8{*B??``zB{S>OLJVWj`xKRq2C?wGOLxcJwXJ+HfYM4TC^ zsqTekhYV-I*8~5|{;NU2GyV8C!2K__`^Ny#(>Thk!IFnL+2K~WYK8oi`QfyiO%lA0 z{eNftYhpChS`46~h#&?jE&wH$+-j@xX(zV(9p8}_{$X49wFTb~4}FmS_^qY@J@(qQA6TL%hC)&Q*auj+97*yq?_`ePsA z7z+U&1xZd!^1+e?edk@>z@}z5k&Ll8)oFbt@Lu7*V@!ESxKk83x z!f8dyWb5h^RGlsXSS<1AAPlAbuR*Fckoc$(0EU+lnMF(uYbxmA<2VnY@8c+j@;HPs zlp2g`iAEPoV%hM4gRMKii%lkEBu^hYLTKo~Gc1?|8xAn6#o+t=d;X66_CK@recB(2 z>*(tFc$i`MnoIM4HM*#*)}Q46>TLRVW~b}>*~;ThzVm4!jxNA+>DAaN+9IvfpUIL}u2{!`9%4A@rLt z*MON*(2;uqBe({pCkKsBal$d*M`)yksd&1A$c}fF<&Btp>>?<&{@MB-zyQiS$h#y# z__O9z<>0o_pi_vL<8Ka%*4n%B_tEV?e5%*-yBkIl+{Z50iy8(oMiY&gk-YX>{j`u) zs^?*qG{uRZxpqSEsEF*zN^em9hzijLrO@4PyiL(+ zOP-lx&2%m=mEx(9G5$fdC1+W5!d3KZ-2OcZLVdm<wK0?&5%#cFR0{K`=_$} zCby?B$r+i>S->g*8P2)mP;qJow+;t2H5EdhG6(BTNW}`X9^!=KKiCbuqI?TmLb94R~AxfxezxU)vqc1g+G%zwmExdwjkb_}?5= zssq-Q9pCpym0dHv*Ss&fO5-S_d>gv2+Dp^CNP$dWz)bYT2+>S$>4d}!M=!NIw|phs z?A|jqOi&1Yj^ij?9Rk!Dn-QzIrlgJLKa&N1c?2u`XF;HS6r55cU&msgJ#Wpr! z8fIY0`J}bro}LF~8j@3_zTxt!0Cx{adV7>*k@&|l%6DsfJi=dex;Q2?W2&|j{dSN! zw9UJ3Fc+|$k^((pf>rnn3&hLOp3^1d)I@}WP0U@Q$VIdL<9h7jm`J81EYF@Jk05*t zO4%vIJe|mNf`x~(!Sw4H*&sN8S!9bW{fW1@k)XvH zTep7{s)YIkwZs#}%NT;#AwibA^q5fQHDD1FNq}R7w}gj6PLa!iVs#-V;7n2`KqNUQ z+klP&iwllBFheMpZE~DQ_<$lYhR})>owxB43c<)b5U$E>jW6;-c%WAXsf@whhm3O| zi$1EcNLElu$=O_(__jy{A|a2jdKiu(rk#`@sKj2p_Xh&Qj&<h;g#aO39ufQ^5!W=BKwVYP1ezb&n+y2y2h_UZCA;nmR5NWwBlMJT$KC2asVm_NL{ap z05w$@R5a@D7P^lzw>0cn(j!0%XoV%|DHSqGVB!S}+4yaCfuThD4>cOq#f_T}X6{BQ zz(Kuo;5idSmvIaPsS|MjuNFXm@kRSVAVUMQREZ`n7`O?BMS~a=+p&sy+mC_KLmh<%2f@nKZ;?Ax8h)&mgGelUjUGy4CFqg$i>T7ZG?A0F znC1j_>6wjftVA;~xU&@YTYNg~scuoRPOUiO^)25^AGs&BI|(c0&#a=v0jul=NoDfh z^Fe6A-i6Vhsy!{$I$j0|%`C~qy-0_?3M!Lc1|>uryz9%y9*YKUtxV@D`o$-$c2n2w zj9F`w85Q*cm!;M;*~sJ>aKFU!aW>3s3D>B6CSjk7?lM$Ko9t>f+pw(BUzC(&RBym_G9~MqNwfqdOFia&G7*vbU|#;J>a#`2G%c!i z1@?#9mv$lTdR_2EV+G2TJYkFw?4yIH%kt-Rn{jJo;YX5GX*8pJ@P7UPu0*lUblU#Ggi3ilAOSXg zgeL=HUWV}FfG2aPIbgSiBl5mN!75tLw(@;BL$0jG`14d$&7^^6UP_HIuHMjVDXo<= zDlQ&6_U)i$hbRLuv-}3foyr69^w}uys!!60#SC*cB}C-W(0D|KqYwyq6=_yrmq?xy zyxHovMm>?Y*Tp5JJ%WOcixW}a407Xu;MHI?8ei&|ATS6PrqYa~lAIkmyg$A4$(7G_;;$TX+~$y$>Zg?6dLyjUK0 zsls|IEW>)OsLBLh22*yYSC8^hGy-LF&Qy`L0+*7s0$n3XEiF7E(srj)cM9WJ zEG=@$X0p&Mbe0w_itkoQo1huS`UGhJkHabNaK2a~jmQ(arAgJvgTZsOMoV z@i0eZ@0nSQH&zDJzMHOs)$QyADPDTaiE?uz_{6|)ijed>_)pLJT|bmHr*&bq*W?>& zEjo_J&P103;D;4DXy{eX4O)Iw+V*S>!ktn&3G9VS+iQe{^QIEqHGk!NvN*?G)C6jn)w6us9T`~{ z(%VwTw52O9g)Q)h>}!hxa51%fXoMr{(y7;US zat4Tb98?!L>+H1L<7iR056OEoM|aYGOn^h->KT%2NbgIl{>isiR zX(|#tn?IE^X({=9BAv}y70)F?Qp-9jzOtpWSbBeQ)IEp0WJ8wj1ILzzYffoseycq} zcVmd%sqtYr%4A^nRJy0V;RKXwg!A3PnGynM!i3I(n&0E+O2Diu)ktmm541KN-JVwC z-_l*Oqw4|FX2}7h`$sUBYy%g0qukWGcJJL2dIUc+X9KjbN+)P!)M>qk(n`iVxnV?{ z2wM7FP}}5`_PfT^l&zZWs;>f_8U!8(DeRuVme9q0>O#A|OsrPzuS1f`|?^@m{S@wqzq z<^_BG>%YADl_v-k1zdkv=tS7Nf3R*4aKtw@augmA0`edm2dxn)){NPi53EsHro$)^ zZP*Ke^4JIF%h*?nBlD+`jR|YvEhJ+owG2KwlCdtGyNd_hmtcA}?C0YiEP=x{zB$Lh z;3yhhzd#JEGn7M_nT^9d_WrE~M%53vDyfB;C7kb&ftia*D!R}Fu_&=#1xj+rWpQa5 zc6Pwtf-mEg)S0|68=-7VQMr&qB^WY9M3m!k6622GstPsqMA%EEDeO_I$-@UiA@gD* z55s3)gYggAUmOr`Vd%b){8P)LQ&iTVzb_LIu7oeCi4}+wW!%?5%{)#wm6S(G3elxwZ`P zUo6O&mJPw~(hb_MwG5mXqRb3e%zMRPZ3^Eo`wG7z>51DSa5|jw!C#sjbT`20_UeZt zA`F>*5e_`Y@HV8xMyqUC)u>f=w>X$wupYwYEHWjWEVWCaA zR$Q~suc6?YzK5I0)s5sjBs0Bx7`Y`3=x9D7iGg|t`q-j1O}JX+nvvFwU^`zxIi={@ z(5g3k1>e==ZfDk0`F1{g!CYRPVjr%E<8I(50J!V);Dg+7vrQq%}k>MV>9oM^# zXykPH^{mR(?s$K0U%cq`)DqS1@auIyzxj&k^}M`&uGjt@$=hkcV>>*4BLk1T?R`?| zU;O+sn)RZt3#MSWS62Z5pzO8ZX`NP@4kOB*waol9Va5k9jLIHQ#XW%EWqfdNEAqpC z#4(Sr(x`==ZjO&toPW(z;r+Rtb?0oq&m$ahPW3ZM6LLYh*jE7Qv0? zh5uRqy6f?UA3u=o>q{J`g@3ae!PQ^zOR4oT-%q#mAb*3-pLX+7fnQtiv~|H7t-ZL7 zi~KV|YI~LZC4*`_>MMR|YW`io{LnYA3*mA7T_7wRCg+bXV*t8y2dAY)2qDI?L;)$> zJ)|57O9*><3AJINr!B<{izk{D=Vc|A-?%nOc&}oxho2L1kRDsM@M^Z;;Z}pwyDtR) zI)2GvK3`hQNpxtLFD2aC-+MN8dA(sNOuJ|>tG>H>HDcAEPQN+ z-P$Wd#q=8R%SL`O7Vwi77&HPVGMa=p7p^W;*({_8l*kt3v?@fW(CqqO_QV{Vtz zX#9Slj=}vCF3Ath2UvReqcv3260F@aTk28`c?T;%iPK`?P;;EAs)NTWRX>I9m5MrJ zRvJg4=eG0+8fy}dCG4sviYipuqC@6?R-zMDR`a|fgn6z^17dr!Xy zsVrma&yn-T*qqLF2PIsiL(dWMM)WFMFVhmuv!ci ze`v1!jwW1}`|rzqC~DQx80l&@cam^K3u}X_Rq_ka-sSf1b=1nCJ)ex-j%Tqo#zimB z8tM(7oy@U3RD6Y136y4Fu5S1qb-gGplJ_aGSng-$zkI9DEBp@Y(1(72%l_F&CmJ#~ zly$cS?QxCxnnIBf8pS`0+Ea$ zHM2Hri~n#^!^6KUt5TGTkdMYgD!d|o8#$K|%zVwn9U5f?(snZ+R+^+JuLqw5&De4% zNa0n@dckkPHxXuS@Pj%68ze&PNf!?oFhOQ)W1)Ivock;=zIsMRw?l6*y~}f&x2!cW z*}6}N34Ik|=vXTImLgmlc&|tG@^}rL4rOkuAwZ`S%Y;$ay9=%!3zY#SRiG7XfJk?YY zV?Hx72XSDhh@oez+OCc&7!5XUCU5D&7u)(SknZy(9)~G3cxiopOB!nv;Y%K5CSwfs>5H-R#5M{$P!t| zWzdvg;;&-cNE#oLiCfqn-c5yauQBsu$N`R3Y;jXl5?{y4+Pmur*V`=WXpr7 zjGNBRIgUj% zovuO6u~QlOCQ@`+N`2-9`^*mHxvq|PuFzJqi}-k&`&Ua#vn(U25$gjT=;i-wJBtMq z!tnk6z=L#J3qp@OwXcio$8!G1*jdLyrE(bb$cedm=?J|n7Xe@@KSPgarK5|Bx6wT2 z`Kx27Bpe4>J=Ky3&hJwQnZXByJleZ~$0Pd2-6ZagrV(K7Ezuc*rv*1Til3fG?*2=` zE?ZA-sCMceQQiN)FKXd*nf$*D#m;le^8deXX^FjKPILW#aK`3}#E_g16si}fT@X&r ztp4xnSByvOMaaL^ID~Q_>WZw3UZ*8DmNC#BENDZ=Ro< zDVFUROpyTV?l~h`-iJVt!dzOP7UY1A=^M!*1S;k~r)jW61)v{TEsS{A71#|hyG*^3 zHLZ+b!cZL?#MG2VcVx(p-@s&X_u&ptg94NB*5rPS&}qSbIS#Zkg?1~6yl8JNTD zSurU692v+T7ckx$`@(o#zx3am-+D=ruh@;3dR3cnwd>q*+7U&gm#80Kt;n@4mzh0$RAi5Q`aw7V)oK^B_uI zZ3$?_>jODP{Hk&@B#TN7;Ompg1y`(c(kOFctV7G9&V--O=nooP;QzkEak9omaI8DMZP! z{6zeCiTnOU_yTwWGj`&%wh^#X&<>zaK$EG58w@y#78;`=eXNDjj*oNzN|yTukd#UG zNZHGzm9$5~(>e@aNMD^TpZ6;m-=`Nnwx1vOEBbmLtsCz!moaf(J0A}xT~|T+{+yd{ z4^ac_{o4AU_av8}=KsRok6*7RfU7XRnx2N1nTNrfnW;-`Q#HDZ^m{(;8JY`uimJHA z_qk(?VfX=VCpTEFewWv4g(tE~UkR0hE(X`LNqJ9V%pj_cy^fJ4?KJ zyMZaAtZxdugb-9&Z;DI)}ePUnr7)*q(+}}X&YUA>ALj)c7;hI^vZU2V+#g+he zc%GH$p<^?3X2>l+aV!|RLbF}2Xp}1*B13|xIQXd9H1Q117&c9(zxLT}I{Q-V6xQC!`gO>4 zXBy4)Km;prmgv_xIypVm+PU+z`ns9vfPW3u8CXPP&RgMB^##wDX8yu5wJ=FfDp@Du|)CZgg;`G;$WuIy>85K$-9<*~2BlbZw7puc%q z>Bx?Lc3@!xio@&k$Gbbl?#JcUH?aQiz#9g6`Cj%DjNS9cdn<=$TY~I4FucG@s$(%2 z5W#UwVxzbaq*708-h3$CT)4Lxb-Wx7JW&n~zIypSE*94D0TO%ZK0*OUrPPwQ^Mj)~ zO}{ZgNGf2}qTl7~UPEdVcfpio5YYKm_>d|A#bJ`+SkQwS3glbuPd$^<h9F$5H zos|3c{s&hHrEAgjK<|6MCuZv+#$qgaI4Pi>>)Vmgw#(xOMU2C{9xp{|ZB{Nz<|$z)*E>YfzAYgm}oFTx<|8QUvA@BaLvImHYoC6KsxGv~9FPkewz?tCpTEqOs z|HwH*KyC_={~88ZNvhj)Y*|vzIjOlGlc^%S$2pLkSJaY z$p@^T!-EM^BF-F%afo|m(<^XD!#54YA{sYl6zky#A(VMCo*!diaQ95?VyUBy#{jlk z(6v%-T%pAY2eLNDMxs{0-#1*cfKo>p3;k zhK*>|Y1^^^nfCQH`6o%F1YLk&zGO%so8!ty9ICq!%eNBWK+x5dPe27 z>_4pOd0M@?8++ca6*uq%=pOHmeS_E^VE_-X#J>Xu;#TaV<;CgSz`pkU`}1wLX~Z8v z5GU@Nw(WCo_qWw-O9%w`qqOVQZNKkI0)naU1H&6=KwY+s)sIyqwtr%s`k^_?=IG_cSec8 zlC=;hJbrL$VGI}koK`BG9Z8S$)el`{*Jt&%Ccq^#5c4z&M1r1cZlU{LO)D`?ms$w4 zJ?u-O4OYsW6~29_jXApFwK}}e8mHB(%_lpNNXPscjvZu_T+C!NNiLI~g%FP`#@&)s z@BVjb$)V@GuLh6O^%1xzk@WHs)N;Jew#SyC59p>aP>Ywt5632g0|`Jv%*>S2R5$1}Iw1*ZqN2TJ2_{rkF-; ztd!BLm>`&;u#UOq*Yjx=1uKo4W}{<OgWEzF_$*5A;o6A;)1-U>bIgW{-J`g{wg z#{GGw_PFkLuWdiAced(fCaBe)9h5kLsa`6bs#z}zwwT?Y?_3|RTp#jWBLqyXlI7YO zcSQKyTJ1&|XV%FWQo?H``=~(m&H9L zt@I9!G{x3LV9k9t==d!d3T2EzkfB{O@fa#2PX;-%H4*WrdvaG3bGjGp`>y?PnyS0N z#@Z<+AX@rfke+3h$M~&rB<$8{8+H+8;tI@6fkUWI=bKg$o(yEp{LcC{;{>B32P0&e z@5j^!l<4jvan}Z)JqeRLJMWjLvX-gQ9bF=c&)n^~eTgv*TL;x1P567AmYID|H=-oX zACj>D$<`qq2=faJ)UskpK1LiwX0dgY?VNBVS))kJ32DeoX?B)+W&@hULG43{4NSEJ zk`m@=YADJ+wr`@R(=%s_J^n0A3hmm7whAL^78c}%HBo&cRqRgJDQGlhuEWRyn43Fq zx+(%Gbp(Rk#e7V`jo*uGWj!-xH`v6_&Nr&&gwlMX376jc=;hA6XFylggcp8I#-f2~ z_b)#+lsf8B{bJ5)2lTU02*I#@PCY zLMmFEhzc#H(UJ1PaR)j&hYiAuwU$jFAxoT!EkgAI4P3vF&u&OQB7Zo#c^_&~LZ$+i zD$MAFJt;79&jguePVxbzy080E0sJX#tU_QxTN{^p^uEFSHp+;gb8-T@BEk40W0D3e zo?`YyFgYWL;oT?<_46{a2L%kBVT13D02&!*}CpKVk*ZCLH z{V602j4`g@5R{45&DoZo-?h;qA&dmEC}w2%v6TdxwAnnz4~~w{gP&e3c8b1%Z_A| z2JWY!Pt(qJ#4|>bLNIh#0nG!6ihB#fQYl+o1iSJh7b8$^hmD z17xUpJhem9M~%_XHVf{(^zd^`&7nee=V~67h@?pxvg!U1b}?+HsJS@~>F428m>=fE zk1@nDY};yHb5%Y;SoGYhD*cTj?*J39I&Bly7fh2$%6lNBI!7d-D&>w#b-BCdgkWF< z9$0vJ<1naXGgCT5{7F@+`UBb}vM_mJOH5_F+}Wl$o9kGGZINtSNiH@a&B-aYFIo8o zy<^xEaMHP>ND(|osT?{{uT9CPOCQ<8ozrwyd6*!ZK%S`i0e~edXprzHYt_f2NZAeu zv5;`k+dd|jhl@GMD=B(;^vyA+7woRHMsO2b8lw(you4`W$4EsyA$7`#*r(YHyEnWy z;|7zQJnJ4HJ6@FC?g&-TnQsU~C`n%ktweIibz!2Y6!cY#(C#bNk`70x5nf)4t${HhJGXX^IH8bu?VQDHLLx`y^3mU-7C>)TQg5?)0(4YEvnUI%frX!|GEh8$CA-=kyeE z<<(m#Q+y2VF=nN0Y(O(Y#mg*8>Tfo-^VGy|K9I_CD+YOtz8wi=H`i{49$K8x@=#1_ z+Idm-%{5k07+8&n5hq>LliQt4RVpZ0IH9uT#us_Wdk?ll`E7qzsRQX}kE>c=asCx0 zJaOKwvZ#2^_#hgqICZ=hE$3|h#CV~sKioR8-%*0=_^*UknECsl3L1$ zIJL#-B{j`~sJW^9T;19d^w+{!8HZ4SRS5Mv=Se7)Q5k}qxuX(fLV=ZG4ZVLEcn_Qr zkx+bRUtXe@aX-ppu5U-~v?L2VY$RVl;TrlR&;QzqkES&$dhWKWS&VkKC$*~ZKlAd_ z1f|T zBSvv&0A^wP;r^{OlUmbW8^>x80VUbNVZs2P4!>emdv_qJ_SUdxXXkC!lzfXJ9z*hO ztyIfO`1L7}R&9!kf#p-X3w0Tx>yd6j>O%SXNV#q>1a~x>1iEqzAlfhkWyeoUf(chM zjSxGW-^+L#kZ-7q%xI7ijqO&?{G-X5e%ek{dU z*VGsPwoaeZ8Lo{|VCVunn+7RCL;V_`>-8(ucOx6>5+w2BpUOScCGvMerSF z{!bD7A6);32!26BN{+A-*?A4fI{gy&IN#kjzxPi2CR+^)N6#lJC`9xZph@RuYl+piz9 zTNWF8~O&TG>ZxuV%CK#hH4?@{30UaY@3GLh+A3Dm2eWm6d4D9 z4Tw%Ya^hL(H)0AG1e>p;j4oCQbgTVH4q<9m7yjj`iZroizRZQMT{83KIo{w{V*hw_ zvfk|Y=T8^K${pT5m6d(HcpK7*O|r4ehS*>s-+kXuR^jvWHXkNUYkU3Dm`BE=;bbI5 z?R3&L#vf7iVmCT(^hiie4+39}H0RXi9?)Nw_!Dz0Ku(Q49n_@gSp%+~ytnc!;H4S! zuoq51IPQO9*dIB*Wvl60Bl-ZLW|W|tXBMWv*YYSr=Kh(8?UAJsefCDTS(qQ>KYHMa z`CGB)26tCHu)zxy38lDf{&R+a@5gudINm7>GOLqQ`w-4i>t4z^$(pPzy`{CBONv68 zhYdDYxu$D@-{yJOB#}McS)%;(PwfTMGt1L`BR;ugW)w*4d(LCTSnC;%CiRouxzs8B zm$xC)w9DI?0=7{1lpjnVa&Y+0@(kwl3=Ds$-zLmdb@FZ~Ry3+Xg|`j_GtVM)Nm4id ztW5O@+Qly*{_^rn0DnU0gHoMS!9~(H zA4x0AxCaSsglb1qBDp#(a7&*tA9F`C^8HzbK$`xH(05}j;eh{o0@K-+`(<=gc=(DSA3A2k~6;nD(|g|@kniWB3+*S`}=F=`-n4{=q_o` zfIazujGOoi961*9Cuz#V8dOIF44w+CkWu+5NED}%L*~)$4>?c2r6>DX>vEwh!Us@g zLkgUHJq|03#ckzZld#w_`&^7eqXASgyV}pn z+i=Ns1cAm&4ZR-U-(RxAgBhJzXb@+b$I3hFgT#UyMrb@i&a#pkq5nC=+}9#f4pCo` zX!bG#sn406P&>NyJsiPu9!kI0`O){wtzosoI_+mm5>k6C+fjuyop4e`x%kp-!KN!E z1zd%h-;R@WuCQ^1L=??KHqCBE_L<(`pYD$Il6KbD>jmUth3KiP3nDX}BK16%gmhQk ztFX}XH)gazIW`&B4CLX;qEW7P<8CeA5{(Az$9`k_D`)b#Dl3dvDb{d_k2LGQ-ieya zJ{r3BGbx%!64TlAu4JLr)l$7xdD81MvJKRw#`MPJTHk(yN{Mqyb9>?XK~Fhre7XBv zg`JESSSOjEpZ`k$5-jc0=(St{4{l@w)G!>bxp9XSg<*~c*@g3-Xyr?-d!{%EEj z`^J@nnkh^j3v@TD&FN6N0wuxto7N2t_!Q~;EXH~dAeox^P~Jx7QWB@WpRkT!a9Mu9 z1^j;ZS~k(yk5|hWFBc6FabYCzJyP@WTu*j-o`G8;MaMRPBw0?T4T@*PNLAb0&dVCTjO1s(6Hy`IcjJgtOU(FgC-h7tzF518$KqgNRk&G27%hYh7s{} z3Ux{PP@8XZC`_cLP)AxTr1RuFJ9pEHolrF;~X(db8s&ZsVxn_rm z#O~6JTTC!G9AZy`j`3)$YkYV#VsKRL9CIzE;eNa=SKM>8uma3QdjiAu6`GbZV>_d% z)o5BHG=X8kHv$D{f&?pC41T3+5wN;=C%CyD4H2P>qX z19QZa?nq@H<2A~j8j^*}lTIRnGHZEfi;jyAyq>h3bCBoCH^yE~eH;>0m70l&HZCWI z=XeG>v**jP5Mggq{j;qv@|8Kje&`14Wlpa|XZdWwTs;QeA*dADBezk>^TQQ%$S!ExqjA)2*et zNGPqD`r^^a=}Jc@weH+0&7_gZTsD?1Bn20<&e=cy%(`cjCS?a5Re)9POk>1wjmskU zQ{3^vN~ZSq?z7Q8q?eHMO4JjD6?Tx$A+%9$m1a5C2?x=5o(zaO5(o^ zlvPTWY@F31v)nknxMAAKC|yaWRmSKNLv#h1Et`-E@TfySA@wg50Z?le|NIV{!ls)n zHKBoL)K3!CWenr$a5PAqB0x|ZHC2&}isyO@2dG$ghQ5!rukg%a%XW}e^F<0Y0y=-z z1cs6S+%5PGGI{&;K2VC3t!Irg&bG1D#b0fb9Ra~#}>JOBAT1iJh4)B zkn#`_!4%Mey4vKMFXO4q2P7IM#vFt+i~=Z99|WIrfhOkuhz|vnPz*u8t&*xh;)4mC zDtpX89u*{2_?Bu(Wdz|-qPf>fEO**#0?5TBgDUYoC70NF=XndcQ1+Wxs%Z>?NE$;v zP=TdXWw}<9D>;HFYihA}7+;l^lhl?S+(k-F5a)2@I;JBqjwX<_Vr8P&`95pNJm^eCay^%b5sFd7da+MP}+>0 zpqDH{o8YxPd2fP`zkByfcMv-_Y{)Aq}$BMrQZ;b#cJ8s7XNL<~x09}_Mh z@sQCHbf;XqWEujl-`w{g;4(ebD!U7Mviz*|%R?Yo6eGmKxW zf9mb-@9%E+cJ}rTe(G-TbbH%Bf$qJI+&mE%kp0xXb6>NAdn6AG@o(CqdNeckQ!_B!1)d1OirEieo_`MeiOU;{&m?JRk=so5|JzD&B>?d){6 z*Np53F4VrpL!`1fsQP1vpb$lCf3~fNtCxC;lh|POTY$OvXa4uMm}|Kg z1`&fn4t@1I$3zu-O5ez~xJRYjlv@}Np@;l6ka(dqa&0pm*F6}7V;CDSxHm=KsLx(SGt+E&M7T40bCF0XoSgV6R7cc9Q=noV|kd2a+yww)RGJ# zmzgIlfdq0uCiXPzy)zSpd@~DLmsaKnllGl<7PThagkbD`s>P zZ!4x-if8d45|r^RA6=thi{nunGH;9p@Y0{_5f~vDoQ#(@T_sT4pF-EjhC)VpM;rZ}6&^06(Odh-@MW z9t|c~@HmcyTdmB;N-%00l@G06>r(=b;RFT8kXtSR-1FMWHR5f#AkM3o75noa*o=op ziWV;Sg^sB5628*eVz{cWo=S=V8pCT$=ZswCHa^BsP#CV1k1a`IXNusYze70~p-eG} ztXsqojr|Knp-#r=(-RGx2^1aE8(nhMNQ*3vrze?I(sZD_e!hu(igVt8)8T9|8=ZP?Qe8$lw4dax|O?vm|Kz46V0Z{*pjqIr^9Tb6)8Igs>psG zeDQ(14jwq(BuqkR{;QoK#rA1cQj|i+g&Fz!Y$4VSJq7w)T{^W7e-GUyy+h@_owgZz zsXL~m4?`MG%z198E}!d7|E6XV`MF6=B2KGB2yi4X71n){M4K9XPEX3Y&5&B=q+B`D zqk@j+^4?2oQWs4^<-Rkas)S>e$x06D8vDoxw{0^~ZCuJ^ZgE^t=f1hW(Px{VA2Zbm zsP+H&@$^Lg!q6~4UgFQlPKu8_tm1j3m@>h;z7$0h>Zg05(G695u~15q_HJq=Md~aA zhTv7KHphP7E&JI#l()KR4r5Rr?W9>-zOu@~hFD zOIJI_dBorl5;%(r_Df#I)B1P&YhziH5WQ|^yVG@9s_Hq!g~UO!WKn`lr@LHSidT}% zui+B$3L!y(9VHMsc`focVqiyV>7Bdy>D5e~$u?4!3i|28wt zhnBBFHMu5Wk)DNi8yMOI?RIMp^qU0`7*jsnEQEV+O@S(qD=yX`yRG0Mu2LMhucDfXsZ8$$72tF>}{KJ{EI}+8Sc+!QfvA zvI_y3ct?pCw+=zqydE(ajxQ+<1P(JlE4m_45SYIMOs-1hE957PhCaO^R;p1HBbOsF z?a3DBc$#=Yzl0Y`j}JvDX~M^&Dh{+w%zjgWX5Kyp>k85V&i zXA3dS?U=~~mu#l7vN{V9v7k&^Dd||cHWdOVLBX=ufQ*#+<*QMZzRfV=48H0ZqNB6y z{TV|AFBX5EkuCPurk7jfCo)K&TTvh+74(EEai+hTmyniWq_`+YaXB(Dz#~Q8FcP#3 z4-W;whj4ytu>!~Iq8cp(Ex;S-Nsj2Yr% z8u;Y{PgV*JI1M5(yMO0kxj>&BUD>?2B=o z<=x&ccL0=(V-fr^{JLDCvZMJOX+-YgT);{A1ZbqU`yezD5nQ&%&EX~YeI)1kh@bM3 z4P==({%~~s4v8@>&?rhU2CGKI&tE+8h0+y-!0FlJU#s5E^C!MovG@7(Mu{YV~^i-)W<)fn;?un#WI6u?V=pU!DS4Z9fcI)z%RQQ-Sz{>W11@QU^zd zM`Q8S70DwZ;FFP}+r5LQzFcX#fhVwB-6b#A+^>1KS&Q+AVgHQU4TG(*MDW031G|wg zb}cV%Q%6Sb_o@876cIIz+cQ7X5__#O=)OTpKplb>pV;i@LrO&nDYiTs5phm$c)Yb2 zm{7IP?hKAFfyTX6Y}3_dcy4hyBoGYwk*5$VroR@CCUycZGW7B>y(!dDY_?4Kfewu> zb~tj%#LKC&FPAQ$4k`F8<80R6W~+C{&Upok$<ZjHx@^2Mzr|y3AC(4BK>!+5=BO8bE>t7`@ z5et6()QVWp385IvU*hgK{(@$|Qwog)()U^VIQ;cfiy(1B*;Qv47ZmQ}FxwEG>mIAF zP5zE_!aB*wct>wBW;iOUrf&lO)HL)ZCH(rSm3|>xgle1D@BaJiSHK_{A@Iv*aQLh8 zJO4vYODE17^6eY=`W4_IK%c=cpF3jA5ET8mNOFHdeFQ$WRCk|R2KtxJ9obv|3Qf%~ zi1@kx{Wth`7Dcth>TjuhBuiXGPbM;;Oi+D}5Sv~aMo=Rx7C}QDC3J$w6r4u^0_rqr zQAsVF(6H*=Sv9~DES?;js!=(!sD^$}_AF%0739sga(WuRd|1AuAtErukDN1A3Ti|= zl;KS?vQF|&bw&vn3}Pazkh;ww!~ydA*D%1oPD-7ACL0NwEJ} zm5fQ&GcROvFJd|N-(SC`vje_;I|N_9W`-&y1{6|gB*@F3*5waz60&dKHdb+)|DbQ& zH^Ss$g-Hk*N9>Wyl04hQ3>pt@6ByR?#>l&x1Bg|DKe~T*vVeB3pZ~^@%jJidjONkJ zyvTBS78S$irl-|Z)6dkzH0=AZ?5l!wKL?MTe{H&e8ChNznCHh7?2fx|GLy6XnR$`n zPcXL)XLs0DWYE9Mas21oVh+vyG8gq62Q|l0^RX8$prg6CWR)^hPqML(Ivdk8vrZ5z z9#O{X>J$=L+LK8I@LHQht9vY#GkUzTP04em!Ktxy(>JaPoNRX=n|2}Vp}j0~W4H}) zF#QcOY(j=hh*M*r1NN)EEK1~6Iyw}nitl%DUS#;!1w3U`7wAOZxd0o1;R2eG(JtW0 zPT>Na%HKNBQtZ3HM{M>AmK7{43x)%Q9wSibWx6|qP&R_3c$98zfo>J08wRVS_qUi- zhuo()I>0F*BKHFO)fhXxBdp->d1Y8hnKRSKfpm7tfqiuAI+5nKkHwvr1Ir47Ltyb1 z=AbjO;1KLr0H>nh5WJ{>jU~Y$cwPaS6$FQ1rvf^a1J)~rIoOa|oS1V^8DVhddl6%Zh~l7yI6rj75k_6iv)@%uV3I(u zv*)j#cVE9adi8p{_j>=uZrANDvpGpwL|(ix9R)!#o@qt|dnyP8Gl>F$OWG*UCIRw# zhV7D^KJ1lU!(?d45FZ!ZDp$wN0HhS zW+GUvSK$rC+JcmF6k8AtlMrks3JsJ=?}U5{8jPv8?7ZPhzXhxIIk99EC@>iYSms=V zy!|qvnfR3ZpR(6i%KX>P{pLm`DO1|S&k~rDQzq;xSHcLN=h1Cg)kZ#wY|;wWih`8S zo+qYOO;M??cdzVQszkc-Y+`X-QJ!7Wq=SZ!A4E|rOyQG2rs~?u*GDf7j$gmrd(nNl z-F>n1@akG&nk!IKX)ABYRdp+sb1R_0C4c2p<_J7<)@}`%N_o*D^rqe0%SJV~1T`;O zb8VbMGD079M(~q}VKR~o`GNh0(M=w01s-DWO2?E!Mt$@051UQ{ySk|M*TKM-7R&$GBulj8T#|Ti0GT(ILUPkSt1lq~Rsehcz0E3A z9$VhV70i{$1uR^y3(LC&SE?*qBc33R7)FJYa)~Dh*g=}ajq1xECUK+LtpO#O+>J)f zE6CxfQZt@7rDfy*a&Uu!K>nMiXKb=5rmNUwQ?#y4|-FVkfiT?8s*X#U&Lm03@0W5Ce3WN{f(D4{=^1FJ|Z9iKVV=@-h}b zOG-hYGj1HJTg=Roq@pr;;~j6t+hod3!S7|VrdKU%X5?DMy?D8DaXhtN6id%)zl@;> zC03xnA};W78iN(2SZz^;<06J-VEWQ~RSwpc2LrF1gj)gR;yo4bqadhvL%#ZEzP6*+ zzD0kAn1_fs9;;B{5<4Nf6;;!DgMIWCPHAM#2)nxX?kinQz@cYFsf;!5gfqL30y<(TMo#JesUy;xPm{a&Ve{t-O=43I3u3{W7ja+fSf68fvTa zEV<_J?T=sjeHEns=f*~%2Pci6mWRQ<^{AHuM?vro33!1Z^Trj^;Sf)6G~)NBSxH*u zIW%;!c2N!#pb;Ye>ttYOiP~YT(S_q<<$S7PVwcxZ;aQTSm(aUH#4i>Y<=T0yG#22S z@RqV5JSyGrT;!#lS z<(z|8LB`dA!wG!s{v=zlJboRN>W-i~Us}pdA@VRR&>f1qX%zYVvus5^)Jl~4bLG`} z+wYF*e7!VR_0@UEkj?zL(&~Jp$2WTXchlpGHF(z$s;||zQ5`NL-%0TYTVS*$00XM3M2m4+fjp@vraev! z3bYa@i-CPZPoVF+e9|rEFDdg8yT~MuEWt;9aEyp@>-{gpsOu+LEvD);B|mr@hksN7 zo(0fT(H1He77a^V9zb>!;1MzKB}bH&&*064m}(viu+>1C01t5xdh(~-sUyz?`Wk<^<0Vy&m@?N^BwE!2!33R33JYnFXrb~) z$jW9)Lj11s@0Q-wY=smPaZ!1lvc)|ZpcBjm!-L46;aE1zAiL09DJ@i@$V+s~6gq^& zbzZrE-qq~2G%MtY(I_n2z7ohumW&q~Z+du+xvc`ZxJx=5*1kOWlng0p=pM6+=eN5WtL&7=zr4NstAkK#^|=oWHM7(}(b4dkSL|q6)}Xm> z9n`$+b0;&X^F&SHZJlYVsMl9lkl1_v{&i8ZhmqA05w+Q_AZjA}EWhGTq9oVAbbIff zH>f)rj%_JCbkv#cMOh@sUMV8jlCGrObex_x%$b$@9@ zSCrPuh-lS~|BCjE*?(18z$rFp5iUtiX-i;@JErVB&qlTs;FTsKN^jyM0FS{G|8h2r zXE4p&-dG7+I*&rc+JW4=+m*+!AJ($|cZPj~Qh9>HJJ{i?%$9k3`SZqLK8sq$mR&YE z-^oV33N~9MVBTT!4&GMm98br(yZRwq1qYof6YyP+;6)d|tY`Dm%NP!4@ZCCR@Bw7! z(8m!k=yU*C!ss1K>QWUg@dl5^fjN>EMI}iPX2(Gl{yu1kF5*4*>h}WX$#=<0Y zcQ5dugL8|<=ahHdMBZKE35tbEW#op+e11t^$KkmZ2aH4rss+BJsuFJryeXSotyC4) z&INTm*X7G-q)d{J<(m94plhaHDs7Z*3=D2XW!%W z-<0Ke?Q(Mb#Yapl{iz^Js>}p1MgY}K9g)aK59Je0y~c>Z+jxbK`GWv{`T4h zc$%_Jd6=ebQ&S73yp)itA^kw*nm!oiXeqUt<~6N5Q13$&ZE~1t09K*Mi=72(m3gs| zN>i>WMy08&mIqoPCT%LKHLRLNrKzmeR91VMe4PAMrxw=s?l^s|L$LPp`>7*obK6`(Zq z51Bds-Xi`cn3OnCXY;2N2HkyXeOqpLU95{;C|ztRVRoj;#S@>D;`E5qj=#DMF`EJ( z3KZXZvYK=aX#mJM^)M93PqU84;XWWHk(Ib4)s(y}d{#=ADYB!OGz$Vx&>?uc`c-ml zs*t0~Q!C9vQ}nV?c^Z``fn1WxgVa9QS9WXxCt+V_BjmNTpl7{qcXnkG6c$p2%=UaD zx99bD@3u}(w*K|6fBkD&6`XOTd2_<6u-K{}O zFLZrJ-RCLRpnJsyo+#T6Npzq@^{Lc!fZTJyP8axa%E182Iif^ah@=<;2kJ$m4>kJG z{PQIAAzN_pZBgD3M}_FV3n(`VQ3BB@M9C*VszOw!qHx`86bJsF8yi~(&vuq(JH&T5B`SYLW?(UK4YHwax-*X~^jMX0ICYyaSWG6*&`c@1z=leekK zTRe`YCT|&@&5=<*kLt+Svt3J7sU!Cb4vj?-l)Keu##)IZA49T6_sWSYlr*t)oqpUi zS$f!l*Q37VG39i>_oLSz+mpkcE?;^H!=J(VtnOcR0CTC+w)pw$EID{oAy!_fZ7tJF zlhtljvf5Q8p=+|)HJMbFo0qKo>Nx;45~@^^cfH(YRW#ltFI(9>Ds@wrC4be)qjHeF zP8f*IHp#->D?)Fj0yGo}j+fUYi0(LGTUn>GG%HD~T#;K;+nb5eT9U?BwDoZG5_(sqrLWyo!>4!Y`CM)UQX4eoY*MZ8 zns+jqVe)gMB0fwK=?N5yqgwqso|SsA1y<{nv6OSe z!yF1;8vQf5wz2-VW#xIi_hZ4|z%2Gp=YY_ZhFPXo-;{>Qfi|UK@=tSg$v;moHsZzN z=aF8wIgsQ)nrv7p^bdJ1X==k*zxpnIqd@=+C>f;%a6HNw;vpqICL`@f01OJW5-x!z#h3kq#Zr6)Xjs~Elj6$&Hz~fF z6ko;TXi|KY;kn93+=}fa`Cye!xYl;cW*7=@jLLUekf=(n!BpLttsvy|tQuQO3ruwd zLrNM7nN+t0E*V?=I4rEmIG}d&PJX+qvC1u`l4_MNba{KuxGJ}69o$OYwfBLcW|kT# zIvNY}iXGLb97hwNgPNCp?qmXVo~Q}Dtusx%0{#B9qL)g+;O zTBcAQP1YF{-z%7*H(7elO4~kDVM%q#S($70qG0>7EZ@_nwK5|5o>4oBu1vhns*<-; z!2Ti}ketAlK=wsvxw`c-u6YL(;8mWf^)Z>*;~@JY%en^z8c~M7Xc#d@n9bPNCDxBL z+Q!LX9^g@#`#5b3Np06H^rnVg8q~E-g9WV4Am;8k^{R`JcrmkW@~NBk4`{|wIWWsl zPVr+?&+TxPU{DpA7$jys@ZSU=GIpvzcOYUV;Z?p zeycjRw!NK)G~Hx3v*jC3V=1Jz)XGmPY@c=MdgaWFmkbdf{G1BHRdPf;dDHow#o~io z6Rj^C&4~wf%!yJ6B$lyOFtVLShLnmD-e{@1)#vo4LP0T^F3;cylUSE515W}bOQJD< zD-L)rQVw(|C@XK5N0WN3@=TMdp({04X}cD&U%wS0UZuG5}@6iY;0_;?{~Z1?$$5;K9)zsYZ&w=d^tHL z7BeyR`y~hX`Ua+=joQ)5Gtc%K(A(%Dy^#ydakFU@&%6#g=+GXcdHO}+;dPDW|Lp0 zG1gEZ;?1WHeynlF=AHx&kh)PQ#t6VL46vv84x~~Q1bXDUoH8W{OfZSQTWoQx3x_a3 zLZG%6K+dt(#0}2_Hl=|LWD_^s#0@ub!*P$bBxPe@E`FAs)n{VUt{`RY?^6Wm*{=wJ%g1GMaDjmxKT`Iz_j?(!+TQ{v+DdC~ZM8lTT2v|i?XKDnzD>~lXg z{%HHFlcck?HUr+%R%>m*R%8c_GeH zFNC_WRL2>!mg!ES%aBT>5*yB2+#90_OfO;X7*(z%;7kpw7Sy=4v!v6?wJ%f}H!*8P z)Ee5X;$gdP95JSKwE`yPC_tV-6?W{Ty3$z{kEXdX&tAShdU0_4`sLn>?#u1&iyb#R zl%Y|Z?rdt*9jW9nMOS!(*pZQw4>q^gBnkvBX^EIyx|I#3y17lkZhejrn^t?_Qc|*A zM^j8+;Gb#nD;$1g!Nrt#W%XzbRcGXKnSN`bCKv>9GNV@KnGKT+z1bGmVM}n|4&1i_ zD=KJ+2~OM{l4|<8AW%tBn9W2A+hlA^yS7-r9PQfWUrM?kjL-+~e3%W9}483L=2OWoWc+6H;iWDN)&jAy(?`T z&o*LmLAM5s-tZ(dUWM}f;To}P*^7ZTJU;Zpy}t&}hlEY0G%hjNx=!?9Lv*bhgsv_G z)ONSl+P9yYXZ4;e&u_snY%>J?3F=Jz<@M3+cDwt#yXxO=w>$gqZg2nKr{3=V{_b{f zXK(M|r*3a|XS??k=q?Y1;wRz)vY)zl?rU~%kL3B;8ojr+_RJ~~Fb5F)Ga4X9kU$&| zDDX7`zaJf)f%V_f0AzPbNPKW~b}G-{0(tVM4WL3d9nL;#Mwh)Im&CWn;8GcWsw zBZvtX;EK>20-zAkyW(K|!|z8IXW){Cpx514dj^g?4{;7WN(7^UTs;^B^afB8OtYOM zA4FVsBO&xRVvOPrkq_c^mTjJ$X3#SWu7~`Oix2NX2$`B5%H-k_1s);~4`TvDWJsCz zQLU}LrVKz3U@ib1O6-y*H-X&56duo>{o&C`2pQ&-#Nn$RolGJkk$|dTBAVc60+6pr z=FfGh0P(}EEuVV4V+=VRk50C7qBDR3ak2HY)T+07`v-dm2iwn|Z+G{0J7X~kHl97} zD8fERpCil^&To#J9#Mm~7c> zOl^Dg;OAk5B7z?s`NzPH-bJk8TQ&GW-Q R|33f#|NpxDc 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 G-~a$Dy6@@$ literal 0 HcmV?d00001 diff --git a/assets/kong/kong-2.41.0.tgz b/assets/kong/kong-2.41.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..73a69b47c2a3bb47b2ba304d44d2b5662f734476 GIT binary patch literal 160982 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%0AL^4-GUCaf{uCR44feJk!pjX1Q-Y4c4K6|ElRsB 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 z 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

L8q!(*?W_yjci1(R0a>mvt7+1Z~X>0e%T{ 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%0A($W%Yw9F;jzJ}Psa{zwY zOM6+s{NPSzHn~XoOg(CA3@lUg)_0qakds+KGsRg64wbqxC?vv0{2(9BoLy?+ps@k# zH@fvRgr9rOw%)KYjgSVO-J89$>+b1w@w0r*y217tLj8JpD1Q^CWa@*d-w0SDjm(0$ zrOgN{PRia`y81N5{b_BA!SXOXuHwZSf`=yas1vy`LIy=O$|w;dR#>23(n3^G^gDc` z5Yf#puf`kc)|C~+r4~7=gT}{&-9yU%D%aDX>5JQP z7Zm_!;dXw=k|EHr9mQq=uo1+isIMi$+TVAh^O)l;*gtj=T?&i`MfVZK&^yB_##e?& zF%xxv%i;aRBQbQu5T}XbX)myW+4))qPVBdBs}|1PlHmBNO|`4xw&EZgA#ZH84VnpT z19L!z1K23kmhc4jeNm_bEUqHtScSY-n1Q|aof>Im9Xx3f+I2~|0Sz2+g!0nepjJ>Q zmzP%sD%);>Gwb~NoA(nq!5P8DXCp@WWEU zvJNF~gcoISxl){0z(t;YNgVTW`1HzUA#O_ym7@}XXIwa5oNAJ(z!r+540LuAgM`CX z=wAmOnNT1Gs8LW>h7A2M3A;b=z|&y#AC^u3y8URfJ0TmGD=nC2%GpOnp+7 z(B}XM$tE1O-Qj(hGQs`y{G!EbvTH4o61K7OP+BUuqJTKbkgD9KR*SmF)LgKsrLug}EUm8@`(dPRz`j>_mjyX;|R zv-jq&`7ScyJX`V5wS@M$$Y9}XZ=ufgSvjLpVvH(lr`(66fC0~FS*Uu}E|#RM>#9jZ zetM4a9SC1af-lq6{OL5Yn1H}%npt8zGlC)j?`uVvQ%v$3ITvX4XqIa$vgTz%SJB6m z>Sx@`^vfkZ}G)|c9F%#sQf##i!!A=TaMD@ zAyJ)51`CjeaC7u3QjC1imYp(i$l?F9Rx%f1O!7RL&Zd|hYs*Du=+^9j-6 zR%uD6)GXThWo_ccHF{59n+a86bdBHI(>ngGhO;4c>S1*qp`A^xSf3QS?|Nj@!MxO( ze%8+YOQWJOm8~5ha4t$rM1E$U$?$B|nm|}ltP*BJ>_JgBrv)D#Q%Z&_?Q~{+mohS` zs!oDfUFZp+dyvdaOkQ3E5A}8)44w`}p*6B+AKr%GRriN4HmQQ$h91u7Dp%2hCKU;h zsvK@rjY2a0nQ+w1SmVYhN$Czo@8?h#?^JyRb@LW2h$kvT4Ptf>b2PK$L8JEC6bt!r9Q)~Oien&@>u{DI471KcS<(MoZE*`ARs>s(m)?^6tE&s7pVV;kkj;09$(-|9s za2lDJIUlhSab3BNYj#%4`XupQ*(Iwy*ul!29Y$$=mP#*3mMJplqi8;bVok>waF#{T z#Craa|1^W(w$pCxqaX&+j~h2Dvj(0`WBbm+*FUc{(fI z$g2sbw3V=hh{aJel7F0o@8$KXu?3@{Ti)vhZJ4KV&Q5Gb)B*QeV{f z9)?u@PhFl>4AH#nyy? z3e^kbVI9n}3bke&*T(@w-q^u*o@ab@vg^`;o|(J5U&hfGOC&WVFYlGVfZQe{QNi97_6)R7Fxg-t=fSVI zB_)}7>OCxvkO!1p0VddW98K|=rMpX#D`MzuEnFRnS#LHujK-h=^Ic|gJMm>Xg&e`H zGI#0YELTPzn)T&%*M4{zsm%Ao522pFEt)923;OvA=|9+-ep7Pvt@x!>?t+*X^LE~3 zi^!YK?}fyZF7>UcAcTYb=V*{wT3bQjP|rA}2ov6*;dUv4&(M_*oys|g9V56a_jLXd|x5t?j-MxnwgslsP8t;?Y(Xk(GwoBpTc_m)l?=O>?N7QjO2li~cawsvctg*7z^ zut0*Zv-sw*rTaIfnfm#<^zkvt^4Z(57D4EKf;u7mxOSgvX?9A;2H#*Z407wHPyeC} za>1bi?Y259>g-oP%g^q8P94R?-PuP63u#d|>$FH$@5lyDbI7K!RDnB&PIcN@06M6^ zvJ0hg9}K&IL-v(-+LJK@68k7EWtb!hLp&O^ z?RB=IcET2GR-R!sAj~2^kC~hUSbh2y69t;e`y5F4();|Bu&Ml4-A`o5?_%%DY)-Bl zyJN#0&v@Wz9uc8o3^>a%y6PZqs~*a${fd@;DbR6(gQkVtFdpO}KD)|SWkI8|yBCe* zW{2BTHiy}uQp{Q!NM1Z;e{5M40x7t%Wla}r+>v%2$0>H5y)pamQOz7w+6QwSIBQr_Ap|^ANv$NoWeG9KLB>cX-E4SrmBsKT zcOy3@WeJ{3KT?Hv?!AVG{1bvSs&Y72hdD?ZG)R70EyYvk5AUnJ9t4r~AAc_=r)ak(&Q_4bfGtthlEW5F8{>Qj7k9>hrG!-g zRwhR(hk`la1&YZ#S#l4sLrv#O_3+e6_0N`ifn%{C^>2m9HW;U}X-V>X8$+)?y6Tk< z4Wt1f7Ub$uufm#JD0PEc_L&PB{)#m8w8JX#R@nDpI`xLXw6TQlMLcj#bc7b5#g=De zfV?^LNdB@XC8gNj>Rm01V;4NGEQcUdWXD!quPDP>Lu4ll@tQkRSME9UnonB>vbL42 zr)ud%>!0?DKlK4a-5__vGm-k!7QTnVI&wB4!4aE=o3lzO1Y;)EZnj8A?>4PI%E z#hLLi9iLFUt~R(yEwroBv`e2#iGS${8q#x)&MeB-;V9h1c3lWZwQie60cmVu@AoS)XWliR1>e&T%wabV9GO7Tqw2r9GM1 z**s28Gs4#=;i-N z{5&XpI#n9AH^|8y%+B+@J$brW5gR>_jKiQP>tE4A;C*_unBm{L_@*v?kEBi;30N+& z=)(>6rT{r1Yf_b3qc%h_`j`QjCZGQ4MOGhcZh2XbGXG?2C_cE5*Kzhm!7ZS}Q}#4^ ztfWIB7*v=@5H}Gou@jfL_{c&SZHR!@;1kCtWGA<(a6XfBs1AyiEjO(N7zA=4f#k3L z1|Wh@^oJ@n*Xn0OhwwXAsb)`mZvzdffv&x&@_U%%3rQ_RWOQbj3$JXcj z7NKHp38fXmzT|5btpfAqWN^3*rL!=3nCxLx(Ey=lA@GU*MuuKungZTxegsS4IpGXQ!-X2bkq!|Rd)AzJR6j{!8(sXz6{gXGewgely|Mkd_^~G zLDt${IvXdV9OLrMGe(|YG~hfx9sS}t-wySQ7zM%xECl)4;uf3F z=8UsvdKloq2J#XeX!u#zo(e^~eHC=nMD8vSj7-Vq{&}6fa4lZ=d8N(&spRriCh!MU z=O4Cv2q=U3fOE%~clZW@vwWgh_npAj@D{bup6A7_j~T+FX%9eDnBdfR-)K9Ghd`q1 zFS8K;kh~hlLMUvUekCMlh@5T=W{R6_mJXbpZ%vKanT7k;+LOzJU?rnZ9$bsfLl?gm zlKY$}zdZ}q(HpufBL`1!p(+}zzmd%4FcZg%^+ zdU?KFoI`s(a`5`S3LSMWwAQ(u0VD;75@-`0x$Tu*t3hRUd~Lpj2^Q2OaU*OcRxwM* zEUa}zfBF6qQXfh7Va;BDJZODP{L7Ls?u2f?Xn6U?(Bj^IhV;!5F}9(#wblLUjpyyl z=*0B7_1-0VP>SQA~Aum1o+0uHa<+)EN?I`L6 zyhpuhAU7U4lsaMuLEk&bPsKTe*a5t_3=kBUgYeb4p z;^^X@Rj^QE6XO%AaB~nosr7)w5$i4WcU!KtDEN6FZYebc^ti6g5QT9x9lhTt%7*>6 zd=9Pu0yZQ`1_M`+S2H5X?{_e7t(oFRx~*AZTStpF`|_9Y^Wou*2fQK4$JsU36zu~f zL2&fN-GReRWx_0y;!Aq3(kr%j1-K}>Kb97zCRZpo6HaQ|O?9NsYZ=!Bc;d&=5I6|D zxwNhPty+BP>1b>Ad-oz6#&D2t{Ov!ln3+CN@`SuoK7UbvB_*=SeQuzRH4|$AzD^z9 zHxvBq8i!k7CNemYkg}6cdq)N1(_fIQL0|ccyT83PF7tg4s zCVy4%*sDJW2fsbvf1W+3zs8^XWBiL3a_bf5a`A#HC3g+ceEs-ck%jFq8aMl`lSt^n zt5WAOyN>}kESc3QR#NeA>?V;vG2ZhIJ#l&6^QdzMOs$o`k_eG4^kRDXmnYSC@$+S) zQ}E<8r}Tf8RPqylSD#JI&)3g~*4DZ0y-`Bp+fgD&>kC^P5st{6ll0_mEPmwnD=PAg zP)G)s1C8-nGEvhx=Nl%h}T<&g1tz7(N}@j zpWlngw6@XC3hDL(B$vm+;O85ykRTpfchsar!VtW(a-&<)T zLUUZRE4qY?U5*8F?U>02^Z3|OaqyRkp(7-ntKZ6{8@NWx*O~QL9}tq~8{2P9Wv;9* zkeP`n6292rfg;3N3!ur%Ukq4k0E){}oAEjnGycjoJ31Bdg4PODuu#zt=J2RTN2Vu^ zvr+~xBo(?~1C|inwne1*(a{Gk%S(kVh$t7g=T=IZd+Y=^a1ouUWub9i{}k93tj!$p zHwq%GgnHh)&saH-z7mWrU-DmP^ZAxrb>&G*a;ft8J?_KWM0Q@$yyzaj+t3~0b8b3Y zo__K(-~~yeChL<_`3BXu6dDM}w@|AF#DY=eS7vnrh5Rls!sB7cS>6>+8m2eddv=$7 zF*`IL5PvZ$es5{%7|vYX7o6IackiEKn7(*D&-X#AwS)f{{5QFLYX7{X+4z91=UMYd z-)?L-OV@6=S=*k2&c-y_nk_1V&=T4!0;F22i0r80k&NB=a%=eKwl{u{{I9AmqVW5( zzyIg<@a^04=kGx#qM5IekC^?LQ{Gr>Ujy%;)(m8eDI$++7m{t|_);4v-U|2Y3q8l% z5!nrA=|Gm@(Q6;tcT#v!F=lU-)CjCc6XZ9VyKiJEYp{t{fg&SmhqWhZLY5R5FRI;D zg`xBMB{m$eV8xl}*W?m7R?SXh+h?~Bka?ZqnpWeE8m&%)z&%d%u8$Rj}BtfSU2aZ~nlIcz;S3wv&YG}b(dF$7rjAG1I-75$gOA@z6)v1K6M<|3 zV4CZHUI?Qpg%G&Secw1GDAMKs!vl=)*H?bUwsu#-lYwgi)IKGJ$%LA3ve_&3(vRhq zt8`8dsdls^|l?M2I#ydyDPgL{QCGZ`{dp8ca_ z*|qu2P*1enR*>ee`)ja z)PCy2aONTJ^6;z|HhhNY{gX>&ZPj07(lG0et`9V0&rH{ez4UvLa!pQA7o`M z@DmL3R`3Ac(YQ4qd49(efzBmi+yW=@Y@qW;g3 z4WDpvHx>1*<%{KoZOJe zgt+0v%?+gUM7bfLrg*LxAR;8tikX~{x&8IpJU%UCfI>b*Nm>cmU(Yx^*mR!&+hi;7 zo>jpm(P|zk?>y}Us*qv6_&30 zpU%p%QvL7w;ogga{7f5PRu`SLzy!H5&O!zC!>|hcr;oOf);8eJbH-%q zCuj8^IU%|>>g(Hkt5Q_$#@P`PJDfnDQO^xQfDON zu(=*N<4VG(G}8M)wjYVd?xEMU_>{Xk81Dt$gN50;hZT{0S<#}>FTwe@8ZL!2pkpGW z3yy>EOVt10x!uLZ`DIB*C0M(ITgSZ5#qQ@q{a-(aS)M))G?}p*4TXkfO(3dMV6$YN zbcO?+hZk)HB<2Lt&>cZ^i!8Ts5(R{x&B9Q(64n^BU9$+{w0dqSB8;Gt!mdI zJ%B@bEwEiyNWbgEM9z1hZ2tP(e1k{FRUPVdNJs85Pc5}mf%=-1{lXab9OQ?|pWS3~eZu8niX%LR8wqovOT@1ic`$wb}-Vkm;$+>8ZjR zXXUhmc>T$%W>kAisYTTUi|@!BWxDR?C&FY0&{rW`iTPH|8medCJIYWDusi_1c?kes7`}_L`dHes1FZUkx|4oz*_J2p0hr}zG2l~Ocs1yf=TWobL1B#EZ z6CJ1eJ+s-1CM2ACVxsx8rU`sEZHnXB+~QizvDfKVQ7hKhq9qs%=h+s<>9*YVW*&c= zd@n3AkA6HzF)GX(dH2n`&TMkyXKOUgZRXMZveVmjs{Vum@h?`o%74u=oy33h{qM8F z{qOTf|G&+Y4)Xu?huEg5j*NjMNnKZMFmPqeAgyAaLPJ}SCRY7aHQ(J3&S^lVhRKCjPe9I~`eHFx^SwWbe#9O$}Ty z@8CwSfH%s{t!Mo5bWL67M-$A( za!nqM0nB2wU3|g~dYHO`v*(B4G9jfip$@{%#mr&`~rI%7^ud7~C$B@m=@v3#Q z{Ao95rl%($CiBcJlyu;x0!&hRnv^R;@IJKx^qV(j6DO)fz$RZSC2Vz#%+zM)P{Z9p z+Ei_INM~v{X3*4O_^C)IvF!#^HWN99DA+0UTa>q5RmTm-wcUw(HlY7?)&KQtgjL@E z?mypq@vLzF`p-dtA$^g8pyZu0izU94Y)>N`@%zHIVg};keZU+>Kg?rt>D+UgZ6FA7Nl0ym&eKEZ$pzI_OEX-57G;G z8d5p;0D`~MXvCIDjPk@{ug8TsEs(=~!;{XV&LRNVL#j|ZLbpU`cNXM^a2)1mR4BRb z#>QFqZFZJJ3kpoL(9hgiCp&1#1ZBE@ncrQEqEl?w@vJy752Ev2pYHD9@l?2XPH)z9 z`^eR>EX-c{wp~>HDyzDHrZZsCFINQeQs)4xAB`YtWY4h?1S|&WIIyic%1H5OJZON+1hM6s_n{11$^I@?^HRAU;j;%Ai z;~%MDd5LHgkPmgOK1+bEc5!T6Y_^N$wU#{KWE^oKIVCp)^6t`6lC9qdMLlS>Ce!DV z`bNcZ?aDlMwMXXc8bp2bS~2)B8xl7Ees;g)P3=K{8}&mHjpd||_V<8>Owka02(l;m z%)e`$$IQ|%a4Z^RSoW!=-}9Kly(sD#z#s86TgSa4EH_s6AeQYQ~w%`C>Ju#A!{50&H4;< zXBt#Z6Epz-qEuQcnDrNfX`1Do<0xR$Wa4x;nw)5WzG5sSILdbQ(}ci_P07@;5sCS9 z$n@P@i>_1aMTwe|qlY%)fMABVvjWo~&0nWg8*6(Kv!St_H@#0rgTe#l9%NwW0X#!B zVNP@wR+D7TypV>0va4A!@4ng`^a4(Hp#qm`0kw5HLb!y5)mUs6xhYa%8@Ie?XZNWv zEmLl=2E7DUeXoFJ$uMc`7GU-ym8>2M3z0kmMo+KFymlCAgQIB9wyDo^`*6A>t-VlB zB?-2B2pxFnEP2;%QN5u!zev)_Qvx$xuEGLsrzg8sYvBjKPgtPIlEtnFa1{qNr4wu# z%pjA025(~4Xfmm$Vky$kJai6ABb+;{B{y9L<6{(&Tf35qGiu0Zmc7Yi3wn&64*lV2 zMs{d`(t#CjDR_iHd4%~zrTk( zgML!k@POs4@3e}N-$!SXhQb>Y`5l>m&Dm5*bvONv=p!#D`kf6dJ*-p>`=gCvUpX+; zP(y#`sMoMfm*P-6x+c#nEHRw5LdLFVG3wu_?b~YVpOqS7wGq+KciRh87wHkl?bub} zj4zn`*-i43We2N_6>4V!>Hkp@N!sdKC1DpXQ#JeN{^#Q7J_;DoajuM*OEz`={pYA} z(X^x2J-IiYz!h|Lo<5~mR@8N#ZQh~b;d2uCF6J)Y&a1%OQzsJPVMv1PV^X`YUb?HP z>W$84*7fqtS*H2;Ddn7JRZ2U3HgpP1W8Z?&cOWWZR``LzMV}8 zr#{->Mq9HuF4np;u~dHTSFK;DFMLW1vbd@N8Iup^`m+8w4Bt=*Hmd&5KmX*+1w4Vi zQ_7o=9KC4Ud3pkaGnko)v_@vZiOFm<3Q6hGD;GKi#MMN-olOhi)pS|z(4RRv#xBEF zyQtq9bsM9YlN-urqNp`sSN#-iPLH}~)0y#;9oRZ5@J&jK#deV0E|=RXi@W4w_`Sb& z>3shu8OLL?%J-l9`-g@6FME5B`Cm6uy2pQUqX}GSZb0znr&M+ucJWn(^x;Voo(nF; zORVuug|@+9azmv@Jo5oy1jDb>xtIAkD8^;UTXfCy{X#Q0Z&!B2m-UTmFG)a77h9Q6 zTjY1R2+CC1&Y70&{_WP$j~;*S|J-*YBDgw5Q(LXXltWgD&ErOL|4LW+pGIY9zXLSL z|GmS#FZ1&M*^9^cUmGc%&yM!8S3^S{|u$q$~;PfwD0@O11)RkZ9`{SsWrK z!3%eIH>q(Xm3%S|?H4!vOIh|Xx5<`wlbBEb2T#N8^49k#0!Y{OuPuSAegC19z5M%+ z!$<$Gjg$`SUq9xjk&c%SPiZAXV|A9dCu?)BS1kcF`DhR zTgrusfs@nq4d&MCryOP&?~=WaZhpkvX6hs#V#cM(9mL}4)JbTnY-H^Cw$9AEbT0JFEJYUoG*A3uKVqdPRjf*d|a0|-Z# zH_&`FqhWwZbc1d%*H>uT!31l+`$o#;Ww8(Ykm_XqRI6=iB1&fDJ z|A3g#O5ZgIJ1xLOc!CA_y3iCXje~p?tNa-5CQ;d28n~*e#un1XN)K(9D8%q*YPYQH zrNTEurd#ibv#H%IH3b_fS9^JrxJ&52I<2Wf$En3iVPmec9142<)c3}$J#+2UcN)Wf zBi{{wgPh8_tA(VRp=L5t!Dq+mXHarU6Kl77PHrgCp7y+_ z@ykGro0`TN3QGuFenJ$nXkco$VY%vy%AD`cHJR^c`4BvIx^iM>yu8PkK_4#RlW&~d z5H84f>c^v($oy$)Wx33)nkVvNm!@9nrPFri+R|Z%oV%D;yf>@0-kU{-?uX|2SnfmV zs{h|&9?@vr=?Kth|J^ItfA?QJ=KtPE>7f7rq)CtPkj#-PTH6D=Gshg6riodGSRn=$9?1k^xihnKl8D<@AN(J*E9-Hf53nKIr#f$ zcVdDMUK}3vbzsn+j?dqozWwG1ou}BNfJov?5}+-mk~@LJKYlz?zo4y{Go?V@R!psff!X}{r zCq9VNGBBeI)F=a|X3w!*JZ>R>lG0KBJH9Quzxr4R90eRVYz7VT|Ha<^VNU+PINX1{ z|Jz9EApeaQ5J4xF?rCJaG-VLxI!$3A#aA0Ysg$FV4y%kqHt=iW$YmY*vnPgj?jP9~ zCZ?Wt`ACtq!O%G|ejnBkK7l$he~5vBR*!2v%*wpey~H^^9mzhM!y;|VxSCcEz0#+? zBaLt69@%zsoik|e`Af-(Chfs=S$J5L>Cd?TwdzRM&Girre-MP9aWbMGT6J?x=ALep z>&bcxx_*S|*(iO(kQ+1W(gtb;<63d}EdTZgBGBevk-;77w*6=(L$P(u5HvyK~!HVC?eH+sYm}VIOF%IHFzC7D+iTkAMk67xCSQCL^_JM{J z^SSd#K-;t-Dgzx)q&2xQo_q6GE8H5Fij5pnBd$Jy*k}YhV_@@A5FL)my8)+t>a~@B zXJ_r*IZuSTE?alBD#DwUo1)T<_Ex%;6TLk#Y(Fii;F=1nDPj?;nfr{*QAxfEH}5iw z_pi!LM8F#jF(=jh*$Fx880qFh%fPT*bZ}p_5yH-NagtYRhRFNd zyXfl#Lay}bJ8Pj|GYJ)os+#*s>bGFRwAC7>sSKw28T+dka@y>GE3@USP#I_g_X5To z+igjIix_fRcC%tLjzyva-4`_BRQ0l?0mpWG&&@ZkIPJ2=GD_VVjW=stZW$DoS!eE! z)Ma5+v|F)ZPOaY#lugy_2T9cw{054;QnHLZ||YWc;72Hv$=^x<5uB7u#w}kOq56TaY`{nhZk4>Fs6^GVNDl z5X$ydVGyb}<7B(2Fyk~Dm2yZ`8jHvqyn8kDhcabeKYSK@$ zF-~z-4&@vy>$l0}cC>qClM_U?Fv+E2smT~;YPMi{U4I~m93)|-S7?DVfIQmX+A15X zv%P`xHC)NDu?5_V*aS?s58L);kmx}7MQv{ty)0{cGu_^E+goc3O_c_{P7BS7&pDMi zG?{6f1+{>gX00aCx+BTMCC&17QA@J*+eJUMX=Wp3Df=J9|8IT>+T{QBqLBah#ooc= z`_GM(h3tRxi~sXx^@hJpHi=Jf_5&o>>iGpDtjWxmpUiGXK4`rX6QA4Df*xNPU>5fG za(j97_ImX8DxUCRMgIkiTA$k2Dj;r;gGTC^-<|4HlD8-W`9zxEFc_MgMO$M=7mDT~;D&NSWEVFYqm>fTs_QkbgE zL1~@kY(mah>oE+KPjDyekkiGIVPHynDm4)$r^}?id;DtdRY`mMt4IwU4P!WGr5f*| z^3h5SD_(Z9`GnS#Vzttltv==#t5=_EOV-AULd+DQ$eLHo3^|1C#Dy*uQ|e{y2qi=0 z=}|M;T@4Dg%-M

oqUbV|Jem4U4JI0r6=-lKgf=0j73DlPt)*{dQo`{2U|pf z@iO*bP6FB{5k!Ok-{G^py`25``InFRA2(Baix_~<72((O{8#hTy|MiQIMrrf_`ICO zSC6nBV{c(H+nHr`vvwBQN{72lC)Z>yycp`{I)aoFnA3lg;77tmg^4cHnbX9((QW!V z7gDtiTPh8c&(T)u{01qJa(ML1oG7*%TNN9S-%C-mrok$6d!=68#t$rSEH3u~D>?}V zRJg{+PE(bb5Su5-t=f8eGEn{?$ni{0y3^CJa5IcELC!jXc`vN_PUgaNhL-Up%*=MR z1vSB4!Ec8)dSBLL=lGxHxUI%_&aGK(+s=yM%7Huk$+@FHe8Y8<8A=P-y1lx5Q|M-V zD(_>-lbP=HUYeZrj;C`;+Jl(JzV%FlMaFELYdmAEObe;r_N&RP+qg8VpZb#t@vlX4 z3j^~F@I#MJg`H8M^*JlR^_oOmMrT0(dWrU*Z?~pIsoJpw|CjdX7`xn^#|riA_O;bP z=i1hLVZTE6QUjQ@pbPFDd1&j^4?3zE-d(YZy&D$er#?SD^s>zP-`(lztN;z?|L2F# z^5_4<{V(?(&;Oe!iyZ&Waah%XgZ_{d&-z+-hx)LvPgpeC+f%}2E3fh;Nq^y|e$`n& zab_?o(qM1TsL2(h?XPyU{baN@DqoeRr_&yn&P^E##T3XnGN9Pm>@Ak%MvlvgNoy^c z)kFa5Xl%Nok)xq_b36?*uN~9FUWGj+RVym(Ddpn|G$s+@Sdw73{WD9G1-@x~UCrQT zfC;d~f=cdLMgg0M8!R#?Rv74?I6 z9)UBM_%iI8we(0R+`u|frO}HdVuT)a=wxzM& zb{O;unx%Rb&q;Di1}NjG2{%J3K^A$=g_0nLm}MsB1x7?AL&^qwATT3}j@`Cdy(cV< zn!s>iqojANYr;jN!hh_>aKW+(aAv;LAVH1-GRiQH;?wINuk|JuHQ~fCCA>emhLj2! z#RIC^=3fhb6!(4+ZS${xF&wn@KmLE^n6;~pdL+3ma%20*=v6H5^5|9EBe&73SdH@N z)&E9Kcuxf7g@p6dGa1FX;6GuaqL`*g+P0nGKSl9aCOpOV@5n2$mi%9x9iM)87LU^V zjj>$*U+;g_`Km7eov*(7%OCZBp5$r58>$!?Q7;W|X-{aa>B^~K=2~hON!+y$oPOJ&_i{Hdckpk z*ze*fYBu5K?cYzYqNv;LYRx)IF-MjnODH<+UGJ?&u0ONSJ6GxvbmC9(Cm(ggB~@HZ zj=%%%261D?2_LoH-+C}JVvopS^a3>aP!2qSBG-Cq*~-90a{AtnJMKicl%+?YEqFTk zj^xn@717$W2H65U$7Iq!$hco*nT>@sC))n2(Zs4o(D(+kjKc>mvb14=Xg1-TDZ$gi z979BrS){EZk_$ejDM}z7=iZm6=ar+7a5tpM5E8<)3S`{>CedMx8P9>?ouda7TCuj= zFhl=cze&J|Ffu?9N70)aIco!$760S6MGr}y%c{3q_a;tp+_o%}VxIBINGpe0S+(7p z|K)u!oOxpVrwo#;kP3xkolAkn{FYRqjG`9k@dQJK5;}3`Z-0(jwu8g?Am0D8{YKk` zsQb`ZMCkJ@<9B-Aiu5uxN3Ql%!DEk%3C+xJ&RBBX@6c*OMiQQ*F{V=5@1s$4B_`Hr z(Ze?3xZkIYDyjkftfA67A5D=d+NUTWd_Kb|%0y6OS;5-RXE^(mW1=mrbCwrs^#{@C z*79f7@7wz9bMzUyPD)6LshIIpn|r*ky6_pUP!)m!0sR8>Zw{#wYctY$==u!ZFeLdO z7Z(lZn~>gB*LZV$)zJU`Ph+LF?CznP-*AS*#h z_$cQLnJNLQ{3_i#t1JY?B4q|Ej|Ykos1uTt9?jMisX4-OFBx0^nJ0~_1@7UZw2c8m zY9|4nW4(O4ZLm8%T}OSrLMkG(-5)H+{zP`i?lDP5^&06@c4!~`34JgEP-*OTiE202 zd=huqC`I}c8h=Yr>g8ZT(s)a**WhkMX{130U_ZyMBf;S73s zL^!1)3j0MSaT?Hd;S76tJUA&cc`Xm1yYFE$WNr$l=#gX&kQ=~x_2&2l1WI0r1UCV9 zLpe(4gSj@GCs(KUK<1`!<~*axWFDyN!l`#MObS8O#C7%jwJU zqbqLPdL9SRP!!PcSzP1;K~k);73>L~Ui;1!+|eupWU??h8FN!k26T+fx~}igys=$s zjgnX|L=5MB=vHTjmc_eXm9%GZ)QzTwg5LpQU;s4U2lHMko?9`r5Cbu$d|cTo(*sOL zefS@On2+*RXBX^pmle>>Q%a8oY~(w#T)8K~|*eP3LqN*0r)t5t4)lJiyw zYnyE5?RbtY`{`Djtv#E$W}ahn|J^7Q)l(BlXIS@0a*HhO&LIK((}g<$@q+1C9^6-e zObezxtI^v&w_<#Jd0uMDn~~j1t+d994@Bde{1i5)$aVYO>)`_zLqV@TAfzsbvszrCrpt~<*`D766PV* z+ZUHa4R0nnc7q9C3d)r9nIz7@$X!Dp238*VW4Z-dnqzW&;m_BOEMu`#1>?tjd+EzVfQ6E^C?F5Giq*J#$u0}Fze%e+WUt*&1V zbc>5I3PIC)SF3oU9`{lAQl1F33XeYv)6FLEb3rmqxD-g98`ze*QP+dO{F{>mYv&Ee zS;p^NilvQ!NS+nH!@?`Df@0G0w2F+V?-~G<}ECRpXfB7TX5* z&7kiVC*?s-i9VNZaf=%q&^-u!Wi?@AzCI_8md!9gUv&gvmHO@+^p#mcT!26&D2~y@ zj?+GnOdv@okeHn#jYB)WmRQzuRVV8hf`*HlOyAeTuRN0d*qz4gyMx9qG%{oZHEcj< z9~x2#&IVP1D!u-@VQPO@OuPs7`#rGV8ePw}J@#g!wO@FdyETvd3`J$Pc8ut2CJ@L4 zj!j5=nMLMN>(OVwk6|VH=0{@vo*ussD=x?Yw-oIOry~Wofsi%YDIG+m_U= zFIce(`B3FqSyYduC@d@Lzhs#rZIW5_Vn`^fPJe3W!o>nsv?+o0U7*bKE%S>(4tbHK zU_r2jdi*eZrBTrr_;Z0wWfT8#QZqWbFS>fy)YgdO+V2%z?JauT)1s|0`Wo(qM`XFJ zbsh5FoJ?E0tG_8|mIAUd6`YN10rm0`nhFw3&@a_%?T6GNo);)jd@{(;^JrL-kL#L{$>4$b$S|8+2U43Rn=P17kpGYhq}Of zKVhOAL8y|p{yb5`jizy1D_~;(ZxiKf?liu|iJrt;D#Mfk34JQ03Z|eTHiu?&gO7$&HI`zpJReIj^+^Y4y%Kg7bi2w74t9`+H`%^#n zNPT#I&EdJn|AL-yVOddS0LQpLO>3QR$y&xrMXksgj|+|bT*;icB*T2*F)78`K+SfREZ_&jy_GI zaL7)JB5VzXzSF&&zL~1;et)vgYG)44RwZ>yN}YBq*(oC_yZ~93nX#36Xk+I!JjMk_ zm5UIPz?rMCG~tCsKp_zv6wYe$Cx8}BkF*}GqF=3&lq`M98`96*q`WQa&845I3iZs? z(=dENw3~O~YIkGW1y}BFg@CiP3+{+~UIGT!y*vpOSI}?j4uyNlUT|Z^gXlL)H(USw zc}W&jUw#^yTZ3*1k&>`fkQ(harQ3<`WlQVkEd5G2pP7aw98X2ZReK(11O9NGMfY<0 zW($%B%ZTWJeeSK#Lh-blpK--}Ac9dgSnY>d!{_oKx5!FI!Wu^VgY5c{tM43EV!^YF zvcU}*=$+po3rLR_%9Yh|EkKchS>(%np6=%PJyEj>*EuGXWIzoDWirGOkwGSz?y4$Z zBwS9*Q3RkSIUeZ_DH}upX+^Fhp9tfd2jxj^UJ{j%agzfS0pKSx$}>EI)O;0F9z{VV zrWHe7l`Rb;SD8~`&#q!qn++)Y6h(>*R&{IpQDhKy(}_E;<4!BZ9wn^R*>8#0hf$Ol zS!PqQS9NNT-Jbxl-Cvd;mbWGthxW_k?2b(2OQ8J<4vn*yCP_%W+_U!|NK~fzdH)?( zmjWd+_0q!Q0>vtTh!A8F0Z@gup6zl-eL2=_0@4G`Y$w3`75F|$Yp1$1x|YurM^TEs zB0zV~UM?|%8ao%Cy=;~%v$|#U)&vl0?#53_5TLBj#mHt#*xFz+B$B;$Li6@9vtfQL zLDyLikD_MDmLbPAYsJ6n{L<9;UqJmP1muU15>XTE)Ez{w1XmM+^WsXf+?66L@#OE} zupF=Kf>D~%J1@C!QjIe%iz6a-h&wGtlV-Lb%-kGXp zjfN|0l~SqUl#os|LK9nOOj52Fwi?8ZRwIf?lAx5|@f25qdu&?5h^N)nl?&mn4RnPh z{UE5q3qt@&e_1)$HT?xQ7~!w~q*0U;HC)y2rK=a+s|cCadMZoJEn{cTI+p0o8aXUp zn-Cy&3IR9 zJi~`vHL}0|w3m(SckXfB$eQv53&8qIx1HAB} z{-f?7;EM~!9#aIk-{zvpTw9ry%XxFaTKbYu*qK4nx6F|G2o2UHDq>QS(Y#)g#gzhR$ZRuG%)kCX8nO?LcI;Gcy^^`-o830uh zv%WT~h$s`RJj%{4-o{b%>eUAm^XLG-LxDhDEn;-{hfE{kzhAwIq842G_;dGKT69nu z&evqv)m4%%?D!-vjfUO?dRz_dM+atlhaUGqN1C#>aI=|yz0ZT$K5b!O;4GW$#_;hQ z6u7+TwJ&z9S%Bo!P09w7?Hao`Ax!gB3L|c?R9U;$5u~x(4a=3;sJ*BK-)k&bJ;+rT z?#{q8K8$N%^~ulerfc0Yz_lEguYg7mcvEL4n{bd@``2sRuMA?%e*enU&W9n9(9_yG z7cM$A%ZH?giY7*&jEXztBR)Wen(}vKQggNXiqSz?XU$?Kno&~}E-Twqc&bV}86lx1 z8(HQ$cdiDfIr~aYQ*CXKUXTi5@<%Kq_$t*-ZuU%nHvE>oRM6K87hw~iQWhxJAJXdR zPKq3#$^;n^l$Rw<%X$Dr*1t|UNk(`9-c_Nvpd^!Rfs$uqY-!*Q%)f`NoJ-ZJ z0I_s#2mP%xlR3>znGf3nTY3&=yw>=jrMUa^ux)m;w=_YfEy)v}Pwa)V|C#W7@^`&^ z9e8PpBG)d3f~D>{)Z?5aL-alDfv;(J5bwi|ZqRT)HFp0VX?_`ziDA9M#2is+B^o~^ zm>Y>t_$be)HJklr;kt;Uf4L5LPZ1;J8cM&rxmG}w)e^#OzR0g$|Z?jQYA|KRB8V9?(`JnH{buYY*Z@Bb6(-3Rh@pIk`H|EYIp zT-CFh(Q1QfBr9YL**2u3`Hy^D4ODQ zLJ%jv=9H5-M2}iirW!MqG84mY*Ys0JS&K%BF4G(=1d*bvo{4T_XNFliX}Hsz64R7$s6}R&CPNgZ(KxVpVlw}K9|;vwgzB-P4WaVv!MU6= zuKGCVNmFaOtyS|tu$)JFY;DyEmD79_Mr>xG*uR5rOD-}pL^#V58o>f;xuG5O%%u6; zt9$)t75`6IbbTK<*6{z{{$Nn$|NBReANc>L_}q%Eg{v4Eoe&|1NKEnI@M!pi91O-! zqo?r!9>mdqlPCM*{^Rk}gZQX-a1cFxeAs^yk+}a9$GxY6!T8|u=*i=w9yxg2-#^?x zdOE_b2}udZQf(;hL2u9x`h%c%blL9@4+g`-UikRQ!Qh~`fA}=$9S(cF_U~ZLeMz6@ z^*_f+PQ-l)fUDR4(cq}JUtRx4hY#}KC;9B4Q!>VXc_NV>bC4tKmf6}tms2Vb6$qpM zIDYXw7&AV@Qj!>WfhurHq6Bk-=9p7FN{B#`p%Fouk``h_Q^`OsL6Xd}1WO{qR%-_Z z0s0{y5uOrB1Uh|rflir{0)PQ25V;_&D9ME+T)!D2^Hc3hI59vjr^G%-DUmmfU+Xs9 zOldTKwekmwsfgH|@P%qiM!0H+5`Ca~V#@L)ZtWnNMoAtMB&P&rEH(m`hG2nr&?uKE zB_u{Elcg%DlCDg-u(i|LLEkJ;th={^aFU?2^Z5bFIGtlzKm;`EEsi3RslGispC6&u z&yNMdoV0e3$Vdc2H4+TTDVB&6!IE4_9Z17}ped4zj7B)|`<0|~%2_%isT85@&X)%7 z5ViZg5dP~v>GXTO@aO=3^n0ED<3ZRz(!U0s{!{hqiT-)i8OOceaM*p))VS)L>)V+oBGEqHRCC&@Yd9-_1HOD4}b5hRtm?uBWY&>fi1Mua0aMl6ZZD*~c_ z)di6-r#Mj(qWXrDgxw&{l4OLV>#)VioT@G8dn(jE^_rljI8B0|Uwaklz@aJsuT-6yOnvPikNYDQ*A$<##hN=`zH7t_qwNeHkIgV&L zv9&=By425xXp9p{0k-%!ZqwNB(u4P=zsyU8 zpAjzH;KoEqnu2I=xximrI|fpzvSlHP?+GH+s7Rg@#L{GeXcf~BPXrnhEOS`f6U7Rs zKrC%FK^_96avL;jk`&?bn5Ihki#XAAvefHQ-IOVvOp)m%P#g`Oa~2<`k{%lvr3u#1 zTUo~07!gC9qIcQseXk6YRA`i(<&vfo&1)rBT^T7ZisP69Qpq&Cw(sPWvwSjDw6=E4%-@CD78DG( zn~n$zXo@Nrs4hnHLAW3GfZaQ>E2XU+H1CH8VQ;Txh*Ln#xOOepdq~Oc zct+G-sJcq+Dc)>oAyuo^JFsE^@C*Eo&hnYZhBFomz2QVSRkJ%UmK%z5u3BAC(YPl2 z-bkzBQth~GMx`G0m(MPLK0bYM_7X)nGZPdxvnfI67w4@V=q}ihi;h&C0@ea_GbJga z=`V^W0dP}JEmULR(0IIm4o6v%PwY;@362-4WyZus;#QQ>XE2xI(#*N!xsZr6CXq36 zMQZ8pK07(RINl4M-bi*$)ZB}%iA0K1qeSh!VDsBSbe1JV%{*AvZ+9E4 zD#b?7jS@;y8BADrl(12E-XDOtkxQC%#|gVJ3!!TWA>oAWwGh(P{&s$$HvFD#+c!BE zMxsSZ>??}7Do|v9hz30)CLEh}j}zqCL}8M|v5`7pJ+v~#I18&OdjDGuLV`ymSyuTu zye#THFA8T_varRKhzAy_R>WpAmR75IVqV56<5VtA5-fz;-`yT&ZDZ$vyIKq;2mpJP zr;^SHf>+3aP;?k!ShTnC!=^G(bNugwo}}J+1;|nCkwDs|d7EBJ%`zHH99-iI&YhMFl2) z0Z!X!=|41oJb2;M5olw8tV+@|zuUuMw^uZ{-j{Zv0K+Fj3iMwzAJXP4XV+EWqAb^6 zDoha1Se{C?<(-_rMtQ2YCoGo@9|rbpASGJiFr#lEA8!ZI(r!SQpAP7Z%oty+Azc@` zBi*+FyM}m@P05UKoCHcga|?edLRTJ{^7l3rTR~ob(JChZRydt{=HxUjL^uP25`Jl7 zEG#KY1CN1QXH5%P_2Qi*JjKbmsbnRQN}mDGwoA@20H91VM1)jAmzW})B9_Y$%hMQL zo}2@ih^47k5Q-(l;~b>ChmZirYo?TmkmhQ;50&s8u}E(B-gsa(8Gzy z6R9PC5rN2@Mqsv5Tn^L?98HPW@>5&!M7?+oU>!y6L($%jAlvS(=`j^olk>D!(DQdC z0()9#r_gcCut*j$r3px*xl0X4sc>?t=alO|L1R$&iV+qk$LBwhy zi}FVU=G-7X1)PrV(j2}k-L|Iy-rdMPOE;l^dNY|tAzv-0xDv}{6U$pZmOQc{{53L2 ziO-1w@*{z|Vw%gC-K5$S;OqvD!Cjd5*4j~-91UWP>9#_YxxqZ`7!to$a!qGSqie<& zUlYz5_dyx6-R>2b;I0tk=;{~2(yP5D_+@*Y0keC>#$#QRrr>oaS9|DeY^N~1?w}ig z3IY$AgGS~0S}k*cl(5M}&B^aCFVE4G;Fxd``d}RJPN@uOW+jKNtqJJSW1w{$732%t@c^MN(lezQE&TPE4Vlj%(HaGWR!zan6QZg z@V%}-L~S-6x54PZrSR6xG0X_{blHS|gt9PkhUlRGv|rS<5h81An|&PW_lo*vrLV7V zn2V}^uwT@-3~oID%TWPB&zHEbqAU+VP`Lu*##O{P5m%lK@tR~3(G-bA8ii2DsIp^Q z7~olR18lRBObFK=3k}D(1CoUutI+~+MUk2xdFFN=J^G5A5IqYgA);gCC{(k5=28E! z*PA`+AVBSrIZ&ex4~M9CU$VCD%Dc+f0Og~|)SJ?`DX32A9)P_TYJ-VU zp2oy_<-GcN3IRJb9-=|NH*nmRrg9Jcm>GLYlncpbR5$~%f-vDM&sKv*yG6mXQ_Y-5 z1k8_0_@ZN^#5c8waf*6-Erce2ijtu3)J@BoLEiXSX7KOd8Fw#Nf z9*aabVrfJ&313XyR`E4REVKY1b$5za@L&(HDCRj+jaFN?bthrc(6ZcEcA-RRG{6X{l`xm-#<&RkTkj= zm`78z`*gq8Yo?aWKy!)FZofb1_xFr>RiKz@2e}Zr+M*UpD#EjWQ9?Rqsg5|o*P@W` zl`;nXWqVb3Qb+YfN42)2TGLS^cN9GxK=gUPgxacis#zhln_bcjyH2)V%enziyhD=iw=qsCe&(H&F5r>X{vsC zVAa&Ngn3KUpHi29;EL4KN_)PIwxEL~vn2IIx$HX>Mzb?Ds>xtjiM2iQp9u-x2%l* zvZSqfVeP+{%mE@cP$WbrIp-vm$wF_yK2{xP!SfUmDyK?! zO3|ZqEFU4Jzb9mZqs1dMV=>Xj0rd^AS_?aWELYuexzr&QBbs8qaI{4b>Y%GnnJ}RX zBF~hl3Sgi*nG;@sw~bQk&9wLhi`633G%b^Ysb_QntCYB=8JbhiYdlyOoKxLt{*lDBWDxh+y>&fXO3a%A<`B{Ntyeo1>wiB`}fHk;+C4lseUJBkl~ zdjg8uP_($$LdZmT=--aigZ<9Y!NIG7_WFqGU2vk1sSBUvOPw!-aWX6AZyG?OS)ta5gpIHUqbYT+g-( z;5WDESK^M=8~80D>#Y3MfToXP>R*n3WL}(n3lG9RM8_~e{*I~je_W8r*R#(#ozsLU zZVP+?G!o(D1PwpqEFwbaSa6z738y*|z@ApqbKeGhDRE0lk)uV1g#cyA9cu$2%EaQ3 z6m%;$|J1}!h}42HxRZe8!h(6k^YmD}V$3MOcn?WM912HLnqM< z7K#mn#-_e9<~&b|V}|GjULYbOoDmdh6O)nnbl5mSO!05a;7x~UX<47l^P$z|tW^{; z*WnfA;TUv5HYc3Z*qV%>)h}798m?PMS?%`*^?icAjqx09Ylqn-}Y(c$6#!Tq554o0Mg2ObxQ-pLm% zPvtq5Qxj6`exfeVQ*WW$2*P4T1@AO(4-yt#E9t>R!e~Z{C96h48I2SylPpD8Z@s`| zb2T{%IYJ4ZN?LI7IW`Q{xdSu;h({JVx3Y(WK$XhEIe~d?15{mrjFGp0Z-_C5xdR^t z+fNq$a5*zKMT3Ht>J$dgP>HGAC!6y1^*9<>d&zBg9LJmp=+VMJTm!4;36_$~GHGNs zB{r50h!|JPnGR%dhH!iOgbFY+fQ48efdTsj3?+`HV5-I1Z$zbMEa)H-PQs3QmyZ$} zSp*PYub&tc=A?)_Kyr3}u9Ygvg9(O>*%bsHXs{*pnxH|i*XtJsjaeoa9cy)g-sy+% z-w+A{qBr`SNB^yPrf@+-w0fxnpNUWnrgM@kj4rHtP4&6If!D^M-v3G(A*q@8W|D#e zN~IvlcopF$UTk>KKhUw&Z-&FS`qz4jHQp-0mrgx~Wl|@1jH!-)*ffubXLYv=)@mMe zz28ZvYV^I}jWct62)iBcgr$gM>V6QZB)%+AlmK3cX`7qH**KxQoVz?qX~!ktzC8RhJBn{!^T&rZRG zx!>B-fw=*Hnr+>f1y$cEs)D}iAAi`ZVu?~;o%i06BQlTez)X?CiVDvETkunWV`gnw zh87d4IA&NTm@T+anao4P_N0)Df075=LV0arkQ$Vb7L zk|Y*;t(_(shGp8|tlPa1=&xdXAl4^Z@$*{{UM6sV*lKz2%CYt{BBmt%Udn860%kdg za~tJjE%9CxlKl*(wV|^h8xx%~n2CyypxDmpMfT03n<-7m&ooXvwhQuKW%j|d6U!hr zJ{;gcZJ?1`v2%qoUIBOSdibXB*MpIDO5V9o!ct*k4<1|$~O5GbJSp+UxU z;sNLq@43wyV?>GWPUS%W$b&f`4+`X3X;2Hw@GTH(QXvVBEz`Aq4Io;`iY=yDm+I-c z188S1(l&2nH5ZXu`A#EL&69~}wHg9wAV}DM9a#n&pi&l*xF$E&!j0W29V5Q$=qXk1 z;+oumv4_GTqyf7i$9 zq2*2;x09Pzk%8o9lsoO)OUgd3GhOi32kA7Zh)Z*N&WHU2DV8<86&?r8;A>g8!J374bZb?(SWfn(&EQx2>N0C~Ri2$D|Xv9_}v1a!jhge6nSil02 zcM+&@+U9BWhOw_V*d-jc8vO3g*n6t`Snm;9N9CTRSXNYQOD#U9vr7|&VI!Q?@Lg%r zv~};QR6mUHH+dQ-m_!(wo9p;z{QP8FXn zae}|)Y^E(x%in8N_DWCv5lPq$_@wRLsb5$3PnU7QgysM-dX3?DMumVh9!0OY^bQxM zxXpGTqv^AE87EM~9hkc&i=ml%p|>SD(18JMgEU!2IN0`-_Ij3@r#k(MWzz1TeC#7B zZ|O54af~Gn6}?-*h9kyeAtaf9xo7^kxt{xRq`H2?Zevh*i$3!@tCapIaGF=GRi})I zmrOo;M}=GlDy4y4A*<^<*PORIHS7Mcz|~T88OpSe%iI(+i`3XCNs7KF$xN$^ zHkB4)I*y~Xeby+sCd(`lABURK?rKhP!y;#6baL!(;lj&3;%KtmrbJhN3O@5??4i>{ zRxUIr_C*GlgA5Q?*%kESl_Q|?y387`JVvMwJxS-~=pdidbda%j*V&KH7dr?G$n5Bm zYwZJ$>>|?Fw#;$JHz&u)aqd$Vd2zpfxrWGJ9N50!E64IGp^vf@W|(2+{-|nfK*`Cm zW#nM%#bwgG$@q~Q(A{x=DI|gj2a2f$ilP7qUcb6k-4MU*wb>u9(oyYI4c7zf=8y|z zzN)rCLswJ+fx^tHB4vRaeH_Pyowl?mUrq_~XA<~84OwQ*3CTFfe1;0Fruh}{1hv*x z4ZC>iG=j1d#FQ&aP0zBlL}W=8_!5Y1@jRsI6v_TE1oRMDYKsE2{?#V4A)e?XQVf8M;>K7-gu9B#h&auxeTzz7~ zephlkr2udK81`>!Pp=rtSIpy zCzLENmFe}l#e+|OL(lI>DyXimnov+F@E{XB$OI2E!5>>DP#Y49-R5GGRCipP-u&?7 zqP2r!7Uc~oN!O$}D5Q%n7J^Pvh+IfnOu9SjU%LbDwVG*fr5Ivc5G`0y7o35E3{XCRZR-WhNik#Vw%bTr*R-1 z((cl3-6;wc)T()4lUjdlavNtuVAFChr#tm%9Gdx?^8`|^*u6XBY)0giEeukc6VmFE=?z4#5iFBj;PH0VF7o~MLbuJ!kpC(tImkzG%Dp~k2uc2ovFVS z=TQ4Smu&FNo@pP;QbrkF1zhWC>;dso7CIP9()ngAMy4UEXi{YJMW~$QdtL7rBUp(W z4eYr>ub)f;69d!nN4PgYeYX+$Ry^1Eo)u}{!Ktc$W4~=KLzA}9h1`|pdi24_+aTM6 znovXu2I&2J6u#2evW0~X@!M}+5gW@kr~hbpYA!2qky|e)=j@gpXM@@_3{>{}R{PLp z_uL*2?0CyY=d<4b(tQ7qyQ`)9^2f_(7omJ7?|@_7{g1t)!^-_XkNf@J!~H*>;&bUG z2``6#pWk4CL>@&%2*_qrWXMPV-~apn{NJtCB|}q^WN=NPmIC!fKNg&|YtM+7LZJw! z76_~gckSczGe}OS4_gkExE`t9Fc8n(ReU^8eM5i+^8txzt96{fo~gsoI}TUOZqkHd zeSLsJq6Ok)0VlJ43d}u`0%Z_++(H{&0cdM~b)he2_?jS*bArg6@P(WzW!xmjE{=wE z;AlUj^k7Ozw+*&o_0g0>*R2*D@}vI%X&?ntib)Jm3__*Hrb>sl-QsajR3RI; z*NQ$Xp8R+86BSf8U79%PPIOYq0AlS(+@82WI{sYev6rvAEaymmFP)gI7q!JxKfj|l8 zT9T~XYOKJ!o7&p;?#j?B6`FGp!D!KcMxh3xPm_>$GH^m}V4EFy>t;+RzJYtVT*T#h zqHo#68HI!BVu;?f+iy#`Q_-8Y20Fu;fOm7kNAP??WT~(guF;!znVR<7%{laD>;G;y zL9SW=j1xaFt7myfEj2WjEsM(6LznF_VhhL+ZknDtI3)@mnu`1O43TXZN z@vE0-FTeX|bPUN@QbFP9Hu!VQA#p6R68oo0XuW)Xfv(A-$hO7FjLl6<_>^#cv}w*L zoR}UFB~j{>1<3-k|0y*$Y$5c2RTl-07CJ_1#+?b&p5d%*8xY!KBB4IC6Us!GTBe~t zt2XATAaZ4$w)SPU9YQsB>(SRj!`9)hRk%H3@ASk5SiRD>MOpE2uSHrZzaH%_WNN65 zlXpAWo>xKR^f01!Lydy|($!~6h-hd>u|V6ai)qHTu9T2?LW(kmiP+bFjjZI0Q=QiB z|K6$MTPp#p_y57ce%1an=pXeS_Ww`vQTzYS&W`#YoqDIzizDRLND9S_sGyf0C;}TR z56i`f=Dj=crrs@thjQ&NLwabI|8ZvI{E`k}GguH=Q34VwWV?ev8R($)4VKZg{k95p zWFA+b{=!DL0#}EWu~?{o3hqW&^~2s{rM`n>^ftJPk*Z@g2<%;2w*h~{_;tc?9InD+ zy>PbhtuRH5@z~5kvk>Z-v@%f@SofBUUUle>>&khv+iwMO$YA@+mfD>T_WkS*ml8i6tBqi|) z;nE=3Rjg%C|Iv?s_R#*(p=-|=?WRmRiq{1G@2Prr_CN^a#PXw?GEtQzbS4ZOU!dL5(E&*#vsQt|^?Y)*()jyE906!e!{(;Bw3!iEqQ$!*$yOJOS@{+xG_(nCNgv*q6{#`HbbHugIK|8^d8iJ(~BGzBBKSh{S!ZS!sZhk=VE5 z7~y3u? zmR96F(Y5jD6!dh3#4>NBA^S*O;G-<}#BGUbaB43jqvqPazus?fcrT+uyS?xwEeyPj##H0axZ0~a*0k>~o) zHCb-C)f*r5EqKo@M|Zn*|1j_$iA$8&L#>xT5rg>LL6=|9XN&mXk97WT|8ei2cK+|^ z@!>=K@2B|OD*o3#**p|W$Om7_w!Rd9k&y^|Cg4*s;uTyDDoS?B?K=ssDc3w!kCReB z0G4_)L{EB8j^L-nd_v@T@vs(^x78d7rUb_c5f6^FTTh0_P6K1N`khXON=(DUWcX4! zLoN73Pl|(s{o0%;6}`jUa60$HtoYrqh^M^<7V)%q_i6CJCVm%e!VDIqk6FWiCQ3yc z53!uH_>>Bs!{xc(X;dLmouZJItsVe)l@Xb4(L8UZqfk;?RDW z)rTo8*VKfGdP?Z$UXO3z=apkd5Q!!^A>}jjI_Abdd#uWMafI&{$ekAZfu?aAwF|#d z8;%;Ut?wvo7lCvhsT)GM!Bl>K1GfY|dq?d}eQne;wP6jVOjh0EORo#wD+2VOPv}HZ z%84iil)qa*E=I8)o&&e0F95?|B3GQN;xoc0WCI*!%J_D;UGcWUYO0tyQVN>NGEo=~ zPu*~rILW=FmsxEq)Xb{NNH(-7){D8k5=F2>`KDpRaelwt?XG9PENkO`?k@PEtLit! z14>TjRQ28WR7l1b&*_XxzgpA#kHhfR)LJtTCO)V(f%QVu^R(Txs*2$_YKnL(nB|4! zSdz)Y@O$%X*gOpyt8F(KNBO!}jtzrc4PE*kwMyfkpb zZ?GWeSWZ#9IbA|~4~Q0jQ#?3468X%}c6uAmv3|@v0Byi+d+JFAK&j(179STC*LC`n zYNwm7t6kb)Zrl!NI%0Wh1^Xdt<0J|4)C*`JaobMi(sH=%g1F0)DAl!6z$Vr1yq4CD z(Pj*?VR$TyYXr>mRMHtaNw5&AS;d%E-)JU^KA>N7CcSdC$xvZ`2VSynmvE-iUAD`; zqUHH}R7bZ46lCPK40k24iU3iT-D)!13Y0egw;AVVjPBlhFNwGYKsKn+7$4fAQQ3e@D%QlCq> zpCv{qA+b*R9YrLQ_Ob^gxta@62O@882#Rp}NFq*>1!5_ZQ!EkVbOI9#uD6FA^^TQl zjon6m*<0_w>Tc0S!+hQ7DAwClZ;@A9-}sD@2%id0m6Jz zN>bjml>{ijam>FSI)k`*T1baQqR6k;Y!U$qw5=nU4uU+Ja2!LOk{#sx!E61dTrpvj zAR%*-eBC5}p+0Am=jvs>j=q0jS*35`Z6k>`BS@fAg4F0NCmkt+FmpJFAyt=;yq3bt z)v>9+0;w2Oy=p^hF!TYLnT|F)^%?+I8&m~~ad9}to1BGzmv%3l5iuq4_flqq6F6*e&Y5JR zd|Xbh9|XD}7~lqhK9>+=nB$r110>nM36?gg;{~$Ka5V^r>Ji83gsg21j$^8x;pCW4 zM7aqde%u!#@-8Es!d)P@M^!oHw6;yp()m_|sq!95lFo;95pg^8l@@q{WFbKY>s!7N z<`qqUxeM;5fv9a2PNd{GBJCAOAPGvd)_1zVL=U|6df|&PMNvsqnrzF7(V_+Pje$SO? zHb_};rQOqsw&!IBvJc34kQ%F0Xwy}2JfkUpur2qB6CBgV4l!qZE~lJ`DNEuZdc0wG zDVU3O{Z+GcxNa%zmDL$spPQahawVj)R<~*m2omL-%7t2e$6j@9j=EJ2dAlj zY;Z4pcXqmmdZ<(haF|%cCM4fAAgS~qLU4K7Ij3`)kO_GvBAmc@6qgQpy{&Y_bA7PB z+=bfd_Dbu{rGh6YFtEXHz(_&UJI#dlY0CGZc>kbmu*r_cl_OMlWK(Yuu1))HYtSWEXil&1W;lGSenF=VpFVxsD}k+e0=BT(1WIhZGeIs~%0ks=HSgX~pO<-maAhKb zYqI#dX|%c~6UwrB5#drSuNiS!?pkB+F(yk(@Y(DpI?YWf=%Grptx2k3x zYOT)2{C)jkcbDrEu@fnzR(doy|x!5wC^P#$mZqSO*z zu*&i5nF_tDvI<{x#L|>RaLd1(67+)$2t>!{XJ`cBr0_=jbg4k9oeqU$<^?Ce=0r%* zL4u(hf^c$!7XpcEnyKo7SWFPFWa@9>q&`cjL~S}r87Ds)KfehhsFj1T#^dv|3y@Hu z)CS`M)dMx$cNvg+tjTzP3s?3gUUj%&HP3+8pVb*}8|@$79^g6Ql*JCz9Uy&M*?QV& z(EI2<`{w>HsH6;dybE6{iq_s$k|kGbE=Rg_Ct1$)Rb7XmHMxZc2jnPKA>4H`uPaFb{ZW{)Ussa0c)1IHb{NdTF)1ObzE{?x>{_M0e3UdW~h}v>W zieB)2+c6^ogq2))uIqL)YuK&rA}fvupydJk{Xu1(E?GNkP_H;Ca4*Qq;j_Be+YW!b z`evJdW6Sl*n;uMQuDMz4VtrW47wFE2oRVC;=1H|H6rQ3$kn^M*=2+Bh!eU};*Fl_0 znGL($;;CIs!JPgh6!R!t8fZFv+I!k-K-@f|nuMq30DiPhY*hoS$_BX!fh&3LssJn0 z7-WSS0o^C>>QVdu<@bwl$1!qr=M2W;#kS#Aev7CYRbkXsnoy{cb^ zy`|a5Rld#5zv{5$u7V&T4tGyhd{tUYZoh5qpvxamf83oDzK32BAvujCl2a;d{HHO0 zb`^HE5M2<`+JRVcG3<6HR8I4eYNLy|suQrklFf_1f0HJFn9|h3jq^x_k57eQ}fEejIn7dmnoEe4fvy^4}fYe{1Bw z!NI{nzv}<%KYsim|9y&2W5{#O<+nnAGK4bP#RJ!i*TSbkbl`hvm;73ft=2C?5lzX= zGx}22m5FHYIYR8Fp!n7Hn?az_{CW0-dvWgBK8?5xGcr@e+iTi6`8B7U#Hf7^jX@b_ za~f-#teZu;*HJ{cq+>`j*|S_MjQpWN`=FDC2aFB~f5jqrN78i!$os zm~r7Dug`6Jm+r}Nb*j2#s<)V}I_)86On$tJvi{&x76&89Ypdqe5Pb-iq!Tz!qbcK} z7 z&E-#;LHd^0pnUYpK1xPloJJ%_=$NSa*?`5`1Z~;prsxuoQNp6@KwOi5n*f5dRFxG_ zq4>o$xjD9lm%!Eb@D-4BfpYCTrSJ|=pd_&XXVhE?@@poV2rvnlLS5=_=NBu1jB+mI zdNALpVrx0###cF%;*U3oJ+^VjRxs1IX+^LhqLCW3vT?bX>g_t;tyzgbNmB9x*+#jwV(2e z3@Yz8gzCBBx;5BkA065#hn~5<5&CSUAX%yR3GQlydl`FMT>)6ibJ*CbO1{d5?bGhD zvAKd#TfixCxhAz@m~(=t)H|NpMFiZQ=E#1K zyMiGqAL;Xbbf$z0oI*=7B_RrlaJtZdG#wycp(){HZ~LYFdrmt0M@@QKk)W4kJYBY{ zZaeeLp&5!(97ynzF7WruTfBL<{ z>iMtU;Nkq&r}>yIh5TAL9qo~?_Q~_Jb}bax9wTz*T<=s^@oa5m)QW(Wn#;>`tI$;O zp&>F!isI$*EmV}}^boa`rlbvab$=6%XH+P919Nw~C?UCjn*+J~Rk4XExx-c}h;u%Y+Wc>CUz-s>A?;Sm^<$pUoc;Nq^YVcd6kQM32oj!N>`gD+jrUfA#=*qySZiCk|I z)#{bpR|o52G12?qAlNs4LDcRio~3cds53Mx9YPX+KF0}=<40fiB|O_>t-CrXq7K0=j=Y1jFovcK(sr{ z6G`oV#gTg-hwE6)cm_BhIM1i$JOB`<#f@Np9{vGfel}C*XUcvyQ|D)xIzJa{^J6ok z=9Tc*f=B)3cg>`i;aQ zmcP0%F~z6;x@@K|RptsvIDpz@bE0n5_RL$F9%viiNuG)A&Z~puX8{LM2 z>nB20^{B8F0Z+_X!$59J*fQudd{^MR;eXxxh_tT)e;4BK6>bR_vI9PYxcr}gmb1(& z`C&qX zf~)5`sC~03ri{f)AT0p_J}&_WbvmexGjsP{321S~&Zl1x{WHd7#!~xBNG!=XPvG}0 znpCD|WC~R;>ft8w$Z}+c>Py@4Chb`%N@Le%Is^Lt65&wIkiEUii{?q7bEv7p<+K`&rOW|z zo&RhN4L^{@h9u}*YU@ZarTk^qw07-GFi|<7iLs_Etp(~Dv9+2d!v^+nGNEv^zv<%6 z7r7e3bnG;yiyE*k>+;ZBI5w##X-GtFX*Z#_*>3qdz%#U7I$re*00D| z0>s+&BEn@b!zrE+UPM;~5e~+j%_8*D^~Zp~)o7?!;uRX*h9xflK*tjdL~ zwStus)C+i9ZkP5Ci8gj~-5cLXUkf1y0^640%axYG)(406LNzz9X-Ua{+M(BoL$=8J z{S3J?knL{UwZY~)UB%-nt9#R;r8SOFg!Q?vd)y=p#I@UmE$2I0+~P4uN$ZDn&2;?M zf3NwK<;AZcmA&E7phC_2N^_d`M?~Vj*1xpIj8K4BW^+3X(Hqo0dG+l0@>$zhjqCa; zJgWfL&+D42QXuub5vGiPh?v^5+in&>ei1=q@@zZ?{ln&-liEw-js!1dOyz>!QD}XG z+2^$XY-j(wT@2uw{Lj6|hey@>KlTqE@;`r)&vN^pN$mV(<)AB1$B&zduC#{lB^})g zi1(P2ZWWe4VPd+5o&SqSPxpn&lJ{aq`rW0ftF`hElPfNolIU800;N{9YB+XZ_T z`b%i9Fb==Lf}CSHMeU`YzxE!`Ev9&IcqH;!Ise8VJ~183@UJ-ubaEHeesXZI-(FGt zQ{}O1)NdZL**#>lyQge+O@h}7thdZ*w{Z@Y`m0bU?fR0^svI2bcb-0dde~l>7A0eG zk-q^)5y>Pn8Z?rBTybK@m4r`HHb~`R)f_c7!@d`XLbUWX2tJ3 z+u7Dh&L9~XCy+->^@w1p11K5Fa_Q$k)2RY)@B*=kGAy|0ab_786l@SJeUVh8FDkiM;KU2QbzeRN6u&y~upQ4XmkblV{5T7~mAu;Y)H zyDezovYTa@TN*)!9#X>nUQ@!|;rhQncP#Eb`T906#)B>XKJSgJ^=R$Jz=l58+KkoC z{Hp^ih2MX+O9US#wJ^vvMe_#cto#oZGW7pod2s~?Hb`Vbcqmg zl1*_Xas%uQBsLN*z#pQvaqU?zZF{>67oX{`ShH;2(Ne@!Is2qRN#c`=Q7u3(pI!cZeEQ<- zrTg{j`0oV;h5&s}{3&Ny9fCH!O_`7{wLPO~hI)8*eo}sLes)?s5ac;c^LKiZ@I28P z(y=&B7cJig*J{x8s%^9YUgSc)@=SZKF7fVvRjA>rc6wo&yA^Kz45t&~@{7!9Iz;_m z&swc#_#K#PpFVwhD-uPXWeL%a2NSou5hZJz;*r|-X+1hT+&^q2)z(;1+QmBiz4~R7 z>S@`YY7D<%wVhH9KeXQ3GEP7xD?p~(0LAPky}>*_K0niMb^3jh%AWxANrLGNHiwOW z&#>yv08UM=5K2Y%G4c?7zT@4G^p^OjgB}%!j2~6c7C*{ZY_~3Z{mCQ$c=4lLkWwwZ zd%@UjwRhff$n1&bKj_F+kN7s8?bR*ZJc2G(t!0OO$28LD=Yfk>pdm&Ql0%9qD)KnxX z$wMuA61KwAi=Qtfgd2}GZUw%G! z-)YEVg{eu&F)K^NE6(?;oMvya?>J85;0DO{^{#D{CZu9Iw>z@J3?{^pe#3GK0Cr)H z({6le@u!ub2nCrp01W%snCibUNxn}ke>2V+Kb|MZT)){K#1U8a=8i(?Tua;Hnx+c4KGpbesdCeUN4gAfi!MM^OM4N%=$QG@4`G(^gS15+Ju z+*Cu{LW0>D!GNU?opIra99d&Sd1ps_xz-dP<}qf|FTbbVH7jz?3z=Y)DUxtWi)U=b zD_8?nl#qd`d(!w7KCs3n)1}faX!g!Q!LS06*cG1oS8zgvPLtM43UNjW5YHeDGb?rG zc3l&|f=+s%CG5P()mrgmQ^c0mTs0+(q4l^qQPS0f>CWiY$@yi<^iFfAb^H@#h%SPB zHGJ#=I@$3%(sJHH*?PYzV#!Rc;SOCQl8M~Scm4BMQTE89h-U5>cl}+|4CAOph6#-jTa=*B$;A3ao_K{Ww_YPu5XP80%zpsgu@S6q-WnceamPAeGXp^ zdJUxAUygF9Yg^E@!x^u*+S-e;k4t`!NQW0n@LS+f*z)U+@Qvj81ENwB($x;Rd>haU z9?CgbIyp$@g8_3Kq4)DSrP3n0Y6yaNXLx7~0Th4Dmc;5*v(R+CSjGb1PN+j17s?+- z@f=(15e34-!eKU08ST)TCb7+I`f}niwaiN@Ih8gZ$`QTtUrN|RsfuW14TP0;tvprC zE!{~qoI%l(<8$j#fnWG2Ro}=}9Y_`k9X}n{-&_QYNDO+_knTnUxt66QDE{h7X2q8y zYA@!d!9hrt4;uW6#N^P?w{56OqrdrVOCmawkS-F%7Z)C&d_qD(YYN_MX_V8*Uw4(z zK+$WBMBzDGYt_+^^{q;m8TAt&L_reH;AgTWZsTGXPbCGF1i(28CAj`-(Sgw?hyPpl z)%%T5ZcT61sKcn%za01vw78@KoF!Wfg6BW@GhOHG+ZFq_{einDlHAnq6j&%qj9q4p zlMO;_LDYi!4)Q#yh%h^wzCB9?{-Ui7`7DDDezsscBWA+lVYU@z)a1%i+eqkpup4^v z->sJ|w6(P(ftnO5_|Q^|X$BFg<0P2IV(Ql4=fnofX&PaCiYUisuvp7pQ$rA!1#y7Q|-d zDvFZgpdE5oI;WE5GX-4V!KItVn&oeV1y0)j@o7Rs0=|S_q43n*bX&7iOtnmQ;NjmX zbTCr#n8aG5iGp=0?7>J-qGJ)2=5ZQLP8|H0HF~ywMwodO=h#_CjtLiN-zd5>YEF5$ z)^=G|x=CeRNA4k!(jwfyKC7dxxe;deMSV!ZOzKk6=@jT5y&sBN6OGrlzNRB+W}TS^ zR4Xu~04l{2q(9}NvF5b=%h^hXEy5r~I$DksWPtA!Y@P~-G{qOP>sIEX$Mwk-p(seuwTlsk=T0G4;>=Y%NQ@} zLho`M$59fLVLe)VeSQL(@EnKa0jW)6mmq~AvNlPQK119N)Waw4uEFDP|PL5k#6WPdJFFSJLKLjzBK|Q!9){^g)Q5?&vW~K~dlTB(3#`1VBy7Io#7e9+vC)G z1a1$-qe%dEd7FDD=4I*SV{Ns39;Ck{YM%FF_;nTTRsV+Uq5_Lg-XTz=rhlb>V=nFS2-p|B09k0et* z#&^C1d%tfc>^A$tYUO#5qb^LzE~=b8y4+fCHPw1w*lR*gzg%%DV?ItHf$Uk>*EFl` zL><7+A@UX;fQk=QWI1^MQ$}_W=oe!=BIqx{%@h#?3Wglui9J-;pc+y$7@LGySULT@ zBm|an;+`?vw^h?jC`Y=$4xAWF`dW@Qw3Y5rxE$|4;~>3QQ8#H@*t}weoGKp3OEJ-h~lQVFS1g-|7p#yO^Oa& z{WN>sh^KKpqU=j*7T)w*5Z3w!vucd1?Fn?4N^L?ClsV=M;;IbWJu{3p7{L@#BHm?4 z$2`1M5X57f4Nu7jNzMIo@F8mb+hl7!*)%%urLNcjmsk-bdH5gF6xH=#fpdJY?vCN-fQI1n-kt6SE|zbw(EvD| zMWjHW@tV-l%>kC+IwvpX@?k^>WoUOYBTfc?)uF>ADbD`xRa(rM=@-@xbAAp4=i0V9 zoj06OQeD7q8C_KRZ*~7TVpB|u$u|Ga<-4KUySwe9D)fr|umzVF-FJ)IBu-{$K2?J4 zjjgKXhM0enGNI|qJ|;l!Yfp}W*5V@7h8>7N%KAF_(|Hr-RlCFzv{tEBrP*H} zG+m1bZ31e?dl}s1VvOt7+Z7Q=^AeWCdBFa%=$x$MEwHNP4z%E+WhvklXrBax51kK) zHvrb6sx2-7OOMm+8iTj}DEi8V%<>AAakz@rlv_V^Oi`kCi#Tk*x5u0imWkk!B$Ok_ ziUbLye}3HDba3%=@YfQn+Qk*?58?j()km1hd6<22gQT2ZGFC2U()!iNl|mw}v7yFP zq-kg;CI2en;l9J9i9%@eAz7S#^U5auuf8T7!mb=bqEbgZ%!-u*0^cb{Z8mNXG8WvC zQG_hs9>(1NXAA1DhRs}THaP#jmIReE$$cv&>X}py*yjqw+T@NhXS&`i@gq+j2IU22 z6=)pp6zPzuA+p505nwJnBN%h2c@Le*lxPgI@|jhC=KiY_;#(R%SLVZa1hf1nnrHz= zJWJ`cPvf5-uQEf-7pb+)3<=aRNn_DA!8E_*Gw>E0g2|1g{3z;FXL=As`39vj$n!^~ z-Pw#5ma;w+;(XG2-aNvv`P|jRU%kB!)N;(#W7)=Kb#=S43+R7%aj9&vbW}1^&Db|u z00H-!@0W;^w8i1_^jFh*Jj&I!9lHoTlH!!Dyxqkf9QawVqY%*c8y*@U40N4GbgP5B zVYG?&B%5~;^Ne>O;u)!jLiYEDodmziN(m?bvcA;9qIb{NmrS%x}S6kRF zfAk0^{Eu1Yt8jVxE#rTACBaE`1fB;*ZG3Sb=8j^Q9jEt1rE@YZo+e#lZrRhO{uqcXaS^!<* z90>Apunc0(uWBCfP`d@*3U%fPPuG&&phTTgP>ov$N($QqUWj2(#PXIfxl=Kcye-$? zM@*35q*bbS*$?0)fAf%o8EqRBR}~V^75$_kOEsRAL{nkak0y*cJzEbSY#^%q>Z)Mj z1~Rkaomcxw8O)%LuVNy5{^VHkkxV@!1pXhGOSwI5^*-jq7G!0*#Tv-4-wR=i6&mh` z7-Pa9P_UP?bb2pD*4j%n8MQAtP4bTTfg?zCj=Om9`Js6$wF4?G-8oN{s>wD&Y=w_R zo2`=&FUoS|fnpYD%hH?B=)3gy_qA4FHuJ${zntLHzk$ZnqZfWXE!$R@M zWHXVR;ZuowUc-~c>~}S96)27&B@c{ol0!OoQY-Uz=HvB?-<09+)PtS^Ei^a`Gx$_Z z3EgvbSCZX%kvjGIM@PWK4_Ug=*j;MlsE|UW5hEgJ{>1;XO)>nanHzZb)f0<(!IniN zf3*vEnak|q1U66{&J;dhQfc{#!VFK7LHT?@o9Byn1tee}Wtd_xXbOXlHNw$KpF7W9 zyqkn+d0lMFOf*nf8gSL;@a#8*{S^&gQf`4F&Pvr=UxW8W;C4Kjz>IAcurO>Bg7hZ6 z-(W;^QD<$~QP1@{&F>&|R@*9x9I0xk-1LxH(^>V(nD|dRActVbk7;NoJx?}VJ+0Lb zlnJswW&GZ=QMQdee=EH=g31uAbl#e*SanKeQ9pC5X)W_YZqCaBe30Yc=F8$DDFM%-A9Lm`0x$ zKl@E~W1AUCm5Et~P9_5E#<*FY^1Fj9ByE=E0r)Q~0lnfW?7GW!!aNd7D@zjL=HefF zNh9g>Yl-f)pw47FR$?8`5XIV6R?dQ@i-zESn`+>FQPdMP7C%h?SRK}uS?m^!+rkc0 z{FfW_M^GK(r}_Ao$TBDH|A9mtNKitD*b!1tk%qG z%6*fE+5*tnu>l)rEG|~Z3Xk9D5jz&4QlqUc`RjW2(OpsYNhXgkqQXuJ0Xs{^;m2@XJQO7 zYgc!|P`p)N#3#|($T=Oi7D{HmA?qS4R{dmtAD>0GD-67L8&Y>!sSI*0J)JqUUn(f_ z@KlglG9sl6t{ydeIny43(JG@`?Pt4OTQZu#Z#pfl+t@huO%=%7FxT7_@K^@CNA}cL zFB!_qf47M!MYRyQEvyEch=D|FT$y6!)+ zxlocOcVAu;BrF<|2jWiF_{z0r*Claa$rsVgay<8(+TDjQNb{8V|4`>YscL&k!4w7* z3-GGHc(*z#oX_)ByVjLa;O_zPd_kTHc)OL52~%U&A0T;Q_qAWyAED+$ZqU=%^U}Ny zgoWQEe$J8tu5>riM+X|n!XmB~62Vkfr%U{OVE=WV_eprIlZq_U zQ4huwel@BdQLTrhBhX7dMdl>U7?Oq<&OA#qFH9Dxt>5mltJF&o7Tt>_1>c`xFNN;x zK|qUW+R7`LX)3}7hD8Lpqss^i|1GI8R`kWc|KZWOl8-P8PdSY9RB6?Qy?S|iAerYR zyIjJFcW0SE?Ldf*AYAla`&ja(Y8)9I@drvU^gDEL&jj9!@l~ct1)fp#!Q$8&2E3C& z936-ezT(P5y3M3)N|6J(`aql_@o&;_b)EQ^k17on05x0h+CuNg( z!g^kOdO6d7=@e+N#oBO$;1jit!N~h}k6RXdNk{!=bhk#`cDV}TK-JG+=ujH0cHvol z5v6f2sgCV>QY@*YKIrgk!g$<90SB{Ya^!~-0n9vFQC{dgMOBv&L+-Wpq}lAU(JZCb zR2zm{*5-+0QIQD%_sF0X)Ur zWBNG_8e(`*EnJYD&*M4MIbBfCqr!0BL<-p>N({;_%+`>Rbwg!B9acKH46lchStxEz zCGYg>fg;U96#p<+k1CuLwicL-!VaW(IgeWo-IPkuQm6qqG!O0F#7TvO#knO)Qcf~u z6z$yXFJk2=^agp}jV-bsRHh9c+%xiU3EA&N{2*ikR=Z31jbsGm=^#)8S4k=zdtF87 zY+8sqc+MUud|UZ=6NqQpDC~0=k~kY$u=UpyNh!66mkAyC^=c&bVDY zTcRD^mg7jq0}&F71gV3tc9e7%4P}4z)j}qx^{w%J-doQ9fRc4`tcD;meS*qn0hB!M6vU_29O|+{tfPPtS(GHjB~W{Q{#cUUlU*e9#PI{ajWf@ zwu0=U?XYg=`y43teK7MX0SmAl#J|wYRA)3j9%*_7XOH~!@TF&}EMzhn8Nty}^0m#5 zvo;vzDk{Tj>iHKBq$nBk1D2U(NMx=WfvY{H>gGtZhuBBX;Rr2t>V6vyL{ zp{a4AE!wrw7{2!8!39@r@2iFS?;FGwy75b+Mi|PyUIxXtnm}S$f^==>FGm<*-}Nx5 z0L`3=LOYvTaiBCao(p%FzL3npRS))rYqTm%K&nSRdHw= zVIJpT&#^DekH7lQ>|c(mdQxE+yjFoht(J*UbpY7R~iY6UY#I(R6 z##j{`5YT}ZnhACdx5buZ1DaZn3TP6dFP9uGjL(K@UVvV%fOJBZ@nHxSU@b!|c*rWU zHn`%FJf+jg|CQb#!zq8CiVr0E%#3rM4Q*^drO2r|Bh4AlE-&&OQold=zxp@`UpS*( zAxU?p>#lF1fv6w_7c$qd_)55nC3`O7qeiYMcFzm-V+Tm{)6Mj>TT%!J(fBT3yDaA4 zSMzJhPVUE+X}KJOK!}Ng<~H~By5Oqi*EsPt7x+G>KjVcgPcDChv0qeMFDr#iN8DV2 zRuxgGO?4~5uCP-*ek>*XR zTsR=C!txL^k4Rg?XkUeo-#oZwk#b|Ul8TPxIg_FtQ{df!f*C$RCUlhZHu)`PQR+sE zpk&F+Y!hL{ag3-Uab0o{yX(aTmz#hYZmEIfHOT|K>nnC;N|F5PvS7^5wEEYUHxoh7BIq~#br zJ{w)E;LfN3i$T;&y%7F<*u#r5s^eE9ZiqlomkBirR~ufTuh7y5e$0EP#wk`Bz@oz*Hd|0s%n>s)qyW5QATjX;%nYl|T;~ zG;faF9K;zypFA10&@rAOWpSj<-p)g2=I2UzOHhiPL00D`Py>UBhV>D}?=sbQLBb{U(l1m~@~ zX9cXs5tFtAN*h28%=*y)Y^Jl7v@Tbq@3$Ut5_lb7HU^%tM!u+BGwo^VQ&km)I&oDw znX%y+SKTL2G26l=r`E&lz0@)bhDG-F=A?NkbN=op)Z{9y9|E3{#ITH|6pm&V>-I2Q~t@)p#ozu^=F?y_# z;;PAm$f_OoUNBp3Oq)WkhjG|mm&mnu40|Vcs8cBT)LEH7;zK@%9YCUMd3}+7=!;C6 z{to$CG1;s%z72w1;?;LrLo5F!31$XhBkEQl*EHB^5$e>dmZlYwfGZ4Qk&P;rzBl~4 ze~T}|;^NV8!6P!qkxat+rbxNR3%UF;E(`O~-pW5ib;Vm9asG5!xi~mz{O$8S&uf!+yZdr?#fl$7)mIEiGRw^U z&3H(Tm$H2=ujrYKXy!(&OjY&vzG#nLlcI8m*b_&p5)n#Ap;V}44{?`!`ga5&JQ?(b#Vc&WVdz;v2EHW^qPD; zP!I)8YC{CZbmVhr%x^6QHdIu4L&Ee5AVi+geLwK)a4QklV>#F@G?3>~#Gy2<6lXeF zKu~=)186ATT8}mo6tLx*!8JNsQ(CV;)g%x%>YPVO-jTZ$uevh*{yl5LzOI3u-&S)7 z?cHSs-jIUlOZWHkC%@A=G~%C*@cP#zYV#1;0Ux-P{s9-9tfr zn|8_h(~g+F>Z4P+jU-l(kwSY%voFMRFczsM$2|)MO+&K;m1OO}%w6^xm(IqUMOE1{ zJ0nw~v_iznp~2{y>^f#ooZWlklNk~rX3B#;~r6&iHi+?N1TFSX9 zZlMYM&W^Q^p&%44s{GhCuI)FyK}_5|1m_)dp(X!v0&W)^7@<3~9+ce5UMnx)CRCm6 zWI*U*JaMz?T53NSa`+rJGt5qX)IzE}$|!>!3?;9~X3Ap@;nLeMWpGW_u8i@|(3S-Y z$kkwS@KZXqs5yN`N8FyQBWTS)`ZDUn_adEVtK@EZRK1}QG`<~T%eD2^aj)la^;1+s zlHGK#@Qw|CI^TA<#e90WRrCP+n~8X~OS1|nuPxM<<*lM}_WYopo&y?|S{Ut%Pojs{ zzX9E&d*9vd2|L@r{*@mtZCmlY2rT* zd*)*Lq?eWbaSIU0Hhx4?xbC_$pUaLP88!%EwLb#wPRpN{hbxVrrt5&_QEvp5E*$0Y zr*nB`?PsIxnrZOI)>!=t2-KuDf!~vbt`DxzT^&NiUoqO@Wh-V7Kg3CWOu=HYb2StX zn9Rn*7dU5;i0%uZU>j+eLj5~z(3H89eoGiF1Xtt2En7deT zCPPMRI?`v7yZpu*pOJN9X%5gQh`ecSU)dfPFZ&D#Yv(mH%TnMN?6-jnf*fXY4zpR= z7zIQHYIBE{j1$*Li|fILHnZ{s?fqCnyrIl*-nld5yXWlgW^pd=udVvi-nA^u!>8_j z%lMSI{v(@(e(J~RCoewZpTKpLjS0i1F`fzGoVTEm_XxQWQzqKK`eQ!(?8IWCG8lWK zzt5ON#gUnnF|}+3QEM9Zs!wR9J<-1U7}!?ulonFhI#jw~mMTLlCizB|IpaUo#%yam zJ}b0` zOu|!zk%pS^2tSZw6x!*n))PsIod=2k{LUbp>pVaQBJep0A3H@y8uBV55Mo1A1s>7k z<+&1F_+>oZce|*JA2$}ng=}$9#d9~ezHn!7hu$7TGe`G;;o27Qulf~<5l>}e02tWW zaM26Ifp~%?kP>~na~Hg%p6WyT9lq2YK{KWUUdb+P_6!HzWq*2y@_Rg-5awJ} zo(;!+jMFoR?1+>7`ZueJC~bWj#`}B5d-v^I^sYWn`bV`>QvGLU(;C$Krw;!9yoBGD zemvxzZG>jkx7d5JYl<=h0R-{XN>i6G>ZQjh$PH=Z+Y){znxTaQgms+OQZVDBN ziTmviutWO#69xjXW*~kZCnUeMX*fc4Z9%LRg?*Vy|JjSTJ_p7(nNlKXZ@GCEc;Txa z!Hur*t;V05{sL8uCoogN(T|Y38@(rllfdR$Bip&;@)3>0xOBaHaqMf3k1-E^Cy+2=wHO6k&^7TUnA!ec=`!Oam5x$FA}ESOT0wNL}pk~?tOYY7COBHEzWnW zyPJInF-iS3%-LB40e?tcKT%2_W!>@K2F6}~f2z~#hdYq0dCvzE&!pMdx?IPVLXlnr zUmr%S8m%9G`5CdJW}-62aUwz(U?Fn+r)IuX3NeV&#>g~>t4^p`SW-1K*XtZ={I>sI zGY%{UV{7`2CgopKPYmDSdEeDNvcMY}QGxOH?c*&bOT|pK~ zeT8OLsJ?6IhgB@3=*L8DD-*UR*pTo8kwos!6;^*cq}^LeL>SRF{j$o<&IEN5a(Xkc zypLGTuy;4@Nx+40EKBpAl3@m&Bp%J=!K5J$VR49;sv+J{~x zQ!4xZaiu0If_Z>((A_4$>T!ixu>y0j!{}Wp+hLou8!jj;gP(&PR+HK{vhdhQQ-H~o z0?}?Hv-9nr0kjK>PBOJun?@n2an(hV(I*nGUU@x=i zhF~2uKQt|sq!Lxi6WA!dj5qhVGnxx-$Ld28JnWxFxn;RN`HDYXUf=3~#M{p<_M^|o zTk)mM+4Ah^`&c*QXBm^?fo*T{DsXG+`jS+msY!;y7lIAUdU;OWQ!4EF8L`y4B5ZMN zJ~SaHJ(tD@;;~?}$WAEjPJyD};=)9A@sX;R*W1<)M)@$hBbnyr%`espAi)=Dbw zr>#_1i-?=?v!~eV&U_H%)0%o&>P(;6cIQ0Rb?L@?@EF{;KTO-_w4d(Wddvi=mDbAh zQ$T0I^-4yZCA@G2}INbpS>@Etg{dnR~073ya0``ys}iWws5WrhQtZsPRd*i9d9A z8Lw44+rxy3w}e9nOUnZ;tj`3pHc?pH@u@j@7$J-{)kWy_O-(AK}=cvZybo}N}jL9ud?qj{DVnvbYK zt;Ixn7Pk-cW-(%)cR4BkXBi;Ih=R%v4BXjP&bF=5yw2hZM$Kx=v04ZlQhrh$x0Yeh z)#qr(*4BNjE-DKuQxM!IQ!SY%L{%&9Ft5iW;7E>$|p$l=TmgrFC97_wd4xw&H$ZjEi(Nz5fSu4h<;S5F~gFIQh>B~P5gR}{?%fce*VB_ zf|9|&kLaF44wF;wBlCYgzyHy`gH8O;t_xsz)~fF&Q_m8|RTCekEOA zcJ*$6?R-o)^CX6NA@n3tE4!DGqAcHn#fUuQEp=etfmylum{-jIU=c=ZlX9aRDF2vn zd}!P1K1P7LEO;mKnF##7;WYfK zbEb$8jbWguWr@zlW^S~*>XvU)9xrouRf$Wy)Wmu)&qy0JU7B!nX#f*EkH#t=B(Cm= z;Bwj8PQ@w%RXjo@gbAG}DdjL8K&BY^yhmf`-l8f3Zz>=@akR0_K{)kHy zmk8h*JbpSi;yl&S_2R>pZMmAUi9r#XhLbzcC4IA?4#1t3pTsv@Y z;fNDk7O&JW+LNc+)_cARxNt)s5NQ;KF$o(-?4_}P1RBa#R``G~*oI&eh@>%OwebGU ztxZ)8_l)IaGv_wqn5Vm@-S?09LGHGt=G)Lkx;uoftJ@D{{$%uKkJ@n?z^qnija9K( zgr@+NH4sV2gU2e0%a3xz_I+D)$TwsiQrhHv`wAhvruoA6)U1F-sFkNE_ z(ifk~p?m>(Pe*(o&7oIFjD%tga)u^Z4-x+dk;!Z>bEC7O!-1Tt1`&Y~emyIGq*QT% zkY<#Kz+A=e%lRB$CM2@6=9p_I5}aRtVe7n+$fBjyU{G#C?zbYvWK9Ub0QvJ z{5-5uQc^-cpuSiK&(y&T5H?rhOEjU+R@e&g(srv`x z5WeD)Yut~6*;bNfe9>$yxd4n7>3Ay8H(f5PkMje4&B|u^BrOm~!9F z!hzK+)T${R?pv(<`4CVcNS=wkhwE#OA9=Gj^WE1FtUsOhKCF>O!}+zZM42?6SvC#Y zt2$(-_yj8MWT%yjSo?0ygII`S3(XU}Ass5#=}#*Sx2RFz4CgZNIt*E^5$v|CP^uCs zN<}-tV>(?2%o#&pBfH7K_*&iEcz~|_B+EwI4oJQ&a3w30cW?c1kFI+r#qiIO)ZWl^ zYt0_mW3IPcD)r`|JhjV^OtzV&zl4z@*BwPu`vq>fO?sL+S*#Cv$a_M2*y>=$w_E@= ziV#h~l3K!^7SpSZ-R!8@g6Xf2fIO5Otka}gx+Dw%bga{1j2MRw2qxCS(z9Ii&C#t<${tFL#`HO~B^-?WRcGNkCb9kn^-sL5Gu-*=esf{U zLyX|E>|>*qssLl~tL_bOL_(bFINi|vp>|C1A%eO!&Q$H)~Raigf zj#r+EKKj3|d`pgkv_rJQq}hQDN@5F@GovLu>L{pxBVq8x2bdXNM;V74XOm53rMT3V zT&)sN@WaSHGO2%i=33Id$8Q-&_E!`@-@JZlkZLA_6e(K@M}8NqY;UcMWkOpY68LCo zCMwXkNQ_$2<}H%4glzp(i#1qhc>5I+p2n1T$Arx+bm*4GEOb|oeeXtc^46M_xeo+z zW8N%pqpAALzHf<8H-B0-A>4cwn^Yg!^Mg`RlJrXKBD04BuI?dkkHxOe*`HtY`4AWc zIIWF$fv?i^$7^@z*YZzyEiR#UCAE~fXU%#{Eh9Yb+I`^rY>wM^95))&qp>G?#Wsid zsjRyC%@vaizo?o#=gBF0y6)ea&mUdokB59*QviON2L_Uy`-i3Jb+_!=xzHE7$X#~- ziN8tr^=G4-D(Bd0iX*DNEImfqCV=`>IYgy#{7(^D+2C#bMqaX_?Ps%9(o-E@Skg8+ z*mp9$V${*_ZGZd#sw+XAHS}AfwNXsi=4%mk;y@-@CgSHWsw1h!LhwSFHcc$RMe+&x z40f(lo|K3uzNqwa0aMW8M!-wFgCQ}QVj(|C7_ALo@FI+ zO-Y0)QcewJw;Fe?bF{wwt=OdKaNyIDCB5~jy3+q`Yf2IGa}X5|uU)*ZhC~?oUMq~d z+b^nJ$EgRWY-S{Ai<*HzqP{A}2%G44!bhx#$OI|^Yu|_%)-*K^tp!F3gFFM9IrjQS z^a`OeJ3AJ&anD&+Oqv(jJx~maDypE5ZBj)8iTX?y674&Nuu|JU!iHfwLB8!`5XJxc zoo0q};LHMU%(xN{ zqg^Qhd^4#^pIQhoOypc>>4`IGlX&PrIW90&vqnK)R~Hu0C>(2D-YPHW&5P3`#%F?BTWbF4`YEGV z!8(z&^7d?mB?5ZEjD2CD|E~~^CwTLBTVn>K)z!c^Y0DN~xKZiO_fIIXANZaej}^l} zPj_V{;v)0J^6^aDDKu@)53C55PUF8PbbTwnEadlqtO{Sh0P8mw+WLj0XPuTAdoRmX zvxO^p*XWpAOA?t)=#@^y_3dX1fE}rJ_l*tXr^b2S>t{37?I(@pr)4Jo!KZiD1bNmZ zfANM*U5XQ@!<~Ys3t^KGo1VKsJhi`yed!Zf@}Ci5x*{|lh#JyRG>FTa1|`a5Ge~et z(BP_WTC8s7Hb3tGig6JqO`fA2d(Af2ws6jF!JlC`SC1Fl{SK}OQ(v&&2OkK?=cki< L9yQ1n7|8zt$kMMM delta 30369 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

O3i^zG$y>p$l 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 literal 0 HcmV?d00001 diff --git a/assets/linkerd/linkerd-crds-2024.8.3.tgz b/assets/linkerd/linkerd-crds-2024.8.3.tgz new file mode 100644 index 0000000000000000000000000000000000000000..a0fb54c4510ac6091f9e232732d792887222e75e GIT binary patch literal 112983 zcmV)`Kz_d;iwG0|00000|0w_~VMtOiV@ORlOnEsqVl!4SWK%V1T2nbTPgYhoO;>Dc zVQyr3R8em|NM&qo0POwUk{h{|FN*tGPl3&u*(%9J)`!$;ckMmf|FXJ!S~1;fg(SCQ zZ`0!fGeHugWFnnNR*CNE9sk>NbFR+)dAIWf=Mhd|EdYs3=Enk6r5VQ%5e}QFP^=4_N$BMFJ3&q zym-ec}*rlv;XJ+|9`PNS*=;FSfWzF zk~Pm)f|cSgTUm;9#vVUfD>ImNRTcW`?95KXOsYpRG5xZ`;aZDIpPAqESvXg-B40iF zAa-}EOkr~D$EO>i*N@DS{M5N38!q#T%UqQ3me_EaU9lujmQzPQ6}SJtOzKL{%+IDv zj5W6c-&Si?nyKBES=S)W9(Am)R@*Ycm2_{cWVPNdW{KLkm)-wgo;|8|g}7q8C^DJA zu72bf^78!h`Rq5dXOI59kKBK#*1`WXm3+9@Z;bH&^JkZrd;I_Tk^g^|b`Zau4RK1j z61uu#dd)AtcyaX`@%(c6Rq|E(oL{ENZ+`P^dGY1)tLN#9^XJc#ufF`^;x~y%FTUdG z`B#^h%jaJ%e)HvvbMgGki)UXvd-2tRKU#@gl)N(c&*bv_@?v`ao9V@u?=Q};o?l*l zaXEW&asK@ISC?OWF+Km{>im3iJl;{QasF?4wiWu`1;DZMe}4I8>-;}IzdS#l|Ig7x z&KH^ZuBwW+YFi0?#j0{Ej)&+!OKY6}N^FXZS3;k?{_*`c?`GA<>OQ_PcK)AVwDrF) zE?+!5p8wC$-mgVN;%1-cRF%wEQ?ve+ zNYDOr^1Pn&zv7j+h(v{9iu% z^7--nf0p+1&r>FsZ1xk1er<7p{qoDB>2%t#vhYHRkCn*He`&id&TcOreUN#2#a?c8 zr8aK`YVKc)rOYKL;u}%%lvn)f5o0Z@6EifYyeLX_E7IAA?Lw5fFk4Kjt1iXAeqyTS z%5T>xFXUOV&9bwLuP&bf;ogmWw%F!r78s#!&u3rGE=FET);!NecE!ZULX>hN@``8h z&d)zHnJ3vc6>Q?PqggP{SyBq4#!MHx37eUDWh~| zl-udSKi^*PtXT6)9DcGE8-8VY1N#xfNXpE%-nU&8GShe;?0F^uPd&mn^C)*>QQ*gH`gGEA@4HZvM|ek;m~l_F8AT>jP5){dux%2%~$f|O&f zNiYhd7jwgRtQ6)eY?}x4tlgOXfXe@}DYSdpS#37kTvj_2O66i(sZyV%;#Op5TCS$N zOxCgzNwqD-nb8QK>p6-DY>N#m%b zLd()@=89Ls907kH%oPpN5MNN@k4EdhJE-FJWkTU5)MMlH_r6_@$md16*XGra^w zz)GwjoQllsARdU0m2&c_7lwqcW*tO9+J-ONiFy0&OLlQ_`3yUYyxDLF-&f>~mxl2h zZNG!2_-NQFs6U1WUd-65H=6NMz-7UWjAl09<&0g|RLy2z7$re0HR`Fzw%1YRU z8T(cloq?MxaDStM(EF5K*IkB5zA+qqX5X46YIEb}C|EAoG946s*R0~O=C^_gX$FtN zf}cg6*BYBXHQJbYwu5BwN;qk1+0|23vYV%kpSt#a$Dp5*MjVW+=pr~NLYo4d4>}H>E<9oTN z9Bng0NV&d4Nh?ZWq)HB~c)MK6k8X7DVP*x--RCS@UhZ$J zE*1qN!Z%>f_GcMop_`>rv;DtykTklnnWDywI{pOT=w~_O=P5XTW^V>>HfKFm^*Z$| z|K1k#oKCKC1uN;`BvHAR zsVF;pX?6&A+lanAgClP&k2xy23MEKzD>Qk1AN|YO!*W1I}5<956y?AQYRF$bHuTa1+dq`!e(3PE@1=k{FD)(*! zRyp%@_ib$`;HxOmfuj}#HkmW9Q7=R#6Q1FBO>gIupS^qcmoxbHFHOUMYx5lFqjD-z z`yn_aU3)rd?ddKK>v#EM*yWEqcX`jAc1D8^x-V5JCVRijN^CmRkUmAkY#mri@Xh~a z%QIx1soHRvgXJGZe(QJXAdGu*cBuN$Nztnm2PqJpBwI>Fvr`fQJe7g~)Odw8#C*br^C3`%5Y>ichBm{Su z|Li0x^3>Z2yGhR2Yh~GgvCWfei>%H}tlh(1n_$B~elPM>wZ3APUp(u2K<4g&i;h1R zysAW*U$K8VnLnM+p8WQYeEQe(=~sU``Qz07>#6(c$!|~Qv%$YVdHVNVdQP{=#t+~X za3pr|V(*VO#=b0hTO%)k555)4QH#nO|0FBLQj{W3gtK&5BOg22>Mb|?%{s;OlRkCL z$q#ot2TNH?pPmKV5kFzSnA#q9NkY!xmkW^sO>R9?QrE_9_y%~W@S`pys_R@B(bSt*-?iXxXn_vwFHS6Mv97iY9efl)D>Mp6&4OYH7#qN7-kqnNQ4hHJ^C@ zfYh$5_U5>L^UCpP@7I)l`sH$4ZA&nCIC_CQ7R-treS<)>wc#Tw?^Ie*Mni8R5J9mL zIxF*Ao=Ff4{i=gUCKWjf8@)SVqe|E_Ia9frMkLrlZnMoQS!9BxQdcrhDrUvOF7ra* z>(#)0n}a>|gT3@}tadMPKlj}d5caT8T1#^WgJH4YC9g!b8|*LIVtcJ2c6}3-WxUWR zNbWg%Te_iEo3tqh)i762}Y@by`xWubBr$O zo4t;Un<#|)g|_DjdC5|mp60+1tw+dRV4bpuKg>_;c0uW~Hc&9`m_zLYw0F`7Vc6zY z8Xn^M-8{aNXawKi=knd%Byj$k8+vPiyUsdk26GS6-$J-^U{$wlt1D6dH@tF7wJl)Z zfhW+s&`ES*HqFW~pi;CcSxGkjbCEsS%a9~~ci;a*j z7`x?@@Iil#;y9`q`@>q~Y@2)IR+niL+kDd7oB0H9VZ$yA*L<&hJVBy5t-ILFN@BlG z+!jFV+Bq;NxRE=)*ahv?yE4S;^ojDIPnZJe5Dx*GWECR z$&a9=xxi!ngs?C#`qpJcKVyxhGmCIN{atQut&Wk<{)ehL9tKFYfF$| zzv(5}5-kHka!6e4ai?KBSZM5}*j$Nm(Q%B&ux^o(BtZ6(91$!DV&u@eH~8FVi%7h5^?D6P300#a<;1-5MWW=6{40P zdr3OU5}4s1oWrFp7K7Q;Zbr)pY=3(R^DOgTCT;&^_PFg{?cB5z!7EfKha_a?0;Sz1 zgsD40I1vaKsweb`naRf(%UOya0A=dm>sxl0l8949G z2ACvN;_wro3xWo>mIf{(9zB7C;ExEMgTlYYUNb$)569x)AJ7P zFR%NY3e0NC4R&v@P4hnV)N*&6>L7r1SilS-2kKdK@sS+?%|BfKPip`fTq|oXvzF+V znlu{-lkR8u-ly4ZbOYZRL`7#ima1e6R>-xwJCn;^qVDJiXBI~Ntu>ey+tRGP`5^k& zPQmoM@xu$DbPzyXUXwyqFw^W%TFI_*`M>GwbSF7c%* zH@vzs8~@p5|3xo1+szew@x>RU+_oH3d0lRE#5ZqA<4A=dP z3NFdul6}=qUJ5Kb&5!mU&}Oh#gPaXbuuFVZ2Ywi${VU$OFiye+e$u`_TKB}Lv^#!( zwC{;tl9Bhvn8A(tlj#pTXf}8egqH~#)*EK@p>gl}?~2wcH|~X@6WO*swX8E%D1+R) z!0`mBi1C4PxlHlKX=gz#h{Tzkrs|y+2G{^i+4xF=x5&BF1if^O1M-zi~;w z1uK!cjJS7aLMjPQG zFFXhsbisF;o!F^+avEl1%Zi=Y!93|^KW2zaRo?M3b!l4eGe)aydf^tB%l%d?b!WiR zm_sIbpC(WJu7060cb1S*Vw>sY1Gj z-tc_K!hSZy9GGAK7>ArPbZ8B+t5-|*lxNvfbJ>H5|8*T4Jzn;R<} z46|z?eAsq9?l6qf#SNj!moL<|Vt3s!4A?gO116hcOkRt!TNE!b@zxVV!i!&tu5mj3 zAAFzHw#)^bH@_bT#6e!!90~}H2jTKgYO_s6Zc!5K8FjHa_E_}K?W<)Sv$Al&3@!T& zSjCi;*WK6#rFC=cRq4W8>paVP1a;?OEM^4#Cv{+C!&|Fg{;%VS+i4foo$8s1{@`5G z#9y{NV|PNX)|JgjfZVlUJA84@3Q;C5?f?%{Ul6(-`^cf$Q(Ee%pMG0E#M<#H?2ptz zH2c0I5q9W5dt{(q($;}Y@+yMUc_7ThO@I~JYm)FLPV}(+)_Wmi+q;(AoJDAut1x%e z-i-Y-z!-1b&HYDj>~6$n+4ImN?K{%JwBQ&ZEf837CT?BcC-~|`V$RhdVFoG}Y~^fc zy;oiwkeV%o#e_4H;u9=KNV=oz`e&}H8D-0i&^<9nc~L4z{q<(urJKT2w$*rxxCsLH z*4X&-ro=Yub$;9DhxZ(|Zh;WH<+olNLuZ7h3n;Xq7%p5kW$CtT3vzJX=tAWKT*9?X zE=96SGBIoS6xriO@Em*(JZB!eY?P`^(N|1-EJ~ppqYVQiQ_TMz^R#D3FN$t$sf;6(GUX(l()5VEqHy%_YG z7cyVXjKn=kbG79q&nqF$EUFOC(cR`w*`7~tl%%z?;qmF`W7ufi44dC3Z^d%_={9@& zCU_hCi8)gRhP$1%)}P8bTHSI%3G)e#eLnG;z>JNh4)3@63Y%R6t{3I#yS8!z_A!CPS4noRcKaOhb?r79NzraY@ptXk z*gV5=cHa{24cF|pVG|!`J27kRVlByAh7!xN_s+O&vfb___O9Kc*KH^^uiYB!HX5q; zkVoQx>5iP4Axmz%O_3pxo;2H>^k8o?X|oL)kK4@(W8VR0&krDFi85X;c-uuLL=^&L zF50CB@z8knS#cEUdC(|}Fa-A^i6qJ45VqKhlBb7py2*8#nwRZ8DQ`t?2X~^MuoD0b zB{Mtlrap1L$g*-|Nw9!RFV*-eq=6*KS8bM{i@OS!s&biw~RpO_E)xUKHB)2Eg?wO=HKw{DHSXS#~#HGp_C0=@YInIvQ1)$0fn zF2c?6K>69Rx8J^up!ntGvvayI7kgH*#awdONMY$w6cMe_O(5pip#46b;bl7NNa=3g zQ_D3JEilSSC2z%yoxBsmL+DjXWqKw>wFJ1$b+yR=Z}ak5h_`u3RD$Y;J`-=+c5V{~ zIc%=cTb>R1%ez~^F)*{xVj7qa>|DZoB+a@rtbq&^IJuV*0w*>Pw)1Yg(1s7^m7j%A z?q)CxdpJgsRKMN|cU_pRGOf3Ytag9`2;YjNYS#w<9p)3@3G>Of`0sKAs%WUybI_T8 z*54ZP54$YP#XY^n=)uZ}g~%+y5MPdBZ9CnpxM4x;;!op1g&3 zJEi>|AdK#22!QY~Am+b!XO&D8wB9QaUp`O;5p6QCrdfp8u#ypM`E zJ1X8s#e3w{qvCy3ypM|aQStWe5Vz(JvMkl%?o51r&y7jGm|AX3pr(U@f^S`LHiSA; z?`3;&)X^)c&=tV$svIlUxv)7+H!2{OeoYAD%^f`caJ{Jh7AqpwDJh5PSV0hRhz~P_ z2io0i9t*6PtqIszD2MPKBYC;`|KGjI#okEIB( zxT9QQccu10&m(!>?FMBnvmK;vwJ<^b>X(CA-tETw0e5VQ#Z%{Ee@eI7VLq74Z4Q9Q z0noIC9z>5Ps2*q&%=@;%C$Il$9bI60w|uRtH=^9g3hPE9Kh zERTRI$78&biT)t8<|`j_brUYmO;GHj7YMey1*K*!>=XhBr=sFAv$f%yb4x%}d`a(Zm4IBaLHb2BT5*2RCLKMSEj9&I&fx7HLf^``=U^j|njl_9C z&@MYPN|F6L1@E#$b*Y#jUKVc2*rVGAwrRFvz!9P)ITnB>?*$V30O0_BHEw6lbM`e3 zStI0X4dZ%eHf^KIS~O|H7t5SyV3V{p!yPULRNtgKolJZA`uc}&*w?S$0hU^s>N?#g zledDYZKY)zH@9|L9dIxt={sn9b5F?SQYPCh&g2L<^iW3^FBo&zigE*pUO|dY+O38Zy=CIVR8!@CL{ zZS*eY_BcIa&o>%4i8^Z@oLm+yhgaPVvm;{A3tDhBW&Oxht5>|>xu zyU^O0!3{L@5E?j&>K&pz)MPy{D)JPMRvbmO(aR89p`{wfO(|;KQhRf=(+Itt=diU3 zO7if4#$(OYU5+Mvgma3c8rBDzc}$N_m;i@|#ytcG>V%_};`$pkJ;SwsS6&sSaS`K* zh;+-LW9rk>4ZG+(K)#`cpEx+-@FAUL$D~8LJMWlu*x%`6(jhy>J|1Hqd)hJf@fiDf zjD0-DJ|1Hq-Q&mDM{LKW!(-CnG3oG_ba+fUJSH6;lMauH_h>sR-ZAZ{cpnw-qvCy3 zypM{vd;F+)WBZSqbO;Ye`!e6}3c+M5@~V!=aAlv-D@ht@rLZ{hj9uGn2O|fr-@HPv zytzc7D(+CZ^sprv*VhvFj{r7d@b zcNg6Y_~Q=#okY{Dfp<64=9sn%!gc7GWA|C2R@GjM);wd@t(jjR{3}Y@#6oHRJW<<{ zuP|xJO{nl0Mm45BiR82|1o_IBGQqOvr7I{$lXRf46Lt>g(}yruyuH@EImm6(=b=ZMzPur}LPyIL-df)5z;#BK~D@2`3lHYdp2Y{z+{tj2tT6(hE~ zQk!TV5FVM1)RdEljLC2#fe?$Bi2ECf*UGH^Q?;miS1*KUL(PQcC`iB~7xBP7}=u zNvG5_)7Zq)m})*lsighsp(8}w)m~x~LL;(JK3~!&aRZMhc1ERgMkQ~$gv_xcK}y$b zrC^TG97)jZO}ZQ*8>VF5Q<^0;v9g^kIYPECm2xmWa)f4`Jb8Z!k&!8obz0-t1{h9y z97|-3piWC&q}&Y=$%^!p7_xcn9#asBylLEBbB~FI5loysWf9{fBnVPd0^4bRBfF|I z32-d2Z-izYdU0Q=eAMKrcTOW7*9Fy?aTzqovsqQs*9=GaQ%@M?5Rz zNpBHpZegC*m=MyJ*w&w{HmWxGRJMCcPa`IzwUW#TM7vYa`qRqB_HvMP_UVaa^whD4 zWHDlT7&RfxR?4Qy*~6b~-U5FB!mSx6y#%8G~1bQSaR#{PsL=x&O^So_4vvRARF}r#Wt<6<}=c}<3WG(s3&Z?Wy zR0$-N3tUGmh<|Z@PPnsQEwRG5%0&%s7TP_{M`gv<-0&;>%#ah8|$Xog4lZ)NdxhoGnDq1<&Cjzy!Y05ROO#PXjEVi&?vF ze$Cm~Er<9JC=5L&RpcIuPkgK_H04%{bR;n10RDJ!4voekhaaPH$Z-?eh_jbqHX|6! z#!O|_3g6euCTn(XA!}=|%XkN#B3=}k9NzaHbJQ9Ss$^{?kZp$M-1mlgEtevxK$};k zxnBo_C>4ZhIZL|@iQbmx8qRj%mbY9#83|9!*PTDxWf*IX}2zVH9V z)p8aJ@7))znuaBr>p*uY<<>o82B<4h=rL>?hsA3Irc9W9 z6dVEHP@zGF5blhpgnDh=}qj&VK-oVYO#9cyL6!kM$~nTc1&-o14%}0zQckVJ*J(A5POItj^Y}o;JWUa6$ykp(OeHj zXpMx1`@CqZ5#D7Q@@iwLo!e~`@0746lkeWYe*<^T#H^2Vn-Snq<50PxqIB;W4KZRh zXc;8;jCUBhm7}JTJa$@?!xWF|$TMbRjyy6N+Dixe1w^1ZiWbxY)FF^0;RJQy|IkPil4v85 zf5@qa^rS=9G- zK8?r3FHuB#-T`YAIi+!Um&9x`dIDZl)>u^1T}-;&rzF}DC*|n$Lkp6M;k%0<;h)4`a~uV#`qayoWwRLzSU*`W|KFD5my6 zY=VR=6NM>5JcJ}PnE)k*K$57Q#X%kQBgph4!w|?0cJh9=*-<4ss${KpRLPDi*-<4M zYDbl9w0B39ETH^1uad>NRVankV@s-gN6E+-sm0Xy3Z;+G9Vw&USt5OekZa zBN81gDqe@75h+HO6F;Dq>E|yY9x3h9%Z49RF#I7(g+EA<@CPXmPAUwJC=^7BqgWL! zGzubFGG+yn)bkpNT|uR)9t6X}wTCI^O)likXoc_?y@Ypk;z_f0AYdF)kUPHoYqXi; z0m^Sja#Fgv`vHn=A8<8APw@fs5m8h-5<7#qfrkrew=pyh5F8pMvs0X`&xN+YF zu^*rmHn|9P#G;KNaWt_uh*UoTk;Apm&c{Bnbamv3rI)LYMeral(O8MrYbOxZZ5Y#dWIjwu^Ql?>ZaCF^WQmF%dJ9aXZUO4jq> zQ6(Gw#J#3$jF+X2El67zn;jV&p%iVq%1!hNSj+CG6E_*scwWsjxSW(%r z8SQ`^9xW$3LbFk9mR3l1oMPNu(o4ubMDf_TvatgtVMo5xS1^`P40eQavs5g#4D8sn zAP)5X7J!W|{n{?;I=c0SioW&~bfq|OJIlR}m2xFGoLhxn$BVd*&}@`=rIv3U<2tsu z>jM;SjV#$pOA(|MYi$=|9U(ecrnSEW>!?+gT%dKlH0wb{Sq~}48dHchq68~RK&8}- z7%Zyyd1^+W5 zQ}GYBc!tU{yv8iSCXesm2J@WV+}!wuU{kgc)mo)jE`|{e|ymt&H__8TdO;e#jJ_T%ON;b z_2`DCbs@|U;oe*cqlLH|Dp!6xL9TKmg1djqHm_4y80?O?73HpR(%?&PO7(Ha1~}yR zil^*%JToFs$x5}Y_C@BE$VCZ}P~bB2Gu1zG=vYxoRmw{KRlru#jXEj8u}Vr=iBj@Y z*a$g{bb#Rativ!>o;;z3M<&kjnEa}6#Wx{bdUfq3c;Zs3);NR zBxl8%FGM91p4l;giu$w9KKSJf{{734mfkblX3xqnK^#QKHPX!IAelW6LqMi_(sf`eoFVVD6x56)1uc0}ns?Mav++AF*t*4jDgjYVhdq6@&R$I&O zMt494;k=GNG%pEnW*Q*cydO@Ttm8<4tRswEVESn0w%iJ+m^VOEV#UKij)O~PK-zKN z8z8z6nYzRNSZSeg-(VF#xn#1^{$iGz-7J+FO1L*7fUKHQKz+^MUfeL}Rp6Wr>RjH8?CrHMn**^;$s?Syw_>%;c=-+145VejMy(Fn zNl$Rle>$IxJ19iweB?=qm_DjQp5%9?IpWDqc(MbY>U=-c@lF{0VGegI(b6TvAK-<6 zOSI&5D-NF_;gN-~g5(Ur^n4v@i;NZ~@n@Mwgc)=2<*6N&4%CX_Q$ZJrDD%bk1frk9 z(~TtdI4kAczFM+OEGvuXq)Mg`LhZDnKm~I}jIF+|SSC1VThL91{blCTF1V8#D6lKJ z%BLad6yfp?IMT)W<#XDFNMkTgLHm?7bDHPFEn2?wrn2Lj5#^moX{RG1=#zz=aC7iH zJyWH(X136asPYO(_yI}BFFZHAFVG_F5q_`z4SYW#wn9I=3p}hYE#IKi ze?1r65a_tIn`iwEKGw{Q!gp(c5O%WFTb^Y*hn}muHoFgV>PqDY1I?+6D6@0oQL4-z zJ1D~2r7%YWYn$_AZ98YNn9y;GHvX#O;NJr?F+SDh;cmggTKv15ubhDz2M=(uJWau* z03q^V2M%~XManxzZl1=ka?N;Qmbo-D8i3FMEmg9W ztJkg_d_||C(?FQ=3+z##;phDz9KhbqTYk_E>dH!~7&(+>&O^x4)OjeRhIyLp!Q)gsVutPS2=ix?Jb8Y8I8JxWF9- znOcI~TVrK_y%`@`F1r#TK&z-&iU#$JCm$@Tt6SDvsU@DOfdvC__&mwBDfTH3A_j17 z;YzbI04Q!B;oS7^SSL<|M5N_{5Si*ZK+xG#4H#R%K!c}fkF0D0J2uJoJJ*%Kn_|sx zg*`v4QupJluYuRSOV|P&!sTi<8b=1HhN3w;rB*K!y!GIF)9IAGH$UsD+z#p@FkJyg zdn!xQi>-!SR&(zd37py0LHk(22N*qLGs`?{o;zy+jn6S?ntiL3y(F=pKMznnJ7aI_ zOkL9%wJ_>oE#GjqRLU^LaDs-c8E0qgpL26bbo3bd$4l_5U*m0*iTUJ|%_nb4wE~4L zUkzvCqxb1+u_`%aVVDp8x-c64529R&e-^ucgwOb&-&G~A#A^4C8}s+!p8wk1RquC& z_{R+|{0~3y!jlay??3)&BPxD-G4sC-5Wo3Xt@5k+q@ImawK2QBsCM%SYxMMLK7qcv z-`&8j<`dJ0!C?KORFzt6msj)2Vpj=$dU0Bc;?x}6f2_YfpFqs#*_lmv!eplbvcG(4 z*h0p2^}gibf>il?Ip%_Hob>&dor}f%1wyJELmFKO(<)EPMJgIzVWk?73>8LT;&BI! zXN2S;P;i1$74>zJta-i?>5QT51GPd%Xd1rx!JH*4ari6{9I^kNPgipv8KG-rJh%zX z@f)^GI*3Z6>`l#A2?ml;OUecdZbWPV`v&Uz>+J^M<9TZOU;hmSqH#Ne?(92`HDoZ>aa)*KG&hsXb;a{!6tGb)J3C?)+ul0aj$K@0sVnIA-p%sI zkAIr&4|n_+e0ACyi;&|kO{vmtV#H~+ ztWy;0WyWYrbINTVi}+X!Ye(2zv>RCPA-YZ1FwMY%o!;biG9txB91Y`awdD{bD^kPW zL)<9pb;Q|Az7g3=u7%@Y$lUO%2-F+kab)H;>J}o073_uH{OP2Q!TIy))t{aQ|2Yc! zO=PKEHtlw6Z1$#A#_yq1r^vo9x8f9wW{q*W-{)|h4^K5Ed2V7pI_z7SvI+EQ>?zx) z`hm3{lN1btFH;vKiVe_lx&-2Fha9- zD`fJ6U|xm6t7#z;4k})`kX6ac9VPPzTf%c&HEg-f5PNNwt5odYbWcug==-o44_l>J zDiW11Gl^vn6i5>tjR-w@yuKpVCqMx>Rd^U$^#Rio-%j?UG zYc%G6gZz0QzjfkRcrL0l>-L-0^yd?2#t*?hv@T)+SB z)LMM)AB;3+eg=LIWmtP@2IVji81uw|q}AJFCe>N05`C7a+-T7HOx=p|R*JhbTikDI z=5LCJM4thnv%iD?8^BOQ)Id8M+9pLhuVD~G2P*$vDM4hmE89ynq-edizKAHVqt7el zL>%|U{wZ>MLzb+yp%EZQ@ElY?Z<|1GW!|4Em8pCsN|uYnaJRC{M~ID7;fWx65(~_X z-zW34`ofr>&8M?J|L=eJFMt1EAD=vV`s>sG_K#Qn5#yuRN8#LIB;Hax&w}G^lL~@A z+N?gK4Gp^~V889VT+y1`=d$eEh7{}IXoXK76V_WxbMWOxe&2YN&;43igTlbPzryEy z(yW#BUOD&QAjM`iPj-T33AKeK3`;YDYtwc7$#6e$Wy7R38A`~^MrR* z0vz<^vO2DyRhqE!F#`TDVAz4-s{WQ7)_?ETGFfBs_@F}zwarsr0@lRKzQXdugiW^~ zR173kCYQDB6fo+bs=QVkQ4L}=Fc;D#nqGSsKW6SE&^T11b})sPF^Dh$&lC2@2HXS& z&{n-dTLyh(5)eK_CJaJ)6caf(cbGhxZR5@k_}N~Cr1&urI3bg`Dd5yMX-8WL9T56{dhMW<=|FLNeT-b_9p?kG+euUz0t?;L-eV5SzEIT~>tC8_e238F zUiBo(>i!BhG@!>m7bpY&PaUiXlQ0H!!LVEPETVC_iH&H3X@0o=pDbA`GYKQJ>b4Lv zy>?jeei(8Mt2#*5*2@OhS68S!SRITGUuHWGhc$c+sJk<{^i@fNv+r?3;IwW_vnRk8 z2m0dhB5@Z|ys?!^1IL)&LI~M%o0+|qseHxw_||W;3yglyOhP<)C3%+ZX3c0S$}L#4 z4yotKgQw55oH>223N zO$>h+i9ThanAH^%TCb9kT5Nc@>Gd#!Qa+xS&|`N&eL^==fjz4y!3C8LEBt{N;n0B1 zkN@4;0j|WyLX;8?X!bvbgbZo{SaR7{Qn6QBSb(lMEM1@o*>X!`;*O$)m>OL+Tl=>b z0A97>;Oa8K;e9YH5jVJ$=7?!!Tvui;3xE~%4n6FljH21D-iO1M#XYV~ zxetdK0N$06_u(MP%b44xaUYHg>Zga?hhxX!Z}C3-+!n5T^X7b_<~`=@AH@0?@v9Hf zp0>QSosW2TQpaD3xx^jfNuQg(ySuIzOzqk+E zNH6yDFOTY=FP9PpCQN)1to&?(+qTHICC}`ChPcG}Hp?F2r$zb`BK*0ZfBt#OM4qx= zetGohSCK7~`3F&^)1*xGStT|_#w(%EdVNZNURPC7B0TMmZ!*d^&d<-!Up#*f|9^gd z-u(YBzx?v@^7*eWp1*kU{PN=27cVY^ zS$1~u)g`j`-i>^=*yd>_rZs@)`RvQt#mGy^n&-L5u2?8v!#h9!>=NwQ#A@|=7L0QS z5WFItE_M?(GxN$=#up;9Gq4ufW~SHX3+5*K`DZqJY5q9_f&G_Xru8p&CD^~QQWP0a z1e^SN!X|&7AXTGr!=Z)_BY&P28PCPku#BI7p1l=DS`#zxNP+hpM(}$F5$w4RR)`Ev ze!nB!NU~-?=u{u{nCCSQOn4<$s`PI9DGOFK;F2C2+YVD#|J?lDXiN=8T6Y>5wafvZ zBlv^is);f@-%m&S$OG6zho+3D$ccIOrUV)OrOLLO+;{h1waVXcBQDI$49uKt=cV_f8b>fN+$$&UjVN2r5m>^ z?Dn>q(p%FEa<1zH|BX4nXv@VCJFLX5=9ESVCVzuJZ3{@EGs5=m#X?m40tG!Bmg^8M zTe21#?rv69i2VA^tDl~|Yy8|%4itOu+&_#v*A6BshsBazh?+~14devW0}C7TS|j>+ zc;&^;>jI~cNO@|}2|-Qx%T|;-BYyBrD9E}RM|JFN8iM%Oyxn7rtzEY!;IeHSyX>l6 zwriJd+qP}nwq3Q$wr$&H*ZY2_Ptqry{@Fk0%FL6MtgK`{V~p#b*i%XJy{SLFCd_wS z8J_TkhVWyZE+0L`j> zp$~Ux1Cbk;KZH6Cl3TXZ)?6KaKQKvSOj-&2L3zRuNZT!O@~L`hNA z{iCmtnz`2V_fTIejA80Vwt2dMaXwtlPt8{$A?=835`-2XNv^d9mV}^@y8CNqKm6YK%+O3M5J@32frWL~~8A${+yw zb>;>f$tOLsSX<1$=EF5}J^UOLQK1Jh7^E;ca|8>()h{M(lp`DM+8g(>H0N31vUU{`DPDHi z@!#x_Jt|xcevQgBnC%Mh=J`>}Jm(t~n~O8Ql%{owU92c69>jJTbO6hgHld93Wb~bo zcg{?dKLXnLZLG4o5y7!w$!4iArre_8L~}AMkl_MiVJuKD9wgJ+?reWO{^6$7c@{+5 z>InQKV011_ygc4mi#tMYAT7KKFcYwGjr|_|D0KUcC2N9!POOA#Rd!JpLPWD$M4!XO z;J@a%2gZ|=dF7IyKAea^C0 zVQ5t$_X|a3!1&x{PEpeMNec3oNR^Oo+nOMit1Qira&`aIz#@>5#A%Qrw=tn~L_sH` zB;z3Ruk$X=AgfGym1wn{N2>*LBuB4k<~G0d$H%GX(?JXT&O6?N8-5@IZXpX&UDjm6 zpF$lwjQR#xx7L03r9BJEOb^$xtBA5oyAqi#tUG%``2iRvXzNP{X!8_5y+^9~shS;Jjq%18&(A=(`W)=W!mU2hyz1ru%I{q6mK|MUhRT~Y);c3Fu zHpX#IX$PL#t7bM&>V`wByKcsxC9Gr}6T^!xCb3SpfwP(Qx1Dux_1tNO{LL%90=fCz9PyaA9`I6FcB@DX}oe}#3=(ldbrVMSI?BEx0&|FmL&Nf**y5${&C3M=E_#3iA%Pee z$#Wt%`ojgm8xBT*5mJe@gB=n8SF7@g`3D>T?!n@I1r7k)6aeZ0sTc_M!50z+C!ZnK zkDtKLyPX>Vc%K01Q(*>_76F)GMzRf%8UYe-W_uH?w8x7?4=>%<43;3k!s*)=5Zn(` zmCsi@|CSGM5@kfYPbk*6%W>Gdy#N4^TRa9h!wCT=mv^_$rwGgsFjyYkLmbW*Xa*Vg zJw_P-0wL>QMKWpbFEA3$HTh~z{E3Xj9sZvie3>h9k|+Gk1>VpBJ5zyg1j6bbkc;zPvWY zF6CXbAYTiR%x&_&{?R`!|LC8I0P?jM)6{nYYbgJ$8@Rgbs42404ONO81PIVtpWj1lqxZN`GfmL)9%ihR zFk!Gca4AmpCG4~d^@WKbl>h5vjGiUOTSsu~Y6YpsSi?oxaM4dN068@-{x5Fb+Q6u6 zGb4<)^<~)F{@ky2_PLU$bEVM~$<>(H=x0M*1d2L$8v93i5`nFB%bemiO10X7YTIPz-HY_4Hq`W30L6RA|BNm;Z>Rt^di^uFv7B-8h(q=H66>M(qf8^qwG3PLX~rK zfV5dDbVGNRW&kRov{nKTE)Lcno{RS$fu@Hff*ljsUB^zSZX&1HOHuS_U2?EP?#h@} zg|=&S9!|4P|8NNu^aFz3wW1x;k8~0)KWJv^i$O)1t36hM{>qTBf`Y}P3*j?byBxu_ zcc?1u%EMK}!vQkdJp7P&MwKxlmL5_$gmh9zW_57mX-U}skhF~L;@BK2x5+v z-k2rWMmzzRb}jfxSl0K#zX6v6nXkfS1Z_*$0V&o=L zj7`s#_8_5)_jn(f}GLg*xTj0LUn19_4T666MFnYb8h zkZCH7nf3kKNckqn_wcY7VG2isM!nxg;bu)FzAE$Ty@^auQyW%KL^riqy+V=lj>vs{Uo4XcVBwf*aZ_6a?vv1^DsG=gi@*Np zP~20?v16z^IL@^x{4iY{QZp+DSI;3R*tr)>*6u%G=I?=3qdQ%YTVQmCQ;L54_9a!1 zCHB$EEjR_~GPW1@VJZmfhezU$=N*>ytA3sPqhlLjwv*)iimI`BzjI&~#-TI}l=-aP zKleRiPV}p%K=h#H@x#UPEz-!tc;OvHEE(Pd<;sbIs_Nt*c0GjZCs|BB{XCI52D$gE zUIlc!xE~*5Mo3hwdwAkwUnnu787*@vgydF2QB}`bmD_(=Molu|WIfaDZrM&+W3%42 z91m1BMa+=cV471z4{uABO93*vfBpq{Y+p$7VLok4_Z8uH96O!9sG#QjDJSHrp z4vxXAf<4B<#9nFoKXDJ_=*90=MRjV1KT@gzZ@NP3TRl*< zL-}E*A!?_1djHCv1Kqz<&iAX&XrX0OLDLadPJ>^k8P6A%WhlS6OwgIm^o%VVGKeOr zjJJmUi~of^b;rk0ApGyTGTx3V4S3P7hP~tSpx@`7`aC!L&F#z5IqGK%-f<{f?U!X; zuG+voE&QTlF7MUaqOrD!2@&99@C5q8vOkr9Ro}nWoBGp~&8d=b*c7SU;Y1C!hIlMi zy9DubnA*h!UrAR-pBkjzBxA+r4!9-2rT9JA4(}tFi4x z-G9F46heD+e_z8hZ;r=&$?yimS|56i7g9vPi(iDHiygR%@g||NA))jB8@6_XsjT8O z7=0dIU$kqsfXw>aVdW6E*INWP(s@Vf6+=3hZXdbX z$X@l$+Zg=P;mZH~b-GqVL<#JF?w5Cu%1z@Sd9;C@d&mrAfk#FZU9U-`o)A6OAb`XJ7B5@^&J9S zJZEP^M!Py?mD(>)p*!%*qoV%}c~*BXn}0&8j5$Y6%n8HZ7U{qp`q!hL`yW=QBTJ?R zzY?vR`k5J05OI4_fMLv`9YXPBWVvU^QlG5?WVFBMIof+3tY6iYY=qk4lt|}Z1C#tM z1OjU<3MWx4k>2VqSESl1oQZeFZbxbj^LZhvUdM(tHv=OakQ3uDCW}p*g$rz#tE52t z;Qr-2VY;kLX8*-`mhw6K4++w}=sj7NgSI8uYB`%G61}@XZ5f4}$usbGQg6i9iMGJ!&sz@q5(`P%Q~RoKL6bZI z_5qq&Y)oYyUs&MOi{vh0eLPNCu8G{%o6ZH(C9_ZWkd?*N3(othXF8T7n9=FzeBZ#n zzddsD=~5|ZmAo6?DbqJqHA?LtElF1dUK(p-A-XK<YPa3LC8$xd{(hL83S7K9~a-4!bKTg->=^fnzRPAZj z=66m$m$*J9?)AJG)BXKrF+yqA=Cr#Mns3Ecx;5NpM1EysherVxPXmNQWW1iv_I!nm z)Oh|P1)|#?;)2StcA_3{-n|97}~K?>oAfFw(FhWtW% z(bJJ}38Fjaw4Mbj%H1wt)Np!P2hN`t2q08ZmP$(IdtdwCbJeVHX6@Vhe`DpU z8^vPuHP7~lhLG(-HLj|}j3|(hkk1__*nyr8(;I>uoH*TR$&3er_w|P}wVr#K;BmVS z^}gzzo0i%++Oa~)%CJ>Ks~+|PPHD+=Tk>Ahi$DWz43 zG{s#~*CTrb4gn#m`m2)*jyX^>Q-{aLbg_R5$iG*B@V4Iy+veGHQ4)axq`*4b}Q>)D_~3BPWw4i6a2v`S(7g^6*gH(qB>cd&oUO5joA!^ccPAT$LQ% zowBv24epnU!}bE%{!Lg>i)P0P?M~iusa#xkBDc}T^P%xedkt28D2c$~OSPCLxJb$b zRE-@}M+fKq@V#=mof_kS@m#&_atT_d1_M~7GI(eeYfGhNvq|fz7os-y!EfG@{?Sy3V?pBChcb0X%1YtrRp`vfc^WkJNUX14`P^SEhRv*Hhi-H*b|tFkJ^NN6NeE z`r)q3y7P7@%H+Me9bc}Z{M0tE$2_akMR`MiiyCsxZnwiU2@>AjBw%7l&R}vybF#Zj zGHZ)5Ry<4Mt1uPI44;ujt<16sXT&ppJ}Ja)bHH6)%^JOvZr)7FAxffysx9Lr1KPfX277^PwrgiIiawKRhP&Z zi0M=pI`gwAqOD%n_8?s zZOCe@pj|^?6<>`SQB+Ezj?HhJ2G^F2!c6_%vG-;_gg!{uPb$a!{F%@=WlwD%U`itOrmVb)O)YkdcC2L zx@tUa8qnyP^8$I~34fDt+BK$a$|#dcBUjJhu5H)-(M!75j5odf<2l1D!)fF9>W@8_B7+po2dS_&Py+X#4_Dzbm?)4Ps6NH{Y$GD=$sw z>k#_o;^;DP0~2vHnpkF&B@xY7;VeGc^-Hqk!XGTQgL3pgdbCMGj~h@DzuWoAdm~^< zk0<*MU}@-r&s&;$31R7?1vUQI3Ux%-k$rZF*NHY1*pv*3i8gXDDz)@ISIs(EIOGgS z87y>A>@W#&OEtX;S6Khfqf^4_<+9rOY;ZWMn%!&pN{Bx8-|*umtkKiovN1LJgG;ex z$z{H2mSfT$Q$1Wi@0CqF@XTEyz3mqLcL3rzP0D^cecmUVxUhL=19{3p$mF!^v6boj zB9rn`Ol*ws&;Qi=J3J3n6e4 zg+4YC`>!DKUxX6;XWcd&1EIeXJ+mo#az*U;v-urj(<|_bN5JI=D9-*kXM?qWPe`JJ z@Bf^UY@T1_Zik-mQQI@pf#&1hh!o;fSgOOuz4>cM%nFl!vUKY=|D}qzY(G@7PnFCe zOaKdp91QwLDq<;|7{Z~8QV2ol4>Q_PF-Br$#fx<*7PabctLsobk%jCitJMo7p-lqx z$p{pj_><$mgrDr7G%Uj0xN=GeO_MV@XBmM9+4A881@s5_ zf40t~_HjLG8?Y%g!t&)vvni3ZPo6qzou|sD(jtwzAs25+6~QNsWtUowstjl= zkI9tY#CArB|BN0MFyLx}M{q!%#5y;my*}9y8CTyBt;Dc<1{ENI}|Uo zvT7W*{0xX?hK`Wlb8sgC+q%%?wirNM8;Ssvt|ugDG~zR3hti^dW-8@N72ffj;MOY0%$3Wf_|2b@~gFD9)q zvtDrHKx`C5yHWu`uL>7kw9lFXRl7r~#kdZS;KfR|yoY`OD2i?QC)!LwZH1}&`nGFH zMvz=Bh~@&TFP!7^C(Pj+%3*xID^*kVDy%i_SWxQL16%sDbfa1l3QdK}lL}ZIfE~E@ z);bjZWTl`+77PN|E%vJlAq{4~?0ZBAdir7vguV!x-{CMk(K9B$5blM-PeT+1!%C}_ zkO+Dtk6}T=Bckb5Ki(P+wT|V0&uK7Q>lAOoLL$(+hcOcckF7%%WK^P3A4po~D zanmD2;LtdfuRNuhpKj1GVqnq3iFKRp)?&0z;e;^5XNo*QDvU-$Xinm7fdiq7w!%h4 z3U=wP=J|D9K(Mi_MB6Heww4iZEFfA#tsz>UL9i`8&-LOwLa;dnW^nZV!QCzPe2)QP zL%sdov|e}>-!18kJfGPgxaYTE?^g#3gst*4@&JQod1^oX%w{g#5V+yK19e?kWzX&i=Ig^u_1(awG;FUAW(y|^H-7@ zTo{G~t!yw^C%b`SPu*Pm4LL@|{DB8T!SEkqG9T%9-ghJ@ zWs7s)kRQDNJA-bx(0O))fw(Li#2u*j5P36>Gt<8^Y!!oy(Thd7Mzt ztasRe=%PzfQ9CS#Ks5<1$nB+%*Oym2Q}D-J?hc#c*lz@~##{5zXCT5D8x%8QW3BxQ zFK5SC0UF`FVSrNIP zZ6qCFO*(AHHL7!9NM=YavTFiG8$?PVFU%S&QUnT*MmT(!2~Z6O)0wPPwRl@vCL5 zO3Mx73n0AYfC3$BEXF zt2VmZ1kM+@LOkJHr06T~q2m;PmmuJFQ@E0%t9_#Zctq@kjZY!s^Z#+UE#!a5X}c@6 zi*1%EVa+G5%_cQ(pvOj`P4IHlJu&oCo72W!Q6n*~((}eI0B98KR*#3&hC^YoZ6~Qu zl(Hsy0%3-0NCOPo+M<^owzU*dGE-j7NwRhGuV}ceU=FGD(I_fIWO7Yg-+(@!U?KWiN57I$RZv}ids zFWwm*TkCoBmv`&;Zy{!@il)~R8id@6colupC@kGCmLM8fT3nt~MLEf^&e&J;CBsM) zJ?+SaNeg4&a@2(lVFjI!9}WsFgu>tI7+FRS(*R~6_)}q&L%I}XpNiJdvRm8p^f$Tn%K zIUqPqUi|@N*f#+*e-w%AFKkSLEXdql%w{h68%H!cF}l~ zOo6u;XEHH_<7SAW6$t>zOrlGn85>FC(2X|tJWd`J}Lvr#P^D#2o#n{gbf_e4V z942NrHS7NI4NNP~6+Wk9a7H_NNu?i`Nbw6h;@A~_Mr5FbGsG?+S3PYY1LGzd(kenT zMw+oNKWikVNb$++Fdl%+1prB10Q~?D&ETE4ZGXOCPC;#7=r6sTA%ne?UqF}_zAWLH zbE#tXjIpS=?^KjaTu|3kV5jE_^j)C|_P?vqQ6)H`gfdbO`Gcpc_39uMMSUAM0qes0 zOxO&cj(z*00ea!;@*opKc56KJswlj+fV+wT)#o|9V(RTt6g&u6`GK0E{Ts;e1dw8# z0A&9Vh$~L-$u7P3R=o3B1nXKyfdrcDSBA>y-UekT zv5PM!sLq9-QUO0r0XFD~D_wYY+ix0dCldM>Q2)ZP>=S}4Kz?@3*l_1D(i$vw_0YeZw^CDTH;SU@2{Mvn|Z zX?0=+06`#YH!=p=&0r0=!d-b(;Z#rk{tVemnSVn2#|h#YiYs}CdODj_OKb+^r^)#j z(xV^+6d~>ZJaCl%4H5t}05gPx9;edv7sINIx)_GDx>rnGor0*E?Zj4K5w!|2S zlRgJ&Crh-P%I0XXPYZrtq$a)rKfKmJlz0u~0q9C}9^jwWol(Qvh z=HB>U`7z}{JvJ%(n_B>dx01L`fMOhM$VdgIes%AfEKdP5={244PRP<%uzvPY+wy{3 zg0;#;Fb581iduRgFKbrz+2m+e?fR zF=W9}RgfFePfyJkOt~FP0*|QRT*NTv-k^uTe`qUcMO}Zc5UT*dH%g^|G zBsC*I7zpJbWy$w-$q*^M=nfzcor%3mfZs^KHU^qn`4pT()AqB0rPa8|i!wT{*p|S{F1Zy1q zDiF+~1!|f3mH%O{;e-FMSGYh^JDR%zd7|{XL4g*8lo5ga8A8oaN8A}`$gv<#dBL6( z2CkkbNxNo1P{JU5sxiSb`xIN?91z_L{&G6ao+4 z(owvo$ydBADB8g{fEIs`$9Y`nX3ZRHaIdJ%=;(}3j{-^b|4I!rJlB^--lRv=gD&*PG0T9A>MAedbQgaK6ADVjG zdg`#9C3M(M*&@F9HvoRM&bosC_|n@zQ^rU!9NmF^ywIN2u6R2@Vr3>`Stv=2EV1gR z7nUbMmZMpF6e|xkONbbfRFa2Y95xeeN@_-r6;zHMFA0H&JfoHxxTO(Xtfn3;)?5Pc z$3_mby^J;T9gmh=uuu&>ix4F~Z>pS%jY(S|xa&pL^e8)GcxHSEr@rhBdZ;nHM|M@i zrYv>pj!vjN1TE|phAT=Ni7X#ON^2+RH-CVUZo5Rs44YF2fRv3KdV5htH`s+XJ9@o} zLoU<>If}hoC=zYs9u0;Hf6n}FJxz{cc#wABVeK6iIJ$NiM>zv4n0#7ND1>A>z=k|^ zWz>|$pt)C5UKEmXcx6qzL9Ts}mwEbpTr!JP&$bl~r(Zr(?xNFN3gvh$f>+yQAlN}) z$;INFk3S!(B~f3n!XIo2Nl~^i#?h>idWt)2*A8fl-uYoX*_Rj2bAJ$AU|90O z(O-HUe@!Nh;Lz%{`Qn>r8wT)pF5hdH7cP3dmsw@zn_)Ao)!Z-Oj`x>#D`Nn2QRFcg za1t$!esTDps57Y)w4wA?yV$p&Ev7HXpr@q%6Rj=g+5S^MP@OjTw|=1PI^X#Qw~SV~ zDYKH}mi>k4Zu0z5$$$Vfxs}&-Z*YkL>31`u`Ys|sa6Swb@=yyjY4`Lkw(b+S$vbou zW5U6KJnsNx3$yEUxfzkT=xNJYeVG{}u);Jfzd|%;8ws5p~@` z9bDe;m|>3TqELC@1FY2M1jDr+0GhFx^3rs5r1^?3cU6VDUdDzXc4MAe#1ZTVxB5@x zFQSKbCadn%iK^soa)Q^=rMoi(UC8bk?0XOjIQ5LWm&qe_)c0on{Ds-=B3fRje}93o zF?(l`9=XJipx^WbYi<{GApb&|(ssNXd0FKYGl`j7-W(;u%VE&s=28QRXE2Fz)f#wx zEin;N8g{Fs5o2GRl!m zS+Tz;L?Cj#?qh3cLf&N(c7v9%itkZzb6Pv7iL#=zN3v^uRlYJq*rbo>oUA!QC>?!7 zu{$<2|705tP$2)53J~Tv#vG%_O*OBVEk)qVfDIwX`2)ZWB_5vFS-u@foZmUC(!b;BV8FR0^Sy6C2)h>vT9cE(N3pO% z;mTnllH+8fI}K#7uWE(h8j+P)o%lN#hZA){Z;93FEEBewD@#jB+8O){lM^=l_6TQZ z(!ZzN*jzHA`2+z<1*qp(%FUOJ~r zO7$4$&*0F-tvJJujPHJ3Ua88s&nk_lc?>@^h4aM;VF@t+{9^e#Ve-xEBy9!Yr~a!9 z`BG4gKB)oei73%aZ~HG)Sp!B~ zO^vpWURcF(1nWHXjLhGoq2h_d2!lpNrVVg_LuEA{PNQxlE%@}x?@uIeJSZmMKN?iC z9KVoftBcW4l01ORE@>52BlTlo=7HmdpZEFdb5%nqEtcW=;5w!OM|J@YYys?l1F+-x z;=u92ffIxP$M*kxoP#$)coOlo>lTc9lkA(DM5jo4Xtn)IiBMyDn7Ag$@0ty1`&KDU zgXt7EeA0SbjGLdGe$gqR)j@Wx+@47@UA%1+GY>i)RmrOM>B6zsTuOV+km3;ESEcl2+3NdlmE5b$S}pw;qC&Hrg=IWQTwD4r492_h)RBzqaxSLU)MWoiGby^ zM_m?BBE#IZ{k_FPJvJi)+ly@BDZP@sOl=H{j8pt9IZ0^(w_Zoky$THlKEOBjupqt&YOQLmwgbr{=fxc ztj{q=yPU%}Ai`XWY6eLPV*leZMOT&@K(aTj%7uX(bXgP;tB|EmpCqBzQN0aJ+Q`1h zm<3m=I3Ta_IT=MIRnLek2OF-(TCFWe$?nd=cR3U7p#A{ArLW6l(oEt@%t4)`l7w`7 zp`&gSluA|HBBTq%ZOmPg^5LsyJTgTs%d4h_J58>)-4*(};9C`vs&V230Zvufa$sek zhKX!~AaVq964%zDQZ-qyA@AHNo76E`(yIt799CQv>XvWSN}9}GA_0m`aK$f(xC5zH ztT-SA-%MTxT%KY`iuTq81uhEy#{IBSv-PU`rzqc~oB9N< z`m`$`c0&ca4mc?862gj3tLgIXN|jid-3{$YQW-(poghr(h9%m7syAyu;Finjk`v7G zAxd0=%piF+T!}@iYB(OwJFa>;GQWVG3fC~mD5)mJap;UXuPqb%0RJPmgW-eO@B7<~ zqgJIOrT8!Oo>YVjN-+KdofDm~9jK)G0_DW;NJT`&^Kvl4367{5VFdC3Np@eyJ6%_& zBh^qNgP_Sr^6964+ZQ^kO+2;m-)Vj&aowII|6J21aU^A>`#;$>kX05?P;r^V=>oid zUji1;{K9AE{vB{i2#*c>(^#^QX9LNVTZy2O9yBB}=1x?!b0{^7pJ7hl&OS3^jG*Y~iy@Kl0y~0ebdkL`9XElH6a6SKmq4_GfAglt8ZSy9Wfnv~iDNjFL!# zvX3uVOqV@~A|X^w+J_=Yi|D5m{~csChGMEIEYWNXz@@Lq?PS)k4r7$N^Ky3#0h-)$ z;G)-Jk)~wts0u=c_9~vyG}+$dTqbH4ngVxV$0uXWf%R{z^VOzOyfo*3Lfn0t{%bd zvn68eOveYfAU_`1zYkl%%c7h^UcWD;Gz+zkeT&q4-l)wWc;stpdZhEVz(wK!5Q->q zT0Nh?_P$|84!`;W!?LJ-LY=+(JF3(S^rd^Aez5O zL$ArQ*KTwNt9j}Ezu4%%RHZ|8~M4{ntCdtTDT?mpD>@vf6MIY_6?^OzzIFK)cXYy0Ky@H}Pt zO8S!cZf|qFg-+*1>~BYBm+SM>-(!tsm18>3>kh7N?^~sw!&^pZpR+3R<}FVhS&*!k zf}dZ?xqsCd$Z{Ok1eBz6RTABy!mR9~c}B`fA+IacPzn(wsim8Yk;+X~q_vxHtrgwk}r)`$4yg=1+e?UZjT?$LOaru?Zp zP7FIFbKKaMLp-?O#vdQOxT|#)xA)J+>zMd1w zmJ95#`4(Ar2&NIRG`%h@<*MFPh1DCyEH!F!A?`kGOZf&3=}Q^j3Vw zYI~j22Gf3RRe$#QcLi8{=gc{Z0ErdvwL zHVxW5K6b4AkvnhkXK-jXcwRe!yJ;eGY@2AOQ5$3{lC6wpT?BiZmawWnvnMb&t)Cid zNnN9s+fkIRHkV&ffP(C%O^bDwMVU6OPYmeCh{AP`E9+;pLF-;5oj_O$k!KCMB|#;y zte+uSmw!Yf7Lj5|i26}E7xbx>*(|qN!KPXLe01y4tlfHTV5O;`bZk#;8I&M zz!Bx5emJ)6EQ`7j=nv%W&!S^vUk8%fOD7XsUaSP}Fvrue8PO3GK)KscuQmljC`&V~ zM6SqCeO!`W3wNn@Dv#TU3PdRVsQL6YfLyQNSPSnjdtsZUn#Z)=F%$t?bs)yEkfhzM zjl3_^iE`a>^m{B}xidjgl*xk@t{`X^ccwfg?}ep#)_iTk2+v{gIx;J(W&HOV=d zLp7mJTE0UA7{Og0(Ot3u=M()CNy&D;bFXmCm)|jr)t_}C^xeDb^YRDl`Pdv}*Y-|wko3YPGI7Mxt6wL#PRy zPWtN5R<*;ctUqjh#3u2JT}KHNPWDn07n#T9TEhcG;`liv-o#p#%ANeFD58fAnX&X9 z3d+Z$=EwXFI}1kkE6vKm=GQ;Qrw9a1DLh zZTMBBE8f}*WgmMY&L_~9EH@rD@u|pTUO*^~Pz9m-B&t|w?D!?SfV2slux4P`^#OOB z;LC_o)xf5T#njSlj4TD~N=a$ZsBy(G1I0FlJZaj@DjO)9rbW)Bu6xg3L{ z!Q*8$d0T9tJ5F;D^)8|YG=Mc(wb2*Dl~Aim=r@lwirl> zPa-8d=^XHwo!6CvT6!V+DB4oS>;ZUqKPS<>sG0?xNwaE`Np{rXH3IbM@9GqGHo zwMOqIhi!&C<{xzewqZ3KMhT!OKy)OE9vAEDxr8`TAd6LqE~<@$KZDkNI>(^&j&tJn zeFcxMrL}<&R0c--@G+_)pa^S!otg`uQ#0T)ebm03jg2uI5LDn0yQ^d?#!qKhoDq7e z-8m*eIHgaAX^{}MtP;$MFOZ^+Jk2PnDGQh16({109)?qPh_4&^p=1?X(U_8@{d+BkO-zyFOhqo#$-x zdFu3!g z0&$|ZH6va>|D`G(@s75X1`0`38B@n>Hw3Bk=i!(Kji9oLt#Jj3m~7_Dbo)1bJ!xqq zTXk_Cl-rXZqE%n6X*xsLsp?dHd*R`dee7!?7!3*1t7n3N#e!Y0LNnEAHXLbg*m_h5 zyihE%_QcQByi;purI{SDAjPV`7l~Sxo_i}0RscXIVgMN-MjjB*l}9A7_i^cAEiZLryGicL2r<`Lu9)9O60Y7Vy-fHE>rMytij z?=EUotzkA&K zn62Efz(5K)SRh`)cIS7t@~oBhXsE3u3_t)ARE|ylhYT>~&qk-62KGN?tTzH~+Bye~ z0w!OQ2h(sPjeh#OpcUkd7i^3Vq#p|`xfYP5D~M|SqRWS#uUC_=gBpR;#3{$iI94L0Qko6F zw589%0A#?C7Cp56Io%cDPlhlK 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ëL?Eywutp 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

e(_ObtKStIQnbMe?x4gpY(WYU3 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

0=6(qlL{-1v@OQ`@0rLGo8|PrPPHV3h2Dr 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%0Aj#=3akXFP#r}_by9ZKFTu?1yLT%D5_ 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

`Q;Qge zGmZx{<9UN!M1;tUu}H=={d7&!7|F6IkNFqIiehM*WpS2}Ry4&B1c6i35MWUY5RplOmKc)860&~=&+7Ef6dJUTn*?E2D$`J>*-shcaiep7$HqjLMj zZ>n3L)=zG!9eVh!bS5RrdExLU2jjKautAtu*%FSd(K&9;HgOf8i{7v#h+X5sf#q9& zth||PoZM2I`;e&bIkxoR@Bj4=%+dtdk!02owdM znfqZFjp8hYVgP3WL9^6)!t70@!%&MJ`r9!p={+fyB1w`$2XdYSi(w><_W}dOYN-wWC!H@*TKfuz*=~6UF0kHar z4BiCHmGrqd1!xv!IOJHFtS=11TK2;1Bhb96Al0kwwaVwcm5WC|U9O!xTz}lN_LHsw?Al_jAU4h z0yIsKG()g_pifcMH1qO(d3EoT?jpqXXAFy>*lLOZaEzrGe0aPx8N<*R127gR0ZXzd z4|1&!U>Z(SfFfy@ASjBUa1JAp7@8RmmIQ%N&DJcz9|-upSvj(}r*ijHZTt4+lPjml z^207@A_tP|(frvBiwDZP{&#s->15^Zjq=XMtsRZ~dlqjKas{0;)TYY>vjAW-duK{PrE7r|&L{Qt-#`rSZHYRL#Uz+fy;40bLS=Foi z8kdeXt{smGf2?ORJ$_ZccD255OYOt1`s2CAj=PmR@4hKN&aNE&q59@-_0*B&>-AGF z1~8Shzo=x#VAH@Si=$9eK4+cq7$gJISFe5?#P)QqNjbvC!xnSe%Lq-0WofGU1wz!42oyyLmg!?iwPO#ew~npcDxE4l zs9oD1S$sOu*mJCUVD87cQ%id#jBFzkSvg77cAQ_?QaSjx^s;v6LHXqJ;qu}61C-RSQuGE1d9|ky( zvjap5FcAJ8B18=2;sUPSR3`ig(g$l0qkDl3YO>HxVVJ>L=tv|)SU1s+CBW~e}mEV!1-z;9K_st%NkGx-mKBZ{MmHa z+eSiJ+eiK%JTpvo_FS}}Pr3%SP}!r z{INv3FwEFAG3?l}aJ)MuSQCq)X-l@|aBCk^#86dM+Xcufyw|y(!H46))fGu-^l^W- zozwgw!n91IgW{rV{YDzX1sGX55>L5YuaD!juPi(u10`*T|#*ff?}ci6PfgtS)poUP!E2B+Dq!|@M5P@5>KIu$@-LVrUD7KdYw*l^luTOxpQxqx-pmt92fAaDcV>xyFI_c=>i^-+|@FpKjW! zhcA5|zM4Mb1ac(c4~ATdZY(W8U87LKNBc1XFmA7xbTcd#U~ty$3s9_|McDu#39r{r z0vyF?;Kcxo19yPLF_H{m9*XSl=SoDZj&VjSM`*LVySuvJO2=IB)i8<{G$5y? ?`8(BZuj{9;H_o5WYwTED=xp64~ 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 literal 0 HcmV?d00001 diff --git a/charts/airlock/microgateway-cni/4.3.2/.helmignore b/charts/airlock/microgateway-cni/4.3.2/.helmignore new file mode 100644 index 0000000000..8561d28926 --- /dev/null +++ b/charts/airlock/microgateway-cni/4.3.2/.helmignore @@ -0,0 +1,27 @@ +# 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/ + +# Helm unit tests +/tests +/validation diff --git a/charts/airlock/microgateway-cni/4.3.2/Chart.yaml b/charts/airlock/microgateway-cni/4.3.2/Chart.yaml new file mode 100644 index 0000000000..ea724bec37 --- /dev/null +++ b/charts/airlock/microgateway-cni/4.3.2/Chart.yaml @@ -0,0 +1,43 @@ +annotations: + artifacthub.io/category: security + artifacthub.io/license: MIT + artifacthub.io/links: | + - name: Airlock Microgateway Documentation + url: https://docs.airlock.com/microgateway/4.3/ + - name: Airlock Microgateway Labs + url: https://play.instruqt.com/airlock/invite/hyi9fy4b4jzc?icp_referrer=artifacthub.io + - name: Airlock Microgateway Forum + url: https://forum.airlock.com/ + catalog.cattle.io/certified: partner + catalog.cattle.io/display-name: Airlock Microgateway CNI + catalog.cattle.io/kube-version: '>=1.25.0-0' + catalog.cattle.io/release-name: microgateway-cni + charts.openshift.io/name: Airlock Microgateway CNI +apiVersion: v2 +appVersion: 4.3.2 +description: A Helm chart for deploying the Airlock Microgateway CNI plugin +home: https://www.airlock.com/en/microgateway +icon: file://assets/icons/microgateway-cni.svg +keywords: +- WAF +- Web Application Firewall +- WAAP +- Web Application and API protection +- OWASP +- Airlock +- Microgateway +- Security +- Filtering +- DevSecOps +- shift left +- CNI +kubeVersion: '>=1.25.0-0' +maintainers: +- email: support@airlock.com + name: Airlock + url: https://www.airlock.com/ +name: microgateway-cni +sources: +- https://github.com/airlock/microgateway +type: application +version: 4.3.2 diff --git a/charts/airlock/microgateway-cni/4.3.2/README.md b/charts/airlock/microgateway-cni/4.3.2/README.md new file mode 100644 index 0000000000..583f3efa88 --- /dev/null +++ b/charts/airlock/microgateway-cni/4.3.2/README.md @@ -0,0 +1,137 @@ +# Airlock Microgateway CNI + +![Version: 4.3.2](https://img.shields.io/badge/Version-4.3.2-informational?style=flat-square) ![AppVersion: 4.3.2](https://img.shields.io/badge/AppVersion-4.3.2-informational?style=flat-square) + +*Airlock Microgateway is a Kubernetes native WAAP (Web Application and API Protection) solution to protect microservices.* + + + + + Microgateway + + +Modern application security is embedded in the development workflow and follows DevSecOps paradigms. Airlock Microgateway is the perfect fit for these requirements. It is a lightweight alternative to the Airlock Gateway appliance, optimized for Kubernetes environments. Airlock Microgateway protects your applications and microservices with the tried-and-tested Airlock security features against attacks, while also providing a high degree of scalability. +__This Helm chart is part of Airlock Microgateway. See our [GitHub repo](https://github.com/airlock/microgateway/tree/4.3.2).__ + +### Features +* Kubernetes native integration with its Operator, Custom Resource Definitions, hot-reload, automatic sidecar injection. +* Reverse proxy functionality with request routing rules, TLS termination and remote IP extraction +* Using native Envoy HTTP filters like Lua scripting, RBAC, ext_authz, JWT authentication +* Content security filters for protecting against known attacks (OWASP Top 10) +* Access control using OpenID Connect to allow only authenticated users to access the protected services +* API security features like JSON parsing, OpenAPI specification enforcement or GraphQL schema validation + +For a list of all features, view the **[comparison of the community and premium edition](https://docs.airlock.com/microgateway/latest/#data/1675772882054.html)**. + +## Documentation and links + +Check the official documentation at **[docs.airlock.com](https://docs.airlock.com/microgateway/latest/)** or the product website at **[airlock.com/microgateway](https://www.airlock.com/en/microgateway)**. The links below point out the most interesting documentation sites when starting with Airlock Microgateway. + +* [Getting Started](https://docs.airlock.com/microgateway/latest/#data/1660804708742.html) +* [System Architecture](https://docs.airlock.com/microgateway/latest/#data/1660804709650.html) +* [Installation](https://docs.airlock.com/microgateway/latest/#data/1660804708637.html) +* [Troubleshooting](https://docs.airlock.com/microgateway/latest/#data/1659430054787.html) +* [GitHub](https://github.com/airlock/microgateway) + +# Quick start guide + +The instructions below provide a quick start guide. Detailed information are provided in the **[manual](https://docs.airlock.com/microgateway/latest/)**. + +## Prerequisites +* [helm](https://helm.sh/docs/intro/install/) (>= v3.8.0) + +## Deploy Airlock Microgateway CNI +1. Install the CNI Plugin with Helm. + > **Note**: Certain environments such as OpenShift or GKE require non-default configurations when installing the CNI plugin. For the most common setups, values files are provided in the [chart folder](/deploy/charts/airlock-microgateway-cni). + ```bash + # Standard setup + helm install airlock-microgateway-cni -n kube-system oci://quay.io/airlockcharts/microgateway-cni --version '4.3.2' + kubectl -n kube-system rollout status daemonset -l app.kubernetes.io/instance=airlock-microgateway-cni + ``` + ```bash + # GKE setup + helm install airlock-microgateway-cni -n kube-system oci://quay.io/airlockcharts/microgateway-cni --version '4.3.2' -f https://raw.githubusercontent.com/airlock/microgateway/4.3.2/deploy/charts/airlock-microgateway-cni/gke-values.yaml + kubectl -n kube-system rollout status daemonset -l app.kubernetes.io/instance=airlock-microgateway-cni + ``` + ```bash + # OpenShift setup + helm install airlock-microgateway-cni -n openshift-operators oci://quay.io/airlockcharts/microgateway-cni --version '4.3.2' -f https://raw.githubusercontent.com/airlock/microgateway/4.3.2/deploy/charts/airlock-microgateway-cni/openshift-values.yaml + kubectl -n openshift-operators rollout status daemonset -l app.kubernetes.io/instance=airlock-microgateway-cni + ``` + **Important:** On OpenShift, all pods which should be protected by Airlock Microgateway must explicitly reference the Airlock Microgateway CNI NetworkAttachmentDefinition via the annotation `k8s.v1.cni.cncf.io/networks` (see [documentation](https://docs.airlock.com/microgateway/latest/#data/1658483168033.html) for details). + +2. (Recommended) You can verify the correctness of the installation with `helm test`. + ```bash + # Standard and GKE setup + helm upgrade airlock-microgateway-cni -n kube-system --set tests.enabled=true --reuse-values oci://quay.io/airlockcharts/microgateway-cni --version '4.3.2' + helm test airlock-microgateway-cni -n kube-system --logs + helm upgrade airlock-microgateway-cni -n kube-system --set tests.enabled=false --reuse-values oci://quay.io/airlockcharts/microgateway-cni --version '4.3.2' + ``` + ```bash + # OpenShift setup + helm upgrade airlock-microgateway-cni -n openshift-operators --set tests.enabled=true --reuse-values oci://quay.io/airlockcharts/microgateway-cni --version '4.3.2' + helm test airlock-microgateway-cni -n openshift-operators --logs + helm upgrade airlock-microgateway-cni -n openshift-operators --set tests.enabled=false --reuse-values oci://quay.io/airlockcharts/microgateway-cni --version '4.3.2' + ``` + + Consult our [documentation](https://docs.airlock.com/microgateway/latest/#data/1699611533587.html) in case of any installation error. + +## Support + +### Premium support +If you have a paid license, please follow the [premium support process](https://techzone.ergon.ch/support-process). + +### Community support +For the community edition, check our **[Airlock community forum](https://forum.airlock.com/)** for FAQs or register to post your question. +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| affinity | object | `{}` | Custom affinity for the DaemonSet to only deploy the CNI plugin on specific nodes. | +| commonAnnotations | object | `{}` | Annotations to add to all resources. | +| commonLabels | object | `{}` | Labels to add to all resources. | +| config.cniBinDir | string | `"/opt/cni/bin"` | Directory where the CNI plugin binaries reside on the host. This path can either be found in the documentation of your Kubernetes distribution or CNI provider. It can also be queried by running the command `crictl info -o go-template --template '{{.config.cni.binDir}}'` on your Kubernetes node. | +| config.cniNetDir | string | `"/etc/cni/net.d"` | Directory where the CNI config files reside on the host. This path can either be found in the documentation of your Kubernetes distribution or CNI provider. It can also be queried by running the command `crictl info -o go-template --template '{{.config.cni.confDir}}'` on your Kubernetes node. | +| config.excludeNamespaces | list | `["kube-system"]` | Namespaces for which this CNI plugin should not apply any modifications. | +| config.installMode | string | `"chained"` | Whether to install the CNI plugin as a `chained` plugin (default, required with most interface CNI providers), as a `standalone` plugin (required for use with Multus CNI, e.g. on OpenShift) or in `manual` mode, where no CNI network configuration is written. | +| config.logLevel | string | `"info"` | Log level for the CNI installer and plugin. | +| fullnameOverride | string | `""` | Allows overriding the name to use as full name of resources. | +| image.digest | string | `"sha256:ed5ec546a65f0ae0bc3e058aafc1d2aa4848996b9f415fe6232486934443b460"` | SHA256 image digest to pull (in the format "sha256:7144f7bab3d4c2648d7e59409f15ec52a18006a128c733fcff20d3a4a54ba44a"). Overrides tag when specified. | +| image.pullPolicy | string | `"IfNotPresent"` | Pull policy for this image. | +| image.repository | string | `"quay.io/airlock/microgateway-cni"` | Image repository from which to pull the Airlock Microgateway CNI image. | +| image.tag | string | `"4.3.2"` | Image tag to pull. | +| imagePullSecrets | list | `[]` | ImagePullSecrets to use when pulling images. | +| multusNetworkAttachmentDefinition.create | bool | `false` | Whether a NetworkAttachmentDefinition CR should be created, which can be used for applying the CNI plugin to Pods. | +| multusNetworkAttachmentDefinition.namespace | string | `"default"` | Namespace in which the NetworkAttachmentDefinition is deployed. Note: If namespace is set to a custom value, referencing the created NetworkAttachmentDefinition from other namespaces may not work if Multus namespace isolation is enabled. https://github.com/k8snetworkplumbingwg/multus-cni/blob/v4.0.2/docs/configuration.md#namespace-isolation | +| nameOverride | string | `""` | Allows overriding the name to use instead of "microgateway-cni". | +| nodeSelector | object | `{"kubernetes.io/os":"linux"}` | NodeSelector to apply to the CNI DaemonSet in order to only deploy the CNI plugin on specific nodes. | +| podAnnotations | object | `{}` | Annotations to add to all Pods. | +| podLabels | object | `{}` | Labels to add to all Pods. | +| privileged | bool | `false` | Whether the DaemonSet should run in privileged mode. Must be enabled for environments which require it for writing files to the host (e.g. OpenShift). | +| rbac.create | bool | `true` | Whether to create RBAC resources which are required for the CNI plugin to function. | +| rbac.createSCCRole | OpenShift | `false` | Whether to create RBAC resources which allow the CNI installer to use the "privileged" security context constraint. | +| resources | object | `{"requests":{"cpu":"10m","memory":"100Mi"}}` | Resource restrictions to apply to the CNI installer container. | +| serviceAccount.annotations | object | `{}` | Annotations to add to the ServiceAccount. | +| serviceAccount.create | bool | `true` | Whether a ServiceAccount should be created. | +| serviceAccount.name | string | `""` | Name of the ServiceAccount to use. If not set and create is true, a name is generated using the fullname template. | +| tests.enabled | bool | `false` | Whether additional resources required for running `helm test` should be created (e.g. Roles and ServiceAccounts). If set to false, `helm test` will not run any tests. | + +## License +View the [detailed license terms](https://www.airlock.com/en/airlock-license) for the software contained in this image. +* Decompiling or reverse engineering is not permitted. +* Using any of the deny rules or parts of these filter patterns outside of the image is not permitted. + +Airlock® is a security innovation by [ergon](https://www.ergon.ch/en) + + + + + + + Airlock Secure Access Hub + + diff --git a/charts/airlock/microgateway-cni/4.3.2/gke-values.yaml b/charts/airlock/microgateway-cni/4.3.2/gke-values.yaml new file mode 100644 index 0000000000..d6d5c21d14 --- /dev/null +++ b/charts/airlock/microgateway-cni/4.3.2/gke-values.yaml @@ -0,0 +1,4 @@ +# values for deploying on GKE + +config: + cniBinDir: "/home/kubernetes/bin" diff --git a/charts/airlock/microgateway-cni/4.3.2/openshift-values.yaml b/charts/airlock/microgateway-cni/4.3.2/openshift-values.yaml new file mode 100644 index 0000000000..3b1d6cccde --- /dev/null +++ b/charts/airlock/microgateway-cni/4.3.2/openshift-values.yaml @@ -0,0 +1,15 @@ +# values for deploying on OpenShift + +rbac: + createSCCRole: true + +privileged: true + +multusNetworkAttachmentDefinition: + create: true + namespace: default + +config: + installMode: "standalone" + cniNetDir: "/etc/cni/multus/net.d" + cniBinDir: "/var/lib/cni/bin" diff --git a/charts/airlock/microgateway-cni/4.3.2/questions.yml b/charts/airlock/microgateway-cni/4.3.2/questions.yml new file mode 100644 index 0000000000..73ed44d646 --- /dev/null +++ b/charts/airlock/microgateway-cni/4.3.2/questions.yml @@ -0,0 +1,18 @@ +questions: + - variable: config.cniNetDir + required: true + type: string + label: CNI Network Configuration Directory + group: "CNI Settings" + description: "Directory where the CNI config files reside on the host. This value depends on the kubernetes distribution and interface CNI Provider used. It can be fetched by running `crictl info -o go-template --template '{{.config.cni.confDir}}'` on your kubernetes host." + - variable: config.cniBinDir + required: true + type: string + label: CNI Plugin Binaries Directory + group: "CNI Settings" + description: "Directory where the CNI plugin binaries reside on the host. This value depends on the kubernetes distribution and interface CNI Provider used. It can be fetched by running `crictl info -o go-template --template '{{.config.cni.binDir}}'` on your kubernetes host." + - variable: config.installMode + required: true + label: CNI Plugin Installation Mode + group: "CNI Settings" + description: "Whether to install the CNI plugin as a `chained` plugin (default, required with most interface CNI providers) as a `standalone` plugin (required for use with Multus CNI, e.g. on OpenShift) or in `manual` mode, where no CNI network configuration is written. Please refer to the CNI installation documentation (https://github.com/airlock/microgateway?tab=readme-ov-file#deploy-airlock-microgateway-cni) to correctly setup the CNI Plugin for your environment." diff --git a/charts/airlock/microgateway-cni/4.3.2/templates/NOTES.txt b/charts/airlock/microgateway-cni/4.3.2/templates/NOTES.txt new file mode 100644 index 0000000000..bb94ff521e --- /dev/null +++ b/charts/airlock/microgateway-cni/4.3.2/templates/NOTES.txt @@ -0,0 +1,15 @@ +Thank you for installing Airlock Microgateway CNI. + +Please ensure that the helm values'.config.cniNetDir' and '.config.cniBinDir' are configured for your Kubernetes distribution. +For further information, consider our manual https://docs.airlock.com/microgateway/{{ include "airlock-microgateway-cni.docsVersion" . }}. +The chapter 'Setup > Installation' describes how to set those settings correctly. + +Further information: +* Documentation: https://docs.airlock.com/microgateway/{{ include "airlock-microgateway-cni.docsVersion" . }} +* Airlock Microgateway Labs: https://play.instruqt.com/airlock/invite/hyi9fy4b4jzc?icp_referrer=helm + +Next steps: +* Install Airlock Microgateway (if not done already) + https://artifacthub.io/packages/helm/airlock-microgateway/microgateway + +Your release version is {{ .Chart.Version }}. \ No newline at end of file diff --git a/charts/airlock/microgateway-cni/4.3.2/templates/_helpers.tpl b/charts/airlock/microgateway-cni/4.3.2/templates/_helpers.tpl new file mode 100644 index 0000000000..996491a873 --- /dev/null +++ b/charts/airlock/microgateway-cni/4.3.2/templates/_helpers.tpl @@ -0,0 +1,101 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "airlock-microgateway-cni.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Convert an image configuration object into an image ref string. +*/}} +{{- define "airlock-microgateway-cni.image" -}} + {{- if .digest -}} + {{- printf "%s@%s" .repository .digest -}} + {{- else if .tag -}} + {{- printf "%s:%s" .repository .tag -}} + {{- else -}} + {{- printf "%s" .repository -}} + {{- end -}} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 50 chars because some Kubernetes name fields are limited to 63 chars (by the DNS naming spec) +and the longest suffix is 13 characters. +If release name contains chart name it will be used as a full name. +*/}} +{{- define "airlock-microgateway-cni.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 50 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 50 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 50 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "airlock-microgateway-cni.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "airlock-microgateway-cni.labels" -}} +helm.sh/chart: {{ include "airlock-microgateway-cni.chart" . }} +{{ include "airlock-microgateway-cni.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- with .Values.commonLabels }} +{{ toYaml .}} +{{- end }} +{{- end }} + +{{/* +Common labels without component +*/}} +{{- define "airlock-microgateway-cni.labelsWithoutComponent" -}} +{{- $labels := fromYaml (include "airlock-microgateway-cni.labels" .) -}} +{{ unset $labels "app.kubernetes.io/component" | toYaml }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "airlock-microgateway-cni.selectorLabels" -}} +app.kubernetes.io/component: cni-plugin-installer +app.kubernetes.io/instance: {{ .Release.Name }} +app.kubernetes.io/name: {{ include "airlock-microgateway-cni.name" . }} +{{- end }} + +{{/* +Create the name of the service account to use for the CNI Plugin +*/}} +{{- define "airlock-microgateway-cni.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "airlock-microgateway-cni.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{- define "airlock-microgateway-cni.isSemver" -}} +{{- regexMatch `^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$` . -}} +{{- end -}} + +{{- define "airlock-microgateway-cni.docsVersion" -}} +{{- if and (eq "true" (include "airlock-microgateway-cni.isSemver" .Chart.AppVersion)) (not (contains "-" .Chart.AppVersion)) -}} + {{- $version := (semver .Chart.AppVersion) -}} + {{- $version.Major }}.{{ $version.Minor -}} +{{- else -}} + {{- print "latest" -}} +{{- end -}} +{{- end -}} diff --git a/charts/airlock/microgateway-cni/4.3.2/templates/clusterrole.yaml b/charts/airlock/microgateway-cni/4.3.2/templates/clusterrole.yaml new file mode 100644 index 0000000000..ef88ac7836 --- /dev/null +++ b/charts/airlock/microgateway-cni/4.3.2/templates/clusterrole.yaml @@ -0,0 +1,22 @@ +{{- if .Values.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "airlock-microgateway-cni.fullname" . }} + labels: + {{- include "airlock-microgateway-cni.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +rules: + - apiGroups: + - "" + resources: + - pods + verbs: + - get + - list + - watch + - patch +{{- end -}} diff --git a/charts/airlock/microgateway-cni/4.3.2/templates/clusterrolebinding.yaml b/charts/airlock/microgateway-cni/4.3.2/templates/clusterrolebinding.yaml new file mode 100644 index 0000000000..04f87cb0fa --- /dev/null +++ b/charts/airlock/microgateway-cni/4.3.2/templates/clusterrolebinding.yaml @@ -0,0 +1,20 @@ +{{- if .Values.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "airlock-microgateway-cni.fullname" . }} + labels: + {{- include "airlock-microgateway-cni.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "airlock-microgateway-cni.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ include "airlock-microgateway-cni.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end -}} diff --git a/charts/airlock/microgateway-cni/4.3.2/templates/configmap.yaml b/charts/airlock/microgateway-cni/4.3.2/templates/configmap.yaml new file mode 100644 index 0000000000..b880116ef9 --- /dev/null +++ b/charts/airlock/microgateway-cni/4.3.2/templates/configmap.yaml @@ -0,0 +1,22 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "airlock-microgateway-cni.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "airlock-microgateway-cni.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +data: + plugin-conf.json: |- + { + "type": "{{ include "airlock-microgateway-cni.fullname" . }}", + "debug": {{ eq .Values.config.logLevel "debug" }}, + "logFilePath": "/var/log/{{ include "airlock-microgateway-cni.fullname" . }}.log", + "kubernetes": { + "kubeconfig": "{{ .Values.config.cniNetDir }}/{{ include "airlock-microgateway-cni.fullname" . }}-kubeconfig", + "excludeNamespaces": {{ toJson .Values.config.excludeNamespaces }} + } + } diff --git a/charts/airlock/microgateway-cni/4.3.2/templates/daemonset.yaml b/charts/airlock/microgateway-cni/4.3.2/templates/daemonset.yaml new file mode 100644 index 0000000000..4ba9f2669c --- /dev/null +++ b/charts/airlock/microgateway-cni/4.3.2/templates/daemonset.yaml @@ -0,0 +1,136 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ include "airlock-microgateway-cni.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "airlock-microgateway-cni.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + selector: + matchLabels: + {{- include "airlock-microgateway-cni.selectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + kubectl.kubernetes.io/default-container: cni-installer + {{- with mustMerge .Values.podAnnotations .Values.commonAnnotations}} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "airlock-microgateway-cni.labels" . | nindent 8 }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - args: + - --log-level + - "{{ .Values.config.logLevel }}" + env: + - name: CNI_NETWORK_CONFIG + valueFrom: + configMapKeyRef: + key: plugin-conf.json + name: {{ include "airlock-microgateway-cni.fullname" . }} + - name: CNI_BIN_DIR + value: /host/opt/cni/bin + - name: CNI_NET_DIR + value: /host/etc/cni/net.d + - name: KUBECONFIG_FILE_NAME + value: "{{ include "airlock-microgateway-cni.fullname" . }}-kubeconfig" + - name: INSTALL_MODE + value: {{ .Values.config.installMode }} + - name: KUBERNETES_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + image: {{ include "airlock-microgateway-cni.image" .Values.image }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + name: cni-installer + {{- with .Values.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + startupProbe: + exec: + command: + - /cni-installer + - probe + failureThreshold: 5 + initialDelaySeconds: 3 + periodSeconds: 3 + timeoutSeconds: 3 + readinessProbe: + exec: + command: + - /cni-installer + - probe + failureThreshold: 1 + periodSeconds: 60 + timeoutSeconds: 3 + securityContext: + allowPrivilegeEscalation: {{ .Values.privileged }} + capabilities: + drop: + - ALL + privileged: {{ .Values.privileged }} + readOnlyRootFilesystem: true + runAsGroup: 0 + runAsNonRoot: false + runAsUser: 0 + seccompProfile: + type: RuntimeDefault + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /host/opt/cni/bin + name: cni-bin-dir + - mountPath: /host/etc/cni/net.d + name: cni-net-dir + - mountPath: /run/cni-installer + name: cni-installer-status + hostNetwork: true + priorityClassName: system-node-critical + restartPolicy: Always + securityContext: + fsGroup: 0 + runAsGroup: 0 + runAsNonRoot: false + runAsUser: 0 + serviceAccountName: {{ include "airlock-microgateway-cni.serviceAccountName" . }} + terminationGracePeriodSeconds: 5 + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + tolerations: + - effect: NoSchedule + operator: Exists + - key: CriticalAddonsOnly + operator: Exists + - effect: NoExecute + operator: Exists + volumes: + - hostPath: + path: "{{ .Values.config.cniBinDir }}" + type: Directory + name: cni-bin-dir + - hostPath: + path: "{{ .Values.config.cniNetDir }}" + type: Directory + name: cni-net-dir + - emptyDir: {} + name: cni-installer-status diff --git a/charts/airlock/microgateway-cni/4.3.2/templates/network-attachment-definition.yaml b/charts/airlock/microgateway-cni/4.3.2/templates/network-attachment-definition.yaml new file mode 100644 index 0000000000..5d657e309c --- /dev/null +++ b/charts/airlock/microgateway-cni/4.3.2/templates/network-attachment-definition.yaml @@ -0,0 +1,13 @@ +{{- if .Values.multusNetworkAttachmentDefinition.create -}} +apiVersion: "k8s.cni.cncf.io/v1" +kind: NetworkAttachmentDefinition +metadata: + name: {{ include "airlock-microgateway-cni.fullname" . }} + namespace: {{ .Values.multusNetworkAttachmentDefinition.namespace }} + labels: + {{- include "airlock-microgateway-cni.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end -}} diff --git a/charts/airlock/microgateway-cni/4.3.2/templates/scc-role.yaml b/charts/airlock/microgateway-cni/4.3.2/templates/scc-role.yaml new file mode 100644 index 0000000000..8627486928 --- /dev/null +++ b/charts/airlock/microgateway-cni/4.3.2/templates/scc-role.yaml @@ -0,0 +1,22 @@ +{{- if .Values.rbac.createSCCRole -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "airlock-microgateway-cni.fullname" . }}-privileged + namespace: {{ .Release.Namespace }} + labels: + {{- include "airlock-microgateway-cni.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +rules: +- apiGroups: + - security.openshift.io + resourceNames: + - privileged + resources: + - securitycontextconstraints + verbs: + - use +{{- end -}} \ No newline at end of file diff --git a/charts/airlock/microgateway-cni/4.3.2/templates/scc-rolebinding.yaml b/charts/airlock/microgateway-cni/4.3.2/templates/scc-rolebinding.yaml new file mode 100644 index 0000000000..ebd02982c0 --- /dev/null +++ b/charts/airlock/microgateway-cni/4.3.2/templates/scc-rolebinding.yaml @@ -0,0 +1,20 @@ +{{- if .Values.rbac.createSCCRole -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "airlock-microgateway-cni.fullname" . }}-privileged + namespace: {{ .Release.Namespace }} + labels: + {{- include "airlock-microgateway-cni.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ include "airlock-microgateway-cni.fullname" . }}-privileged +subjects: +- kind: ServiceAccount + name: {{ include "airlock-microgateway-cni.serviceAccountName" . }} +{{- end -}} diff --git a/charts/airlock/microgateway-cni/4.3.2/templates/serviceaccount.yaml b/charts/airlock/microgateway-cni/4.3.2/templates/serviceaccount.yaml new file mode 100644 index 0000000000..3dc8d58eae --- /dev/null +++ b/charts/airlock/microgateway-cni/4.3.2/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "airlock-microgateway-cni.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "airlock-microgateway-cni.labels" . | nindent 4 }} + {{- with mustMerge .Values.serviceAccount.annotations .Values.commonAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end -}} diff --git a/charts/airlock/microgateway-cni/4.3.2/templates/tests/rbac.yaml b/charts/airlock/microgateway-cni/4.3.2/templates/tests/rbac.yaml new file mode 100644 index 0000000000..744799333f --- /dev/null +++ b/charts/airlock/microgateway-cni/4.3.2/templates/tests/rbac.yaml @@ -0,0 +1,64 @@ +{{- if .Values.tests.enabled -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: "{{ include "airlock-microgateway-cni.fullname" . }}-tests" + namespace: {{ .Release.Namespace }} + labels: + {{- include "airlock-microgateway-cni.labelsWithoutComponent" . | nindent 4 }} + app.kubernetes.io/component: tests +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: "{{ include "airlock-microgateway-cni.fullname" . }}-tests" + namespace: {{ .Release.Namespace }} + labels: + {{- include "airlock-microgateway-cni.labelsWithoutComponent" . | nindent 4 }} + app.kubernetes.io/component: tests +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: "{{ include "airlock-microgateway-cni.fullname" . }}-tests" +subjects: +- kind: ServiceAccount + name: "{{ include "airlock-microgateway-cni.fullname" . }}-tests" +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: "{{ include "airlock-microgateway-cni.fullname" . }}-tests" + namespace: {{ .Release.Namespace }} + labels: + {{- include "airlock-microgateway-cni.labelsWithoutComponent" . | nindent 4 }} + app.kubernetes.io/component: tests +rules: +- apiGroups: + - "apps" + resources: + - daemonsets + resourceNames: + - {{ include "airlock-microgateway-cni.fullname" . }} + verbs: + - get + - watch + - list +- apiGroups: + - "" + resources: + - pods + - pods/log + verbs: + - get + - list +{{- if .Values.rbac.createSCCRole }} +- apiGroups: + - security.openshift.io + resourceNames: + - privileged + resources: + - securitycontextconstraints + verbs: + - use +{{- end -}} +{{- end -}} diff --git a/charts/airlock/microgateway-cni/4.3.2/templates/tests/test-install.yaml b/charts/airlock/microgateway-cni/4.3.2/templates/tests/test-install.yaml new file mode 100644 index 0000000000..12d8c8de78 --- /dev/null +++ b/charts/airlock/microgateway-cni/4.3.2/templates/tests/test-install.yaml @@ -0,0 +1,103 @@ +{{- if .Values.tests.enabled -}} +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "airlock-microgateway-cni.fullname" . }}-test-install" + namespace: {{ .Release.Namespace }} + labels: + {{- include "airlock-microgateway-cni.labelsWithoutComponent" . | nindent 4 }} + app.kubernetes.io/component: test-install + annotations: + helm.sh/hook: test + helm.sh/hook-delete-policy: before-hook-creation +spec: + restartPolicy: Never + containers: + - name: test + image: "bitnami/kubectl:{{ .Capabilities.KubeVersion.Major }}.{{ .Capabilities.KubeVersion.Minor }}" + securityContext: + allowPrivilegeEscalation: {{ .Values.privileged }} + capabilities: + drop: + - ALL + privileged: {{ .Values.privileged }} + readOnlyRootFilesystem: true + runAsGroup: 0 + runAsNonRoot: false + runAsUser: 0 + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /host/opt/cni/bin + name: cni-bin-dir + readOnly: true + - mountPath: /host/etc/cni/net.d + name: cni-net-dir + readOnly: true + command: + - sh + - -c + - | + set -eu + + fail() { + echo "Error: ${1}" + echo "" + echo 'CNI installer logs:' + kubectl logs -n {{ .Release.Namespace }} daemonsets/{{ include "airlock-microgateway-cni.fullname" .}} -c cni-installer + exit 1 + } + + containsMGWCNIConf() { + cat "${1}" | grep -qe '"type":.*"{{ include "airlock-microgateway-cni.fullname" . }}"' + } + + if ! kubectl rollout status --timeout=60s -n {{ .Release.Namespace }} daemonsets/{{ include "airlock-microgateway-cni.fullname" .}}; then + fail 'CNI DaemonSet rollout did not complete within timeout' + fi + + echo "Checking whether CNI binary was installed" + if ! [ -f "/host/opt/cni/bin/{{ include "airlock-microgateway-cni.fullname" . }}" ]; then + fail 'CNI binary was not installed' + fi + + echo "Checking whether CNI kubeconfig was installed" + if ! [ -f "/host/etc/cni/net.d/{{ include "airlock-microgateway-cni.fullname" . }}-kubeconfig" ]; then + fail 'CNI kubeconfig was not created' + fi + + echo "Checking whether CNI configuration was written" + case {{ .Values.config.installMode }} in + "chained") + for file in "/host/etc/cni/net.d/"*.conflist; do + if containsMGWCNIConf "${file}"; then + echo "Success" + exit 0 + fi + done + ;; + "standalone") + if containsMGWCNIConf "/host/etc/cni/net.d/{{ include "airlock-microgateway-cni.fullname" . }}.conflist"; then + echo "Success" + exit 0 + fi + ;; + "manual") + echo "- Skipping because we are in 'manual' install mode" + echo "Success" + exit 0 + ;; + esac + + fail 'Configuration for plugin "{{ include "airlock-microgateway-cni.fullname" . }}" was not found' + serviceAccountName: "{{ include "airlock-microgateway-cni.fullname" . }}-tests" + volumes: + - hostPath: + path: "{{ .Values.config.cniBinDir }}" + type: Directory + name: cni-bin-dir + - hostPath: + path: "{{ .Values.config.cniNetDir }}" + type: Directory + name: cni-net-dir +{{- end -}} diff --git a/charts/airlock/microgateway-cni/4.3.2/values.schema.json b/charts/airlock/microgateway-cni/4.3.2/values.schema.json new file mode 100644 index 0000000000..e087bd7004 --- /dev/null +++ b/charts/airlock/microgateway-cni/4.3.2/values.schema.json @@ -0,0 +1,225 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "properties": { + "nameOverride": { + "type": "string" + }, + "fullnameOverride": { + "type": "string" + }, + "commonLabels": { + "$ref": "#/definitions/StringMap" + }, + "commonAnnotations": { + "$ref": "#/definitions/StringMap" + }, + "imagePullSecrets": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "name" + ], + "additionalProperties": true + } + }, + "image": { + "$ref": "#/definitions/Image" + }, + "podAnnotations": { + "$ref": "#/definitions/StringMap" + }, + "podLabels": { + "$ref": "#/definitions/StringMap" + }, + "resources": { + "type": "object" + }, + "nodeSelector": { + "$ref": "#/definitions/StringMap" + }, + "affinity": { + "type": "object" + }, + "rbac": { + "type": "object", + "properties": { + "create": { + "type": "boolean" + }, + "createSCCRole": { + "type": "boolean" + } + }, + "required": [ + "create", + "createSCCRole" + ], + "additionalProperties": false + }, + "privileged": { + "type": "boolean" + }, + "serviceAccount": { + "type": "object", + "properties": { + "create": { + "type": "boolean" + }, + "annotations": { + "$ref": "#/definitions/StringMap" + }, + "name": { + "type": "string" + } + }, + "required": [ + "annotations", + "create", + "name" + ], + "additionalProperties": false + }, + "multusNetworkAttachmentDefinition": { + "type": "object", + "properties": { + "create": { + "type": "boolean" + }, + "namespace": { + "type": "string" + } + }, + "required": [ + "create", + "namespace" + ], + "additionalProperties": false + }, + "config": { + "type": "object", + "properties": { + "installMode": { + "type": "string", + "enum": [ + "chained", + "standalone", + "manual" + ] + }, + "logLevel": { + "type": "string", + "enum": [ + "debug", + "info", + "warn", + "error" + ] + }, + "cniNetDir": { + "type": "string", + "minLength": 1 + }, + "cniBinDir": { + "type": "string", + "minLength": 1 + }, + "excludeNamespaces": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "cniBinDir", + "cniNetDir", + "excludeNamespaces", + "installMode", + "logLevel" + ], + "additionalProperties": false + }, + "tests": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + } + }, + "required": [ + "enabled" + ], + "additionalProperties": false + }, + "global": { + "type": "object" + } + }, + "required": [ + "affinity", + "commonAnnotations", + "commonLabels", + "config", + "fullnameOverride", + "image", + "imagePullSecrets", + "multusNetworkAttachmentDefinition", + "nameOverride", + "nodeSelector", + "podAnnotations", + "podLabels", + "privileged", + "rbac", + "resources", + "serviceAccount", + "tests" + ], + "additionalProperties": false, + "definitions": { + "StringMap": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "Image": { + "type": "object", + "properties": { + "repository": { + "type": "string", + "minLength": 1 + }, + "tag": { + "type": "string" + }, + "digest": { + "type": "string", + "pattern": "^$|^sha256:[a-f0-9]{64}$" + }, + "pullPolicy": { + "type": "string", + "enum": [ + "Always", + "IfNotPresent", + "Never" + ] + } + }, + "required": [ + "digest", + "pullPolicy", + "repository", + "tag" + ], + "additionalProperties": false + } + } +} diff --git a/charts/airlock/microgateway-cni/4.3.2/values.yaml b/charts/airlock/microgateway-cni/4.3.2/values.yaml new file mode 100644 index 0000000000..5aa03a45c8 --- /dev/null +++ b/charts/airlock/microgateway-cni/4.3.2/values.yaml @@ -0,0 +1,85 @@ +# -- Allows overriding the name to use instead of "microgateway-cni". +nameOverride: "" +# -- Allows overriding the name to use as full name of resources. +fullnameOverride: "" +# -- Labels to add to all resources. +commonLabels: {} +# -- Annotations to add to all resources. +commonAnnotations: {} +# -- ImagePullSecrets to use when pulling images. +imagePullSecrets: [] +# - name: myRegistryKeySecretName + +# Specifies the Airlock Microgateway CNI image. +image: + # -- Image repository from which to pull the Airlock Microgateway CNI image. + repository: "quay.io/airlock/microgateway-cni" + # -- Image tag to pull. + tag: "4.3.2" + # -- SHA256 image digest to pull (in the format "sha256:7144f7bab3d4c2648d7e59409f15ec52a18006a128c733fcff20d3a4a54ba44a"). + # Overrides tag when specified. + digest: "sha256:ed5ec546a65f0ae0bc3e058aafc1d2aa4848996b9f415fe6232486934443b460" + # -- Pull policy for this image. + pullPolicy: IfNotPresent +# -- Annotations to add to all Pods. +podAnnotations: {} +# -- Labels to add to all Pods. +podLabels: {} +# -- Resource restrictions to apply to the CNI installer container. +resources: + requests: + cpu: 10m + memory: 100Mi +# -- NodeSelector to apply to the CNI DaemonSet in order to only deploy the CNI plugin on specific nodes. +nodeSelector: + kubernetes.io/os: linux +# -- Custom affinity for the DaemonSet to only deploy the CNI plugin on specific nodes. +affinity: {} +# Configures the generation of RBAC Roles and RoleBindings. +rbac: + # -- Whether to create RBAC resources which are required for the CNI plugin to function. + create: true + # -- (OpenShift) Whether to create RBAC resources which allow the CNI installer to use the "privileged" security context constraint. + createSCCRole: false +# -- Whether the DaemonSet should run in privileged mode. Must be enabled for environments which require it for writing files to the host (e.g. OpenShift). +privileged: false +# Configures the generation of the ServiceAccount. +serviceAccount: + # -- Whether a ServiceAccount should be created. + create: true + # -- Annotations to add to the ServiceAccount. + annotations: {} + # -- Name of the ServiceAccount to use. + # If not set and create is true, a name is generated using the fullname template. + name: "" +# Configures the generation of a NetworkAttachmentDefinition for use with Multus CNI (OpenShift) +multusNetworkAttachmentDefinition: + # -- Whether a NetworkAttachmentDefinition CR should be created, which can be used for applying the CNI plugin to Pods. + create: false + # -- Namespace in which the NetworkAttachmentDefinition is deployed. + # Note: If namespace is set to a custom value, referencing the created NetworkAttachmentDefinition from other namespaces + # may not work if Multus namespace isolation is enabled. https://github.com/k8snetworkplumbingwg/multus-cni/blob/v4.0.2/docs/configuration.md#namespace-isolation + namespace: default +# Parameters for the CNI installer configuration. +config: + # -- Whether to install the CNI plugin as a `chained` plugin (default, required with most interface CNI providers), + # as a `standalone` plugin (required for use with Multus CNI, e.g. on OpenShift) + # or in `manual` mode, where no CNI network configuration is written. + installMode: "chained" + # -- Log level for the CNI installer and plugin. + logLevel: info + # -- Directory where the CNI config files reside on the host. + # This path can either be found in the documentation of your Kubernetes distribution or CNI provider. + # It can also be queried by running the command `crictl info -o go-template --template '{{.config.cni.confDir}}'` on your Kubernetes node. + cniNetDir: "/etc/cni/net.d" + # -- Directory where the CNI plugin binaries reside on the host. + # This path can either be found in the documentation of your Kubernetes distribution or CNI provider. + # It can also be queried by running the command `crictl info -o go-template --template '{{.config.cni.binDir}}'` on your Kubernetes node. + cniBinDir: "/opt/cni/bin" + # -- Namespaces for which this CNI plugin should not apply any modifications. + excludeNamespaces: + - kube-system +tests: + # -- Whether additional resources required for running `helm test` should be created (e.g. Roles and ServiceAccounts). + # If set to false, `helm test` will not run any tests. + enabled: false diff --git a/charts/airlock/microgateway/4.3.2/.helmignore b/charts/airlock/microgateway/4.3.2/.helmignore new file mode 100644 index 0000000000..101ff5ac56 --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/.helmignore @@ -0,0 +1,28 @@ +# 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/ +# CRDs kustomization.yaml +/crds/kustomization.yaml +# Helm unit tests +/tests +/validation diff --git a/charts/airlock/microgateway/4.3.2/Chart.yaml b/charts/airlock/microgateway/4.3.2/Chart.yaml new file mode 100644 index 0000000000..63e5bc58d6 --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/Chart.yaml @@ -0,0 +1,44 @@ +annotations: + artifacthub.io/category: security + artifacthub.io/license: MIT + artifacthub.io/links: | + - name: Airlock Microgateway Documentation + url: https://docs.airlock.com/microgateway/4.3/ + - name: Airlock Microgateway Labs + url: https://play.instruqt.com/airlock/invite/hyi9fy4b4jzc?icp_referrer=artifacthub.io + - name: Airlock Microgateway Forum + url: https://forum.airlock.com/ + catalog.cattle.io/certified: partner + catalog.cattle.io/display-name: Airlock Microgateway + catalog.cattle.io/kube-version: '>=1.25.0-0' + catalog.cattle.io/release-name: microgateway + charts.openshift.io/name: Airlock Microgateway +apiVersion: v2 +appVersion: 4.3.2 +description: A Helm chart for deploying the Airlock Microgateway +home: https://www.airlock.com/en/microgateway +icon: file://assets/icons/microgateway.svg +keywords: +- WAF +- Web Application Firewall +- WAAP +- Web Application and API protection +- OWASP +- Airlock +- Microgateway +- Security +- Filtering +- DevSecOps +- shift left +- control plane +- Operator +kubeVersion: '>=1.25.0-0' +maintainers: +- email: support@airlock.com + name: Airlock + url: https://www.airlock.com/ +name: microgateway +sources: +- https://github.com/airlock/microgateway +type: application +version: 4.3.2 diff --git a/charts/airlock/microgateway/4.3.2/README.md b/charts/airlock/microgateway/4.3.2/README.md new file mode 100644 index 0000000000..ddb26273cf --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/README.md @@ -0,0 +1,180 @@ +# Airlock Microgateway + +![Version: 4.3.2](https://img.shields.io/badge/Version-4.3.2-informational?style=flat-square) ![AppVersion: 4.3.2](https://img.shields.io/badge/AppVersion-4.3.2-informational?style=flat-square) + +*Airlock Microgateway is a Kubernetes native WAAP (Web Application and API Protection) solution to protect microservices.* + + + + + Microgateway + + +Modern application security is embedded in the development workflow and follows DevSecOps paradigms. Airlock Microgateway is the perfect fit for these requirements. It is a lightweight alternative to the Airlock Gateway appliance, optimized for Kubernetes environments. Airlock Microgateway protects your applications and microservices with the tried-and-tested Airlock security features against attacks, while also providing a high degree of scalability. +__This Helm chart is part of Airlock Microgateway. See our [GitHub repo](https://github.com/airlock/microgateway/tree/4.3.2).__ + +### Features +* Kubernetes native integration with its Operator, Custom Resource Definitions, hot-reload, automatic sidecar injection. +* Reverse proxy functionality with request routing rules, TLS termination and remote IP extraction +* Using native Envoy HTTP filters like Lua scripting, RBAC, ext_authz, JWT authentication +* Content security filters for protecting against known attacks (OWASP Top 10) +* Access control using OpenID Connect to allow only authenticated users to access the protected services +* API security features like JSON parsing, OpenAPI specification enforcement or GraphQL schema validation + +For a list of all features, view the **[comparison of the community and premium edition](https://docs.airlock.com/microgateway/latest/#data/1675772882054.html)**. + +## Documentation and links + +Check the official documentation at **[docs.airlock.com](https://docs.airlock.com/microgateway/latest/)** or the product website at **[airlock.com/microgateway](https://www.airlock.com/en/microgateway)**. The links below point out the most interesting documentation sites when starting with Airlock Microgateway. + +* [Getting Started](https://docs.airlock.com/microgateway/latest/#data/1660804708742.html) +* [System Architecture](https://docs.airlock.com/microgateway/latest/#data/1660804709650.html) +* [Installation](https://docs.airlock.com/microgateway/latest/#data/1660804708637.html) +* [Troubleshooting](https://docs.airlock.com/microgateway/latest/#data/1659430054787.html) +* [GitHub](https://github.com/airlock/microgateway) + +# Quick start guide + +The instructions below provide a quick start guide. Detailed information are provided in the **[manual](https://docs.airlock.com/microgateway/latest/)**. + +## Prerequisites +* [Airlock Microgateway CNI](https://artifacthub.io/packages/helm/airlock-microgateway-cni/microgateway-cni) +* [Airlock Microgateway License](#obtain-airlock-microgateway-license) +* [cert-manager](https://cert-manager.io/) +* [helm](https://helm.sh/docs/intro/install/) (>= v3.8.0) + +In order to use Airlock Microgateway you need a license and the cert-manager. You may either request a community license free of charge or purchase a premium license. +For an easy start in non-production environments, you may deploy the same cert-manager we are using internally for testing. +### Obtain Airlock Microgateway License +1. Either request a community or premium license + * Community license: [airlock.com/microgateway-community](https://airlock.com/en/microgateway-community) + * Premium license: [airlock.com/microgateway-premium](https://airlock.com/en/microgateway-premium) +2. Check your inbox and save the license file microgateway-license.txt locally. + +> See [Community vs. Premium editions in detail](https://docs.airlock.com/microgateway/latest/#data/1675772882054.html) to choose the right license type. +### Deploy cert-manager +```bash +helm repo add jetstack https://charts.jetstack.io +helm install cert-manager jetstack/cert-manager --version '1.15.1' -n cert-manager --create-namespace --set crds.enabled=true --wait +``` + +## Deploy Airlock Microgateway Operator + +> This guide assumes a microgateway-license.txt file is present in the working directory. + +1. Install CRDs and Operator. + ```bash + # Create namespace + kubectl create namespace airlock-microgateway-system + + # Install License + kubectl -n airlock-microgateway-system create secret generic airlock-microgateway-license --from-file=microgateway-license.txt + + # Install Operator (CRDs are included via the standard Helm 3 mechanism, i.e. Helm will handle initial installation but not upgrades) + helm install airlock-microgateway -n airlock-microgateway-system oci://quay.io/airlockcharts/microgateway --version '4.3.2' --wait + ``` + +2. (Recommended) You can verify the correctness of the installation with `helm test`. + ```bash + helm upgrade airlock-microgateway -n airlock-microgateway-system --set tests.enabled=true --reuse-values oci://quay.io/airlockcharts/microgateway --version '4.3.2' + helm test airlock-microgateway -n airlock-microgateway-system --logs + helm upgrade airlock-microgateway -n airlock-microgateway-system --set tests.enabled=false --reuse-values oci://quay.io/airlockcharts/microgateway --version '4.3.2' + ``` + +### Upgrading CRDs + +The `helm install/upgrade` command currently does not support upgrading CRDs that already exist in the cluster. +CRDs should instead be manually upgraded before upgrading the Operator itself via the following command: +```bash +kubectl apply -k https://github.com/airlock/microgateway/deploy/charts/airlock-microgateway/crds/?ref=4.3.2 --server-side --force-conflicts +``` + +**Note**: Certain GitOps solutions such as e.g. Argo CD or Flux CD have their own mechanisms for automatically upgrading CRDs included with Helm charts. + +## Support + +### Premium support +If you have a paid license, please follow the [premium support process](https://techzone.ergon.ch/support-process). + +### Community support +For the community edition, check our **[Airlock community forum](https://forum.airlock.com/)** for FAQs or register to post your question. +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| commonAnnotations | object | `{}` | Annotations to add to all resources. | +| commonLabels | object | `{}` | Labels to add to all resources. | +| crds.skipVersionCheck | bool | `false` | Whether to skip the sanity check which prevents installing/upgrading the helm chart in a cluster with outdated Airlock Microgateway CRDs. The check aims to prevent unexpected behavior and issues due to Helm v3 not automatically upgrading CRDs which are already present in the cluster when performing a "helm install/upgrade". | +| dashboards.config.grafana.dashboardLabel.name | string | `"grafana_dashboard"` | Name of the label that lets Grafana identify ConfigMaps that represent dashboards. | +| dashboards.config.grafana.dashboardLabel.value | string | `"1"` | Value of the label that lets Grafana identify ConfigMaps that represent dashboards. | +| dashboards.config.grafana.folderAnnotation.name | string | `"grafana_folder"` | Name of the annotation containing the folder name to file dashboards into. | +| dashboards.config.grafana.folderAnnotation.value | string | `"Airlock Microgateway"` | Name of the folder dashboards are filed into within the Grafana UI. | +| dashboards.create | bool | `false` | Whether to create any ConfigMaps containing Grafana dashboards to import. | +| dashboards.instances.blockLogs.create | bool | `true` | Whether to create the block logs dashboard. | +| dashboards.instances.blockMetrics.create | bool | `true` | Whether to create the block metrics dashboard. | +| dashboards.instances.license.create | bool | `true` | Whether to create the license dashboard. | +| dashboards.instances.overview.create | bool | `true` | Whether to create the overview dashboard. | +| engine.image.digest | string | `"sha256:8d42759d999e6b69efa9ef1ecfdc84dc1f8f6f1ca822c8d2d3ef8ff1e335b9c9"` | SHA256 image digest to pull (in the format "sha256:a3051f42d3013813b05f7513bb86ed6a3209cb3003f1bb2f7b72df249aa544d3"). Overrides tag when specified. | +| engine.image.pullPolicy | string | `"IfNotPresent"` | Pull policy for this image. | +| engine.image.repository | string | `"quay.io/airlock/microgateway-engine"` | Image repository from which to pull the Airlock Microgateway Engine image. | +| engine.image.tag | string | `"4.3.2"` | Image tag to pull. | +| engine.resources | object | `{}` | Resource restrictions to apply to the Airlock Microgateway Engine container. | +| engine.sidecar.podMonitor.create | bool | `false` | Whether to create a PodMonitor resource for monitoring. | +| engine.sidecar.podMonitor.labels | object | `{}` | Labels to add to the PodMonitor. | +| fullnameOverride | string | `""` | Allows overriding the name to use as full name of resources. | +| imagePullSecrets | list | `[]` | ImagePullSecrets to use when pulling images. | +| license.secretName | string | `"airlock-microgateway-license"` | Name of the secret containing the "microgateway-license.txt" key. | +| nameOverride | string | `""` | Allows overriding the name to use instead of "microgateway". | +| networkValidator.image.digest | string | `"sha256:d1c484f4b9ea6218e2b1925f6b08d54dd352c7aaf653977bbbbeeb21eb3e19dd"` | SHA256 image digest to pull (in the format "sha256:d1c484f4b9ea6218e2b1925f6b08d54dd352c7aaf653977bbbbeeb21eb3e19dd"). Overrides tag when specified. | +| networkValidator.image.pullPolicy | string | `"IfNotPresent"` | Pull policy for this image. | +| networkValidator.image.repository | string | `"cgr.dev/chainguard/netcat"` | Image repository from which to pull the netcat image for the Airlock Microgateway Network Validator init-container. | +| networkValidator.image.tag | string | `""` | Image tag to pull. | +| operator.affinity | object | `{}` | Custom affinity to apply to the operator Deployment. Used to influence the scheduling. | +| operator.config.logLevel | string | `"info"` | Operator application log level. | +| operator.image.digest | string | `"sha256:d22f2ca35603b805caa67dd07aba524c3e4d68c3b59f7ddfc0e22e7fc09a200c"` | SHA256 image digest to pull (in the format "sha256:c79ee3f85862fb386e9dd62b901b607161d27807f512d7fbdece05e9ee3d7c63"). Overrides tag when specified. | +| operator.image.pullPolicy | string | `"IfNotPresent"` | Pull policy for this image. | +| operator.image.repository | string | `"quay.io/airlock/microgateway-operator"` | Image repository from which to pull the Airlock Microgateway Operator image. | +| operator.image.tag | string | `"4.3.2"` | Image tag to pull. | +| operator.nodeSelector | object | `{}` | Custom nodeSelector to apply to the operator Deployment in order to constrain its Pods to certain nodes. | +| operator.podAnnotations | object | `{}` | Annotations to add to all Pods. | +| operator.podLabels | object | `{}` | Labels to add to all Pods. | +| operator.rbac.create | bool | `true` | Whether to create RBAC resources which are required for the Airlock Microgateway Operator to function. | +| operator.replicaCount | int | `2` | Number of replicas for the operator Deployment. | +| operator.resources | object | `{}` | Resource restrictions to apply to the operator container. | +| operator.serviceAccount.annotations | object | `{}` | Annotations to add to the ServiceAccount. | +| operator.serviceAccount.create | bool | `true` | Whether a ServiceAccount should be created. | +| operator.serviceAccount.name | string | `""` | Name of the ServiceAccount to use. If not set and create is true, a name is generated using the fullname template. | +| operator.serviceAnnotations | object | `{}` | Annotations to add to the Service. | +| operator.serviceLabels | object | `{}` | Labels to add to the Service. | +| operator.serviceMonitor.create | bool | `false` | Whether to create a ServiceMonitor resource for monitoring. | +| operator.serviceMonitor.labels | object | `{}` | Labels to add to the ServiceMonitor. | +| operator.tolerations | list | `[]` | Custom tolerations to apply to the operator Deployment in order to allow its Pods to run on tainted nodes. | +| operator.updateStrategy | object | `{"type":"RollingUpdate"}` | Specifies the operator update strategy. | +| operator.watchNamespaceSelector | object | `{}` | Allows to dynamically select watch namespaces of the operator and the scope of the webhooks based on a Namespace label selector. It is able to detect and reconcile resources in all namespaces that match the label selector automatically, even for new namespaces, without restarting the operator. This facilitates a dynamic `MultiNamespace` installation mode, but still requires cluster-scoped permissions (i.e., ClusterRoles and ClusterRoleBindings). An `AllNamespaces` installation or the usage of the `watchNamespaces` requires the `watchNamespaceSelector` to be empty. Please note that this feature requires a Premium license. | +| operator.watchNamespaces | list | `[]` | Allows to restrict the operator to specific namespaces, depending on your needs. For a `OwnNamespace` or `SingleNamespace` installation the list may only contain one namespace (e.g., `watchNamespaces: ["airlock-microgateway-system"]`). In case of the `OwnNamespace` installation mode the specified namespace should be equal to the installation namespace. For a static `MultiNamespace` installation, the complete list of namespaces must be provided in the `watchNamespaces`. An `AllNamespaces` installation or the usage of the `watchNamespaceSelector` requires the `watchNamespaces` to be empty. Regardless of the installation modes supported by `watchNamespaces`, RBAC is created only namespace-scoped (using Roles and RoleBindings) in the respective namespaces. Please note that this feature requires a Premium license. | +| sessionAgent.image.digest | string | `"sha256:d487f4099c267310debffe5d5cac168deeddf6082dafbee352550f2792b9609c"` | SHA256 image digest to pull (in the format "sha256:a3051f42d3013813b05f7513bb86ed6a3209cb3003f1bb2f7b72df249aa544d3"). Overrides tag when specified. | +| sessionAgent.image.pullPolicy | string | `"IfNotPresent"` | Pull policy for this image. | +| sessionAgent.image.repository | string | `"quay.io/airlock/microgateway-session-agent"` | Image repository from which to pull the Airlock Microgateway Session Agent image. | +| sessionAgent.image.tag | string | `"4.3.2"` | Image tag to pull. | +| sessionAgent.resources | object | `{}` | Resource restrictions to apply to the Airlock Microgateway Session Agent container. | +| tests.enabled | bool | `false` | Whether additional resources required for running `helm test` should be created (e.g. Roles and ServiceAccounts). If set to false, `helm test` will not run any tests. | + +## License +View the [detailed license terms](https://www.airlock.com/en/airlock-license) for the software contained in this image. +* Decompiling or reverse engineering is not permitted. +* Using any of the deny rules or parts of these filter patterns outside of the image is not permitted. + +Airlock® is a security innovation by [ergon](https://www.ergon.ch/en) + + + + + + + Airlock Secure Access Hub + + diff --git a/charts/airlock/microgateway/4.3.2/app-readme.md b/charts/airlock/microgateway/4.3.2/app-readme.md new file mode 100644 index 0000000000..e32cac0259 --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/app-readme.md @@ -0,0 +1,28 @@ +# Airlock Microgateway + +*Airlock Microgateway is a Kubernetes native WAAP (Web Application and API Protection) solution to protect microservices.* + +## Features +* Kubernetes native integration with its Operator, Custom Resource Definitions, hot-reload, automatic sidecar injection. +* Reverse proxy functionality with request routing rules, TLS termination and remote IP extraction +* Using native Envoy HTTP filters like Lua scripting, RBAC, ext_authz, JWT authentication +* Content security filters for protecting against known attacks (OWASP Top 10) +* Access control to allow only authenticated users to access the protected services +* API security features like JSON parsing or OpenAPI specification enforcement + +For a list of all features, view the **[comparison of the community and premium edition](https://docs.airlock.com/microgateway/latest/#data/1675772882054.html)**. + +## Requirements +* [Airlock Microgateway CNI Helm Chart](https://artifacthub.io/packages/helm/airlock-microgateway-cni/microgateway-cni) (Also available as Rancher Chart) +* [Airlock Microgateway License](https://github.com/airlock/microgateway?tab=readme-ov-file#obtain-airlock-microgateway-license) (After obtaining the license install it according to the [documentation](https://github.com/airlock/microgateway?tab=readme-ov-file#deploy-airlock-microgateway-operator)) +* [cert-manager](https://cert-manager.io/docs/installation/) + +## Documentation and links + +Check the official documentation at **[docs.airlock.com](https://docs.airlock.com/microgateway/latest/)** or the product website at **[airlock.com/microgateway](https://www.airlock.com/en/microgateway)**. The links below point out the most interesting documentation sites when starting with Airlock Microgateway. + +* [Getting Started](https://docs.airlock.com/microgateway/latest/#data/1660804708742.html) +* [System Architecture](https://docs.airlock.com/microgateway/latest/#data/1660804709650.html) +* [Installation](https://docs.airlock.com/microgateway/latest/#data/1660804708637.html) +* [Troubleshooting](https://docs.airlock.com/microgateway/latest/#data/1659430054787.html) +* [GitHub](https://github.com/airlock/microgateway) \ No newline at end of file diff --git a/charts/airlock/microgateway/4.3.2/crds/accesscontrols.microgateway.airlock.com.yaml b/charts/airlock/microgateway/4.3.2/crds/accesscontrols.microgateway.airlock.com.yaml new file mode 100644 index 0000000000..056dd32d95 --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/crds/accesscontrols.microgateway.airlock.com.yaml @@ -0,0 +1,124 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + labels: + app.kubernetes.io/name: airlock-microgateway-operator + app.kubernetes.io/version: 4.3.2 + name: accesscontrols.microgateway.airlock.com +spec: + group: microgateway.airlock.com + names: + categories: + - airlock-microgateway + kind: AccessControl + listKind: AccessControlList + plural: accesscontrols + singular: accesscontrol + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: AccessControl specifies the options to perform access control with a Microgateway Engine container. + 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: Specifies how the Airlock Microgateway Engine performs access control. + properties: + policies: + description: Policies configures access control policies. + items: + properties: + authorization: + description: Authorization configures how requests are authorized. An empty object value {} disables authorization. + properties: + authentication: + description: Authentication specifies that clients need to be authenticated with the provided method. + properties: + oidc: + description: OIDC configures client authentication using OpenID Connect. + properties: + oidcRelyingPartyRef: + description: OIDCRelyingPartyRef configures how the Airlock Microgateway Engine interacts with the OpenID provider. + properties: + name: + description: Name of the resource + minLength: 1 + type: string + required: + - name + type: object + required: + - oidcRelyingPartyRef + type: object + type: object + type: object + identityPropagation: + description: IdentityPropagation configures how the authenticated user's identity is communicated to the protected application. + properties: + actions: + description: Actions specifies the propagation actions. + items: + properties: + identityPropagationRef: + description: IdentityPropagationRef selects an IdentityPropagation to apply. + properties: + name: + description: Name of the resource + minLength: 1 + type: string + required: + - name + type: object + required: + - identityPropagationRef + type: object + type: array + onFailure: + description: |- + OnFailure configures what should happen, if an identity propagation fails. Meaning of the possible values: + _Pass_: The request should be forwarded to the upstream, without including the information from the failed identity propagations. + enum: + - Pass + type: string + required: + - actions + - onFailure + type: object + required: + - authorization + type: object + maxItems: 1 + minItems: 1 + type: array + required: + - policies + type: object + required: + - spec + type: object + served: true + storage: true + subresources: {} diff --git a/charts/airlock/microgateway/4.3.2/crds/contentsecurities.microgateway.airlock.com.yaml b/charts/airlock/microgateway/4.3.2/crds/contentsecurities.microgateway.airlock.com.yaml new file mode 100644 index 0000000000..6d6092e381 --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/crds/contentsecurities.microgateway.airlock.com.yaml @@ -0,0 +1,139 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + labels: + app.kubernetes.io/name: airlock-microgateway-operator + app.kubernetes.io/version: 4.3.2 + name: contentsecurities.microgateway.airlock.com +spec: + group: microgateway.airlock.com + names: + categories: + - airlock-microgateway + kind: ContentSecurity + listKind: ContentSecurityList + plural: contentsecurities + singular: contentsecurity + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: ContentSecurity specifies the options to secure an upstream web application with a Microgateway Engine container. + 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: Specifies the options to secure an upstream web application with a Microgateway Engine container. + properties: + apiProtection: + description: |- + APIProtection defines the relevant configurations to protect APIs. + If undefined, default settings are applied, designed to work with most upstream web application services. + properties: + graphQLRef: + description: |- + GraphQLRef selects the relevant GraphQL configuration resource. + If undefined, default settings are applied, designed to work with most upstream web application services. + properties: + name: + description: Name of the resource + minLength: 1 + type: string + required: + - name + type: object + openAPIRef: + description: |- + OpenAPIRef selects the relevant OpenAPI configuration resource. + If undefined, default settings are applied, designed to work with most upstream web application services. + properties: + name: + description: Name of the resource + minLength: 1 + type: string + required: + - name + type: object + type: object + filter: + description: |- + Filter defines the set of filters, e.g. Airlock Deny Rules, to be applied to incoming requests + to protect against various attack patterns. + If undefined, default settings are applied, designed to work with most upstream web application services. + properties: + denyRulesRef: + description: |- + DenyRulesRef selects the relevant DenyRules configuration resource. + If undefined, default settings are applied, designed to work with most upstream web application services. + properties: + name: + description: Name of the resource + minLength: 1 + type: string + required: + - name + type: object + type: object + headerRewritesRef: + description: |- + HeaderRewritesRef selects the relevant HeaderRewrites. + If undefined, default settings are applied, designed to work with most upstream web application services. + properties: + name: + description: Name of the resource + minLength: 1 + type: string + required: + - name + type: object + limitsRef: + description: |- + LimitsRef selects the relevant Limits configuration resource. + If undefined, default settings are applied, designed to work with most upstream web application services. + properties: + name: + description: Name of the resource + minLength: 1 + type: string + required: + - name + type: object + parserRef: + description: |- + ParserRef selects the relevant Parser configuration resource. + If undefined, default settings are applied, designed to work with most upstream web application services. + properties: + name: + description: Name of the resource + minLength: 1 + type: string + required: + - name + type: object + type: object + type: object + served: true + storage: true + subresources: {} diff --git a/charts/airlock/microgateway/4.3.2/crds/denyrules.microgateway.airlock.com.yaml b/charts/airlock/microgateway/4.3.2/crds/denyrules.microgateway.airlock.com.yaml new file mode 100644 index 0000000000..e54df2ee24 --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/crds/denyrules.microgateway.airlock.com.yaml @@ -0,0 +1,1804 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + labels: + app.kubernetes.io/name: airlock-microgateway-operator + app.kubernetes.io/version: 4.3.2 + name: denyrules.microgateway.airlock.com +spec: + group: microgateway.airlock.com + names: + categories: + - airlock-microgateway + kind: DenyRules + listKind: DenyRulesList + plural: denyrules + singular: denyrules + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + DenyRules configures request filtering using Airlock built-in and custom deny rules. + Deny rules establish a negative security model. They define prohibited patterns which, when a match is found in a request, lead to it being blocked from reaching the upstream web application. + To handle possible false positives, lower the security level or define fine-granular deny rule exceptions + If undefined, default settings are applied, designed to work with most upstream web application services. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of the desired deny rules behavior. + properties: + request: + description: Request configures deny rules for downstream requests. + properties: + builtIn: + description: BuiltIn configures the built-in deny rules. + properties: + exceptions: + description: Exceptions allows to define exceptions for specific requests and deny rules. + items: + description: |- + DenyRulesException defines an exception for deny rules. Exceptions may be defined by any or a combination of the following elements: blockedData (the request data causing a block) or requestConditions (properties of a request without taking into consideration the reason why a request has been blocked). + At least one of blockedData and requestConditions must be set. + properties: + blockedData: + description: BlockedData defines an exception based on the request data causing the block. + properties: + graphQL: + description: |- + GraphQL defines an exception based on a blocked GraphQL query. + Only one of parameter, header, path, pathSegment, json or graphQL can be set. + properties: + argument: + description: |- + Argument defines an argument of a field of the GraphQL query. + At least one of field, argument and value must be set. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + field: + description: |- + Field defines a field of the GraphQL query. + At least one of field, argument and value must be set. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + value: + description: |- + Value defines the value of an argument of the GraphQL query. + At least one of field, argument and value must be set. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + type: object + header: + description: |- + Header defines an exception based on a blocked header. + Only one of parameter, header, path, pathSegment, json or graphQL can be set. + properties: + name: + description: Name defines the name of a header. + properties: + matcher: + description: Matcher defines the way to match a string. In comparison to a normal StringMatcher, a value is always matched ignoring the case and can't be inverted. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + value: + description: Value defines the value of a header. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + type: object + json: + description: |- + JSON defines an exception based on a blocked JSON property. + Only one of parameter, header, path, pathSegment, json or graphQL can be set. + properties: + jsonPath: + description: |- + JSONPath defines the JSONPath pattern to match the path within the JSON. + Expressions in JSONPath i.e. `?(expr)` are not supported. + minLength: 1 + type: string + key: + description: |- + Key defines the key of the JSON property. + At most one of key and value can be set. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + value: + description: |- + Value defines the value of the JSON property. + At most one of key and value can be set. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + type: object + parameter: + description: |- + Parameter defines an exception based on a blocked parameter. + Only one of parameter, header, path, pathSegment, json or graphQL can be set. + properties: + name: + description: Name defines the name of a parameter. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + source: + default: Any + description: Source defines the source of the parameter. + enum: + - Query + - Post + - Any + type: string + value: + description: Value defines the value of a parameter. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + type: object + path: + description: |- + Path defines an exception based on the blocked path. + Only one of parameter, header, path, pathSegment, json or graphQL can be set. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + pathSegment: + description: |- + PathSegment defines an exception based on a blocked path segment. + Only one of parameter, header, path, pathSegment, json or graphQL can be set. + properties: + segments: + description: Segments defines the position of a segment within the path. + properties: + index: + description: Index specifies an exact path segment position by index (0-based). + minimum: 0 + type: integer + type: object + value: + description: Value defines the value of a path segment. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + type: object + type: object + requestConditions: + description: RequestConditions defines an exception based on a property of a request without taking into consideration the reason why a request has been blocked. + properties: + header: + description: Header defines the matching headers of a request. + properties: + name: + description: Name defines the name of a header. + properties: + matcher: + description: Matcher defines the way to match a string. In comparison to a normal StringMatcher, a value is always matched ignoring the case and can't be inverted. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + value: + description: Value defines the value of a header. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + type: object + invert: + default: false + description: Invert indicates whether the request condition should be inverted. + type: boolean + mediaType: + description: MediaType defines the matching media type from the content-type header of a request. + properties: + matcher: + description: |- + NonInvertableCaseInsensitiveStringMatcher defines the way to match a string. + In comparison to a normal StringMatcher, a value is always matched ignoring the case and can't be inverted. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + method: + description: Method defines the matching methods of a request. + items: + description: Method defines common HTTP methods. + enum: + - GET + - HEAD + - POST + - PUT + - PATCH + - DELETE + - CONNECT + - OPTIONS + - TRACE + type: string + type: array + path: + description: Path defines the matching path of a request. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + remoteIP: + description: RemoteIP defines the matching remote IPs of a request. + properties: + cidrRanges: + description: CIDRRanges defines the IPv4 or IPv6 CIDR ranges, e.g. ``196.148.3.128/26`` or ``2001:db8::/28``. + items: + description: CIDRRange defines an IPv4 or IPv6 CIDR range, e.g. “196.148.3.128/26“ or “2001:db8::/28“. + format: cidr + type: string + minItems: 1 + type: array + invert: + default: false + description: Invert indicates whether the match should be inverted. + type: boolean + required: + - cidrRanges + type: object + type: object + ruleKeys: + description: RuleKeys restricts the exception to a set of deny rules. + items: + description: |- + A deny rule name can be any of the following values: + ENCODING | + EXPLOIT | + HPP | + HTML | + IDOR | + LDAP | + NOSQL | + OGNL | + PHP | + PROTOCOL | + SANITY | + SCANNING | + SQL | + TEMPLATE | + UNIXCMD | + WINCMD | + XSS + enum: + - ENCODING + - EXPLOIT + - HPP + - HTML + - IDOR + - LDAP + - NOSQL + - OGNL + - PHP + - PROTOCOL + - SANITY + - SCANNING + - SQL + - TEMPLATE + - UNIXCMD + - WINCMD + - XSS + type: string + minItems: 1 + type: array + type: object + type: array + overrides: + description: Overrides allows to override the builtIn settings for specific deny rules. + items: + description: DenyRulesOverride allows to override the builtIn settings for specific deny rules. + properties: + conditions: + description: Conditions select which built-in deny rules' settings will be adjusted. + properties: + ruleKeys: + description: RuleKeys is a list of built-in deny rule names. + items: + description: |- + A deny rule name can be any of the following values: + ENCODING | + EXPLOIT | + HPP | + HTML | + IDOR | + LDAP | + NOSQL | + OGNL | + PHP | + PROTOCOL | + SANITY | + SCANNING | + SQL | + TEMPLATE | + UNIXCMD | + WINCMD | + XSS + enum: + - ENCODING + - EXPLOIT + - HPP + - HTML + - IDOR + - LDAP + - NOSQL + - OGNL + - PHP + - PROTOCOL + - SANITY + - SCANNING + - SQL + - TEMPLATE + - UNIXCMD + - WINCMD + - XSS + type: string + minItems: 1 + type: array + types: + description: Types defines the type of attributes the override should be applied on. If Types are defined without any RuleKeys the override is applied to all deny rules. + items: + description: |- + A deny rule override type name can be any of the following values: + Header | + Parameter | + Path | + JSON | + GraphQL + enum: + - Header + - Parameter + - Path + - PathSegment + - JSON + - GraphQL + type: string + minItems: 0 + type: array + type: object + settings: + description: Settings override the corresponding properties for the selected rules. + properties: + level: + description: Level specifies the filter strength. + enum: + - Unfiltered + - Basic + - Standard + - Strict + type: string + threatHandlingMode: + description: ThreatHandlingMode specifies how threats should be handled. + enum: + - Block + - LogOnly + type: string + type: object + type: object + type: array + settings: + description: Settings contains the keys which will be adjusted. + properties: + level: + default: Standard + description: Level represents a set of deny rules with different filter strengths. + enum: + - Unfiltered + - Basic + - Standard + - Strict + type: string + threatHandlingMode: + default: Block + description: ThreatHandlingMode specifies how threats should be handled when a deny rule matches. + enum: + - Block + - LogOnly + type: string + type: object + type: object + custom: + description: Custom allows configuring additional deny rules. + properties: + rules: + description: Rules defines list of additional deny rules. + items: + properties: + blockData: + description: BlockData specifies the request data which should cause a block. + properties: + graphQL: + description: |- + GraphQL specifies to block requests containing a matching GraphQL property. + At least one of field, argument and value must be set. + properties: + argument: + description: |- + Argument defines an argument of a field of the GraphQL query. + At least one of field, argument and value must be set. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + field: + description: |- + Field defines a field of the GraphQL query. + At least one of field, argument and value must be set. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + value: + description: |- + Value defines the value of an argument of the GraphQL query. + At least one of field, argument and value must be set. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + type: object + header: + description: |- + Header specifies to block requests containing a matching header. + Only one of parameter, header, path, pathSegment or json can be set. + properties: + name: + description: Name defines the name of a header. + properties: + matcher: + description: |- + NonInvertableCaseInsensitiveStringMatcher defines the way to match a string. + In comparison to a normal StringMatcher, a value is always matched ignoring the case and can't be inverted. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + value: + description: Value defines the value of a header. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + type: object + json: + description: |- + JSON specifies to block requests containing a matching JSON property in the body. + Only one of parameter, header, path, pathSegment or json can be set. + properties: + key: + description: Key defines the key of a JSON object. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + value: + description: Value defines the value of a JSON object. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + type: object + parameter: + description: |- + Parameter specifies to block requests containing a matching parameter. + Only one of parameter, header, path, pathSegment or json can be set. + properties: + name: + description: Name defines the name of a parameter. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + value: + description: Value defines the value of a parameter. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + type: object + path: + description: |- + Path specifies to block requests with a matching path. + Only one of parameter, header, path, pathSegment or json can be set. + properties: + matcher: + description: Matcher specifies which path to block. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + pathSegment: + description: |- + PathSegment specifies to block requests containing a matching path segment. + Only one of parameter, header, path, pathSegment or json can be set. + properties: + segments: + description: |- + Segments restricts which path segments are filtered by this rule. + If not specified, all segments of a path are filtered. + properties: + index: + description: Index restricts the rule to the path segment at this index (0-based). + minimum: 0 + type: integer + type: object + value: + description: Value specifies which path segment values to block. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + required: + - value + type: object + type: object + requestConditions: + description: RequestConditions defines additional request properties which must be matched in order for this rule to apply. + properties: + header: + description: Header defines the matching headers of a request. + properties: + name: + description: Name defines the name of a header. + properties: + matcher: + description: Matcher defines the way to match a string. In comparison to a normal StringMatcher, a value is always matched ignoring the case and can't be inverted. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + value: + description: Value defines the value of a header. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + type: object + invert: + default: false + description: Invert indicates whether the request condition should be inverted. + type: boolean + mediaType: + description: MediaType defines the matching media type from the content-type header of a request. + properties: + matcher: + description: |- + NonInvertableCaseInsensitiveStringMatcher defines the way to match a string. + In comparison to a normal StringMatcher, a value is always matched ignoring the case and can't be inverted. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + method: + description: Method defines the matching methods of a request. + items: + description: Method defines common HTTP methods. + enum: + - GET + - HEAD + - POST + - PUT + - PATCH + - DELETE + - CONNECT + - OPTIONS + - TRACE + type: string + type: array + path: + description: Path defines the matching path of a request. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + remoteIP: + description: RemoteIP defines the matching remote IPs of a request. + properties: + cidrRanges: + description: CIDRRanges defines the IPv4 or IPv6 CIDR ranges, e.g. ``196.148.3.128/26`` or ``2001:db8::/28``. + items: + description: CIDRRange defines an IPv4 or IPv6 CIDR range, e.g. “196.148.3.128/26“ or “2001:db8::/28“. + format: cidr + type: string + minItems: 1 + type: array + invert: + default: false + description: Invert indicates whether the match should be inverted. + type: boolean + required: + - cidrRanges + type: object + type: object + ruleKey: + description: RuleKey defines a technical key for the deny rule. Must be unique. + minLength: 1 + pattern: ^[A-Z][A-Z0-9_]*$ + type: string + threatHandlingMode: + default: Block + description: ThreatHandlingMode specifies how threats should be handled when a deny rule matches. + enum: + - Block + - LogOnly + type: string + required: + - blockData + - ruleKey + type: object + type: array + x-kubernetes-list-map-keys: + - ruleKey + x-kubernetes-list-type: map + type: object + type: object + type: object + type: object + served: true + storage: true + subresources: {} diff --git a/charts/airlock/microgateway/4.3.2/crds/envoyclusters.microgateway.airlock.com.yaml b/charts/airlock/microgateway/4.3.2/crds/envoyclusters.microgateway.airlock.com.yaml new file mode 100644 index 0000000000..f5f2572644 --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/crds/envoyclusters.microgateway.airlock.com.yaml @@ -0,0 +1,58 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + labels: + app.kubernetes.io/name: airlock-microgateway-operator + app.kubernetes.io/version: 4.3.2 + name: envoyclusters.microgateway.airlock.com +spec: + group: microgateway.airlock.com + names: + categories: + - airlock-microgateway + kind: EnvoyCluster + listKind: EnvoyClusterList + plural: envoyclusters + singular: envoycluster + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: EnvoyCluster is an additional Envoy Cluster resource which is added to those defined by the Airlock Microgateway. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of the desired additional Envoy cluster. + properties: + value: + description: Value defines the Envoy Cluster which is added to those configured by the Airlock Microgateway. + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + type: object + served: true + storage: true + subresources: {} diff --git a/charts/airlock/microgateway/4.3.2/crds/envoyconfigurations.microgateway.airlock.com.yaml b/charts/airlock/microgateway/4.3.2/crds/envoyconfigurations.microgateway.airlock.com.yaml new file mode 100644 index 0000000000..9a26a34f4e --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/crds/envoyconfigurations.microgateway.airlock.com.yaml @@ -0,0 +1,185 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + labels: + app.kubernetes.io/name: airlock-microgateway-operator + app.kubernetes.io/version: 4.3.2 + name: envoyconfigurations.microgateway.airlock.com +spec: + group: microgateway.airlock.com + names: + categories: + - airlock-microgateway + kind: EnvoyConfiguration + listKind: EnvoyConfigurationList + plural: envoyconfigurations + singular: envoyconfiguration + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.status + name: Status + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + EnvoyConfiguration is the Schema for the envoyconfigurations API + {{% notice warning %}} EnvoyConfiguration resources may contain sensitive information and thus RBAC permissions should be granted with care. {{% /notice %}} + 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: EnvoyConfigurationSpec defines the desired state of EnvoyConfiguration + properties: + envoyResources: + properties: + clusters: + items: + type: object + x-kubernetes-preserve-unknown-fields: true + type: array + endpoints: + items: + type: object + x-kubernetes-preserve-unknown-fields: true + type: array + extensions: + items: + type: object + x-kubernetes-preserve-unknown-fields: true + type: array + listeners: + items: + type: object + x-kubernetes-preserve-unknown-fields: true + type: array + routes: + items: + type: object + x-kubernetes-preserve-unknown-fields: true + type: array + runtimes: + items: + type: object + x-kubernetes-preserve-unknown-fields: true + type: array + scopedRoutes: + items: + type: object + x-kubernetes-preserve-unknown-fields: true + type: array + secrets: + items: + type: object + x-kubernetes-preserve-unknown-fields: true + type: array + type: object + envoyResourcesRaw: + description: |- + EnvoyResourcesRaw defines the desired state for each resource type. The resources are stored as zstd compressed JSON bytes. + For debugging purposes, the resources can be inspected with the following command: `kubectl get envoyconfiguration -ojsonpath='{.spec.envoyResourcesRaw}' | base64 -d | zstd -d | jq` + format: byte + type: string + nodeID: + description: '**Deprecated:** This field is now ignored as NodeID is always derived from the resource name.' + type: string + type: object + status: + description: EnvoyConfigurationStatus defines the observed state of EnvoyConfiguration + properties: + conditions: + items: + properties: + lastTransitionTime: + description: Last time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: A human-readable message indicating details about the transition. + type: string + reason: + description: The reason for the condition's last transition. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: Type of EnvoyConfiguration condition. + type: string + required: + - status + - type + type: object + type: array + status: + type: string + xds: + properties: + resourceTypes: + additionalProperties: + description: XdsResourceTypeSyncStatus defines the sync status of xDS for a specific resource type + properties: + errorMessage: + description: ErrorMessage defines an optional message why the currently served resources of this resource type are rejected by the client. + type: string + resources: + additionalProperties: + description: XdsResourceStatus defines the status of xDS for a specific resource + properties: + version: + description: Version defines the version which is currently served for this resource. + type: string + required: + - version + type: object + description: Resources defines the resources which are currently served for this resource type. + type: object + status: + description: Status defines the current sync status of this resource type. + type: string + version: + description: Version defines the version which is currently served for this resource type. + type: string + required: + - resources + - status + - version + type: object + description: ResourceTypes defines the sync statuses for each resource type. + type: object + version: + description: Version defines the version of the underlying xDS snapshot. + type: integer + required: + - version + type: object + required: + - status + - xds + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/airlock/microgateway/4.3.2/crds/envoyhttpfilters.microgateway.airlock.com.yaml b/charts/airlock/microgateway/4.3.2/crds/envoyhttpfilters.microgateway.airlock.com.yaml new file mode 100644 index 0000000000..0b963eeccd --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/crds/envoyhttpfilters.microgateway.airlock.com.yaml @@ -0,0 +1,58 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + labels: + app.kubernetes.io/name: airlock-microgateway-operator + app.kubernetes.io/version: 4.3.2 + name: envoyhttpfilters.microgateway.airlock.com +spec: + group: microgateway.airlock.com + names: + categories: + - airlock-microgateway + kind: EnvoyHTTPFilter + listKind: EnvoyHTTPFilterList + plural: envoyhttpfilters + singular: envoyhttpfilter + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: EnvoyHTTPFilter is an additional Envoy HTTP Filter resource which is added to those defined by the Airlock Microgateway. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of the desired additional Envoy HTTP filter. + properties: + value: + description: Value defines the HTTP filter which is added to those configured by the Airlock Microgateway. + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + type: object + served: true + storage: true + subresources: {} diff --git a/charts/airlock/microgateway/4.3.2/crds/graphqls.microgateway.airlock.com.yaml b/charts/airlock/microgateway/4.3.2/crds/graphqls.microgateway.airlock.com.yaml new file mode 100644 index 0000000000..5029d7e16a --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/crds/graphqls.microgateway.airlock.com.yaml @@ -0,0 +1,88 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + labels: + app.kubernetes.io/name: airlock-microgateway-operator + app.kubernetes.io/version: 4.3.2 + name: graphqls.microgateway.airlock.com +spec: + group: microgateway.airlock.com + names: + categories: + - airlock-microgateway + kind: GraphQL + listKind: GraphQLList + plural: graphqls + singular: graphql + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: GraphQL contains the configuration for the GraphQL specification. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of the desired GraphQL specification. + properties: + settings: + description: Settings defines the settings to configure GraphQL. + properties: + allowIntrospection: + default: true + description: AllowIntrospection specifies if the introspection system is exposed. + type: boolean + allowMutations: + default: true + description: AllowMutations specifies if mutations are allowed. + type: boolean + schema: + description: Specifies the GraphQL schema. + properties: + source: + description: Source specifies the GraphQL schema to be enforced. + properties: + configMapRef: + description: ConfigMapRef references the configmap by its name containing the well-known key 'schema.graphql'. + properties: + name: + description: Name of the resource + minLength: 1 + type: string + required: + - name + type: object + type: object + required: + - source + type: object + threatHandlingMode: + default: Block + description: ThreatHandlingMode specifies how threats should be handled. + enum: + - Block + - LogOnly + type: string + type: object + type: object + type: object + served: true + storage: true diff --git a/charts/airlock/microgateway/4.3.2/crds/headerrewrites.microgateway.airlock.com.yaml b/charts/airlock/microgateway/4.3.2/crds/headerrewrites.microgateway.airlock.com.yaml new file mode 100644 index 0000000000..166db49b7e --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/crds/headerrewrites.microgateway.airlock.com.yaml @@ -0,0 +1,759 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + labels: + app.kubernetes.io/name: airlock-microgateway-operator + app.kubernetes.io/version: 4.3.2 + name: headerrewrites.microgateway.airlock.com +spec: + group: microgateway.airlock.com + names: + categories: + - airlock-microgateway + kind: HeaderRewrites + listKind: HeaderRewritesList + plural: headerrewrites + singular: headerrewrites + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: HeaderRewrites is the Schema for the headerrewrites API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of the desired header rewriting behavior. + properties: + request: + description: Request defines manipulations on upstream request headers. + properties: + add: + description: Add defines which request headers will be added before forwarding to the upstream. + properties: + custom: + description: |- + Custom allows configuring additional upstream request headers. + Add selected headers. + items: + properties: + headers: + description: Headers to add. + items: + description: HeaderRewritesHeader specifies a header with a particular value + properties: + name: + description: Name defines the name of a header. + minLength: 1 + type: string + value: + description: Value defines the value of a header. + type: string + required: + - name + - value + type: object + minItems: 1 + type: array + mode: + default: AddIfAbsent + description: Mode defines the header addition strategy. + enum: + - AddIfAbsent + - OverwriteOrAdd + type: string + name: + description: Name describing the configured operation. + minLength: 1 + type: string + required: + - headers + - name + type: object + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + allow: + description: |- + Allow defines which request headers will be forwarded to the upstream. + This can either be allHeaders or matchingHeaders. + Default: matchingHeaders: {...} + properties: + allHeaders: + description: AllHeaders specifies that all request headers should be forwarded. + type: object + matchingHeaders: + description: MatchingHeaders specifies which request headers should be forwarded. + properties: + builtIn: + description: BuiltIn allows configuring a set of predefined upstream request headers. + properties: + standardHeaders: + default: true + description: StandardHeaders defines whether the request headers which are forwarded to the upstream will be restricted to a set of common request headers. + type: boolean + type: object + custom: + description: Custom allows configuring additional upstream request headers. + items: + properties: + headers: + description: Headers to allow. + items: + description: |- + HeaderMatcher defines a matcher for an HTTP header. + At least one of name and value must be set. + properties: + name: + description: Name defines the name of a header. + properties: + matcher: + description: Matcher defines the way to match a string. In comparison to a normal StringMatcher, a value is always matched ignoring the case and can't be inverted. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + value: + description: Value defines the value of a header. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + type: object + minItems: 1 + type: array + name: + description: Name describing the configured operation. Must be unique. + minLength: 1 + type: string + required: + - headers + - name + type: object + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: object + remove: + description: Remove defines which request headers will be removed before forwarding to the upstream. + properties: + builtIn: + description: BuiltIn allows configuring a set of predefined upstream request headers. + properties: + alternativeForwardedHeaders: + default: true + description: |- + AlternativeForwardedHeaders removes downstream request headers which could potentially + be abused to alter the upstream's view of the remote connection. + type: boolean + type: object + custom: + description: Custom allows configuring additional upstream request headers. + items: + properties: + headers: + description: Headers to remove. + items: + description: |- + HeaderMatcher defines a matcher for an HTTP header. + At least one of name and value must be set. + properties: + name: + description: Name defines the name of a header. + properties: + matcher: + description: Matcher defines the way to match a string. In comparison to a normal StringMatcher, a value is always matched ignoring the case and can't be inverted. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + value: + description: Value defines the value of a header. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + type: object + minItems: 1 + type: array + name: + description: Name describing the configured operation. Must be unique. + minLength: 1 + type: string + required: + - headers + - name + type: object + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: object + response: + description: Response defines manipulations on upstream response headers. + properties: + add: + description: Add defines which response headers will be added before forwarding to the downstream. + properties: + builtIn: + description: BuiltIn allows configuring a set of predefined upstream response headers. + properties: + csp: + default: true + description: |- + CSP sets a content security policy which allows only same-origin requests except for images + if the 'Content-Security-Policy' header is not set by the upstream. + type: boolean + featurePolicy: + default: false + description: |- + FeaturePolicy sets a feature policy which prevents cross-origin use of several browser features + if the 'Feature-Policy' header is not set by the upstream. + **Deprecated:** Use permissionsPolicy instead. + type: boolean + hsts: + default: true + description: HSTS enforces the use of HTTPS if the 'Strict-Transport-Security' header is not already set by the upstream. + type: boolean + hstsPreload: + default: false + description: HSTSPreload enforces the use of HTTPS including for subdomains and enables HSTS preload. + type: boolean + permissionsPolicy: + default: true + description: |- + PermissionsPolicy sets a permissions policy which prevents cross-origin use of several browser features + if the 'Permissions-Policy' header is not set by the upstream. + type: boolean + referrerPolicy: + default: true + description: |- + ReferrerPolicy ensures that no 'Referer' header is sent for cross-origin requests + if the 'Referrer-Policy' header is not set by the upstream. + type: boolean + xContentTypeOptions: + default: true + description: XContentTypeOptions sets 'X-Content-Type-Options' to 'nosniff' if it is not set by the upstream. + type: boolean + xFrameOptions: + default: true + description: XFrameOptions sets 'X-Frame-Options' to SAMEORIGIN if it is not set by the upstream. + type: boolean + type: object + custom: + description: Custom allows configuring additional upstream response headers. + items: + properties: + headers: + description: Headers to add. + items: + description: HeaderRewritesHeader specifies a header with a particular value + properties: + name: + description: Name defines the name of a header. + minLength: 1 + type: string + value: + description: Value defines the value of a header. + type: string + required: + - name + - value + type: object + minItems: 1 + type: array + mode: + default: AddIfAbsent + description: Mode defines the header addition strategy. + enum: + - AddIfAbsent + - OverwriteOrAdd + type: string + name: + description: Name describing the configured operation. + minLength: 1 + type: string + required: + - headers + - name + type: object + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + allow: + description: |- + Allow defines which response headers will be forwarded to the downstream. + This can either be allHeaders or matchingHeaders. + Default: allHeaders: {} + properties: + allHeaders: + description: AllHeaders specifies that all response headers should be forwarded. + type: object + matchingHeaders: + description: MatchingHeaders specifies which response headers should be forwarded. + properties: + builtIn: + description: BuiltIn allows configuring a set of predefined upstream response header. + properties: + standardHeaders: + default: false + description: StandardHeaders defines whether the response headers which are forwarded to the downstream will be restricted to a set of common response headers. + type: boolean + type: object + custom: + description: Custom allows configuring additional upstream response headers. + items: + properties: + headers: + description: Headers to allow. + items: + description: |- + HeaderMatcher defines a matcher for an HTTP header. + At least one of name and value must be set. + properties: + name: + description: Name defines the name of a header. + properties: + matcher: + description: Matcher defines the way to match a string. In comparison to a normal StringMatcher, a value is always matched ignoring the case and can't be inverted. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + value: + description: Value defines the value of a header. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + type: object + minItems: 1 + type: array + name: + description: Name describing the configured operation. Must be unique. + minLength: 1 + type: string + required: + - headers + - name + type: object + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: object + remove: + description: Remove defines which response headers will be removed before forwarding to the downstream. + properties: + builtIn: + description: BuiltIn allows configuring a set of predefined upstream response headers. + properties: + auth: + description: Auth defines the categories of headers concerning authentication. + properties: + basic: + default: false + description: Basic removes upstream response headers that advise clients to authenticate with Basic Authentication. + type: boolean + negotiate: + default: true + description: Negotiate removes upstream response headers that advise clients to authenticate with Negotiate. + type: boolean + ntlm: + default: true + description: |- + NTLM removes upstream response headers that advise clients to authenticate with NTLM. + By default, these headers are removed, because NTLM pass-through is not supported. + type: boolean + type: object + informationLeakage: + description: InformationLeakage defines the categories of headers concerning information leakage. + properties: + application: + default: true + description: Application removes upstream response headers that leak information about the deployed software. + type: boolean + server: + default: true + description: Server removes upstream response headers that leak information about the server. + type: boolean + type: object + permissiveCors: + default: true + description: PermissiveCORS removes upstream response headers for CORS (Cross-Origin Resource Sharing) which have no restrictions and therefore reduce client-side security. + type: boolean + type: object + custom: + description: Custom allows configuring additional upstream response headers. + items: + properties: + headers: + description: Headers to remove. + items: + description: |- + HeaderMatcher defines a matcher for an HTTP header. + At least one of name and value must be set. + properties: + name: + description: Name defines the name of a header. + properties: + matcher: + description: Matcher defines the way to match a string. In comparison to a normal StringMatcher, a value is always matched ignoring the case and can't be inverted. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + value: + description: Value defines the value of a header. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + type: object + minItems: 1 + type: array + name: + description: Name describing the configured remove operation. Must be unique. + minLength: 1 + type: string + required: + - headers + - name + type: object + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: object + settings: + description: Settings configures the HeaderRewrites filter. + properties: + operationalMode: + default: Production + description: OperationalMode defines the behavior of the filter. In integration mode more information is logged about the requests and responses. + enum: + - Production + - Integration + type: string + type: object + type: object + type: object + served: true + storage: true diff --git a/charts/airlock/microgateway/4.3.2/crds/identitypropagations.microgateway.airlock.com.yaml b/charts/airlock/microgateway/4.3.2/crds/identitypropagations.microgateway.airlock.com.yaml new file mode 100644 index 0000000000..e01a242b16 --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/crds/identitypropagations.microgateway.airlock.com.yaml @@ -0,0 +1,108 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + labels: + app.kubernetes.io/name: airlock-microgateway-operator + app.kubernetes.io/version: 4.3.2 + name: identitypropagations.microgateway.airlock.com +spec: + group: microgateway.airlock.com + names: + categories: + - airlock-microgateway + kind: IdentityPropagation + listKind: IdentityPropagationList + plural: identitypropagations + singular: identitypropagation + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: IdentityPropagation specifies the desired identity propagation. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of the desired identity propagation. + properties: + header: + description: Header configures identity propagation via a request header. + properties: + name: + description: Name of the header to set. + minLength: 1 + type: string + value: + description: Value to propagate to the application. + properties: + source: + description: Source from which to extract the value. + properties: + metadata: + description: Metadata specifies to extract a value from an Envoy dynamic filter metadata key. + properties: + key: + description: Key specifies the metadata key from which to load the value, e.g. `some_payload.aud`. + minLength: 1 + type: string + namespace: + description: Namespace specifies the metadata namespace within which the lookup should be performed, e.g. `envoy.filters.http.jwt_authn`. + minLength: 1 + type: string + required: + - key + - namespace + type: object + oidc: + description: OIDC specifies to extract a value from the result of an OpenID Connect flow. + properties: + idToken: + description: IDToken specifies to extract the value from the OpenID Connect ID Token. + properties: + claim: + description: Claim selects the JWT claim from which to extract the value. + minLength: 1 + type: string + required: + - claim + type: object + required: + - idToken + type: object + type: object + required: + - source + type: object + required: + - name + - value + type: object + type: object + required: + - spec + type: object + served: true + storage: true + subresources: {} diff --git a/charts/airlock/microgateway/4.3.2/crds/limits.microgateway.airlock.com.yaml b/charts/airlock/microgateway/4.3.2/crds/limits.microgateway.airlock.com.yaml new file mode 100644 index 0000000000..4dad85aaf3 --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/crds/limits.microgateway.airlock.com.yaml @@ -0,0 +1,651 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + labels: + app.kubernetes.io/name: airlock-microgateway-operator + app.kubernetes.io/version: 4.3.2 + name: limits.microgateway.airlock.com +spec: + group: microgateway.airlock.com + names: + categories: + - airlock-microgateway + kind: Limits + listKind: LimitsList + plural: limits + singular: limits + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: Limits contains the configuration for limits. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of the desired limits behavior. + properties: + request: + description: Request defines the limits for requests. + properties: + limited: + description: Limited enables limits on request scope. + properties: + exceptions: + description: Exceptions defines limit exceptions. + items: + description: LimitsException defines an exception for limits. + properties: + length: + description: Length defines an exception for length limits based on the data element exceeding the limit. + properties: + graphQL: + description: GraphQL defines a field, argument or value length limit exception for a GraphQL query. + properties: + argument: + description: |- + Argument restricts the exception to GraphQL queries with a matching argument of a field. + At least one of field, argument and value must be set. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + field: + description: |- + Field restricts the exception to GraphQL queries with a matching field. + At least one of field, argument and value must be set. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + value: + description: |- + Value restricts the exception to GraphQL queries with a matching argument value. + At least one of field, argument and value must be set. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + type: object + json: + description: JSON defines a key and value length limit exception for a JSON property. + properties: + jsonPath: + description: |- + JSONPath restricts the exception to JSON properties with a matching JSONPath. + Expressions in JSONPath i.e. `?(expr)` are not supported. + minLength: 1 + type: string + required: + - jsonPath + type: object + parameter: + description: Parameter defines a name and value length limit exception for a parameter. + properties: + name: + description: Name restricts the exception to parameters with a matching name. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + source: + default: Any + description: Source restricts the exception to parameters of this kind. + enum: + - Query + - Post + - Any + type: string + required: + - name + type: object + type: object + requestConditions: + description: RequestConditions defines additional request properties which must be matched in order for this exception to apply. + properties: + header: + description: Header defines the matching headers of a request. + properties: + name: + description: Name defines the name of a header. + properties: + matcher: + description: Matcher defines the way to match a string. In comparison to a normal StringMatcher, a value is always matched ignoring the case and can't be inverted. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + value: + description: Value defines the value of a header. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + type: object + invert: + default: false + description: Invert indicates whether the request condition should be inverted. + type: boolean + mediaType: + description: MediaType defines the matching media type from the content-type header of a request. + properties: + matcher: + description: |- + NonInvertableCaseInsensitiveStringMatcher defines the way to match a string. + In comparison to a normal StringMatcher, a value is always matched ignoring the case and can't be inverted. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + method: + description: Method defines the matching methods of a request. + items: + description: Method defines common HTTP methods. + enum: + - GET + - HEAD + - POST + - PUT + - PATCH + - DELETE + - CONNECT + - OPTIONS + - TRACE + type: string + type: array + path: + description: Path defines the matching path of a request. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + remoteIP: + description: RemoteIP defines the matching remote IPs of a request. + properties: + cidrRanges: + description: CIDRRanges defines the IPv4 or IPv6 CIDR ranges, e.g. ``196.148.3.128/26`` or ``2001:db8::/28``. + items: + description: CIDRRange defines an IPv4 or IPv6 CIDR range, e.g. “196.148.3.128/26“ or “2001:db8::/28“. + format: cidr + type: string + minItems: 1 + type: array + invert: + default: false + description: Invert indicates whether the match should be inverted. + type: boolean + required: + - cidrRanges + type: object + type: object + type: object + type: array + general: + description: General defines general request limits. + properties: + bodySize: + anyOf: + - type: integer + - type: string + default: 100Mi + description: BodySize limits the total size of the request body. It specifies the number of bytes (0 = unlimited). This limit is effective for any request not processed by one of the content parsers (e.g. json) as configured in the Parser CRD. **Note** This limit does not apply to WebSocket or gRPC traffic. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + pathLength: + anyOf: + - type: integer + - type: string + default: 1Ki + description: PathLength defines the maximum path length for all requests (parsed and unparsed). + 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 + graphQL: + description: GraphQL defines the limits for GraphQL requests. + properties: + nestingDepth: + default: 10 + description: NestingDepth defines the maximum depth of nesting for GraphQL objects. + format: int64 + type: integer + querySize: + anyOf: + - type: integer + - type: string + default: 1Ki + description: QuerySize defines the maximum size for GraphQL queries. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + valueLength: + anyOf: + - type: integer + - type: string + default: "256" + description: ValueLength defines the maximum length for GraphQL values. + 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 + json: + description: JSON defines the limits for JSON requests. + properties: + bodySize: + anyOf: + - type: integer + - type: string + default: 100Ki + description: BodySize limits the total size of the JSON request body. It specifies the number of bytes (0 = unlimited). + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + elementCount: + default: 10000 + description: ElementCount defines the maximum number of keys and array items in the whole JSON document (recursive). + format: int64 + type: integer + keyCount: + default: 250 + description: KeyCount defines the maximum number of keys of a single JSON object (non-recursive). + format: int64 + type: integer + keyLength: + anyOf: + - type: integer + - type: string + default: "128" + description: KeyLength defines the maximum length for JSON keys. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + nestingDepth: + default: 100 + description: NestingDepth defines the maximum depth of nesting for JSON objects and JSON arrays. + format: int64 + type: integer + valueLength: + anyOf: + - type: integer + - type: string + default: 8Ki + description: ValueLength defines the maximum length for JSON values. + 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 + multipart: + description: Multipart defines the limits for Multipart requests. + properties: + bodySize: + anyOf: + - type: integer + - type: string + default: 100Mi + description: BodySize limits the total size of the Multipart request body. It specifies the number of bytes (0 = unlimited). + 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 + parameter: + description: Parameter defines the limits for request parameters. + properties: + bodySize: + anyOf: + - type: integer + - type: string + default: 100Ki + description: BodySize limits the total size of the form data body. It specifies the number of bytes (0 = unlimited). + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + count: + default: 128 + description: Count defines the maximum number of request parameters. + format: int64 + type: integer + nameLength: + anyOf: + - type: integer + - type: string + default: "128" + description: NameLength defines the maximum length for parameter names. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + valueLength: + anyOf: + - type: integer + - type: string + default: 8Ki + description: ValueLength defines the maximum length for parameter values. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + unlimited: + description: Unlimited disables all limits on request scope. + type: object + type: object + settings: + description: Settings configures the limits filter. + properties: + threatHandlingMode: + default: Block + description: ThreatHandlingMode specifies how threats should be handled when a limit hits. + enum: + - Block + - LogOnly + type: string + type: object + type: object + type: object + served: true + storage: true diff --git a/charts/airlock/microgateway/4.3.2/crds/oidcproviders.microgateway.airlock.com.yaml b/charts/airlock/microgateway/4.3.2/crds/oidcproviders.microgateway.airlock.com.yaml new file mode 100644 index 0000000000..7d2ef8e9e7 --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/crds/oidcproviders.microgateway.airlock.com.yaml @@ -0,0 +1,305 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + labels: + app.kubernetes.io/name: airlock-microgateway-operator + app.kubernetes.io/version: 4.3.2 + name: oidcproviders.microgateway.airlock.com +spec: + group: microgateway.airlock.com + names: + categories: + - airlock-microgateway + kind: OIDCProvider + listKind: OIDCProviderList + plural: oidcproviders + singular: oidcprovider + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + OIDCProvider specifies an OpenID Provider (OP). + + + {{% notice warning %}} The OIDC feature is currently in an experimental state. + + + We encourage you to try it out and give feedback, but be aware that we do not recommend using it in a production environment yet, as security has not yet been hardened. + In particular, the current implementation has the following limitations, which we intend to address in future Microgateway releases: + - The state parameter is guessable. + - Sessions are always shared across all Microgateway Engines using the same Redis instance. + I.e. if application A and B (with different SidecarGateways) have the same Redis instance configured in their SessionHandling CR, users which are logged into application A + may be able to access authenticated routes on application B, even if their OIDCRelyingParty configuration differs. + + + {{% /notice %}} + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of an OpenID Provider. + properties: + static: + description: Static configures an OpenID Provider by explicitly specifying all endpoints. + properties: + endpoints: + description: Endpoints specifies the OpenID Provider endpoints. + properties: + authorization: + description: Authorization specifies the endpoint to which the authorization request is sent. + properties: + uri: + description: URI specifies the endpoint address. + format: uri + minLength: 1 + pattern: ^(http|https)://.*$ + type: string + required: + - uri + type: object + token: + description: Token configures the endpoint from which the access, ID and refresh tokens are obtained. + properties: + tls: + description: TLS defines TLS settings. + properties: + certificateVerification: + description: CertificateVerification specifies how the certificate presented by the server is verified. + properties: + custom: + description: |- + Custom explicitly specifies how the server certificate should be verified. + Typical use cases include specifying a custom CA and SAN match when working with self-signed certificates or pinning a specific public key. + properties: + allowedSANs: + description: |- + AllowedSANs is a list of matchers to verify the Subject Alternative name. If specified, it will verify that the + Subject Alternative Name of the presented certificate matches one of the specified matchers. The matching uses “any” semantics, + that is to say, the SAN is verified if at least one matcher is matched. + AllowedSANs requires trustedCA to be set. + items: + description: |- + TLSValidationContextSANMatcher is a list of matchers to verify the Subject Alternative name. If specified, it will verify that the + Subject Alternative Name of the presented certificate matches one of the specified matchers. + properties: + matcher: + description: Matcher defines the string matcher for the SAN value. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + sanType: + description: SanType defines the type of SAN matcher. + enum: + - DNS + - Email + - URI + - IPAddress + type: string + required: + - matcher + - sanType + type: object + minItems: 1 + type: array + certificatePinning: + description: |- + CertificatePinning defines constraints the presented certificate must fulfill. + If more than one constraint is configured only one must be satisfied. + At least one of allowedSPKIs and allowedHashes must be set. + properties: + allowedHashes: + description: |- + AllowedHashes is a list of hex-encoded SHA-256 hashes. + If specified, it will verify that the SHA-256 of the DER-encoded presented certificate matches one of the specified values. + items: + type: string + minItems: 1 + type: array + allowedSPKIs: + description: |- + AllowedSPKIs is a list of base64-encoded SHA-256 hashes. + If specified, it will verify that the SHA-256 of the DER-encoded Subject Public Key Information (SPKI) of the presented certificate matches one of the specified values. + items: + type: string + minItems: 1 + type: array + type: object + crl: + description: CRL defines the Certificate Revocation List (CRL) settings. + properties: + lists: + description: Lists defines the list of secretRefs containing Certificate Revocation Lists. + items: + properties: + secretRef: + description: SecretRef defines the reference to a secret containing one or more CRL's (in PEM format) under the key 'ca.crl'. + properties: + name: + description: Name of the resource + minLength: 1 + type: string + required: + - name + type: object + required: + - secretRef + type: object + minItems: 1 + type: array + validationMode: + default: VerifyChain + description: ValidationMode defines whether only the leaf certificate or also the CA certs should be checked. + enum: + - VerifyLeafCertOnly + - VerifyChain + type: string + type: object + trustedCA: + description: TrustedCA defines which CA certificates are trusted. + properties: + certificates: + description: Certificates defines the list of secretRefs containing trusted CA certificates. + items: + properties: + secretRef: + description: SecretRef defines the reference to a secret containing one or more CA certificates under the key 'ca.crt'. + properties: + name: + description: Name of the resource + minLength: 1 + type: string + required: + - name + type: object + required: + - secretRef + type: object + minItems: 1 + type: array + verificationDepth: + default: 1 + description: |- + VerificationDepth specifies the hops in the certificate chain at which validation is performed. + 1 means that either the leaf or the signing CA must be in the set of trusted certificates. + format: int32 + type: integer + required: + - certificates + type: object + type: object + disabled: + description: |- + Disabled specifies to trust any certificate without verification. + THIS IS INSECURE AND SHOULD ONLY BE USED FOR TESTING. + type: object + publicCAs: + description: PublicCAs specifies to only accept certificates with a SAN matching "uri" and which are signed by a CA which is either directly or indirectly trusted by any of the root CA certificates shipped with the Airlock Microgateway Engine's base image. + type: object + type: object + ciphers: + description: Ciphers defines a list of the supported TLS cipher suites. For details on cipher list refer to the envoy documentation on cipher_suites in common tls configuration. + items: + type: string + minItems: 1 + type: array + protocol: + description: Protocol defines the supported TLS protocol versions. + properties: + maximum: + description: Maximum supported TLS version. + enum: + - TLSv1_0 + - TLSv1_1 + - TLSv1_2 + - TLSv1_3 + type: string + minimum: + description: Minimum supported TLS version. + enum: + - TLSv1_0 + - TLSv1_1 + - TLSv1_2 + - TLSv1_3 + type: string + type: object + type: object + uri: + description: URI specifies the endpoint address. + format: uri + minLength: 1 + pattern: ^(http|https)://.*$ + type: string + required: + - uri + type: object + required: + - authorization + - token + type: object + required: + - endpoints + type: object + type: object + required: + - spec + type: object + served: true + storage: true + subresources: {} diff --git a/charts/airlock/microgateway/4.3.2/crds/oidcrelyingparties.microgateway.airlock.com.yaml b/charts/airlock/microgateway/4.3.2/crds/oidcrelyingparties.microgateway.airlock.com.yaml new file mode 100644 index 0000000000..b1cba83b16 --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/crds/oidcrelyingparties.microgateway.airlock.com.yaml @@ -0,0 +1,224 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + labels: + app.kubernetes.io/name: airlock-microgateway-operator + app.kubernetes.io/version: 4.3.2 + name: oidcrelyingparties.microgateway.airlock.com +spec: + group: microgateway.airlock.com + names: + categories: + - airlock-microgateway + kind: OIDCRelyingParty + listKind: OIDCRelyingPartyList + plural: oidcrelyingparties + singular: oidcrelyingparty + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + OIDCRelyingParty specifies how the Airlock Microgateway Engine interacts with an OpenID Provider (OP). + + + {{% notice warning %}} The OIDC feature is currently in an experimental state. + + + We encourage you to try it out and give feedback, but be aware that we do not recommend using it in a production environment yet, as security has not yet been hardened. + In particular, the current implementation has the following limitations, which we intend to address in future Microgateway releases: + - The state parameter is guessable. + - Sessions are always shared across all Microgateway Engines using the same Redis instance. + I.e. if application A and B (with different SidecarGateways) have the same Redis instance configured in their SessionHandling CR, users which are logged into application A + may be able to access authenticated routes on application B, even if their OIDCRelyingParty configuration differs. + + + {{% /notice %}} + {{% notice info %}} The OIDC feature requires SessionHandling to be configured in the SidecarGateway. {{% /notice %}} + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of the OIDC Relying Party configuration. + properties: + clientID: + description: ClientID specifies the OIDCRelyingParty "client_id". + minLength: 1 + type: string + credentials: + description: Credentials used for client authentication on the back-channel with the authorization server. + properties: + clientSecret: + description: ClientSecret authenticates with the client password issued by the OpenID Provider (OP). + properties: + method: + default: BasicAuth + description: Method specifies in which format the client secret is sent with the authorization request. + enum: + - BasicAuth + - FormURLEncoded + type: string + secretRef: + description: SecretRef specifies the kubernetes secret containing the client password with key "client.secret". + properties: + name: + description: Name of the resource + minLength: 1 + type: string + required: + - name + type: object + required: + - secretRef + type: object + required: + - clientSecret + type: object + oidcProviderRef: + description: OIDCProviderRef selects the OpenID Provider (OP) used to authenticate users. + properties: + name: + description: Name of the resource + minLength: 1 + type: string + required: + - name + type: object + pathMapping: + description: PathMapping configures the action matching. + properties: + logoutPath: + description: LogoutPath specifies which request paths should initiate a logout. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + redirectPath: + description: RedirectPath specifies which request paths should be interpreted as a response from the authorization endpoint. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + required: + - logoutPath + - redirectPath + type: object + redirectURI: + description: |- + RedirectURI configures the "redirect_uri" parameter included in the authorization request. + May contain envoy command operators, e.g. '%REQ(:x-forwarded-proto)%://%REQ(:authority)%/callback'. + minLength: 1 + type: string + required: + - clientID + - credentials + - oidcProviderRef + - pathMapping + - redirectURI + type: object + required: + - spec + type: object + served: true + storage: true + subresources: {} diff --git a/charts/airlock/microgateway/4.3.2/crds/openapis.microgateway.airlock.com.yaml b/charts/airlock/microgateway/4.3.2/crds/openapis.microgateway.airlock.com.yaml new file mode 100644 index 0000000000..7ba7160c52 --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/crds/openapis.microgateway.airlock.com.yaml @@ -0,0 +1,167 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + labels: + app.kubernetes.io/name: airlock-microgateway-operator + app.kubernetes.io/version: 4.3.2 + name: openapis.microgateway.airlock.com +spec: + group: microgateway.airlock.com + names: + categories: + - airlock-microgateway + kind: OpenAPI + listKind: OpenAPIList + plural: openapis + singular: openapi + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: OpenAPI contains the configuration for the OpenAPI specification. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of the desired OpenAPI specification. + properties: + response: + description: Response defines the validation behaviour for responses. + properties: + secured: + description: Secured enables response checking. + properties: + validation: + default: Lax + description: Validation defines the validation mode for responses. + enum: + - Lax + - Strict + type: string + type: object + unsecured: + description: Unsecured disables response checking. + type: object + type: object + settings: + description: Settings defines the settings to configure OpenAPI specification enforcement. + properties: + logging: + description: Logging specifies the access log behavior. + properties: + maxFailedSubvalidations: + default: 10 + description: MaxFailedSubvalidations defines the maximum number of failed subvalidations being logged. + format: int64 + type: integer + type: object + schema: + description: Schema configures the OpenAPI specification. + properties: + source: + description: Source specifies the OpenAPI specification to be enforced. + properties: + configMapRef: + description: ConfigMapRef references the configmap by its name containing the well-known key 'openapi.json'. + properties: + name: + description: Name of the resource + minLength: 1 + type: string + required: + - name + type: object + type: object + required: + - source + type: object + threatHandlingMode: + default: Block + description: ThreatHandlingMode specifies how threats should be handled. + enum: + - Block + - LogOnly + type: string + validation: + description: Validation specifies the patterns for the validation behavior. + properties: + authentication: + description: Authentication defines the settings for the authentication scheme. + properties: + oAuth2: + description: OAuth2 specifies the OAuth2 parameters. + properties: + allowedParameters: + description: AllowedParameters specifies the allowed parameters for the authentication scheme. + properties: + builtIn: + description: BuiltIn allows configuring a set of predefined allowed parameters. + properties: + standardParameters: + default: true + description: StandardParameters defines whether the allowed parameters should be expanded by the set of common parameters. + type: boolean + type: object + custom: + description: Custom allows configuring additional allowed parameters. + items: + minLength: 1 + type: string + minItems: 1 + type: array + type: object + type: object + oidc: + description: Oidc specifies the OIDC parameters. + properties: + allowedParameters: + description: AllowedParameters specifies the allowed parameters for the authentication scheme. + properties: + builtIn: + description: BuiltIn allows configuring a set of predefined allowed parameters. + properties: + standardParameters: + default: true + description: StandardParameters defines whether the allowed parameters should be expanded by the set of common parameters. + type: boolean + type: object + custom: + description: Custom allows configuring additional allowed parameters. + items: + minLength: 1 + type: string + minItems: 1 + type: array + type: object + type: object + type: object + type: object + required: + - schema + type: object + required: + - settings + type: object + required: + - spec + type: object + served: true + storage: true diff --git a/charts/airlock/microgateway/4.3.2/crds/parsers.microgateway.airlock.com.yaml b/charts/airlock/microgateway/4.3.2/crds/parsers.microgateway.airlock.com.yaml new file mode 100644 index 0000000000..b3d51efe6b --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/crds/parsers.microgateway.airlock.com.yaml @@ -0,0 +1,358 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + labels: + app.kubernetes.io/name: airlock-microgateway-operator + app.kubernetes.io/version: 4.3.2 + name: parsers.microgateway.airlock.com +spec: + group: microgateway.airlock.com + names: + categories: + - airlock-microgateway + kind: Parser + listKind: ParserList + plural: parsers + singular: parser + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: Parser contains the configuration for content parsers (default and custom). + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of the desired parser behavior. + properties: + request: + description: Request defines the parsing for downstream requests. + properties: + custom: + description: Custom allows configuring additional rules for parser selection. + properties: + rules: + description: |- + Rules defines a custom set prepended before built-in rules of enabled request parsers. + Disable all built-in parsers to overrule them completely. + items: + properties: + action: + description: |- + Action specifies what should happen when a request condition matches. + Only one of parse or skip can be set. + properties: + parse: + description: Parse activates the configured parser. + properties: + form: + description: Form activates the Form parser. + type: object + json: + description: JSON activates the JSON parser. + type: object + multipart: + description: Multipart activates the multipart parser. + type: object + type: object + skip: + description: Skip disables any content parsing + type: object + type: object + requestConditions: + description: RequestConditions defines additional request properties which must be matched in order for this rule to apply. + properties: + header: + description: Header defines the matching headers of a request. + properties: + name: + description: Name defines the name of a header. + properties: + matcher: + description: Matcher defines the way to match a string. In comparison to a normal StringMatcher, a value is always matched ignoring the case and can't be inverted. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + value: + description: Value defines the value of a header. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + type: object + invert: + default: false + description: Invert indicates whether the request condition should be inverted. + type: boolean + mediaType: + description: MediaType defines the matching media type from the content-type header of a request. + properties: + matcher: + description: |- + NonInvertableCaseInsensitiveStringMatcher defines the way to match a string. + In comparison to a normal StringMatcher, a value is always matched ignoring the case and can't be inverted. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + method: + description: Method defines the matching methods of a request. + items: + description: Method defines common HTTP methods. + enum: + - GET + - HEAD + - POST + - PUT + - PATCH + - DELETE + - CONNECT + - OPTIONS + - TRACE + type: string + type: array + path: + description: Path defines the matching path of a request. + properties: + matcher: + description: StringMatcher defines the way to match a string. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + required: + - matcher + type: object + remoteIP: + description: RemoteIP defines the matching remote IPs of a request. + properties: + cidrRanges: + description: CIDRRanges defines the IPv4 or IPv6 CIDR ranges, e.g. ``196.148.3.128/26`` or ``2001:db8::/28``. + items: + description: CIDRRange defines an IPv4 or IPv6 CIDR range, e.g. “196.148.3.128/26“ or “2001:db8::/28“. + format: cidr + type: string + minItems: 1 + type: array + invert: + default: false + description: Invert indicates whether the match should be inverted. + type: boolean + required: + - cidrRanges + type: object + type: object + required: + - action + - requestConditions + type: object + type: array + type: object + defaultContentType: + default: application/x-www-form-urlencoded + description: DefaultContentType specifies the content-type header which should be injected into the request before parser selection if it is not already present and the request has a body. + minLength: 1 + type: string + parsers: + description: Parsers defines the configuration for the available content parsers. + properties: + form: + description: Form defines the configuration for the form parser. + properties: + enable: + default: true + description: Enable defines whether form payloads are inspected. + type: boolean + mediaTypePattern: + default: .*urlencoded.* + description: MediaTypePattern is a regex specifying the media types for which the request body should be treated as form arguments. + minLength: 1 + type: string + type: object + json: + description: JSON defines the configuration for the JSON parser. + properties: + enable: + default: true + description: Enable defines whether json payloads are inspected. + type: boolean + mediaTypePattern: + default: .*json.* + description: MediaTypePattern is a regex specifying the media types for which the request body should be treated as JSON. + minLength: 1 + type: string + type: object + multipart: + description: Multipart defines the configuration for the multipart parser. + properties: + enable: + default: true + description: Enable defines whether multipart payloads are inspected. + type: boolean + mediaTypePattern: + default: .*multipart.* + description: MediaTypePattern is a regex specifying the media types for which the request body should be treated as a multipart payload. + minLength: 1 + type: string + type: object + type: object + type: object + type: object + type: object + served: true + storage: true diff --git a/charts/airlock/microgateway/4.3.2/crds/redisproviders.microgateway.airlock.com.yaml b/charts/airlock/microgateway/4.3.2/crds/redisproviders.microgateway.airlock.com.yaml new file mode 100644 index 0000000000..32a23cbc11 --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/crds/redisproviders.microgateway.airlock.com.yaml @@ -0,0 +1,159 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + labels: + app.kubernetes.io/name: airlock-microgateway-operator + app.kubernetes.io/version: 4.3.2 + name: redisproviders.microgateway.airlock.com +spec: + group: microgateway.airlock.com + names: + categories: + - airlock-microgateway + kind: RedisProvider + listKind: RedisProviderList + plural: redisproviders + singular: redisprovider + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: RedisProvider contains a client configuration for connecting to a Redis database. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of a Redis database client configuration. + properties: + auth: + description: Auth specifies the Redis credentials. + properties: + password: + description: Password specifies the Redis password. + properties: + secretRef: + description: SecretRef selects the secret containing the Redis password under the key 'redis.password'. + properties: + name: + description: Name of the resource + minLength: 1 + type: string + required: + - name + type: object + required: + - secretRef + type: object + username: + default: default + description: Username specifies the Redis username to authenticate with. + minLength: 1 + pattern: ^[^\s]+$ + type: string + required: + - password + type: object + mode: + description: Mode configures the redis deployment mode. + properties: + standalone: + description: Standalone specifies the standalone Redis instance to connect to. + properties: + host: + description: Host specifies the IP or hostname. + minLength: 1 + pattern: ^(\d{1,3}(\.\d{1,3}){3}|([0-9a-fA-F]{1,4}|:)+(:\d{1,3}(\.\d{1,3}){3})?|[a-z0-9\-]+(\.[a-z0-9\-]+)*)$ + type: string + port: + default: 6379 + description: Port specifies the port. + maximum: 65535 + minimum: 1 + type: integer + required: + - host + type: object + type: object + timeouts: + description: Timeouts specifies the timeouts when interacting with the Redis endpoint. + properties: + connect: + default: 5s + description: Connect specifies the timeout for establishing a connection. + type: string + maxDuration: + default: 2s + description: MaxDuration specifies the response timeout. + type: string + type: object + tls: + description: TLS defines TLS settings. If not specified, TLS is disabled i.e. unencrypted TCP is used when connecting to the Redis instance. + properties: + certificateVerification: + description: CertificateVerification specifies how the certificate presented by the server is verified. + properties: + custom: + description: Custom explicitly specifies how the server certificate should be verified. + properties: + trustedCA: + description: TrustedCA defines which CA certificates are trusted. + properties: + certificates: + description: Certificates defines the list of secretRefs containing trusted CA certificates. + items: + properties: + secretRef: + description: SecretRef defines the reference to a secret containing one or more CA certificates under the key 'ca.crt'. + properties: + name: + description: Name of the resource + minLength: 1 + type: string + required: + - name + type: object + required: + - secretRef + type: object + minItems: 1 + type: array + required: + - certificates + type: object + required: + - trustedCA + type: object + disabled: + description: 'Disabled specifies to trust any certificate without verification. THIS IS INSECURE AND SHOULD ONLY BE USED FOR TESTING. Note: This setting currently also disables TLS SNI.' + type: object + publicCAs: + description: PublicCAs specifies to only accept certificates with a SAN matching the host and which are signed by a CA which is either directly or indirectly trusted by any of the root CA certificates shipped with the Airlock Microgateway Session Agent’s base image. + type: object + type: object + type: object + required: + - mode + type: object + required: + - spec + type: object + served: true + storage: true diff --git a/charts/airlock/microgateway/4.3.2/crds/sessionhandlings.microgateway.airlock.com.yaml b/charts/airlock/microgateway/4.3.2/crds/sessionhandlings.microgateway.airlock.com.yaml new file mode 100644 index 0000000000..da22e63a57 --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/crds/sessionhandlings.microgateway.airlock.com.yaml @@ -0,0 +1,77 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + labels: + app.kubernetes.io/name: airlock-microgateway-operator + app.kubernetes.io/version: 4.3.2 + name: sessionhandlings.microgateway.airlock.com +spec: + group: microgateway.airlock.com + names: + categories: + - airlock-microgateway + kind: SessionHandling + listKind: SessionHandlingList + plural: sessionhandlings + singular: sessionhandling + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + SessionHandling contains the configuration for session handling. + + + {{% notice warning %}} The Session Handling feature (required for OIDC) is currently in an experimental state. + + + We encourage you to try it out and give feedback, but be aware that we do not recommend using it in a production environment yet, as high-availability Redis configurations (e.g. Sentinel/Cluster) are not yet supported. + {{% /notice %}} + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of the desired session handling behavior. + properties: + persistence: + description: Persistence configures where to store the session state. + properties: + redisProviderRef: + description: RedisProviderRef specifies to cache session information in the provided Redis instance. + properties: + name: + description: Name of the resource + minLength: 1 + type: string + required: + - name + type: object + required: + - redisProviderRef + type: object + required: + - persistence + type: object + required: + - spec + type: object + served: true + storage: true diff --git a/charts/airlock/microgateway/4.3.2/crds/sidecargateways.microgateway.airlock.com.yaml b/charts/airlock/microgateway/4.3.2/crds/sidecargateways.microgateway.airlock.com.yaml new file mode 100644 index 0000000000..c9ec220a86 --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/crds/sidecargateways.microgateway.airlock.com.yaml @@ -0,0 +1,758 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + labels: + app.kubernetes.io/name: airlock-microgateway-operator + app.kubernetes.io/version: 4.3.2 + name: sidecargateways.microgateway.airlock.com +spec: + group: microgateway.airlock.com + names: + categories: + - airlock-microgateway + kind: SidecarGateway + listKind: SidecarGatewayList + plural: sidecargateways + singular: sidecargateway + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.status + name: Status + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: SidecarGateway contains the configuration how to configure the Airlock Microgateway Engine when used as Sidecar Container within the Pod of an application. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of the desired sidecar gateway behavior. + properties: + applications: + description: Applications defines applications which run on different ports. + items: + properties: + containerPort: + default: 8080 + description: |- + ContainerPort refers to the container port. + This must be a valid port number, 0 < x < 65536. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + downstream: + description: Downstream defines the downstream configuration for this application + properties: + protocol: + description: |- + Protocol defines the exposed HTTP protocol version. At most one of http1, http2 and auto can be set. + Default: auto: {} + properties: + auto: + description: Auto specifies that the protocol should be inferred. + properties: + http2: + description: HTTP2 specifies the settings for when HTTP/2 is inferred. + properties: + allowConnect: + default: false + description: Allows proxying Websocket and other upgrades over H2 connect. + type: boolean + type: object + type: object + http1: + description: HTTP1 specifies that the client is assumed to speak HTTP/1.1. + type: object + http2: + description: HTTP2 specifies that the client is assumed to speak HTTP/2. + properties: + allowConnect: + default: false + description: Allows proxying Websocket and other upgrades over H2 connect. + type: boolean + type: object + type: object + remoteIP: + description: |- + RemoteIP defines how the remote IP of a client is propagated. + Default: xff: {...} + properties: + connectionIP: + description: ConnectionIP configures to use the source IP address of the direct downstream connection. + type: object + customHeader: + description: CustomHeader specifies to use a custom header for remote IP extraction. + properties: + headerName: + description: HeaderName specifies the name of the custom header containing the remote IP. + minLength: 1 + type: string + required: + default: true + description: Required specifies if the custom header is required. If true and not available the request will be rejected with 403. + type: boolean + required: + - headerName + type: object + xff: + description: XFF configures to use the standard 'X-Forwarded-For' header for IP extraction. + properties: + numTrustedHops: + default: 1 + description: NumTrustedHops specifies to extract the client's originating IP from the nth rightmost entry in the X-Forwarded-For header. With the default value of 1, the IP is extracted from the rightmost entry. + format: int32 + minimum: 1 + type: integer + type: object + type: object + requestNormalizations: + description: RequestNormalizations defines a set of normalization actions which are applied to the request before route matching. + properties: + mergeSlashes: + default: true + description: MergeSlashes ensures that adjacent slashes in the path are merged into one. + type: boolean + normalizePath: + default: true + description: NormalizePath ensures normalization according to RFC 3986 without case normalization. + type: boolean + type: object + restrictions: + description: Restrictions defines restrictions for downstream. + properties: + http: + description: HTTP defines limits for the HTTP protocol. + properties: + headersLength: + anyOf: + - type: integer + - type: string + default: 60Ki + description: HeadersLength defines maximum size of all request headers combined. Requests that exceed this limit will receive a 431 response. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + timeouts: + description: Timeouts defines timeouts for downstream + properties: + http: + description: HTTP defines the settings for HTTP timeouts. + properties: + idle: + default: 5m + description: |- + Idle defines the settings for the idle timeout when no data is sent or received. + A value of 0 will completely disable the timeout. + Default: 5m + type: string + maxDuration: + default: 5m + description: |- + MaxDuration defines the total duration for a HTTP request/response stream. + A value of 0 will completely disable the timeout. + Default: 5m + type: string + requestHeaders: + default: 10s + description: |- + RequestHeaders defines the duration before all request headers must be received. + A value of 0 will completely disable the timeout. + Default: 10s + type: string + type: object + type: object + tls: + description: TLS defines the TLS settings. + properties: + ciphers: + description: Ciphers defines a list of the supported TLS cipher suites. For details on cipher list refer to the envoy documentation on cipher_suites in common tls configuration. + items: + type: string + minItems: 1 + type: array + clientCertificate: + description: |- + ClientCertificate defines the TLS settings for verification of client certificates. + At most one of ignored, optional and required can be set. + Default: ignored: {} + properties: + ignored: + description: Ignored disables verification of the client certificate. + type: object + optional: + description: |- + Optional enables verification of the client certificate if one is presented. + In this mode only trustedCA and crl settings can be configured since certificatePinning and allowedSANs require a client certificate. + properties: + crl: + description: CRL defines the Certificate Revocation List (CRL) settings. + properties: + lists: + description: Lists defines the list of secretRefs containing Certificate Revocation Lists. + items: + properties: + secretRef: + description: SecretRef defines the reference to a secret containing one or more CRL's (in PEM format) under the key 'ca.crl'. + properties: + name: + description: Name of the resource + minLength: 1 + type: string + required: + - name + type: object + required: + - secretRef + type: object + minItems: 1 + type: array + validationMode: + default: VerifyChain + description: ValidationMode defines whether only the leaf certificate or also the CA certs should be checked. + enum: + - VerifyLeafCertOnly + - VerifyChain + type: string + type: object + trustedCA: + description: TrustedCA defines which CA certificates are trusted. + properties: + certificates: + description: Certificates defines the list of secretRefs containing trusted CA certificates. + items: + properties: + secretRef: + description: SecretRef defines the reference to a secret containing one or more CA certificates under the key 'ca.crt'. + properties: + name: + description: Name of the resource + minLength: 1 + type: string + required: + - name + type: object + required: + - secretRef + type: object + minItems: 1 + type: array + verificationDepth: + default: 1 + description: |- + VerificationDepth specifies the hops in the certificate chain at which validation is performed. + 1 means that either the leaf or the signing CA must be in the set of trusted certificates. + format: int32 + type: integer + required: + - certificates + type: object + required: + - trustedCA + type: object + required: + description: |- + Required contains settings for client certificate verification. A client must present a valid certificate. + At least one of trustedCA and certificatePinning must be set. + properties: + allowedSANs: + description: |- + AllowedSANs is a list of matchers to verify the Subject Alternative name. If specified, it will verify that the + Subject Alternative Name of the presented certificate matches one of the specified matchers. The matching uses “any” semantics, + that is to say, the SAN is verified if at least one matcher is matched. + AllowedSANs requires trustedCA to be set. + items: + description: |- + TLSValidationContextSANMatcher is a list of matchers to verify the Subject Alternative name. If specified, it will verify that the + Subject Alternative Name of the presented certificate matches one of the specified matchers. + properties: + matcher: + description: Matcher defines the string matcher for the SAN value. + properties: + contains: + description: |- + Contains defines a substring match on the substring specified here. Empty contains match is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + exact: + description: |- + Exact defines an explicit match on the string specified here. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + ignoreCase: + default: false + description: IgnoreCase indicates whether the matching should be case-insensitive. In case of a regex match, the regex gets wrapped with a group `(?i:...)`. + type: boolean + prefix: + description: |- + Prefix defines a prefix match on the prefix specified here. Empty prefix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + regex: + description: |- + Regex defines a regex match on the regular expression specified here. Google's [RE2 regex engine](https://github.com/google/re2/wiki/Syntax) is used. + The regex matches only single-line by default, even with ".*". To match a multi-line string prepend (?s) to your regex. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + suffix: + description: |- + Suffix defines a suffix match on the suffix specified here. Empty suffix is not allowed, please use regex instead. + Only one of exact, prefix, suffix, regex or contains can be set. + minLength: 1 + type: string + type: object + sanType: + description: SanType defines the type of SAN matcher. + enum: + - DNS + - Email + - URI + - IPAddress + type: string + required: + - matcher + - sanType + type: object + minItems: 1 + type: array + certificatePinning: + description: |- + CertificatePinning defines the constraints a client certificate must fulfill. + If more than one constraint is configured only one must be satisfied. + At least one of allowedSPKIs and allowedHashes must be set. + properties: + allowedHashes: + description: |- + AllowedHashes is a list of hex-encoded SHA-256 hashes. + If specified, it will verify that the SHA-256 of the DER-encoded presented certificate matches one of the specified values. + items: + type: string + minItems: 1 + type: array + allowedSPKIs: + description: |- + AllowedSPKIs is a list of base64-encoded SHA-256 hashes. + If specified, it will verify that the SHA-256 of the DER-encoded Subject Public Key Information (SPKI) of the presented certificate matches one of the specified values. + items: + type: string + minItems: 1 + type: array + type: object + crl: + description: CRL defines the Certificate Revocation List (CRL) settings. + properties: + lists: + description: Lists defines the list of secretRefs containing Certificate Revocation Lists. + items: + properties: + secretRef: + description: SecretRef defines the reference to a secret containing one or more CRL's (in PEM format) under the key 'ca.crl'. + properties: + name: + description: Name of the resource + minLength: 1 + type: string + required: + - name + type: object + required: + - secretRef + type: object + minItems: 1 + type: array + validationMode: + default: VerifyChain + description: ValidationMode defines whether only the leaf certificate or also the CA certs should be checked. + enum: + - VerifyLeafCertOnly + - VerifyChain + type: string + type: object + trustedCA: + description: TrustedCA defines which CA certificates are trusted. + properties: + certificates: + description: Certificates defines the list of secretRefs containing trusted CA certificates. + items: + properties: + secretRef: + description: SecretRef defines the reference to a secret containing one or more CA certificates under the key 'ca.crt'. + properties: + name: + description: Name of the resource + minLength: 1 + type: string + required: + - name + type: object + required: + - secretRef + type: object + minItems: 1 + type: array + verificationDepth: + default: 1 + description: |- + VerificationDepth specifies the hops in the certificate chain at which validation is performed. + 1 means that either the leaf or the signing CA must be in the set of trusted certificates. + format: int32 + type: integer + required: + - certificates + type: object + type: object + type: object + enable: + default: false + description: Enable defines if the downstream connection is encrypted. + type: boolean + protocol: + description: Protocol defines the supported TLS protocol versions. + properties: + maximum: + description: Maximum supported TLS version. + enum: + - TLSv1_0 + - TLSv1_1 + - TLSv1_2 + - TLSv1_3 + type: string + minimum: + description: Minimum supported TLS version. + enum: + - TLSv1_0 + - TLSv1_1 + - TLSv1_2 + - TLSv1_3 + type: string + type: object + secretRef: + description: SecretRef defines the reference to the TLS server certificate (secret of type kubernetes.io/tls). + properties: + name: + description: Name of the resource + minLength: 1 + type: string + required: + - name + type: object + xfcc: + description: |- + XFCC defines the handling of X-Forwarded-Client-Cert header. Meaning of the possible values: + _Sanitize_: Do not send the XFCC header to the next hop. This is the default value. + _ForwardOnly_: When the client connection is mTLS (Mutual TLS), forward the XFCC header in the request. + _AppendAndForward_: When the client connection is mTLS, append the client certificate information to the request’s XFCC header and forward it. + _SanitizeAndSet_: When the client connection is mTLS, reset the XFCC header with the client certificate information and send it to the next hop. + _AlwaysForwardOnly_: Always forward the XFCC header in the request, regardless of whether the client connection is mTLS. + Note: When forwarding the XFCC header in the request you might have to adjust the header length restrictions (See sidecargateway.spec.applications.downstream.restrictions.http) + enum: + - Sanitize + - ForwardOnly + - AppendAndForward + - SanitizeAndSet + - AlwaysForwardOnly + type: string + type: object + type: object + envoyHTTPFilterRefs: + description: EnvoyHTTPFilterRefs selects the relevant EnvoyHTTPFilters. + properties: + prepend: + description: Prepend selects the relevant EnvoyHTTPFilters which are added before those configured by the Airlock Microgateway. + items: + properties: + name: + description: Name of the resource + minLength: 1 + type: string + required: + - name + type: object + type: array + type: object + routes: + description: Routes defines the security configurations for different paths. The first matching route (from top to bottom) applies. + items: + description: |- + SidecarGatewayApplicationRoute defines the security configurations for different paths. + At most one of secured and unsecured can be set. + Default: secured: {...} + properties: + pathPrefix: + default: / + description: PathPrefix defines the path prefix used during route selection. + minLength: 1 + type: string + secured: + description: Secured enables WAF processing for this route. + properties: + accessControlRef: + description: |- + AccessControlRef selects the relevant AccessControl configuration resource. + If undefined, Airlock Microgateway does not perform any access control. + properties: + name: + description: Name of the resource + minLength: 1 + type: string + required: + - name + type: object + contentSecurityRef: + description: |- + ContentSecurityRef selects the relevant ContentSecurity configuration resource. + If undefined, default settings are applied, designed to work with most upstream web application services. + properties: + name: + description: Name of the resource + minLength: 1 + type: string + required: + - name + type: object + type: object + unsecured: + description: |- + Unsecured disables all WAF functionality and therefore protection for this route. + WARNING: Using this setting when the application is exposed to untrusted downstream traffic is highly discouraged. + type: object + type: object + type: array + x-kubernetes-list-map-keys: + - pathPrefix + x-kubernetes-list-type: map + telemetryRef: + description: |- + TelemetryRef selects the relevant Telemetry configuration resource. + If undefined, default settings are applied, designed to work with most upstream web application services. + properties: + name: + description: Name of the resource + minLength: 1 + type: string + required: + - name + type: object + upstream: + description: Upstream defines the upstream configuration for this application + properties: + protocol: + description: |- + Protocol defines HTTP protocol version used to communicate with the upstream. At most one of http1, http2 and auto can be set. + Default: auto: {} + properties: + auto: + description: Auto specifies to negotiate the protocol with TLS ALPN (if TLS is enabled) or, as a fallback, use the same protocol that is used by the downstream connection. + properties: + http2: + description: HTTP2 specifies the settings for when HTTP/2 is inferred. + properties: + allowConnect: + default: false + description: Allows proxying Websocket and other upgrades over H2 connect. + type: boolean + type: object + type: object + http1: + description: HTTP1 specifies to use HTTP/1.1. + type: object + http2: + description: HTTP2 specifies to use HTTP/2. + properties: + allowConnect: + default: false + description: Allows proxying Websocket and other upgrades over H2 connect. + type: boolean + type: object + type: object + timeouts: + description: Timeouts defines the timeout settings. + properties: + http: + description: HTTP defines the settings for HTTP timeouts. + properties: + idle: + description: |- + Timeout defines the settings for http timeouts. If this setting is not specified, the value of applications[].downstream.timeouts.http.idle is inherited. + A value of 0 will completely disable the timeout. + type: string + maxDuration: + default: 15s + description: |- + MaxDuration defines the total duration for a HTTP request/response stream. + Default: 15s + type: string + type: object + type: object + tls: + description: TLS defines the TLS settings. + properties: + ciphers: + description: Ciphers defines a list of the supported TLS cipher suites. For details on cipher list refer to the envoy documentation on cipher_suites in common tls configuration. + items: + type: string + minItems: 1 + type: array + enable: + default: false + description: Enable defines if the upstream connection is encrypted. + type: boolean + protocol: + description: Protocol defines the supported TLS protocol versions. + properties: + maximum: + description: Maximum supported TLS version. + enum: + - TLSv1_0 + - TLSv1_1 + - TLSv1_2 + - TLSv1_3 + type: string + minimum: + description: Minimum supported TLS version. + enum: + - TLSv1_0 + - TLSv1_1 + - TLSv1_2 + - TLSv1_3 + type: string + type: object + type: object + type: object + type: object + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - containerPort + x-kubernetes-list-type: map + envoyClusterRefs: + description: EnvoyClusterRefs selects the relevant EnvoyClusters. + items: + properties: + name: + description: Name of the resource + minLength: 1 + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + podSelector: + description: PodSelector defines to which Pods the configuration will be applied to. + properties: + matchLabels: + additionalProperties: + type: string + description: MatchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels. + type: object + type: object + sessionHandlingRef: + description: SessionHandlingRef selects the SessionHandling configuration to apply. + properties: + name: + description: Name of the resource + minLength: 1 + type: string + required: + - name + type: object + required: + - applications + type: object + status: + description: Most recently observed status of the SidecarGateway which is populated by the system. This data is read-only and may not be up to date. + properties: + conditions: + items: + properties: + lastTransitionTime: + description: Last time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: A human-readable message indicating details about the transition. + type: string + reason: + description: The reason for the condition's last transition. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: Type of SidecarGateway condition. + type: string + required: + - status + - type + type: object + type: array + pods: + items: + properties: + envoyConfig: + description: EnvoyConfig indicates the name of the EnvoyConfig CR for the Pod. + type: string + name: + description: Name indicates the name of a Pod selected by the SidecarGateway. + type: string + sessionAgentSecret: + type: string + required: + - name + type: object + type: array + status: + type: string + unmanagedPods: + items: + properties: + managedBy: + description: ManagedBy indicates the Airlock Microgateway Operator instance which manages this Pod. + type: string + name: + description: Name indicates the name of a Pod selected by the SidecarGateway. + type: string + sessionAgentSecret: + type: string + required: + - name + type: object + type: array + required: + - status + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/airlock/microgateway/4.3.2/crds/telemetries.microgateway.airlock.com.yaml b/charts/airlock/microgateway/4.3.2/crds/telemetries.microgateway.airlock.com.yaml new file mode 100644 index 0000000000..47d03cd4cd --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/crds/telemetries.microgateway.airlock.com.yaml @@ -0,0 +1,96 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + labels: + app.kubernetes.io/name: airlock-microgateway-operator + app.kubernetes.io/version: 4.3.2 + name: telemetries.microgateway.airlock.com +spec: + group: microgateway.airlock.com + names: + categories: + - airlock-microgateway + kind: Telemetry + listKind: TelemetryList + plural: telemetries + singular: telemetry + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: Telemetry contains the configuration for telemetry (logging, metrics & tracing). + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of the desired telemetry behavior. + properties: + correlation: + description: Correlation defines the correlation aspects of Telemetry. + properties: + idSource: + description: IDSource specifies how an external correlation ID should be obtained for a request. If not specified, no correlation ID will be logged. + properties: + header: + description: Header specifies to extract the correlation ID from a request header. If the header is absent from a request, no correlation ID will be logged. + properties: + name: + default: X-Correlation-Id + description: Name of the header (case-insensitive) from which to extract the correlation ID. + minLength: 1 + type: string + type: object + required: + - header + type: object + request: + description: Request defines the request related correlation settings of Telemetry. + properties: + allowDownstreamRequestID: + default: true + description: AllowDownstreamRequestID defines whether trace sampling will consider a provided x-request-id. + type: boolean + alterRequestID: + default: true + description: AlterRequestID defines whether to alter the UUID to reflect the trace sampling decision. If disabled no modification to the UUID will be performed, this may break tracing in the upstream. + type: boolean + type: object + type: object + logging: + description: Logging defines the logging aspects of Telemetry. + properties: + accessLog: + description: AccessLog defines the access log settings of Telemetry. + properties: + format: + description: Format defines the Access Log format of the sidecar. + properties: + json: + description: JSON defines the Access Log format as JSON. + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + type: object + type: object + type: object + type: object + served: true + storage: true diff --git a/charts/airlock/microgateway/4.3.2/dashboards/blockLogs.json b/charts/airlock/microgateway/4.3.2/dashboards/blockLogs.json new file mode 100644 index 0000000000..ef0ce6d624 --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/dashboards/blockLogs.json @@ -0,0 +1,510 @@ +{ + "__inputs": [ + { + "name": "DS_LOKI", + "label": "Loki", + "description": "", + "type": "datasource", + "pluginId": "loki", + "pluginName": "Loki" + }, + { + "name": "DS_PROMETHEUS", + "label": "Prometheus", + "description": "", + "type": "datasource", + "pluginId": "prometheus", + "pluginName": "Prometheus" + } + ], + "__elements": {}, + "__requires": [ + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "10.2.0" + }, + { + "type": "datasource", + "id": "loki", + "name": "Loki", + "version": "1.0.0" + }, + { + "type": "datasource", + "id": "prometheus", + "name": "Prometheus", + "version": "1.0.0" + }, + { + "type": "panel", + "id": "table", + "name": "Table", + "version": "" + } + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "description": "Blocked requests by Airlock Microgateway retrieved from corresponding access logs.\n\nThe dashboard can be filtered by namespace and block type. Column filters on the table allow for even a more granular filtering of the logs.", + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": null, + "links": [ + { + "asDropdown": true, + "icon": "external link", + "includeVars": true, + "keepTime": true, + "tags": [ + "airlock-microgateway" + ], + "targetBlank": true, + "title": "Airlock Microgateway", + "tooltip": "", + "type": "dashboards", + "url": "" + } + ], + "panels": [ + { + "datasource": { + "type": "loki", + "uid": "${DS_LOKI}" + }, + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "text", + "mode": "fixed" + }, + "custom": { + "align": "auto", + "cellOptions": { + "type": "auto" + }, + "filterable": true, + "inspect": true + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Namespace" + }, + "properties": [ + { + "id": "custom.width", + "value": 221 + }, + { + "id": "custom.filterable" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Timestamp" + }, + "properties": [ + { + "id": "custom.width", + "value": 214 + }, + { + "id": "unit", + "value": "dateTimeAsIso" + }, + { + "id": "custom.filterable" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Method" + }, + "properties": [ + { + "id": "custom.width", + "value": 89 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Client IP" + }, + "properties": [ + { + "id": "custom.width", + "value": 138 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Request ID" + }, + "properties": [ + { + "id": "custom.width", + "value": 328 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Block Type" + }, + "properties": [ + { + "id": "custom.width", + "value": 116 + }, + { + "id": "custom.filterable", + "value": false + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Request Size" + }, + "properties": [ + { + "id": "custom.width", + "value": 126 + }, + { + "id": "unit", + "value": "bytes" + }, + { + "id": "custom.align", + "value": "right" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Attack Type" + }, + "properties": [ + { + "id": "custom.width", + "value": 217 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Application" + }, + "properties": [ + { + "id": "custom.width", + "value": 207 + } + ] + } + ] + }, + "gridPos": { + "h": 27, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 2, + "options": { + "cellHeight": "sm", + "footer": { + "countRows": false, + "enablePagination": true, + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true, + "sortBy": [] + }, + "pluginVersion": "11.0.0", + "targets": [ + { + "datasource": { + "type": "loki", + "uid": "${DS_LOKI}" + }, + "editorMode": "code", + "expr": "{container=\"airlock-microgateway-engine\", namespace=~\"${namespace:regex}\"} |= \"airlock_request_blocked_deny_rule\" |= \"envoy.access\"\n| json http_method=\"http.request.method\", url=\"url.path\", request_size=\"http.request.bytes\", client_ip=\"network.forwarded_ip\", request_id=\"http.request.id\", details=\"airlock.deny_rules.matches\"\n| label_format block_type=\"deny_rules\", attack_type=`{{ range $q := fromJson .details }} {{ if eq $q.threat_handling_mode \"block\" }} {{ $q.rule_key }} {{ end }} {{ end }}` | block_type=~\"${blockType:regex}\"", + "hide": false, + "queryType": "range", + "refId": "Deny Rule Blocks" + }, + { + "datasource": { + "type": "loki", + "uid": "${DS_LOKI}" + }, + "editorMode": "code", + "expr": "{container=\"airlock-microgateway-engine\", namespace=~\"${namespace:regex}\"} |= \"airlock_request_blocked_limit\" |= \"envoy.access\"\n| json http_method=\"http.request.method\", url=\"url.path\", request_size=\"http.request.bytes\", client_ip=\"network.forwarded_ip\", request_id=\"http.request.id\", details=\"airlock.limits.matches\"\n| label_format block_type=\"limits\", attack_type=`{{ range $q := fromJson .details }} {{ if eq $q.threat_handling_mode \"block\" }} {{ $q.rule }} {{ end }} {{ end }}` | block_type=~\"${blockType:regex}\"", + "hide": false, + "queryType": "range", + "refId": "Limit Blocks" + }, + { + "datasource": { + "type": "loki", + "uid": "${DS_LOKI}" + }, + "editorMode": "code", + "expr": "{container=\"airlock-microgateway-engine\", namespace=~\"${namespace:regex}\"} |= \"airlock_request_blocked_openapi\" |= \"envoy.access\"\n| json http_method=\"http.request.method\", url=\"url.path\", request_size=\"http.request.bytes\", client_ip=\"network.forwarded_ip\", request_id=\"http.request.id\", reference=\"airlock.openapi.reference\", constraint=\"airlock.openapi.request.failed_validation.constraint\", position=\"airlock.openapi.request.failed_validation.position\", message=\"airlock.openapi.request.failed_validation.message\"\n| label_format block_type=\"openapi\", attack_type=\"openapi\", details=`{{.reference }}: {{.constraint }} at {{ .position }} ({{ .message }})` | block_type=~\"${blockType:regex}\"", + "hide": false, + "queryType": "range", + "refId": "OpenAPI Blocks" + }, + { + "datasource": { + "type": "loki", + "uid": "${DS_LOKI}" + }, + "editorMode": "code", + "expr": "{container=\"airlock-microgateway-engine\", namespace=~\"${namespace:regex}\"} |= \"airlock_request_blocked_parser\" |= \"envoy.access\"\n| json http_method=\"http.request.method\", url=\"url.path\", request_size=\"http.request.bytes\", client_ip=\"network.forwarded_ip\", request_id=\"http.request.id\", attack_type=\"airlock.parser\", failed_check=\"airlock.parser.matches[0].failed_check\", message=\"airlock.parser.matches[0].message\"\n| label_format block_type=\"parsing\", attack_type=\"parsing\", details=`{{.failed_check}}: {{.message}}` | block_type=~\"${blockType:regex}\"", + "hide": false, + "queryType": "range", + "refId": "Parser Blocks" + }, + { + "datasource": { + "type": "loki", + "uid": "${DS_LOKI}" + }, + "editorMode": "code", + "expr": "{container=\"airlock-microgateway-engine\", namespace=~\"${namespace:regex}\"} |= \"airlock_request_blocked_graphql\" |= \"envoy.access\"\n| json http_method=\"http.request.method\", url=\"url.path\", request_size=\"http.request.bytes\", client_ip=\"network.forwarded_ip\", request_id=\"http.request.id\", reference=\"airlock.graphql.reference\", message=\"airlock.graphql.request.failed_validation.message\"\n| label_format block_type=\"graphql\", attack_type=\"graphql\", details=`{{ .reference }}: {{ .message }}` | block_type=~\"${blockType:regex}\"", + "hide": false, + "queryType": "range", + "refId": "GraphQL Blocks" + } + ], + "title": "Blocked Request logs", + "transformations": [ + { + "id": "merge", + "options": {} + }, + { + "id": "extractFields", + "options": { + "format": "json", + "source": "labels" + } + }, + { + "id": "filterFieldsByName", + "options": { + "byVariable": false, + "include": { + "names": [ + "Time", + "attack_type", + "block_type", + "client_ip", + "details", + "http_method", + "namespace", + "request_id", + "request_size", + "url", + "pod" + ] + } + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Line": true, + "id": true, + "labelTypes": true, + "labels": true, + "tsNs": false + }, + "includeByName": {}, + "indexByName": { + "Time": 0, + "attack_type": 7, + "block_type": 6, + "client_ip": 9, + "details": 8, + "http_method": 3, + "namespace": 1, + "pod": 2, + "request_id": 10, + "request_size": 5, + "url": 4 + }, + "renameByName": { + "Time": "Timestamp", + "attack_type": "Attack Type", + "block_type": "Block Type", + "client_ip": "Client IP", + "details": "Details", + "http_method": "Method", + "namespace": "Namespace", + "pod": "Pod", + "request_id": "Request ID", + "request_size": "Request Size", + "tsNs": "", + "url": "Path" + } + } + } + ], + "type": "table" + } + ], + "schemaVersion": 39, + "tags": [ + "airlock-microgateway" + ], + "templating": { + "list": [ + { + "current": { + "selected": false, + "text": "Loki", + "value": "P8E80F9AEF21F6940" + }, + "hide": 2, + "includeAll": false, + "label": "DS_LOKI", + "multi": false, + "name": "DS_LOKI", + "options": [], + "query": "loki", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + }, + { + "allValue": ".*", + "current": {}, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "definition": "label_values(microgateway_license_http_rq_total,namespace)", + "hide": 0, + "includeAll": true, + "label": "Application Namespace", + "multi": true, + "name": "namespace", + "options": [], + "query": { + "qryType": 1, + "query": "label_values(microgateway_license_http_rq_total,namespace)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 5, + "type": "query" + }, + { + "allValue": ".*", + "current": {}, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "definition": "label_values(microgateway_http_downstream_rq_threats_blocked_total,block_type)", + "hide": 0, + "includeAll": true, + "label": "Block Type", + "multi": true, + "name": "blockType", + "options": [], + "query": { + "qryType": 1, + "query": "label_values(microgateway_http_downstream_rq_threats_blocked_total,block_type)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 5, + "type": "query" + }, + { + "current": { + "selected": false, + "text": "Prometheus", + "value": "PBFA97CFB590B2093" + }, + "hide": 2, + "includeAll": false, + "label": "DS_PROMETHEUS", + "multi": false, + "name": "DS_PROMETHEUS", + "options": [], + "query": "prometheus", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + } + ] + }, + "time": { + "from": "now-15m", + "to": "now" + }, + "timeRangeUpdatedDuringEditOrView": false, + "timepicker": {}, + "timezone": "browser", + "title": "Airlock Microgateway Blocked Request Logs", + "uid": "adnyzcvwnyadcc", + "version": 3, + "weekStart": "" +} \ No newline at end of file diff --git a/charts/airlock/microgateway/4.3.2/dashboards/blockMetrics.json b/charts/airlock/microgateway/4.3.2/dashboards/blockMetrics.json new file mode 100644 index 0000000000..ba383d22e8 --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/dashboards/blockMetrics.json @@ -0,0 +1,758 @@ +{ + "__inputs": [ + { + "name": "DS_PROMETHEUS", + "label": "Prometheus", + "description": "", + "type": "datasource", + "pluginId": "prometheus", + "pluginName": "Prometheus" + } + ], + "__elements": {}, + "__requires": [ + { + "type": "panel", + "id": "barchart", + "name": "Bar chart", + "version": "" + }, + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "10.2.0" + }, + { + "type": "datasource", + "id": "prometheus", + "name": "Prometheus", + "version": "1.0.0" + }, + { + "type": "panel", + "id": "stat", + "name": "Stat", + "version": "" + }, + { + "type": "panel", + "id": "timeseries", + "name": "Time series", + "version": "" + } + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "description": "Metrics on requests blocked by Airlock Microgateway.\n\nDashboard can be filtered by namespaces as well as block types.", + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": null, + "links": [ + { + "asDropdown": true, + "icon": "external link", + "includeVars": true, + "keepTime": true, + "tags": [ + "airlock-microgateway" + ], + "targetBlank": true, + "title": "Airlock Microgateway", + "tooltip": "", + "type": "dashboards", + "url": "" + } + ], + "panels": [ + { + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 6, + "title": "Airlock Microgateway Block Metrics", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "Total number of requests processed by Airlock Microgateway.", + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "text", + "mode": "fixed" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 4, + "x": 0, + "y": 1 + }, + "id": 1, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "code", + "exemplar": false, + "expr": "round(sum(increase(microgateway_license_http_rq_total{namespace=~\"${namespace:regex}\", job=~\"${operator_namespace.regex}/.*-engine\"}[$__range])))", + "format": "time_series", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "instant": true, + "legendFormat": "Processed Requests", + "range": false, + "refId": "A", + "useBackend": false + } + ], + "title": "Requests", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "Ratio of blocked requests vs. processed requests by Airlock Microgateway.", + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "text", + "mode": "fixed" + }, + "mappings": [ + { + "options": { + "match": "nan", + "result": { + "index": 0, + "text": "n/a" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 4, + "x": 4, + "y": 1 + }, + "id": 2, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "last" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "code", + "exemplar": false, + "expr": "sum(increase(microgateway_http_downstream_rq_threats_blocked_total{block_type=~\"${blockType:regex}\", namespace=~\"${namespace:regex}\", job=~\"${operator_namespace.regex}/.*-engine\"}[$__range])) / sum(increase(microgateway_license_http_rq_total{namespace=~\"${namespace:regex}\", job=~\"${operator_namespace.regex}/.*-engine\"}[$__range]))", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": true, + "legendFormat": "Blocked Requests (%)", + "range": false, + "refId": "A", + "useBackend": false + } + ], + "title": "% Blocked Requests", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "Requests per second processed by Airlock Microgateway along with the corresponding block rate.", + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "blue", + "mode": "fixed" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "left", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "blue", + "value": null + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "% Blocks" + }, + "properties": [ + { + "id": "custom.axisPlacement", + "value": "right" + }, + { + "id": "unit", + "value": "percentunit" + }, + { + "id": "color", + "value": { + "fixedColor": "orange", + "mode": "fixed" + } + }, + { + "id": "max", + "value": 1 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Requests per second" + }, + "properties": [ + { + "id": "unit", + "value": "short" + }, + { + "id": "custom.fillOpacity", + "value": 25 + } + ] + } + ] + }, + "gridPos": { + "h": 10, + "w": 20, + "x": 0, + "y": 5 + }, + "id": 3, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "timezone": [ + "" + ], + "tooltip": { + "maxHeight": 600, + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum(rate(microgateway_license_http_rq_total{namespace=~\"${namespace:regex}\", job=~\"${operator_namespace.regex}/.*-engine\"}[1m]))", + "instant": false, + "legendFormat": "Requests per second", + "range": true, + "refId": "Requests per Second" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(rate(microgateway_http_downstream_rq_threats_blocked_total{block_type=~\"${blockType:regex}\", namespace=~\"${namespace:regex}\", job=~\"${operator_namespace.regex}/.*-engine\"}[1m])) / sum(rate(microgateway_license_http_rq_total{namespace=~\"${namespace:regex}\", job=~\"${operator_namespace.regex}/.*-engine\"}[1m]))", + "hide": false, + "instant": false, + "legendFormat": "% Blocks", + "range": true, + "refId": "Blocks" + } + ], + "title": "Requests vs. % Blocks", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "Blocked requests by block type.", + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "super-light-orange", + "mode": "fixed" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisGridShow": true, + "axisLabel": "", + "axisPlacement": "auto", + "fillOpacity": 80, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineWidth": 0, + "scaleDistribution": { + "type": "linear" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "fieldMinMax": false, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 11, + "w": 10, + "x": 0, + "y": 15 + }, + "id": 4, + "options": { + "barRadius": 0, + "barWidth": 0.8, + "fullHighlight": false, + "groupWidth": 0.7, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": false + }, + "orientation": "horizontal", + "showValue": "never", + "stacking": "none", + "tooltip": { + "maxHeight": 600, + "mode": "single", + "sort": "asc" + }, + "xField": "block_type", + "xTickLabelRotation": 0, + "xTickLabelSpacing": 0 + }, + "pluginVersion": "10.4.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "round(sum by (block_type) (increase(microgateway_http_downstream_rq_threats_blocked_total{block_type=~\"${blockType:regex}\", namespace=~\"${namespace:regex}\", job=~\"${operator_namespace.regex}/.*-engine\"}[$__range])))", + "format": "time_series", + "instant": true, + "legendFormat": "__auto", + "range": false, + "refId": "A" + } + ], + "title": "Block Type", + "transformations": [ + { + "id": "reduce", + "options": { + "includeTimeField": false, + "labelsToFields": true, + "mode": "seriesToRows", + "reducers": [ + "sum" + ] + } + } + ], + "type": "barchart" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "Blocked requests by attack type, which are subsets of the various block types.", + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "light-orange", + "mode": "fixed" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "fillOpacity": 80, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineWidth": 1, + "scaleDistribution": { + "type": "linear" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 11, + "w": 10, + "x": 10, + "y": 15 + }, + "id": 5, + "options": { + "barRadius": 0, + "barWidth": 0.8, + "fullHighlight": false, + "groupWidth": 0.7, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": false + }, + "orientation": "horizontal", + "showValue": "never", + "stacking": "none", + "tooltip": { + "maxHeight": 600, + "mode": "single", + "sort": "none" + }, + "xField": "attack_type", + "xTickLabelRotation": 0, + "xTickLabelSpacing": 0 + }, + "pluginVersion": "10.4.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "round(sum by (attack_type) (increase(microgateway_http_downstream_rq_threats_blocked_total{block_type=~\"${blockType:regex}\", namespace=~\"${namespace:regex}\", job=~\"${operator_namespace.regex}/.*-engine\"}[$__range])))", + "instant": true, + "legendFormat": "__auto", + "range": false, + "refId": "A" + } + ], + "title": "Attack Type", + "transformations": [ + { + "id": "reduce", + "options": { + "labelsToFields": true, + "reducers": [ + "sum" + ] + } + } + ], + "type": "barchart" + } + ], + "refresh": "", + "schemaVersion": 39, + "tags": [ + "airlock-microgateway" + ], + "templating": { + "list": [ + { + "current": { + "selected": false, + "text": "Prometheus", + "value": "PBFA97CFB590B2093" + }, + "hide": 2, + "includeAll": false, + "label": "Datasource Prometheus", + "multi": false, + "name": "DS_PROMETHEUS", + "options": [], + "query": "prometheus", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + }, + { + "current": { + "selected": false, + "text": "Loki", + "value": "P8E80F9AEF21F6940" + }, + "hide": 2, + "includeAll": false, + "label": "DS_LOKI", + "multi": false, + "name": "DS_LOKI", + "options": [], + "query": "loki", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + }, + { + "allValue": ".*", + "current": {}, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "definition": "label_values(microgateway_license_valid,namespace)", + "hide": 0, + "includeAll": true, + "label": "Operator Namespace", + "multi": true, + "name": "operator_namespace", + "options": [], + "query": { + "qryType": 1, + "query": "label_values(microgateway_license_valid,namespace)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 2, + "regex": ".*", + "skipUrlSync": false, + "sort": 0, + "type": "query" + }, + { + "allValue": ".*", + "current": {}, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "definition": "label_values(microgateway_license_http_rq_total,namespace)", + "hide": 0, + "includeAll": true, + "label": "Application Namespace", + "multi": true, + "name": "namespace", + "options": [], + "query": { + "qryType": 1, + "query": "label_values(microgateway_license_http_rq_total,namespace)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 5, + "type": "query" + }, + { + "allValue": ".*", + "current": {}, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "definition": "label_values(microgateway_http_downstream_rq_threats_blocked_total,block_type)", + "hide": 0, + "includeAll": true, + "label": "Block Type", + "multi": true, + "name": "blockType", + "options": [], + "query": { + "qryType": 1, + "query": "label_values(microgateway_http_downstream_rq_threats_blocked_total,block_type)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 5, + "type": "query" + } + ] + }, + "time": { + "from": "now-24h", + "to": "now" + }, + "timeRangeUpdatedDuringEditOrView": false, + "timepicker": { + "hidden": false + }, + "timezone": "browser", + "title": "Airlock Microgateway Block Metrics", + "uid": "ddnqoczu7qvb4cdd3dd", + "version": 3, + "weekStart": "" +} \ No newline at end of file diff --git a/charts/airlock/microgateway/4.3.2/dashboards/license.json b/charts/airlock/microgateway/4.3.2/dashboards/license.json new file mode 100644 index 0000000000..b9d5777e23 --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/dashboards/license.json @@ -0,0 +1,521 @@ +{ + "__inputs": [ + { + "name": "DS_PROMETHEUS", + "label": "Prometheus", + "description": "", + "type": "datasource", + "pluginId": "prometheus", + "pluginName": "Prometheus" + } + ], + "__elements": {}, + "__requires": [ + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "10.2.0" + }, + { + "type": "datasource", + "id": "prometheus", + "name": "Prometheus", + "version": "1.0.0" + }, + { + "type": "panel", + "id": "stat", + "name": "Stat", + "version": "" + }, + { + "type": "panel", + "id": "timeseries", + "name": "Time series", + "version": "" + } + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": null, + "links": [ + { + "asDropdown": true, + "icon": "external link", + "includeVars": true, + "keepTime": true, + "tags": [ + "airlock-microgateway" + ], + "targetBlank": true, + "title": "Airlock Microgateway", + "tooltip": "", + "type": "dashboards", + "url": "" + } + ], + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "License status of Airlock Microgateway.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "0": { + "color": "red", + "index": 1, + "text": "Invalid" + }, + "1": { + "color": "green", + "index": 0, + "text": "Valid" + } + }, + "type": "value" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 0, + "y": 0 + }, + "id": 1, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "min(microgateway_license_valid{namespace=~\"${operator_namespace.regex}\"})", + "instant": true, + "legendFormat": "License Status", + "range": false, + "refId": "Licenses" + } + ], + "title": "License Status", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "Expiry date of the Airlock Microgateway license associated with the selected operator.", + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "text", + "mode": "fixed" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "time: L" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 4, + "x": 3, + "y": 0 + }, + "id": 4, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "min(microgateway_license_expiry_timestamp_seconds{namespace=~\"${operator_namespace.regex}\"})*1000", + "instant": true, + "legendFormat": "Expiry Date (MM/DD/YYYY)", + "range": false, + "refId": "A" + } + ], + "title": "License Expiry Date", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "Number of licensed requests for applications protected by Airlock Microgateway.", + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "text", + "mode": "fixed" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 4, + "x": 7, + "y": 0 + }, + "id": 6, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum(microgateway_license_max_rq_count_per_month{namespace=~\"${operator_namespace.regex}\"})", + "instant": true, + "legendFormat": "Licensed Requests", + "range": false, + "refId": "A" + } + ], + "title": "Licensed Requests", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "Estimated number of requests protected by Airlock Microgateway over 30 days based on the last 7 days.", + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "text", + "mode": "fixed" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 5, + "x": 11, + "y": 0 + }, + "id": 2, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum(increase(microgateway_license_http_rq_total{job=~\"${operator_namespace.regex}/.*-engine\"}[7d]))/7*30", + "instant": true, + "legendFormat": "Estimated Requests", + "range": false, + "refId": "A" + } + ], + "title": "Requests over 30 days (estimated)", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "Number of requests per week processed by Airlock Microgateway.", + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "blue", + "mode": "fixed" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 12, + "w": 16, + "x": 0, + "y": 4 + }, + "id": 5, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "maxHeight": 600, + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(avg_over_time(increase(microgateway_license_http_rq_total{job=~\"${operator_namespace.regex}/.*-engine\"}[7d])[2m:30s]))", + "instant": false, + "legendFormat": "# Requests per week", + "range": true, + "refId": "A" + } + ], + "title": "Processed Requests per week", + "type": "timeseries" + } + ], + "schemaVersion": 39, + "tags": [ + "airlock-microgateway" + ], + "templating": { + "list": [ + { + "current": { + "selected": false, + "text": "Prometheus", + "value": "PBFA97CFB590B2093" + }, + "hide": 2, + "includeAll": false, + "label": "DS_PROMETHEUS", + "multi": false, + "name": "DS_PROMETHEUS", + "options": [], + "query": "prometheus", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + }, + { + "allValue": ".*", + "current": {}, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "definition": "label_values(microgateway_license_valid,namespace)", + "description": "", + "hide": 0, + "includeAll": false, + "label": "Operator Namespace", + "multi": false, + "name": "operator_namespace", + "options": [], + "query": { + "qryType": 1, + "query": "label_values(microgateway_license_valid,namespace)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "type": "query" + } + ] + }, + "time": { + "from": "now-7d", + "to": "now" + }, + "timeRangeUpdatedDuringEditOrView": false, + "timepicker": {}, + "timezone": "browser", + "title": "Airlock Microgateway License", + "uid": "cdpq79bzrr01se", + "version": 2, + "weekStart": "" +} \ No newline at end of file diff --git a/charts/airlock/microgateway/4.3.2/dashboards/overview.json b/charts/airlock/microgateway/4.3.2/dashboards/overview.json new file mode 100644 index 0000000000..0942766217 --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/dashboards/overview.json @@ -0,0 +1,1138 @@ +{ + "__inputs": [ + { + "name": "DS_PROMETHEUS", + "label": "Prometheus", + "description": "", + "type": "datasource", + "pluginId": "prometheus", + "pluginName": "Prometheus" + } + ], + "__elements": {}, + "__requires": [ + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "10.2.0" + }, + { + "type": "datasource", + "id": "prometheus", + "name": "Prometheus", + "version": "1.0.0" + }, + { + "type": "panel", + "id": "stat", + "name": "Stat", + "version": "" + }, + { + "type": "panel", + "id": "table", + "name": "Table", + "version": "" + }, + { + "type": "panel", + "id": "timeseries", + "name": "Time series", + "version": "" + } + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": null, + "links": [ + { + "asDropdown": true, + "icon": "external link", + "includeVars": true, + "keepTime": true, + "tags": [ + "airlock-microgateway" + ], + "targetBlank": true, + "title": "Airlock Microgateway", + "tooltip": "", + "type": "dashboards", + "url": "" + } + ], + "panels": [ + { + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 3, + "title": "Overview", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "Number of pods that are protected by Airlock Microgateway.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "text", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 0, + "y": 1 + }, + "id": 11, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "last" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum(microgateway_sidecars{namespace=~\"${operator_namespace.regex}\"})", + "instant": true, + "legendFormat": "Protected Pods", + "range": false, + "refId": "A" + } + ], + "title": "Protected Pods", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "Total number of requests processed by Airlock Microgateway.", + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "text", + "mode": "fixed" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 3, + "y": 1 + }, + "id": 4, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "last" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "code", + "exemplar": false, + "expr": "round(sum(increase(microgateway_license_http_rq_total{namespace=~\"${namespace:regex}\", job=~\"${operator_namespace.regex}/.*-engine\"}[$__range])))", + "format": "time_series", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "instant": true, + "legendFormat": "Processed Requests", + "range": false, + "refId": "A", + "useBackend": false + } + ], + "title": "Requests", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "Ratio of blocked requests vs. processed requests by Airlock Microgateway.", + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "text", + "mode": "fixed" + }, + "mappings": [ + { + "options": { + "match": "nan", + "result": { + "index": 0, + "text": "n/a" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 6, + "y": 1 + }, + "id": 5, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "last" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "code", + "exemplar": false, + "expr": "sum(increase(microgateway_http_downstream_rq_threats_blocked_total{namespace=~\"${namespace:regex}\", job=~\"${operator_namespace.regex}/.*-engine\"}[$__range])) / sum(increase(microgateway_license_http_rq_total{namespace=~\"${namespace:regex}\", job=~\"${operator_namespace.regex}/.*-engine\"}[$__range]))", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": true, + "legendFormat": "Blocked Requests (%)", + "range": false, + "refId": "A", + "useBackend": false + } + ], + "title": "% Blocked Requests", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "License status of Airlock Microgateway.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "0": { + "color": "red", + "index": 1, + "text": "Invalid" + }, + "1": { + "color": "green", + "index": 0, + "text": "Valid" + } + }, + "type": "value" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 9, + "y": 1 + }, + "id": 10, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "min(microgateway_license_valid{namespace=~\"${operator_namespace.regex}\"})", + "instant": true, + "legendFormat": "License Status", + "range": false, + "refId": "Licenses" + } + ], + "title": "License", + "type": "stat" + }, + { + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 5 + }, + "id": 2, + "title": "Blocks", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "Requests per second processed by Airlock Microgateway along with the corresponding block rate.", + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "blue", + "mode": "fixed" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "left", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "blue", + "value": null + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "% Blocks" + }, + "properties": [ + { + "id": "custom.axisPlacement", + "value": "right" + }, + { + "id": "unit", + "value": "percentunit" + }, + { + "id": "color", + "value": { + "fixedColor": "orange", + "mode": "fixed" + } + }, + { + "id": "max", + "value": 1 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Requests per second" + }, + "properties": [ + { + "id": "unit", + "value": "short" + }, + { + "id": "custom.fillOpacity", + "value": 25 + } + ] + } + ] + }, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 6 + }, + "id": 6, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "timezone": [ + "" + ], + "tooltip": { + "maxHeight": 600, + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum(rate(microgateway_license_http_rq_total{namespace=~\"${namespace:regex}\", job=~\"${operator_namespace.regex}/.*-engine\"}[1m]))", + "instant": false, + "legendFormat": "Requests per second", + "range": true, + "refId": "Requests per Second" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(rate(microgateway_http_downstream_rq_threats_blocked_total{namespace=~\"${namespace:regex}\", job=~\"${operator_namespace.regex}/.*-engine\"}[1m])) / sum(rate(microgateway_license_http_rq_total{namespace=~\"${namespace:regex}\", job=~\"${operator_namespace.regex}/.*-engine\"}[1m]))", + "hide": false, + "instant": false, + "legendFormat": "% Blocks", + "range": true, + "refId": "Blocks" + } + ], + "title": "Requests vs. % Blocks", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "Requests blocked by Airlock Microgateway categorized by their corresponding type.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "auto", + "cellOptions": { + "barAlignment": 0, + "drawStyle": "line", + "gradientMode": "none", + "hideValue": false, + "lineInterpolation": "linear", + "lineStyle": { + "dash": [ + 10, + 10 + ], + "fill": "solid" + }, + "showPoints": "never", + "spanNulls": false, + "type": "sparkline" + }, + "inspect": false + }, + "displayName": "Block Type", + "fieldMinMax": false, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "block_type" + }, + "properties": [ + { + "id": "custom.width", + "value": 153 + }, + { + "id": "custom.cellOptions", + "value": { + "type": "auto" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Trend #Block Types" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "orange", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 6 + }, + "id": 7, + "options": { + "cellHeight": "lg", + "footer": { + "countRows": false, + "enablePagination": false, + "fields": [ + "Value" + ], + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": false, + "sortBy": [ + { + "desc": true, + "displayName": "block_type" + } + ] + }, + "pluginVersion": "11.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum by (block_type) (increase(microgateway_http_downstream_rq_threats_blocked_total{namespace=~\"${namespace:regex}\", job=~\"${operator_namespace.regex}/.*-engine\"}[1m] offset -1m))/(60000/$__interval_ms)", + "format": "time_series", + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "Block Types" + } + ], + "title": "Blocked Requests by Type", + "transformations": [ + { + "id": "timeSeriesTable", + "options": { + "A": { + "timeField": "Time" + }, + "Block Types": { + "stat": "sum", + "timeField": "Time" + } + } + } + ], + "type": "table" + }, + { + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 16 + }, + "id": 1, + "title": "Latency", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "Percentiles of the application downstream latency over one minute.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "ms" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "25th Percentile" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "super-light-purple", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "50th Percentile" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "purple", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "95th Percentile" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-purple", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 17 + }, + "id": 8, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "maxHeight": 600, + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "histogram_quantile(0.25, sum(rate(envoy_http_downstream_rq_time_bucket{envoy_http_conn_manager_prefix=\"http\", namespace=~\"${namespace:regex}\", job=~\"${operator_namespace.regex}/.*-engine\"}[1m])) by (le))", + "instant": false, + "legendFormat": "25th Percentile", + "range": true, + "refId": "25th Percentile" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "histogram_quantile(0.5, sum(rate(envoy_http_downstream_rq_time_bucket{envoy_http_conn_manager_prefix=\"http\", namespace=~\"${namespace:regex}\", job=~\"${operator_namespace.regex}/.*-engine\"}[1m])) by (le))", + "hide": false, + "instant": false, + "legendFormat": "50th Percentile", + "range": true, + "refId": "50th Percentile" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "histogram_quantile(0.95, sum(rate(envoy_http_downstream_rq_time_bucket{envoy_http_conn_manager_prefix=\"http\", namespace=~\"${namespace:regex}\", job=~\"${operator_namespace.regex}/.*-engine\"}[1m])) by (le))", + "hide": false, + "instant": false, + "legendFormat": "95th Percentile", + "range": true, + "refId": "95th Percentile" + } + ], + "title": "Application Downstream Latency", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "Percentiles of the Airlock Microgateway processing time over one minute.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "ms" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "25th Percentile" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "super-light-purple", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "50th Percentile" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "purple", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "95th Percentile" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-purple", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 17 + }, + "id": 9, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "maxHeight": 600, + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "histogram_quantile(0.25, sum(rate(microgateway_rq_processing_time_ms_bucket{namespace=~\"${namespace:regex}\", job=~\"${operator_namespace.regex}/.*-engine\"}[1m])) by (le))", + "instant": false, + "legendFormat": "25th Percentile", + "range": true, + "refId": "0.25 Percentile" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "histogram_quantile(0.5, sum(rate(microgateway_rq_processing_time_ms_bucket{namespace=~\"${namespace:regex}\", job=~\"${operator_namespace.regex}/.*-engine\"}[1m])) by (le))", + "hide": false, + "instant": false, + "legendFormat": "50th Percentile", + "range": true, + "refId": "0.5 Percentile" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "histogram_quantile(0.95, sum(rate(microgateway_rq_processing_time_ms_bucket{namespace=~\"${namespace:regex}\", job=~\"${operator_namespace.regex}/.*-engine\"}[1m])) by (le))", + "hide": false, + "instant": false, + "legendFormat": "95th Percentile", + "range": true, + "refId": "0.95 Percentile" + } + ], + "title": "Airlock Microgateway Processing Time", + "type": "timeseries" + } + ], + "refresh": "", + "schemaVersion": 39, + "tags": [ + "airlock-microgateway" + ], + "templating": { + "list": [ + { + "current": { + "selected": false, + "text": "Prometheus", + "value": "PBFA97CFB590B2093" + }, + "hide": 2, + "includeAll": false, + "label": "DS_PROMETHEUS", + "multi": false, + "name": "DS_PROMETHEUS", + "options": [], + "query": "prometheus", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + }, + { + "allValue": ".*", + "current": {}, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "definition": "label_values(microgateway_license_valid,namespace)", + "hide": 0, + "includeAll": true, + "label": "Operator Namespace", + "multi": true, + "name": "operator_namespace", + "options": [], + "query": { + "qryType": 1, + "query": "label_values(microgateway_license_valid,namespace)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 2, + "regex": ".*", + "skipUrlSync": false, + "sort": 0, + "type": "query" + }, + { + "allValue": ".*", + "current": {}, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "definition": "label_values(microgateway_license_http_rq_total,namespace)", + "hide": 0, + "includeAll": true, + "label": "Application Namespace", + "multi": true, + "name": "namespace", + "options": [], + "query": { + "qryType": 1, + "query": "label_values(microgateway_license_http_rq_total,namespace)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "type": "query" + } + ] + }, + "time": { + "from": "now-24h", + "to": "now" + }, + "timeRangeUpdatedDuringEditOrView": false, + "timepicker": {}, + "timezone": "browser", + "title": "Airlock Microgateway Overview", + "uid": "fdp5jb8fnrmyoa", + "version": 1, + "weekStart": "" +} \ No newline at end of file diff --git a/charts/airlock/microgateway/4.3.2/templates/NOTES.txt b/charts/airlock/microgateway/4.3.2/templates/NOTES.txt new file mode 100644 index 0000000000..6e5ce218ae --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/templates/NOTES.txt @@ -0,0 +1,47 @@ +Thank you for installing Airlock Microgateway. + +Please ensure the following prerequisites are fulfilled: +* Cert-Manager is installed. + https://cert-manager.io/docs/installation/helm/ +* Airlock Microgateway CNI is also installed on the cluster. + https://artifacthub.io/packages/helm/airlock-microgateway-cni/microgateway-cni +* A valid Airlock Microgateway license is deployed in the Kubernetes secret 'airlock-microgateway-license'. + * Get a free Community license: https://airlock.com/en/microgateway-community + * Order a Premium license: https://airlock.com/en/microgateway-premium + +Further information: +* Documentation: https://docs.airlock.com/microgateway/{{ include "airlock-microgateway.docsVersion" . }} +* CRD API reference documentation: https://docs.airlock.com/microgateway/{{ include "airlock-microgateway.docsVersion" . }}/api/crds +* Airlock Microgateway Labs: https://play.instruqt.com/airlock/invite/hyi9fy4b4jzc?icp_referrer=helm +{{- if .Values.crds.skipVersionCheck }} + +Warning: CRD version check skipped +{{- else -}} +{{- $outdatedCRDs := (include "airlock-microgateway.outdatedCRDs" .) -}} +{{- if $outdatedCRDs -}} + {{- fail (printf ` + +Helm does not automatically upgrade CRDs from the chart's 'crds/' directory during 'helm install/upgrade'. +Therefore, the CRDs must be manually upgraded with the following command before deploying this chart: + +kubectl apply -k https://github.com/airlock/microgateway/deploy/charts/airlock-microgateway/crds/?ref=%s --server-side --force-conflicts + +If you are not using the helm install/upgrade command and instead rely on some other mechanism which is able to upgrade CRDs for deploying this chart, you can suppress this error by setting the helm value 'crds.skipVersionCheck=true'.` + .Chart.AppVersion) + -}} +{{- end -}} +{{- end -}} +{{- if .Values.tests.enabled -}} + {{- if .Values.operator.watchNamespaces -}} + {{- if not (has .Release.Namespace .Values.operator.watchNamespaces) -}} + {{- fail (printf ` + +To execute 'helm test', it is necessary that the release namespace '%s' is part of the operator's watch scope. Either disable the tests or ensure that the release namespace is added to watch namspace list ('operator.watchNamespaces') in the helm values. +` + .Release.Namespace) + -}} + {{- end -}} + {{- end -}} +{{- end }} + +Your release version is {{ .Chart.Version }}. \ No newline at end of file diff --git a/charts/airlock/microgateway/4.3.2/templates/_helpers.tpl b/charts/airlock/microgateway/4.3.2/templates/_helpers.tpl new file mode 100644 index 0000000000..733ba96486 --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/templates/_helpers.tpl @@ -0,0 +1,153 @@ +{{/* +Expand the name of the chart. +We truncate at 49 chars because some Kubernetes name fields are limited to 63 chars (by the DNS naming spec) +and the longest explicit suffix is 14 characters. +*/}} +{{- define "airlock-microgateway.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 49 | trimSuffix "-" }} +{{- end }} + +{{/* +Convert an image configuration object into an image ref string. +*/}} +{{- define "airlock-microgateway.image" -}} + {{- if .digest -}} + {{- printf "%s@%s" .repository .digest -}} + {{- else if .tag -}} + {{- printf "%s:%s" .repository .tag -}} + {{- else -}} + {{- printf "%s" .repository -}} + {{- end -}} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 36 chars because some Kubernetes name fields are limited to 63 chars (by the DNS naming spec) +and the longest implicit suffix is 27 characters. +If release name contains chart name it will be used as a full name. +*/}} +{{- define "airlock-microgateway.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 36 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 36 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 36 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "airlock-microgateway.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "airlock-microgateway.sharedLabels" -}} +helm.sh/chart: {{ include "airlock-microgateway.chart" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +app.kubernetes.io/part-of: {{ .Chart.Name }} +{{- with .Values.commonLabels }} +{{ toYaml .}} +{{- end }} +{{- end }} + +{{/* +Common Selector labels +*/}} +{{- define "airlock-microgateway.sharedSelectorLabels" -}} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Restricted Container Security Context +*/}} +{{- define "airlock-microgateway.restrictedSecurityContext" -}} +allowPrivilegeEscalation: false +privileged: false +runAsNonRoot: true +capabilities: + drop: ["ALL"] +readOnlyRootFilesystem: true +seccompProfile: + type: RuntimeDefault +{{- end }} + +{{/* Precondition: May only be used if AppVersion is isSemver */}} +{{- define "airlock-microgateway.supportedCRDVersionPattern" -}} +{{- $version := (semver .Chart.AppVersion) -}} +{{- if $version.Prerelease -}} +>= {{ $version.Major }}.{{ $version.Minor }}.{{ $version.Patch }}-{{ $version.Prerelease }} +{{- else -}} +>= {{ $version.Major }}.{{ $version.Minor }}.0 || >= {{ $version.Major }}.{{ $version.Minor }}.{{ add1 $version.Patch }}-0 +{{- end -}} +{{- end -}} + +{{- define "airlock-microgateway.outdatedCRDs" -}} +{{- if (eq "true" (include "airlock-microgateway.isSemver" .Chart.AppVersion)) -}} + {{- $supportedVersion := (include "airlock-microgateway.supportedCRDVersionPattern" .) -}} + {{- range $path, $_ := .Files.Glob "crds/*.yaml" -}} + {{- $api := ($.Files.Get $path | fromYaml).metadata.name -}} + {{- $crd := (lookup "apiextensions.k8s.io/v1" "CustomResourceDefinition" "" $api) -}} + {{- $isOutdated := false -}} + {{- if $crd -}} + {{/* If CRD is already present in the cluster, it must have the minimum supported version */}} + {{- $isOutdated = true -}} + {{- if hasKey $crd.metadata "labels" -}} + {{- $crdVersion := get $crd.metadata.labels "app.kubernetes.io/version" -}} + {{- if (eq "true" (include "airlock-microgateway.isSemver" $crdVersion)) -}} + {{- if (semverCompare $supportedVersion $crdVersion) }} + {{- $isOutdated = false -}} + {{- end }} + {{- end -}} + {{- end -}} + {{- end -}} + {{- if $isOutdated }} +{{ base $path }} + {{- end }} + {{- end -}} +{{- end -}} +{{- end -}} + +{{- define "airlock-microgateway.isSemver" -}} +{{- regexMatch `^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$` . -}} +{{- end -}} + +{{- define "airlock-microgateway.docsVersion" -}} +{{- if and (eq "true" (include "airlock-microgateway.isSemver" .Chart.AppVersion)) (not (contains "-" .Chart.AppVersion)) -}} + {{- $version := (semver .Chart.AppVersion) -}} + {{- $version.Major }}.{{ $version.Minor -}} +{{- else -}} + {{- print "latest" -}} +{{- end -}} +{{- end -}} + +{{- define "airlock-microgateway.watchNamespaceSelector.labelQuery" -}} +{{- $list := list -}} +{{- with .matchLabels -}} + {{- range $key, $value := . -}} + {{- $list = append $list (printf "%s=%s" $key $value) -}} + {{- end -}} +{{- end -}} +{{- with .matchExpressions -}} + {{- range . -}} + {{- if has .operator (list "In" "NotIn") -}} + {{- $list = append $list (printf "%s %s (%s)" .key (lower .operator) (join "," .values)) -}} + {{- else if eq .operator "Exists" -}} + {{- $list = append $list .key -}} + {{- else if eq .operator "DoesNotExist" -}} + {{- $list = append $list (printf "!%s" .key) -}} + {{- end -}} + {{- end -}} +{{- end -}} +{{- join "," $list -}} +{{- end -}} \ No newline at end of file diff --git a/charts/airlock/microgateway/4.3.2/templates/operator/_operator_helpers.tpl b/charts/airlock/microgateway/4.3.2/templates/operator/_operator_helpers.tpl new file mode 100644 index 0000000000..a540ff9f4f --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/templates/operator/_operator_helpers.tpl @@ -0,0 +1,42 @@ +{{/* +Create a default fully qualified name for operator components. +*/}} +{{- define "airlock-microgateway.operator.fullname" -}} +{{ include "airlock-microgateway.fullname" . }}-operator +{{- end }} + + +{{/* +Common operator labels +*/}} +{{- define "airlock-microgateway.operator.labels" -}} +{{ include "airlock-microgateway.sharedLabels" . }} +{{ include "airlock-microgateway.operator.selectorLabels" . }} +{{- end }} + +{{/* +Operator Selector labels +*/}} +{{- define "airlock-microgateway.operator.selectorLabels" -}} +{{ include "airlock-microgateway.sharedSelectorLabels" . }} +app.kubernetes.io/name: {{ include "airlock-microgateway.name" . }}-operator +app.kubernetes.io/component: controller +{{- end }} + +{{/* +Create the name of the service account to use for the operator +*/}} +{{- define "airlock-microgateway.operator.serviceAccountName" -}} +{{- if .Values.operator.serviceAccount.create }} +{{- default (include "airlock-microgateway.operator.fullname" .) .Values.operator.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.operator.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +ServiceMonitor metrics regex pattern for leader only metrics +*/}} +{{- define "airlock-microgateway.operator.metricsLeaderOnlyRegexPattern" -}} +^(microgateway_license|microgateway_sidecars).*$ +{{- end }} diff --git a/charts/airlock/microgateway/4.3.2/templates/operator/_rbac.gen.tpl b/charts/airlock/microgateway/4.3.2/templates/operator/_rbac.gen.tpl new file mode 100644 index 0000000000..83b314cbcf --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/templates/operator/_rbac.gen.tpl @@ -0,0 +1,237 @@ +{{/* AUTOGENERATED FILE DO NOT EDIT */}} + +{{/* +Operator rbac permission rules +*/}} +{{- define "airlock-microgateway-operator.rbacRules" -}} +- apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +- apiGroups: + - "" + resources: + - namespaces + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - pods + verbs: + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - "" + resources: + - pods/finalizers + verbs: + - update +- apiGroups: + - "" + resources: + - pods/status + verbs: + - patch + - update +- apiGroups: + - "" + resources: + - secrets + verbs: + - create + - delete + - get + - list + - update + - watch +- apiGroups: + - microgateway.airlock.com + resources: + - accesscontrols + verbs: + - get + - list + - watch +- apiGroups: + - microgateway.airlock.com + resources: + - contentsecurities + verbs: + - get + - list + - watch +- apiGroups: + - microgateway.airlock.com + resources: + - denyrules + verbs: + - get + - list + - watch +- apiGroups: + - microgateway.airlock.com + resources: + - envoyclusters + verbs: + - get + - list + - watch +- apiGroups: + - microgateway.airlock.com + resources: + - envoyconfigurations + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - microgateway.airlock.com + resources: + - envoyconfigurations/status + verbs: + - get + - patch + - update +- apiGroups: + - microgateway.airlock.com + resources: + - envoyhttpfilters + verbs: + - get + - list + - watch +- apiGroups: + - microgateway.airlock.com + resources: + - graphqls + verbs: + - get + - list + - watch +- apiGroups: + - microgateway.airlock.com + resources: + - headerrewrites + verbs: + - get + - list + - watch +- apiGroups: + - microgateway.airlock.com + resources: + - identitypropagations + verbs: + - get + - list + - watch +- apiGroups: + - microgateway.airlock.com + resources: + - limits + verbs: + - get + - list + - watch +- apiGroups: + - microgateway.airlock.com + resources: + - oidcproviders + verbs: + - get + - list + - watch +- apiGroups: + - microgateway.airlock.com + resources: + - oidcrelyingparties + verbs: + - get + - list + - watch +- apiGroups: + - microgateway.airlock.com + resources: + - openapis + verbs: + - get + - list + - watch +- apiGroups: + - microgateway.airlock.com + resources: + - parsers + verbs: + - get + - list + - watch +- apiGroups: + - microgateway.airlock.com + resources: + - redisproviders + verbs: + - get + - list + - watch +- apiGroups: + - microgateway.airlock.com + resources: + - sessionhandlings + verbs: + - get + - list + - watch +- apiGroups: + - microgateway.airlock.com + resources: + - sidecargateways + verbs: + - get + - list + - patch + - update + - watch +- apiGroups: + - microgateway.airlock.com + resources: + - sidecargateways/finalizers + verbs: + - update +- apiGroups: + - microgateway.airlock.com + resources: + - sidecargateways/status + verbs: + - get + - patch + - update +- apiGroups: + - microgateway.airlock.com + resources: + - telemetries + verbs: + - get + - list + - watch +{{- end }} diff --git a/charts/airlock/microgateway/4.3.2/templates/operator/_webhooks.gen.tpl b/charts/airlock/microgateway/4.3.2/templates/operator/_webhooks.gen.tpl new file mode 100644 index 0000000000..02e3048904 --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/templates/operator/_webhooks.gen.tpl @@ -0,0 +1,339 @@ +{{/* AUTOGENERATED FILE DO NOT EDIT */}} + +{{/* +Operator mutating webhooks +*/}} +{{- define "airlock-microgateway-operator.mutatingWebhooks" -}} +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: airlock-microgateway-operator-webhook + namespace: '{{ .Release.Namespace }}' + path: /mutate-v1-pod + failurePolicy: Fail + name: mutate-pod.microgateway.airlock.com + reinvocationPolicy: IfNeeded + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + resources: + - pods + sideEffects: None + objectSelector: + matchLabels: + sidecar.microgateway.airlock.com/inject: "true" +{{- end }} + +{{/* +Operator validating webhooks +*/}} +{{- define "airlock-microgateway-operator.validatingWebhooks" -}} +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: airlock-microgateway-operator-webhook + namespace: '{{ .Release.Namespace }}' + path: /validate-v1-pod + failurePolicy: Fail + name: validate-pod.microgateway.airlock.com + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - pods + sideEffects: None + objectSelector: + matchLabels: + sidecar.microgateway.airlock.com/inject: "true" +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: airlock-microgateway-operator-webhook + namespace: '{{ .Release.Namespace }}' + path: /validate-microgateway-airlock-com-v1alpha1-accesscontrol + failurePolicy: Fail + name: validate-accesscontrol.microgateway.airlock.com + rules: + - apiGroups: + - microgateway.airlock.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - accesscontrols + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: airlock-microgateway-operator-webhook + namespace: '{{ .Release.Namespace }}' + path: /validate-microgateway-airlock-com-v1alpha1-denyrules + failurePolicy: Fail + name: validate-denyrules.microgateway.airlock.com + rules: + - apiGroups: + - microgateway.airlock.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - denyrules + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: airlock-microgateway-operator-webhook + namespace: '{{ .Release.Namespace }}' + path: /validate-microgateway-airlock-com-v1alpha1-envoycluster + failurePolicy: Fail + name: validate-envoycluster.microgateway.airlock.com + rules: + - apiGroups: + - microgateway.airlock.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - envoyclusters + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: airlock-microgateway-operator-webhook + namespace: '{{ .Release.Namespace }}' + path: /validate-microgateway-airlock-com-v1alpha1-envoyhttpfilter + failurePolicy: Fail + name: validate-envoyhttpfilter.microgateway.airlock.com + rules: + - apiGroups: + - microgateway.airlock.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - envoyhttpfilters + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: airlock-microgateway-operator-webhook + namespace: '{{ .Release.Namespace }}' + path: /validate-microgateway-airlock-com-v1alpha1-graphql + failurePolicy: Fail + name: validate-graphql.microgateway.airlock.com + rules: + - apiGroups: + - microgateway.airlock.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - graphqls + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: airlock-microgateway-operator-webhook + namespace: '{{ .Release.Namespace }}' + path: /validate-microgateway-airlock-com-v1alpha1-headerrewrites + failurePolicy: Fail + name: validate-headerrewrites.microgateway.airlock.com + rules: + - apiGroups: + - microgateway.airlock.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - headerrewrites + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: airlock-microgateway-operator-webhook + namespace: '{{ .Release.Namespace }}' + path: /validate-microgateway-airlock-com-v1alpha1-identitypropagation + failurePolicy: Fail + name: validate-identitypropagation.microgateway.airlock.com + rules: + - apiGroups: + - microgateway.airlock.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - identitypropagations + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: airlock-microgateway-operator-webhook + namespace: '{{ .Release.Namespace }}' + path: /validate-microgateway-airlock-com-v1alpha1-limits + failurePolicy: Fail + name: validate-limits.microgateway.airlock.com + rules: + - apiGroups: + - microgateway.airlock.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - limits + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: airlock-microgateway-operator-webhook + namespace: '{{ .Release.Namespace }}' + path: /validate-microgateway-airlock-com-v1alpha1-oidcprovider + failurePolicy: Fail + name: validate-oidcprovider.microgateway.airlock.com + rules: + - apiGroups: + - microgateway.airlock.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - oidcproviders + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: airlock-microgateway-operator-webhook + namespace: '{{ .Release.Namespace }}' + path: /validate-microgateway-airlock-com-v1alpha1-oidcrelyingparty + failurePolicy: Fail + name: validate-oidcrelyingparty.microgateway.airlock.com + rules: + - apiGroups: + - microgateway.airlock.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - oidcrelyingparties + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: airlock-microgateway-operator-webhook + namespace: '{{ .Release.Namespace }}' + path: /validate-microgateway-airlock-com-v1alpha1-openapi + failurePolicy: Fail + name: validate-openapi.microgateway.airlock.com + rules: + - apiGroups: + - microgateway.airlock.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - openapis + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: airlock-microgateway-operator-webhook + namespace: '{{ .Release.Namespace }}' + path: /validate-microgateway-airlock-com-v1alpha1-parser + failurePolicy: Fail + name: validate-parser.microgateway.airlock.com + rules: + - apiGroups: + - microgateway.airlock.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - parsers + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: airlock-microgateway-operator-webhook + namespace: '{{ .Release.Namespace }}' + path: /validate-microgateway-airlock-com-v1alpha1-redisprovider + failurePolicy: Fail + name: validate-redisprovider.microgateway.airlock.com + rules: + - apiGroups: + - microgateway.airlock.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - redisproviders + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: airlock-microgateway-operator-webhook + namespace: '{{ .Release.Namespace }}' + path: /validate-microgateway-airlock-com-v1alpha1-sidecargateway + failurePolicy: Fail + name: validate-sidecargateway.microgateway.airlock.com + rules: + - apiGroups: + - microgateway.airlock.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - sidecargateways + sideEffects: None +{{- end }} diff --git a/charts/airlock/microgateway/4.3.2/templates/operator/configmap.yaml b/charts/airlock/microgateway/4.3.2/templates/operator/configmap.yaml new file mode 100644 index 0000000000..95e52d7df1 --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/templates/operator/configmap.yaml @@ -0,0 +1,394 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "airlock-microgateway.operator.fullname" . }}-config + namespace: {{ .Release.Namespace }} + labels: + {{- include "airlock-microgateway.operator.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +data: + engine_bootstrap_config_template.yaml: | + # Base configuration, admin interface on port 19000 + admin: + address: + socket_address: + address: 127.0.0.1 + port_value: 19000 + dynamic_resources: + cds_config: + initial_fetch_timeout: 10s + resource_api_version: V3 + api_config_source: + api_type: GRPC + transport_api_version: V3 + grpc_services: + - envoy_grpc: + cluster_name: xds_cluster + set_node_on_first_message_only: true + # Prevent Envoy Node from overloading the xDS server due to rejected configuration when using xDS SotW gRPC + rate_limit_settings: + max_tokens: 5 + fill_rate: 0.2 + lds_config: + resource_api_version: V3 + initial_fetch_timeout: 10s + api_config_source: + api_type: GRPC + transport_api_version: V3 + grpc_services: + - envoy_grpc: + cluster_name: xds_cluster + set_node_on_first_message_only: true + # Prevent Envoy Node from overloading the xDS server due to rejected configuration when using xDS SotW gRPC + rate_limit_settings: + max_tokens: 5 + fill_rate: 0.2 + static_resources: + listeners: + - name: probe + address: + socket_address: + address: 0.0.0.0 + port_value: 19001 + filter_chains: + - filters: + - name: http_connection_manager + typed_config: + '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + stat_prefix: probe + codec_type: AUTO + http2_protocol_options: + initial_connection_window_size: 1048576 + initial_stream_window_size: 65536 + max_concurrent_streams: 100 + route_config: + name: probe + virtual_hosts: + - name: probe + domains: + - '*' + routes: + - name: ready + match: + path: /ready + headers: + - name: ':method' + string_match: + exact: 'GET' + route: + cluster: airlock_microgateway_engine_admin + http_filters: + - name: envoy.filters.http.router + typed_config: + '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + - name: metrics + address: + socket_address: + address: 0.0.0.0 + port_value: 19002 + filter_chains: + - filters: + - name: http_connection_manager + typed_config: + '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + stat_prefix: metrics + codec_type: AUTO + http2_protocol_options: + initial_connection_window_size: 1048576 + initial_stream_window_size: 65536 + max_concurrent_streams: 100 + route_config: + name: metrics + virtual_hosts: + - name: metrics + domains: + - '*' + routes: + - name: metrics + match: + path: /metrics + headers: + - name: ':method' + string_match: + exact: 'GET' + route: + prefix_rewrite: '/stats/prometheus' + cluster: airlock_microgateway_engine_admin + http_filters: + - name: envoy.filters.http.router + typed_config: + '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + clusters: + - name: xds_cluster + connect_timeout: 1s + type: STRICT_DNS + load_assignment: + cluster_name: xds_cluster + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: airlock-microgateway-operator-xds.$(OPERATOR_NAMESPACE).svc.cluster.local + port_value: 13377 + typed_extension_protocol_options: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions + explicit_http_config: + http2_protocol_options: + connection_keepalive: + interval: 360s + timeout: 5s + transport_socket: + name: envoy.transport_sockets.tls + typed_config: + '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext + common_tls_context: + tls_params: + tls_minimum_protocol_version: TLSv1_3 + tls_maximum_protocol_version: TLSv1_3 + validation_context_sds_secret_config: + name: validation_context_sds + sds_config: + resource_api_version: V3 + path_config_source: + path: /etc/envoy/validation_context_sds_secret.yaml + watched_directory: + path: /etc/envoy/ + tls_certificate_sds_secret_configs: + - name: tls_certificate_sds + sds_config: + resource_api_version: V3 + path_config_source: + path: /etc/envoy/tls_certificate_sds_secret.yaml + watched_directory: + path: /etc/envoy/ + - name: airlock_microgateway_engine_admin + connect_timeout: 1s + type: STATIC + load_assignment: + cluster_name: airlock_microgateway_engine_admin + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: 127.0.0.1 + port_value: 19000 + typed_extension_protocol_options: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions + explicit_http_config: + http2_protocol_options: + connection_keepalive: + interval: 360s + timeout: 5s + stats_config: + stats_tags: + - tag_name: "block_type" + regex: "\\.(block_type\\.([^.]+))" + - tag_name: "attack_type" + regex: "\\.(attack_type\\.([^.]+))" + - tag_name: "envoy_cluster_name" + regex: "\\.(cluster\\.([^.]+))" + - tag_name: "version" + regex: "\\.(version\\.([^.]+))" + use_all_default_tags: true + overload_manager: + resource_monitors: + - name: "envoy.resource_monitors.global_downstream_max_connections" + typed_config: + "@type": type.googleapis.com/envoy.extensions.resource_monitors.downstream_connections.v3.DownstreamConnectionsConfig + max_active_downstream_connections: 50000 + bootstrap_extensions: + - name: airlock.bootstrap.engine_build_info + typed_config: + '@type': type.googleapis.com/airlock.extensions.bootstrap.stats.v1alpha.Stats + application_log_config: + log_format: + text_format: '{"@timestamp":"%Y-%m-%dT%T.%e%z","log":{"logger":"%n","level":"%l","origin":{"file":{"name":"%g","line":%#},"function":"%!"}},"event":{"module":"envoy","dataset":"envoy.application"},"process":{"pid":%P,"thread":{"id":%t}},"ecs":{"version":"8.5"},"message":"%j"}' + engine_container_template.yaml: | + name: "$(ENGINE_NAME)" + image: "$(ENGINE_IMAGE)" + imagePullPolicy: {{ .Values.engine.image.pullPolicy }} + args: + - "--config-path" + - "/etc/envoy/bootstrap_config.yaml" + - "--base-id" + - "$(BASE_ID)" + - "--file-flush-interval-msec" + - '1000' + - "--drain-time-s" + - '60' + - "--service-node" + - "$(POD_NAME).$(POD_NAMESPACE)" + - "--service-cluster" + - "$(APP_NAME).$(POD_NAMESPACE)" + - "--log-path" + - "/dev/stdout" + - "--log-level" + - "$(LOG_LEVEL)" + volumeMounts: + - name: airlock-microgateway-bootstrap-secret-volume + mountPath: /etc/envoy + readOnly: true + env: + - name: POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: POD_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.podIP + ports: + - containerPort: 13378 + protocol: TCP + - containerPort: 19001 + protocol: TCP + - containerPort: 19002 + protocol: TCP + livenessProbe: + httpGet: + path: /ready + port: 19001 + scheme: HTTP + initialDelaySeconds: 5 + periodSeconds: 5 + failureThreshold: 5 + successThreshold: 1 + timeoutSeconds: 1 + readinessProbe: + httpGet: + path: /ready + port: 19001 + scheme: HTTP + initialDelaySeconds: 5 + periodSeconds: 5 + failureThreshold: 3 + successThreshold: 1 + timeoutSeconds: 1 + securityContext: + {{- include "airlock-microgateway.restrictedSecurityContext" . | nindent 6 }} + runAsUser: $(SECURITYCONTEXT_UID) + {{- with .Values.engine.resources }} + resources: + {{- toYaml . | nindent 6 }} + {{- end }} + session_agent_container_template.yaml: | + name: "$(SESSION_AGENT_NAME)" + image: "$(SESSION_AGENT_IMAGE)" + imagePullPolicy: {{ .Values.sessionAgent.image.pullPolicy }} + args: + - "--port" + - "19004" + - "--config-path" + - "/etc/microgateway-session-agent/config.json" + volumeMounts: + - name: airlock-microgateway-session-agent-volume + mountPath: /etc/microgateway-session-agent + readOnly: true + env: + - name: POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + ports: + - containerPort: 19004 + livenessProbe: + {{- if (semverCompare ">=1.27 || >=1.27.1-0" .Capabilities.KubeVersion.Version)}} + grpc: + port: 19004 + {{- else }} + tcpSocket: + port: 19004 + {{- end }} + initialDelaySeconds: 5 + periodSeconds: 5 + failureThreshold: 5 + successThreshold: 1 + timeoutSeconds: 5 + readinessProbe: + {{- if (semverCompare ">=1.27 || >=1.27.1-0" .Capabilities.KubeVersion.Version)}} + grpc: + port: 19004 + {{- else }} + tcpSocket: + port: 19004 + {{- end }} + initialDelaySeconds: 5 + periodSeconds: 5 + failureThreshold: 3 + successThreshold: 1 + timeoutSeconds: 5 + securityContext: + {{- include "airlock-microgateway.restrictedSecurityContext" . | nindent 6 }} + runAsUser: $(SECURITYCONTEXT_UID) + {{- with .Values.sessionAgent.resources }} + resources: + {{- toYaml . | nindent 6 }} + {{- end }} + network_validator_container_template.yaml: | + name: "$(NETWORK_VALIDATOR_NAME)" + image: "$(NETWORK_VALIDATOR_IMAGE)" + imagePullPolicy: {{ .Values.networkValidator.image.pullPolicy }} + command: ["/bin/sh", "-c"] + args: + - |- + echo 'pong' | nc -v -l 127.0.0.1 13378 & + for i in 1 2 3; do + sleep 1s + if r=$(echo 'ping' | nc -v -q 0 127.0.0.1 19003) && [ $r == pong ]; then + echo -n 'Traffic redirection to Airlock Microgateway Engine is working.' > /dev/termination-log + exit 0 + fi + done + echo -en 'Traffic redirection to Airlock Microgateway Engine is not working.\nRestart the pod after ensuring that hostNetwork is disabled and a compatible Airlock Microgateway CNI version is installed on the node.\nCertain environments may also require additional configuration (see docs.airlock.com for more information).' > /dev/termination-log + exit 1 + securityContext: + {{- include "airlock-microgateway.restrictedSecurityContext" . | nindent 6 }} + runAsUser: $(SECURITYCONTEXT_UID) + operator_config.yaml: | + apiVersion: config.airlock.com/v1alpha1 + kind: OperatorConfig + health: + healthProbeBindAddress: :8081 + metrics: + bindAddress: 0.0.0.0:8080 + webhook: + port: 9443 + deployment: + sidecar: + engineContainerTemplate: "/sidecar/engine_container_template.yaml" + networkValidatorContainerTemplate: "/sidecar/network_validator_container_template.yaml" + sessionAgentContainerTemplate: "/sidecar/session_agent_container_template.yaml" + engine: + bootstrapConfigTemplate: "/engine_bootstrap_config_template.yaml" + log: + level: {{ .Values.operator.config.logLevel }} + {{- with $.Values.operator.watchNamespaceSelector }} + namespaces: + selector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with $.Values.operator.watchNamespaces }} + namespaces: + list: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/charts/airlock/microgateway/4.3.2/templates/operator/dashboard-configmap.yaml b/charts/airlock/microgateway/4.3.2/templates/operator/dashboard-configmap.yaml new file mode 100644 index 0000000000..b71ac89b65 --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/templates/operator/dashboard-configmap.yaml @@ -0,0 +1,28 @@ +{{- if .Values.dashboards.create -}} +{{- range $instance := (keys .Values.dashboards.instances | sortAlpha) -}} +{{- $dashboard := get $.Values.dashboards.instances $instance -}} +{{- if $dashboard.create }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "airlock-microgateway.fullname" $ }}-dashboard-{{ $instance | lower }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "airlock-microgateway.operator.labels" $ | nindent 4 }} + {{- with $.Values.dashboards.config.grafana.dashboardLabel -}} + {{- .name | nindent 4 -}}: {{ .value | quote }} + {{- end }} + annotations: + {{- with $.Values.dashboards.config.grafana.folderAnnotation -}} + {{- .name | nindent 4 -}}: {{ .value | quote }} + {{- end }} + {{- with $.Values.commonAnnotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +data: + {{- printf "%s.json" $instance | nindent 2 }}: |- + {{- ($.Files.Get (printf "dashboards/%s.json" $instance)) | nindent 4 -}} +{{- end -}} +{{- end -}} +{{- end -}} \ No newline at end of file diff --git a/charts/airlock/microgateway/4.3.2/templates/operator/deployment.yaml b/charts/airlock/microgateway/4.3.2/templates/operator/deployment.yaml new file mode 100644 index 0000000000..db340cdecc --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/templates/operator/deployment.yaml @@ -0,0 +1,143 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "airlock-microgateway.operator.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "airlock-microgateway.operator.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.operator.replicaCount }} + {{- with .Values.operator.updateStrategy }} + strategy: + {{- toYaml . | trim | nindent 4 }} + {{- end }} + selector: + matchLabels: + {{- include "airlock-microgateway.operator.selectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + checksum/config: {{ include (print $.Template.BasePath "/operator/configmap.yaml") . | sha256sum }} + kubectl.kubernetes.io/default-container: manager + {{- with mustMerge .Values.operator.podAnnotations .Values.commonAnnotations}} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "airlock-microgateway.operator.labels" . | nindent 8 }} + {{- with .Values.operator.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + containers: + - args: + - --config=operator_config.yaml + env: + - name: ENGINE_IMAGE + value: {{ include "airlock-microgateway.image" .Values.engine.image }} + - name: NETWORK_VALIDATOR_IMAGE + value: {{ include "airlock-microgateway.image" .Values.networkValidator.image }} + - name: SESSION_AGENT_IMAGE + value: {{ include "airlock-microgateway.image" .Values.sessionAgent.image }} + - name: OPERATOR_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: OPERATOR_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + image: {{ include "airlock-microgateway.image" .Values.operator.image }} + imagePullPolicy: {{ .Values.operator.image.pullPolicy }} + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + timeoutSeconds: 5 + name: manager + ports: + - containerPort: 9443 + name: webhook-server + protocol: TCP + - containerPort: 13377 + name: xds-server + protocol: TCP + - containerPort: 8080 + protocol: TCP + - containerPort: 8081 + protocol: TCP + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + timeoutSeconds: 5 + {{- with .Values.operator.resources }} + resources: + {{- toYaml . | nindent 10 }} + {{- end }} + securityContext: + {{- include "airlock-microgateway.restrictedSecurityContext" . | nindent 10 }} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - mountPath: /tmp/k8s-webhook-server/serving-certs + name: cert + readOnly: true + - mountPath: /opt/airlock/license/ + name: airlock-microgateway-license + readOnly: true + - mountPath: /operator_config.yaml + name: operator-config + subPath: operator_config.yaml + - mountPath: /sidecar/engine_container_template.yaml + name: operator-config + subPath: engine_container_template.yaml + - mountPath: /sidecar/network_validator_container_template.yaml + name: operator-config + subPath: network_validator_container_template.yaml + - mountPath: /sidecar/session_agent_container_template.yaml + name: operator-config + subPath: session_agent_container_template.yaml + - mountPath: /engine_bootstrap_config_template.yaml + name: operator-config + subPath: engine_bootstrap_config_template.yaml + securityContext: + runAsNonRoot: true + serviceAccountName: {{ include "airlock-microgateway.operator.serviceAccountName" . }} + terminationGracePeriodSeconds: 10 + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.operator.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.operator.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.operator.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: cert + secret: + defaultMode: 420 + secretName: {{ include "airlock-microgateway.operator.fullname" . }}-webhook-server-cert + - name: airlock-microgateway-license + secret: + defaultMode: 292 + optional: true + secretName: {{ .Values.license.secretName }} + - configMap: + name: {{ include "airlock-microgateway.operator.fullname" . }}-config + name: operator-config diff --git a/charts/airlock/microgateway/4.3.2/templates/operator/manager-role.yaml b/charts/airlock/microgateway/4.3.2/templates/operator/manager-role.yaml new file mode 100644 index 0000000000..90335bcfe1 --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/templates/operator/manager-role.yaml @@ -0,0 +1,33 @@ +{{- if .Values.operator.rbac.create }} +{{- if empty .Values.operator.watchNamespaces }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "airlock-microgateway.operator.fullname" . }}-manager-{{ .Release.Namespace }} + labels: + {{- include "airlock-microgateway.operator.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +rules: +{{ include "airlock-microgateway-operator.rbacRules" . -}} +{{- else }} +{{- range $namespace := (append .Values.operator.watchNamespaces .Release.Namespace | uniq) }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "airlock-microgateway.operator.fullname" $ }}-manager + namespace: {{ $namespace }} + labels: + {{- include "airlock-microgateway.operator.labels" $ | nindent 4 }} + {{- with $.Values.commonAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +rules: +{{ include "airlock-microgateway-operator.rbacRules" $ }} +--- +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/charts/airlock/microgateway/4.3.2/templates/operator/manager-rolebinding.yaml b/charts/airlock/microgateway/4.3.2/templates/operator/manager-rolebinding.yaml new file mode 100644 index 0000000000..ae99cfb7b6 --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/templates/operator/manager-rolebinding.yaml @@ -0,0 +1,45 @@ +{{- if .Values.operator.rbac.create }} +{{- if empty .Values.operator.watchNamespaces }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "airlock-microgateway.operator.fullname" . }}-manager-{{ .Release.Namespace }} + labels: + {{- include "airlock-microgateway.operator.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "airlock-microgateway.operator.fullname" . }}-manager-{{ .Release.Namespace }} +subjects: + - kind: ServiceAccount + name: {{ include "airlock-microgateway.operator.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- else }} +{{- range $namespace := (append .Values.operator.watchNamespaces .Release.Namespace | uniq) }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "airlock-microgateway.operator.fullname" $ }}-manager + namespace: {{ $namespace }} + labels: + {{- include "airlock-microgateway.operator.labels" $ | nindent 4 }} + {{- with $.Values.commonAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ include "airlock-microgateway.operator.fullname" $ }}-manager +subjects: + - kind: ServiceAccount + name: {{ include "airlock-microgateway.operator.serviceAccountName" $ }} + namespace: {{ $.Release.Namespace }} +--- +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/charts/airlock/microgateway/4.3.2/templates/operator/metrics-service.yaml b/charts/airlock/microgateway/4.3.2/templates/operator/metrics-service.yaml new file mode 100644 index 0000000000..34d23f6d67 --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/templates/operator/metrics-service.yaml @@ -0,0 +1,47 @@ +apiVersion: v1 +kind: Service +metadata: + name: airlock-microgateway-operator-metrics + namespace: {{ .Release.Namespace }} + labels: + {{- include "airlock-microgateway.operator.labels" . | nindent 4 }} + {{- with .Values.operator.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with mustMerge .Values.operator.serviceAnnotations .Values.commonAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + ports: + - appProtocol: http + name: metrics + port: 8080 + protocol: TCP + selector: + {{- include "airlock-microgateway.operator.selectorLabels" . | nindent 4 }} +--- +apiVersion: v1 +kind: Service +metadata: + name: airlock-microgateway-operator-leader-metrics + namespace: {{ .Release.Namespace }} + labels: + {{- include "airlock-microgateway.operator.labels" . | nindent 4 }} + {{- with .Values.operator.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + operator.microgateway.airlock.com/isLeader: "true" + {{- with mustMerge .Values.operator.serviceAnnotations .Values.commonAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + ports: + - appProtocol: http + name: metrics + port: 8080 + protocol: TCP + selector: + {{- include "airlock-microgateway.operator.selectorLabels" . | nindent 4 }} + operator.microgateway.airlock.com/isLeader: "true" \ No newline at end of file diff --git a/charts/airlock/microgateway/4.3.2/templates/operator/mutating-webhook.yaml b/charts/airlock/microgateway/4.3.2/templates/operator/mutating-webhook.yaml new file mode 100644 index 0000000000..311f9726ad --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/templates/operator/mutating-webhook.yaml @@ -0,0 +1,28 @@ +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + name: {{ include "airlock-microgateway.operator.fullname" . }}-webhook-{{ .Release.Namespace }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "airlock-microgateway.operator.labels" . | nindent 4 }} + annotations: + cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/{{ include "airlock-microgateway.operator.fullname" . }}-serving-cert + {{- with .Values.commonAnnotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +webhooks: +{{- range $webhook := (include "airlock-microgateway-operator.mutatingWebhooks" .) | fromYamlArray }} +- {{ toYaml $webhook | indent 2 | trim }} + {{- with $.Values.operator.watchNamespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $.Values.operator.watchNamespaces }} + namespaceSelector: + matchExpressions: + - key: kubernetes.io/metadata.name + operator: In + values: + {{- toYaml . | nindent 10 }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/airlock/microgateway/4.3.2/templates/operator/podmonitor.yaml b/charts/airlock/microgateway/4.3.2/templates/operator/podmonitor.yaml new file mode 100644 index 0000000000..1fe34fcb35 --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/templates/operator/podmonitor.yaml @@ -0,0 +1,27 @@ +{{- if .Values.engine.sidecar.podMonitor.create }} +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + name: {{ include "airlock-microgateway.fullname" . }}-engine + namespace: {{ .Release.Namespace }} + labels: + {{- include "airlock-microgateway.operator.labels" . | nindent 4 }} + {{- with .Values.engine.sidecar.podMonitor.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.commonAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + namespaceSelector: + any: true + selector: + matchLabels: + sidecar.microgateway.airlock.com/inject: "true" + microgateway.airlock.com/managedBy: {{ .Release.Namespace }} + podMetricsEndpoints: + - targetPort: 19002 + path: /metrics + scheme: http +{{- end -}} \ No newline at end of file diff --git a/charts/airlock/microgateway/4.3.2/templates/operator/role.yaml b/charts/airlock/microgateway/4.3.2/templates/operator/role.yaml new file mode 100644 index 0000000000..5378be8ef9 --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/templates/operator/role.yaml @@ -0,0 +1,45 @@ +{{- if .Values.operator.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "airlock-microgateway.operator.fullname" . }}-leader-election + namespace: {{ .Release.Namespace }} + labels: + {{- include "airlock-microgateway.operator.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +rules: + - apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +{{- end -}} \ No newline at end of file diff --git a/charts/airlock/microgateway/4.3.2/templates/operator/rolebinding.yaml b/charts/airlock/microgateway/4.3.2/templates/operator/rolebinding.yaml new file mode 100644 index 0000000000..bafec10156 --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/templates/operator/rolebinding.yaml @@ -0,0 +1,20 @@ +{{- if .Values.operator.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "airlock-microgateway.operator.fullname" . }}-leader-election + namespace: {{ .Release.Namespace }} + labels: + {{- include "airlock-microgateway.operator.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ include "airlock-microgateway.operator.fullname" . }}-leader-election +subjects: + - kind: ServiceAccount + name: {{ include "airlock-microgateway.operator.serviceAccountName" . }} +{{- end -}} diff --git a/charts/airlock/microgateway/4.3.2/templates/operator/selfsigned-issuer.yaml b/charts/airlock/microgateway/4.3.2/templates/operator/selfsigned-issuer.yaml new file mode 100644 index 0000000000..466c56338e --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/templates/operator/selfsigned-issuer.yaml @@ -0,0 +1,13 @@ +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: {{ include "airlock-microgateway.operator.fullname" . }}-selfsigned-issuer + namespace: {{ .Release.Namespace }} + labels: + {{- include "airlock-microgateway.operator.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + selfSigned: {} diff --git a/charts/airlock/microgateway/4.3.2/templates/operator/serviceaccount.yaml b/charts/airlock/microgateway/4.3.2/templates/operator/serviceaccount.yaml new file mode 100644 index 0000000000..434d7e9d30 --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/templates/operator/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.operator.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "airlock-microgateway.operator.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "airlock-microgateway.operator.labels" . | nindent 4 }} + {{- with mustMerge .Values.operator.serviceAccount.annotations .Values.commonAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end -}} diff --git a/charts/airlock/microgateway/4.3.2/templates/operator/servicemonitor.yaml b/charts/airlock/microgateway/4.3.2/templates/operator/servicemonitor.yaml new file mode 100644 index 0000000000..ff85a9a310 --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/templates/operator/servicemonitor.yaml @@ -0,0 +1,60 @@ +{{- if .Values.operator.serviceMonitor.create }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "airlock-microgateway.operator.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "airlock-microgateway.operator.labels" . | nindent 4 }} + {{- with .Values.operator.serviceMonitor.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.commonAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + selector: + matchLabels: + {{- include "airlock-microgateway.operator.selectorLabels" . | nindent 6 }} + matchExpressions: + - { key: "operator.microgateway.airlock.com/isLeader", operator: DoesNotExist } + endpoints: + - path: /metrics + port: metrics + scheme: http + metricRelabelings: + - sourceLabels: + - __name__ + regex: {{ include "airlock-microgateway.operator.metricsLeaderOnlyRegexPattern" . }} + action: drop +--- +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "airlock-microgateway.operator.fullname" . }}-leader + namespace: {{ .Release.Namespace }} + labels: + {{- include "airlock-microgateway.operator.labels" . | nindent 4 }} + {{- with .Values.operator.serviceMonitor.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.commonAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + selector: + matchLabels: + {{- include "airlock-microgateway.operator.selectorLabels" . | nindent 6 }} + operator.microgateway.airlock.com/isLeader: "true" + endpoints: + - path: /metrics + port: metrics + scheme: http + metricRelabelings: + - sourceLabels: + - __name__ + regex: {{ include "airlock-microgateway.operator.metricsLeaderOnlyRegexPattern" . }} + action: keep +{{- end -}} \ No newline at end of file diff --git a/charts/airlock/microgateway/4.3.2/templates/operator/serving-certificate.yaml b/charts/airlock/microgateway/4.3.2/templates/operator/serving-certificate.yaml new file mode 100644 index 0000000000..60b92e1e2c --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/templates/operator/serving-certificate.yaml @@ -0,0 +1,19 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: {{ include "airlock-microgateway.operator.fullname" . }}-serving-cert + namespace: {{ .Release.Namespace }} + labels: + {{- include "airlock-microgateway.operator.labels" . | nindent 4 }} + {{- with .Values.commonAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + dnsNames: + - airlock-microgateway-operator-webhook.{{ .Release.Namespace }}.svc + - airlock-microgateway-operator-webhook.{{ .Release.Namespace }}.svc.cluster.local + issuerRef: + kind: Issuer + name: {{ include "airlock-microgateway.operator.fullname" . }}-selfsigned-issuer + secretName: {{ include "airlock-microgateway.operator.fullname" . }}-webhook-server-cert diff --git a/charts/airlock/microgateway/4.3.2/templates/operator/validating-webhook.yaml b/charts/airlock/microgateway/4.3.2/templates/operator/validating-webhook.yaml new file mode 100644 index 0000000000..5d6b4396ba --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/templates/operator/validating-webhook.yaml @@ -0,0 +1,28 @@ +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: {{ include "airlock-microgateway.operator.fullname" . }}-webhook-{{ .Release.Namespace }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "airlock-microgateway.operator.labels" . | nindent 4 }} + annotations: + cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/{{ include "airlock-microgateway.operator.fullname" . }}-serving-cert + {{- with .Values.commonAnnotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +webhooks: +{{- range $webhook := (include "airlock-microgateway-operator.validatingWebhooks" .) | fromYamlArray }} +- {{ toYaml $webhook | indent 2 | trim }} + {{- with $.Values.operator.watchNamespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $.Values.operator.watchNamespaces }} + namespaceSelector: + matchExpressions: + - key: kubernetes.io/metadata.name + operator: In + values: + {{- toYaml . | nindent 10 }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/airlock/microgateway/4.3.2/templates/operator/webhook-service.yaml b/charts/airlock/microgateway/4.3.2/templates/operator/webhook-service.yaml new file mode 100644 index 0000000000..477ea839f3 --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/templates/operator/webhook-service.yaml @@ -0,0 +1,23 @@ +apiVersion: v1 +kind: Service +metadata: + name: airlock-microgateway-operator-webhook + namespace: {{ .Release.Namespace }} + labels: + {{- include "airlock-microgateway.operator.labels" . | nindent 4 }} + {{- with .Values.operator.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with mustMerge .Values.operator.serviceAnnotations .Values.commonAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + ports: + - appProtocol: https + name: webhook + port: 443 + protocol: TCP + targetPort: 9443 + selector: + {{- include "airlock-microgateway.operator.selectorLabels" . | nindent 4 }} \ No newline at end of file diff --git a/charts/airlock/microgateway/4.3.2/templates/operator/xds-service.yaml b/charts/airlock/microgateway/4.3.2/templates/operator/xds-service.yaml new file mode 100644 index 0000000000..81b41acf5b --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/templates/operator/xds-service.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +kind: Service +metadata: + name: airlock-microgateway-operator-xds + namespace: {{ .Release.Namespace }} + labels: + {{- include "airlock-microgateway.operator.labels" . | nindent 4 }} + {{- with .Values.operator.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with mustMerge .Values.operator.serviceAnnotations .Values.commonAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + ports: + - appProtocol: grpc + name: xds + port: 13377 + protocol: TCP + targetPort: 13377 + selector: + {{- include "airlock-microgateway.operator.selectorLabels" . | nindent 4 }} + operator.microgateway.airlock.com/isLeader: "true" diff --git a/charts/airlock/microgateway/4.3.2/templates/tests/rbac.yaml b/charts/airlock/microgateway/4.3.2/templates/tests/rbac.yaml new file mode 100644 index 0000000000..93bd4cd1bd --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/templates/tests/rbac.yaml @@ -0,0 +1,143 @@ +{{- if .Values.tests.enabled -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: tests + app.kubernetes.io/name: {{ include "airlock-microgateway.name" . }}-tests + {{- include "airlock-microgateway.sharedLabels" . | nindent 4 }} + name: "{{ include "airlock-microgateway.fullname" . }}-tests" + namespace: {{ .Release.Namespace }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: tests + app.kubernetes.io/name: {{ include "airlock-microgateway.name" . }}-tests + {{- include "airlock-microgateway.sharedLabels" . | nindent 4 }} + name: "{{ include "airlock-microgateway.fullname" . }}-tests" + namespace: {{ .Release.Namespace }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: "{{ include "airlock-microgateway.fullname" . }}-tests" +subjects: +- kind: ServiceAccount + name: "{{ include "airlock-microgateway.fullname" . }}-tests" +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: tests + app.kubernetes.io/name: {{ include "airlock-microgateway.name" . }}-tests + {{- include "airlock-microgateway.sharedLabels" . | nindent 4 }} + name: "{{ include "airlock-microgateway.fullname" . }}-tests" + namespace: {{ .Release.Namespace }} +rules: +- apiGroups: + - microgateway.airlock.com + resources: + - sidecargateways + resourceNames: + - "{{ include "airlock-microgateway.fullname" . }}-test-sidecargateway" + verbs: + - get + - list + - watch + - delete +- apiGroups: + - microgateway.airlock.com + resources: + - sidecargateways + verbs: + - create +- apiGroups: + - "" + resources: + - events + verbs: + - list +- apiGroups: + - "apps" + resources: + - deployments + resourceNames: + - "{{ include "airlock-microgateway.operator.fullname" . }}" + verbs: + - get + - list + - watch +- apiGroups: + - "apps" + resources: + - statefulsets + - statefulsets/scale + resourceNames: + - "{{ include "airlock-microgateway.fullname" . }}-test-backend" + verbs: + - get + - list + - watch + - patch +- apiGroups: + - "" + resources: + - pods + - pods/log + - pods/status + - pods/attach + resourceNames: + - "{{ include "airlock-microgateway.fullname" . }}-test-backend-0" + - "{{ include "airlock-microgateway.fullname" . }}-test-valid-request" + - "{{ include "airlock-microgateway.fullname" . }}-test-injection-request" + verbs: + - get + - list + - create + - watch + - delete +- apiGroups: + - "" + resources: + - pods + verbs: + - create +{{- if .Values.operator.watchNamespaceSelector }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/component: tests + app.kubernetes.io/name: {{ include "airlock-microgateway.name" . }}-tests + {{- include "airlock-microgateway.sharedLabels" . | nindent 4 }} + name: "{{ include "airlock-microgateway.fullname" . }}-tests-{{ .Release.Namespace }}" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: "{{ include "airlock-microgateway.fullname" . }}-tests-{{ .Release.Namespace }}" +subjects: + - kind: ServiceAccount + name: "{{ include "airlock-microgateway.fullname" . }}-tests" + namespace: {{ .Release.Namespace }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: tests + app.kubernetes.io/name: {{ include "airlock-microgateway.name" . }}-tests + {{- include "airlock-microgateway.sharedLabels" . | nindent 4 }} + name: "{{ include "airlock-microgateway.fullname" . }}-tests-{{ .Release.Namespace }}" +rules: +- apiGroups: + - "" + resources: + - namespaces + verbs: + - get + - list +{{- end }} +{{- end -}} diff --git a/charts/airlock/microgateway/4.3.2/templates/tests/service.yaml b/charts/airlock/microgateway/4.3.2/templates/tests/service.yaml new file mode 100644 index 0000000000..30ddc278d6 --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/templates/tests/service.yaml @@ -0,0 +1,23 @@ +{{- if .Values.tests.enabled -}} +apiVersion: v1 +kind: Service +metadata: + name: "{{ include "airlock-microgateway.fullname" . }}-test-service" + namespace: {{ .Release.Namespace }} + labels: + app: test-service + app.kubernetes.io/component: test-install + app.kubernetes.io/name: {{ include "airlock-microgateway.name" . }}-tests + {{- include "airlock-microgateway.sharedLabels" . | nindent 4 }} + {{- include "airlock-microgateway.sharedSelectorLabels" . | nindent 4 }} +spec: + selector: + app.kubernetes.io/component: test-install + app.kubernetes.io/name: {{ include "airlock-microgateway.name" . }}-tests + app: "{{ include "airlock-microgateway.fullname" . }}-test-backend" + {{- include "airlock-microgateway.sharedSelectorLabels" . | nindent 4 }} + ports: + - name: http + port: 8080 + targetPort: 8080 +{{- end -}} \ No newline at end of file diff --git a/charts/airlock/microgateway/4.3.2/templates/tests/statefulset.yaml b/charts/airlock/microgateway/4.3.2/templates/tests/statefulset.yaml new file mode 100644 index 0000000000..710a7b9f67 --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/templates/tests/statefulset.yaml @@ -0,0 +1,56 @@ +{{- if .Values.tests.enabled -}} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: "{{ include "airlock-microgateway.fullname" . }}-test-backend" + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/component: test-install + app.kubernetes.io/name: {{ include "airlock-microgateway.name" . }}-tests + app: "{{ include "airlock-microgateway.fullname" . }}-test-backend" + {{- include "airlock-microgateway.sharedLabels" . | nindent 4 }} + {{- include "airlock-microgateway.sharedSelectorLabels" . | nindent 4 }} +spec: + serviceName: nginx + replicas: 0 + selector: + matchLabels: + app.kubernetes.io/component: test-install + app.kubernetes.io/name: {{ include "airlock-microgateway.name" . }}-tests + app: "{{ include "airlock-microgateway.fullname" . }}-test-backend" + {{- include "airlock-microgateway.sharedSelectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + k8s.v1.cni.cncf.io/networks: default/airlock-microgateway-cni + labels: + sidecar.microgateway.airlock.com/inject: "true" + sidecar.istio.io/inject: "false" + app.kubernetes.io/component: test-install + app.kubernetes.io/name: {{ include "airlock-microgateway.name" . }}-tests + app: "{{ include "airlock-microgateway.fullname" . }}-test-backend" + {{- include "airlock-microgateway.sharedLabels" . | nindent 8 }} + {{- include "airlock-microgateway.sharedSelectorLabels" . | nindent 8 }} + spec: + containers: + - image: cgr.dev/chainguard/nginx + name: nginx + ports: + - containerPort: 8080 + volumeMounts: + - mountPath: /var/lib/nginx/tmp/ + name: nginx-tmp + - mountPath: /var/run + name: nginx-run + securityContext: + {{- include "airlock-microgateway.restrictedSecurityContext" . | nindent 12 }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - emptyDir: {} + name: nginx-tmp + - emptyDir: {} + name: nginx-run +{{- end -}} \ No newline at end of file diff --git a/charts/airlock/microgateway/4.3.2/templates/tests/test-install.yaml b/charts/airlock/microgateway/4.3.2/templates/tests/test-install.yaml new file mode 100644 index 0000000000..ab82abea73 --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/templates/tests/test-install.yaml @@ -0,0 +1,227 @@ +{{- if .Values.tests.enabled -}} +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "airlock-microgateway.fullname" . }}-test-install" + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/component: test-install + app.kubernetes.io/name: {{ include "airlock-microgateway.name" . }}-tests + sidecar.istio.io/inject: "false" + {{- include "airlock-microgateway.sharedLabels" . | nindent 4 }} + {{- include "airlock-microgateway.sharedSelectorLabels" . | nindent 4 }} + annotations: + helm.sh/hook: test + helm.sh/hook-delete-policy: before-hook-creation +spec: + restartPolicy: Never + containers: + - name: test + image: "bitnami/kubectl:{{ .Capabilities.KubeVersion.Major }}.{{ .Capabilities.KubeVersion.Minor }}" + securityContext: + {{- include "airlock-microgateway.restrictedSecurityContext" . | nindent 6 }} + command: + - sh + - -c + - | + set -eu + + clean_up() { + echo "" + echo "### Clean up test resources" + kubectl delete --ignore-not-found=true -n {{ .Release.Namespace }} sidecargateways.microgateway.airlock.com {{ include "airlock-microgateway.fullname" . }}-test-sidecargateway || true + echo "" + echo "### Scale down '{{ include "airlock-microgateway.fullname" . }}-test-backend'" + kubectl scale -n {{ .Release.Namespace }} statefulset/{{ include "airlock-microgateway.fullname" . }}-test-backend --replicas=0 --timeout=60s + sleep 3s + echo "" + } + + fail() { + echo "" + echo "### Error: ${1}" + echo "" + + if kubectl get -n {{ .Release.Namespace }} sidecargateway.microgateway.airlock.com/{{ include "airlock-microgateway.fullname" . }}-test-sidecargateway >/dev/null 2>&1; then + echo "" + echo 'Microgateway Sidecargateway status:' + kubectl get -n {{ .Release.Namespace }} sidecargateway.microgateway.airlock.com/{{ include "airlock-microgateway.fullname" . }}-test-sidecargateway -o jsonpath-as-json='{.status}' || true + echo "" + echo "" + fi + + if kubectl get -n {{ .Release.Namespace }} pods/{{ include "airlock-microgateway.fullname" . }}-test-backend-0 >/dev/null 2>&1; then + echo "Pod '{{ include "airlock-microgateway.fullname" . }}-test-backend-0':" + kubectl describe -n {{ .Release.Namespace }} pods/{{ include "airlock-microgateway.fullname" . }}-test-backend-0 || true + echo "" + echo "" + echo 'Logs of Nginx container:' + kubectl logs -n {{ .Release.Namespace }} pods/{{ include "airlock-microgateway.fullname" . }}-test-backend-0 -c nginx --tail 5 || true + echo "" + echo "" + # Wait for engine logs + sleep 10s + echo 'Logs of Microgateway Engine container:' + kubectl logs -n {{ .Release.Namespace }} pods/{{ include "airlock-microgateway.fullname" . }}-test-backend-0 -c airlock-microgateway-engine --tail 5 || true + fi + + exit 1 + } + + create_sidecargateway() { + # create SidecarGateway resource for testing purposes + kubectl delete --ignore-not-found=true -n {{ .Release.Namespace }} sidecargateways.microgateway.airlock.com {{ include "airlock-microgateway.fullname" . }}-test-sidecargateway || true + kubectl apply -f - </dev/null 2>&1; do sleep 1s; i=$((i+1)); done + kubectl logs -f -n {{ .Release.Namespace }} {{ include "airlock-microgateway.fullname" . }}-test-valid-request + kubectl delete pod --ignore-not-found=true -n {{ .Release.Namespace }} {{ include "airlock-microgateway.fullname" . }}-test-valid-request + } + + {{- if .Values.operator.watchNamespaceSelector }} + echo "### Verify that Namespace Selector matches Namespace '{{ .Release.Namespace }}'" + if ! kubectl get namespace -l '{{ include "airlock-microgateway.watchNamespaceSelector.labelQuery" .Values.operator.watchNamespaceSelector }}' | grep -q {{ .Release.Namespace }}; then + labels=$(kubectl get namespace {{ .Release.Namespace }} -o jsonpath={.metadata.labels} | jq | awk '{print " " $0}') + fail {{printf `"Operator namespace '%s' is not part of the operator's watch scope. To execute 'helm test', the selector configured in the helm value 'operator.watchNamespaceSelector' must match the namespace's labels:\n* Current selector:\n%s\n\n* Current labels:\n$labels\n###"` + .Release.Namespace + (replace "\"" "\\\"" (replace "\n" "\\n" (.Values.operator.watchNamespaceSelector | toPrettyJson | indent 2))) + }} + fi + echo "" + {{- end }} + + trap clean_up EXIT + echo "" + + echo "### Waiting for Microgateway Operator Deployments to be ready" + if ! kubectl rollout status -n {{ .Release.Namespace }} --timeout=90s \ + deployments/{{ include "airlock-microgateway.operator.fullname" . }}; then + fail 'Timout occurred' + fi + echo "" + + echo "### Scale '{{ include "airlock-microgateway.fullname" . }}-test-backend' to '1' replica" + # scale to zero replicas to ensure no pods are present from previous runs + kubectl scale -n {{ .Release.Namespace }} statefulset/{{ include "airlock-microgateway.fullname" . }}-test-backend --replicas=0 --timeout=10s + kubectl scale -n {{ .Release.Namespace }} statefulset/{{ include "airlock-microgateway.fullname" . }}-test-backend --replicas=1 --timeout=10s + echo "" + + echo "### Waiting for backend pod" + i=0 + while true; do + if kubectl get -n {{ .Release.Namespace }} pods/{{ include "airlock-microgateway.fullname" . }}-test-backend-0; then + break + elif [ $i -gt 3 ]; then + fail 'Pod not ready' + fi + sleep 2s + i=$((i+1)) + done + + echo "### Checking Microgateway Engine sidecar container was injected" + if ! kubectl get -n {{ .Release.Namespace }} pods/{{ include "airlock-microgateway.fullname" . }}-test-backend-0 -o jsonpath='{.spec.containers[?(@.name=="airlock-microgateway-engine")]}' | grep -q "airlock-microgateway-engine"; then + fail 'Microgateway Engine sidecar container not injected' + fi + echo "True" + echo "" + + echo "### Checking for valid license" + i=0 + while true; do + if [ "$(kubectl get -n {{ .Release.Namespace }} pods/{{ include "airlock-microgateway.fullname" . }}-test-backend-0 -o jsonpath='{.metadata.labels.sidecar\.microgateway\.airlock\.com/licensed}')" = 'true' ]; then + break + elif [ $i -gt 30 ]; then + fail 'Microgateway license is missing or invalid' + fi + sleep 2s + i=$((i+1)) + done + echo "True" + echo "" + + echo "### Create SidecarGateway resource for testing" + if ! create_sidecargateway ; then + fail 'Creation of SidecarGateway resource failed' + fi + echo "" + + echo "### Waiting for '{{ include "airlock-microgateway.fullname" . }}-test-backend' to be ready" + if ! kubectl rollout status -n {{ .Release.Namespace }} statefulset/{{ include "airlock-microgateway.fullname" . }}-test-backend --timeout=90s; then + fail 'Timout occurred' + fi + echo "" + + echo "### Waiting for 'engine-config-valid' condition" + if ! kubectl wait -n {{ .Release.Namespace }} pods --field-selector=metadata.name={{ include "airlock-microgateway.fullname" . }}-test-backend-0 --timeout=90s --for=condition=microgateway.airlock.com/engine-config-valid=True; then + fail 'Configuration was never accepted by the Microgateway Engine' + fi + sleep 5s + echo "" + echo "" + + echo "### Checking whether a valid request is successful and returns HTTP status code '200'" + out=$(curl -vsS --retry 3 --retry-connrefused --connect-timeout 10 "http://{{ include "airlock-microgateway.fullname" . }}-test-service:8080/" || true) + echo "Response:" + echo "${out}" + if ! echo "${out}" | grep -q "200 OK"; then + fail 'A valid request was not successful' + fi + echo "" + echo "" + + echo "### Checking whether a request with an injection attack is blocked and returns HTTP status code '400'" + out=$(curl -vsS --retry 3 --retry-connrefused --connect-timeout 10 "http://{{ include "airlock-microgateway.fullname" . }}-test-service:8080/?token='%20UnION%20all%20select%20A" || true) + echo "Response:" + echo "${out}" + if ! echo "${out}" | grep -q "400 Bad Request"; then + fail 'A malicious request was not blocked' + fi + echo "" + echo "" + + echo "### Installation of '{{ include "airlock-microgateway.fullname" . }}' succeeded" + exit 0 + serviceAccountName: "{{ include "airlock-microgateway.fullname" . }}-tests" +{{- end -}} diff --git a/charts/airlock/microgateway/4.3.2/values.schema.json b/charts/airlock/microgateway/4.3.2/values.schema.json new file mode 100644 index 0000000000..173d6b084c --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/values.schema.json @@ -0,0 +1,540 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "properties": { + "nameOverride": { + "type": "string" + }, + "fullnameOverride": { + "type": "string" + }, + "commonLabels": { + "$ref": "#/definitions/StringMap" + }, + "commonAnnotations": { + "$ref": "#/definitions/StringMap" + }, + "crds": { + "type": "object", + "properties": { + "skipVersionCheck": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + "imagePullSecrets": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "name" + ], + "additionalProperties": true + } + }, + "operator": { + "type": "object", + "properties": { + "replicaCount": { + "type": "integer", + "minimum": 0 + }, + "updateStrategy": { + "$ref": "#/definitions/UpdateStrategy" + }, + "image": { + "$ref": "#/definitions/Image" + }, + "podAnnotations": { + "$ref": "#/definitions/StringMap" + }, + "podLabels": { + "$ref": "#/definitions/StringMap" + }, + "serviceAnnotations": { + "$ref": "#/definitions/StringMap" + }, + "serviceLabels": { + "$ref": "#/definitions/StringMap" + }, + "resources": { + "type": "object" + }, + "nodeSelector": { + "$ref": "#/definitions/StringMap" + }, + "tolerations": { + "type": "array", + "items": { + "type": "object" + } + }, + "affinity": { + "type": "object" + }, + "config": { + "type": "object", + "properties": { + "logLevel": { + "type": "string", + "enum": [ + "debug", + "info", + "warn", + "error" + ] + } + }, + "required": [ + "logLevel" + ], + "additionalProperties": false + }, + "serviceAccount": { + "type": "object", + "properties": { + "create": { + "type": "boolean" + }, + "annotations": { + "$ref": "#/definitions/StringMap" + }, + "name": { + "type": "string" + } + }, + "required": [ + "annotations", + "create", + "name" + ], + "additionalProperties": false + }, + "watchNamespaces": { + "type": "array", + "items": { + "type": "string" + } + }, + "watchNamespaceSelector": { + "$ref": "#/definitions/LabelSelector" + }, + "rbac": { + "type": "object", + "properties": { + "create": { + "type": "boolean" + } + }, + "required": [ + "create" + ], + "additionalProperties": false + }, + "serviceMonitor": { + "type": "object", + "properties": { + "create": { + "type": "boolean" + }, + "labels": { + "$ref": "#/definitions/StringMap" + } + }, + "required": [ + "create" + ], + "additionalProperties": false + } + }, + "oneOf": [ + { + "properties": { + "watchNamespaces": { + "minItems": 1 + }, + "watchNamespaceSelector": { + "additionalProperties": false + } + } + }, + { + "properties": { + "watchNamespaces": { + "maxItems": 0 + }, + "watchNamespaceSelector": { + "$ref": "#/definitions/LabelSelector" + } + } + } + ], + "required": [ + "affinity", + "config", + "image", + "updateStrategy", + "nodeSelector", + "podAnnotations", + "podLabels", + "rbac", + "replicaCount", + "resources", + "serviceAccount", + "serviceAnnotations", + "serviceLabels", + "serviceMonitor", + "tolerations" + ], + "additionalProperties": false + }, + "engine": { + "type": "object", + "properties": { + "image": { + "$ref": "#/definitions/Image" + }, + "resources": { + "type": "object" + }, + "sidecar": { + "type": "object", + "properties":{ + "podMonitor": { + "type": "object", + "properties": { + "create": { + "type": "boolean" + }, + "labels": { + "$ref": "#/definitions/StringMap" + } + }, + "required": [ + "create" + ], + "additionalProperties": false + } + }, + "required": [ + "podMonitor" + ], + "additionalProperties": false + } + }, + "required": [ + "image", + "resources", + "sidecar" + ], + "additionalProperties": false + }, + "networkValidator": { + "type": "object", + "properties": { + "image": { + "$ref": "#/definitions/Image" + } + }, + "required": [ + "image" + ], + "additionalProperties": false + }, + "sessionAgent": { + "type": "object", + "properties": { + "image": { + "$ref": "#/definitions/Image" + }, + "resources": { + "type": "object" + } + }, + "required": [ + "image", + "resources" + ], + "additionalProperties": false + }, + "license": { + "type": "object", + "properties": { + "secretName": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "secretName" + ], + "additionalProperties": false + }, + "dashboards": { + "type": "object", + "properties" : { + "create": { + "type": "boolean" + }, + "config": { + "type": "object", + "properties": { + "grafana": { + "type": "object", + "properties": { + "folderAnnotation": { + "$ref": "#/definitions/NameValuePair" + }, + "dashboardLabel": { + "$ref": "#/definitions/NameValuePair" + } + }, + "required": [ + "folderAnnotation", + "dashboardLabel" + ], + "additionalProperties": false + } + }, + "required": [ + "grafana" + ], + "additionalProperties": false + }, + "instances": { + "type": "object", + "properties": { + "overview": { + "$ref": "#/definitions/DashboardInstance" + }, + "license" : { + "$ref": "#/definitions/DashboardInstance" + }, + "blockMetrics" : { + "$ref": "#/definitions/DashboardInstance" + }, + "blockLogs" : { + "$ref": "#/definitions/DashboardInstance" + } + }, + "required": [ + "overview", + "license", + "blockMetrics", + "blockLogs" + ], + "additionalProperties": false + } + }, + "required": [ + "create", + "config", + "instances" + ], + "additionalProperties": false + }, + "tests": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + } + }, + "required": [ + "enabled" + ], + "additionalProperties": false + }, + "global": { + "type": "object" + } + }, + "required": [ + "commonAnnotations", + "commonLabels", + "crds", + "engine", + "fullnameOverride", + "imagePullSecrets", + "license", + "nameOverride", + "operator", + "networkValidator", + "sessionAgent", + "dashboards", + "tests" + ], + "additionalProperties": false, + "definitions": { + "StringMap": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "Image": { + "type": "object", + "properties": { + "repository": { + "type": "string", + "minLength": 1 + }, + "tag": { + "type": "string" + }, + "digest": { + "type": "string", + "pattern": "^$|^sha256:[a-f0-9]{64}$" + }, + "pullPolicy": { + "type": "string", + "enum": [ + "Always", + "IfNotPresent", + "Never" + ] + } + }, + "required": [ + "digest", + "pullPolicy", + "repository", + "tag" + ], + "additionalProperties": false + }, + "LabelSelector": { + "type": "object", + "properties": { + "matchExpressions": { + "type": "array", + "items": { + "type": "object", + "required": [ + "key", + "operator" + ], + "properties": { + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "values": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + } + }, + "matchLabels": { + "$ref": "#/definitions/StringMap" + } + }, + "additionalProperties": false + }, + "UpdateStrategy": { + "type": "object", + "oneOf" : [ + { + "properties": { + "type": { + "$ref": "#/definitions/RecreateType" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + }, + { + "properties": { + "type": { + "$ref": "#/definitions/RollingUpdateType" + }, + "rollingUpdate": { + "$ref": "#/definitions/RollingUpdate" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + } + ] + }, + "RecreateType": { + "type": "string", + "enum": [ + "Recreate" + ] + }, + "RollingUpdateType": { + "type": "string", + "enum": [ + "RollingUpdate" + ] + }, + "RollingUpdate": { + "type": "object", + "properties": { + "maxSurge": { + "type": ["integer", "string"], + "minimum": 0, + "pattern": "^\\d+%?$" + }, + "maxUnavailable": { + "type": ["integer", "string"], + "minimum": 0, + "pattern": "^\\d+%?$" + } + }, + "anyOf": [ + {"required": ["maxSurge"]}, + {"required": ["maxUnavailable"]} + ], + "additionalProperties": false + }, + "DashboardInstance" : { + "type" : "object", + "properties" : { + "create" : { + "type" : "boolean" + } + }, + "required" : [ + "create" + ], + "additionalProperties": false + }, + "NameValuePair" : { + "type" : "object", + "properties" : { + "name" : { + "type": "string", + "minLength": 1 + }, + "value" : { + "type" : "string", + "minLength": 1 + } + }, + "required" : [ + "name", + "value" + ], + "additionalProperties": false + } + } +} diff --git a/charts/airlock/microgateway/4.3.2/values.yaml b/charts/airlock/microgateway/4.3.2/values.yaml new file mode 100644 index 0000000000..36f513b486 --- /dev/null +++ b/charts/airlock/microgateway/4.3.2/values.yaml @@ -0,0 +1,213 @@ +# -- Allows overriding the name to use instead of "microgateway". +nameOverride: "" +# -- Allows overriding the name to use as full name of resources. +fullnameOverride: "" +# -- Labels to add to all resources. +commonLabels: {} +# -- Annotations to add to all resources. +commonAnnotations: {} +# -- ImagePullSecrets to use when pulling images. +imagePullSecrets: [] +# - name: myRegistryKeySecretName + +crds: + # -- Whether to skip the sanity check which prevents installing/upgrading the helm chart in a cluster with outdated Airlock Microgateway CRDs. + # The check aims to prevent unexpected behavior and issues due to Helm v3 not automatically upgrading CRDs which are already present in the cluster + # when performing a "helm install/upgrade". + skipVersionCheck: false +operator: + # -- Number of replicas for the operator Deployment. + replicaCount: 2 + # -- Specifies the operator update strategy. + updateStrategy: + type: RollingUpdate + # Specifies the Airlock Microgateway Operator image. + image: + # -- Image repository from which to pull the Airlock Microgateway Operator image. + repository: "quay.io/airlock/microgateway-operator" + # -- Image tag to pull. + tag: "4.3.2" + # -- SHA256 image digest to pull (in the format "sha256:c79ee3f85862fb386e9dd62b901b607161d27807f512d7fbdece05e9ee3d7c63"). + # Overrides tag when specified. + digest: "sha256:d22f2ca35603b805caa67dd07aba524c3e4d68c3b59f7ddfc0e22e7fc09a200c" + # -- Pull policy for this image. + pullPolicy: IfNotPresent + # -- Annotations to add to all Pods. + podAnnotations: {} + # -- Labels to add to all Pods. + podLabels: {} + # -- Annotations to add to the Service. + serviceAnnotations: {} + # prometheus.io/scrape: "true" + # prometheus.io/port: "8080" + + # -- Labels to add to the Service. + serviceLabels: {} + # -- Resource restrictions to apply to the operator container. + resources: {} + # We recommend at least the following resource specification. + # limits: + # cpu: 1000m + # memory: 512Mi + # requests: + # cpu: 100m + # memory: 512Mi + + # -- Custom nodeSelector to apply to the operator Deployment in order to constrain its Pods to certain nodes. + nodeSelector: {} + # -- Custom tolerations to apply to the operator Deployment in order to allow its Pods to run on tainted nodes. + tolerations: [] + # -- Custom affinity to apply to the operator Deployment. Used to influence the scheduling. + affinity: {} + # Parameters for the operator configuration. + config: + # -- Operator application log level. + logLevel: "info" + # Configures the generation of the ServiceAccount. + serviceAccount: + # -- Whether a ServiceAccount should be created. + create: true + # -- Annotations to add to the ServiceAccount. + annotations: {} + # -- Name of the ServiceAccount to use. + # If not set and create is true, a name is generated using the fullname template. + name: "" + # -- Allows to restrict the operator to specific namespaces, depending on your needs. + # For a `OwnNamespace` or `SingleNamespace` installation the list may only contain one namespace (e.g., `watchNamespaces: ["airlock-microgateway-system"]`). + # In case of the `OwnNamespace` installation mode the specified namespace should be equal to the installation namespace. + # For a static `MultiNamespace` installation, the complete list of namespaces must be provided in the `watchNamespaces`. + # An `AllNamespaces` installation or the usage of the `watchNamespaceSelector` requires the `watchNamespaces` to be empty. + # Regardless of the installation modes supported by `watchNamespaces`, RBAC is created only namespace-scoped (using Roles and RoleBindings) in the respective namespaces. + # Please note that this feature requires a Premium license. + watchNamespaces: [] + # -- Allows to dynamically select watch namespaces of the operator and the scope of the webhooks based on a Namespace label selector. + # It is able to detect and reconcile resources in all namespaces that match the label selector automatically, even for new namespaces, without restarting the operator. + # This facilitates a dynamic `MultiNamespace` installation mode, but still requires cluster-scoped permissions (i.e., ClusterRoles and ClusterRoleBindings). + # An `AllNamespaces` installation or the usage of the `watchNamespaces` requires the `watchNamespaceSelector` to be empty. + # Please note that this feature requires a Premium license. + watchNamespaceSelector: {} + # For further examples, see: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#resources-that-support-set-based-requirements. + # matchLabels: + # microgateway.airlock.com/enable: "true" + # matchExpressions: + # - { key: environment, operator: NotIn, values: [dev] } + + # Configures the generation of Role and RoleBinding as well as ClusterRoles and ClusterRoleBinding pairs for the ServiceAccount specified above. + rbac: + # -- Whether to create RBAC resources which are required for the Airlock Microgateway Operator to function. + create: true + # Configures the generation of a Prometheus Operator ServiceMonitor. + serviceMonitor: + # -- Whether to create a ServiceMonitor resource for monitoring. + create: false + # -- Labels to add to the ServiceMonitor. + labels: {} + # release: "" +engine: + # Specifies the Airlock Microgateway Engine image. + image: + # -- Image repository from which to pull the Airlock Microgateway Engine image. + repository: "quay.io/airlock/microgateway-engine" + # -- Image tag to pull. + tag: "4.3.2" + # -- SHA256 image digest to pull (in the format "sha256:a3051f42d3013813b05f7513bb86ed6a3209cb3003f1bb2f7b72df249aa544d3"). + # Overrides tag when specified. + digest: "sha256:8d42759d999e6b69efa9ef1ecfdc84dc1f8f6f1ca822c8d2d3ef8ff1e335b9c9" + # -- Pull policy for this image. + pullPolicy: IfNotPresent + # -- Resource restrictions to apply to the Airlock Microgateway Engine container. + resources: {} + # We recommend at least the following resource specification. + # limits: + # cpu: 500m + # memory: 128Mi + # requests: + # cpu: 10m + # memory: 40Mi + + # Additional configuration when deployed as a sidecar. + sidecar: + # Configures the generation of a Prometheus Operator PodMonitor. + podMonitor: + # -- Whether to create a PodMonitor resource for monitoring. + create: false + # -- Labels to add to the PodMonitor. + labels: {} + # release: "" +networkValidator: + # Specifies the Airlock Microgateway Network Validator image to be injected as an init-container. + image: + # -- Image repository from which to pull the netcat image for the Airlock Microgateway Network Validator init-container. + repository: "cgr.dev/chainguard/netcat" + # -- Image tag to pull. + tag: "" + # -- SHA256 image digest to pull (in the format "sha256:d1c484f4b9ea6218e2b1925f6b08d54dd352c7aaf653977bbbbeeb21eb3e19dd"). + # Overrides tag when specified. + digest: "sha256:d1c484f4b9ea6218e2b1925f6b08d54dd352c7aaf653977bbbbeeb21eb3e19dd" + # -- Pull policy for this image. + pullPolicy: IfNotPresent +sessionAgent: + # Specifies the Airlock Microgateway Session Agent image. + image: + # -- Image repository from which to pull the Airlock Microgateway Session Agent image. + repository: "quay.io/airlock/microgateway-session-agent" + # -- Image tag to pull. + tag: "4.3.2" + # -- SHA256 image digest to pull (in the format "sha256:a3051f42d3013813b05f7513bb86ed6a3209cb3003f1bb2f7b72df249aa544d3"). + # Overrides tag when specified. + digest: "sha256:d487f4099c267310debffe5d5cac168deeddf6082dafbee352550f2792b9609c" + # -- Pull policy for this image. + pullPolicy: IfNotPresent + # -- Resource restrictions to apply to the Airlock Microgateway Session Agent container. + resources: {} + # We recommend at least the following resource specification. + # limits: + # cpu: 150m + # memory: 32Mi + # requests: + # cpu: 10m + # memory: 8Mi +license: + # -- Name of the secret containing the "microgateway-license.txt" key. + secretName: "airlock-microgateway-license" +# Creates dashboards in the form of ConfigMaps that can be imported +# by Grafana using its sidecar setup. +dashboards: + # -- Whether to create any ConfigMaps containing Grafana dashboards to import. + create: false + config: + # Configures the necessary label and annotations along with their values + # to enable Grafana to correctly identify the ConfigMaps containing + # dashboards and file them within a dedicated folder in the dashboard overview. + # These settings need to match the Grafana sidecar configuration. + grafana: + folderAnnotation: + # -- Name of the annotation containing the folder name to file dashboards into. + name: "grafana_folder" + # -- Name of the folder dashboards are filed into within the Grafana UI. + value: "Airlock Microgateway" + dashboardLabel: + # -- Name of the label that lets Grafana identify ConfigMaps that represent dashboards. + name: "grafana_dashboard" + # -- Value of the label that lets Grafana identify ConfigMaps that represent dashboards. + value: "1" + instances: + # Available dashboard instances that can be individually created/deployed. + overview: + # -- Whether to create the overview dashboard. + create: true + license: + # -- Whether to create the license dashboard. + create: true + blockMetrics: + # -- Whether to create the block metrics dashboard. + create: true + blockLogs: + # -- Whether to create the block logs dashboard. + create: true +# Check whether the installation of the Airlock Microgateway Helm Chart was successful. +# Requires a secret with a valid Airlock Microgateway license key already to be present. +tests: + # -- Whether additional resources required for running `helm test` should be created (e.g. Roles and ServiceAccounts). + # If set to false, `helm test` will not run any tests. + enabled: false diff --git a/charts/kong/kong/2.41.0/CHANGELOG.md b/charts/kong/kong/2.41.0/CHANGELOG.md new file mode 100644 index 0000000000..f7656c4608 --- /dev/null +++ b/charts/kong/kong/2.41.0/CHANGELOG.md @@ -0,0 +1,1932 @@ +# Changelog + +## 2.41.0 + +### Changes + +* Bumped default `kong/kubernetes-ingress-controller` image tag to 3.3. + [#1121](https://github.com/Kong/charts/pull/1121) + +## 2.40.0 + +* Add `deployment.revisionHistoryLimit` to set how many old `ReplicaSet`s you want to retain. + +### Changes +* Added support for ServiceMonitor relabelings allowing labels manipulation before scraping. + [#1095](https://github.com/Kong/charts/pull/1095) + +### Fixed +* Populate `KONG_ADMIN_GUI_SESSION_CONF` even if `enterprise.rbac.admin_gui_auth` is set to `openid-connect` + for Kong versions < 3.6.0. + [#1101](https://github.com/Kong/charts/pull/1101) + +### Breaking changes + +* Added `ingressController.konnect.controlPlaneID` and deprecated `ingressController.konnect.runtimeGroupID` + [#1099](https://github.com/Kong/charts/pull/1099) + +## 2.39.3 + +### Fixed + +* `KONG_ADMIN_GUI_SESSION_CONF` is not populated only when `enterprise.rbac.admin_gui_auth` + is set to `openid-connect`. The default value of `enterprise.rbac.session_conf_secret` is + restored to `kong-session-config` to avoid breaking changes. + [#1093](https://github.com/Kong/charts/pull/1093) + +## 2.39.2 + +### Fixed + +* Fixes `KongLicense` policy rules for Ingress controller when using `watchNamespaces` + [#1084](https://github.com/Kong/charts/pull/1084) + +## 2.39.1 + +### Fixed + +* Added missing `KongCustomEntity` CRD for KIC 3.2. + +## 2.39.0 + +### Changes + +* Updated handling of `session_conf_secret` to accommodate Kong 3.6. + It can now be omitted [when using OIDC](https://docs.konghq.com/gateway/3.6.x/kong-manager/auth/oidc/migrate/). + [#1033](https://github.com/Kong/charts/pull/1033) +* Setting a Service's `servicePort` to 0 now disables that port on the Service, + for use when the external Service and container listens should differ, such + as when terminating TLS at a LoadBalancer. + [#1021](https://github.com/Kong/charts/pull/1021) +* Added an `ingressController.admissionWebhook.filterSecrets` option. When + enabled, the webhook will only validate Secrets that have one of the + recognized KIC labels: + + * `konghq.com/credential: <"key-auth", "jwt", etc. credential types>` + * `konghq.com/validate: <"plugin", "custom">` + + Earlier versions checked all Secrets and did not require labels, interfering + with non-KIC labels. Requires KIC 3.0+. + [#1061](https://github.com/Kong/charts/pull/1061) +* Add RBAC policy rules for Custom Entities + [#1081](https://github.com/Kong/charts/pull/1081) +* Bumped default `kong/kubernetes-ingress-controller` image tag to 3.2. + [#1085](https://github.com/Kong/charts/pull/1085) + +## 2.38.0 + +### Changes + +* Added support for setting `SVC.tls.appProtocol` and `SVC.http.appProtocol` values to configure the appProtocol fields + for Kubernetes Service HTTP and TLS ports. It might be useful for integration with external load balancers like GCP. + [#1018](https://github.com/Kong/charts/pull/1018) + +## 2.37.1 + +* Rename the controller status port. This fixes a collision with the proxy status port in the Prometheus ServiceMonitor. + [#1008](https://github.com/Kong/charts/pull/1008) + +## 2.37.0 + +### Changes + +* Bumped default `kong/kubernetes-ingress-controller` image tag and updated CRDs to 3.1. + [#1011](https://github.com/Kong/charts/pull/1011) +* Bumped default `kong` image tag to 3.6. + [#1011](https://github.com/Kong/charts/pull/1011) + +## 2.36.0 + +### Fixed + +* Add `KongLicense` RBAC rules. + [#1006](https://github.com/Kong/charts/pull/1006) + +## 2.35.1 + +### Fixed + +* The plugin helper no longer sets the plugin list when not in use. + [#1002](https://github.com/Kong/charts/pull/1002) + +## 2.35.0 + +### Added + +* Added controller's RBAC rules for `KongVault` CRD (installed only when KIC + version >= 3.1.0). + [#992](https://github.com/Kong/charts/pull/992) + +### Fixed + +* Added a missing `envFrom` render in the main Kong proxy container. + [#994](https://github.com/Kong/charts/pull/994) + +## 2.34.0 + +### Added + +* The `envFrom` and `ingressController.envFrom` values.yaml keys now populate + the container field of the same name. This loads environment variables from + ConfigMap or Secret resource keys in bulk: + https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#configure-all-key-value-pairs-in-a-configmap-as-container-environment-variables + [#987](https://github.com/Kong/charts/pull/987) +* Kong listens now use both IPv4 and IPv6 addresses. + [#986](https://github.com/Kong/charts/pull/986) + +## 2.33.3 + +### Fixed + +* Add RBAC rules for get, list and watch operations on namespaces so that Gateway API + controllers in KIC can access using a cached controller-runtime client. + [#974](https://github.com/Kong/charts/pull/974) + +## 2.33.2 + +### Fixed + +* Fix a template bug related to the `affinity` field for migrations Pods. + [#972](https://github.com/Kong/charts/pull/972) + +## 2.33.1 + +### Fixed + +* Use changed `incubator.ingress-controller.konghq.com` API group name in `KongServiceFacade` + RBAC rules. Refer to [KIC#5302](https://github.com/Kong/kubernetes-ingress-controller/pull/5302) + for rename reasoning. + [#968](https://github.com/Kong/charts/pull/968) + +## 2.33.0 + +### Improvements + +* Only allow `None` ClusterIPs on ClusterIP-type Services. + [#961](https://github.com/Kong/charts/pull/961) + [#962](https://github.com/Kong/charts/pull/962) +* Bumped Kong version to 3.5. + [#957](https://github.com/Kong/charts/pull/957) +* Support for `affinity` configuration has been added to migration job templates. +* Display a warning message when Kong Manager is enabled and the Admin API is disabled. +* Validate Gateway API's `Gateway` and `HTTPRoute` resources in the controller's + admission webhook only when KIC version is 3.0 or higher. + [#954](https://github.com/Kong/charts/pull/954) +* Added controller's RBAC rules for `KongServiceFacade` CRD (installed only when + KongServiceFacade feature gate turned on and KIC version >= 3.1.0). + [#963](https://github.com/Kong/charts/pull/963) + +## 2.32.0 + +### Improvements + +* Add new `deployment.hostname` value to make identifying instances in + controlplane/dataplane configurations easier. + [#943](https://github.com/Kong/charts/pull/943) + +## 2.31.0 + +### Improvements + +* Added controller's RBAC rules for `KongUpstreamPolicy` CRD. + [#917](https://github.com/Kong/charts/pull/917) +* Added services resource to admission webhook config for KIC >= 3.0.0. + [#919](https://github.com/Kong/charts/pull/919) +* Update default ingress controller version to v3.0 + [#929](https://github.com/Kong/charts/pull/929) + [#930](https://github.com/Kong/charts/pull/930) + +### Fixed + +* The target port for cmetrics should only be applied if the ingress controller is enabled. + [#926](https://github.com/Kong/charts/pull/926) +* Fix RBAC for Gateway API v1. + [#928](https://github.com/Kong/charts/pull/928) +* Enable Admission webhook for Gateway API v1 resources. + [#928](https://github.com/Kong/charts/pull/928) + +## 2.30.0 + +### Improvements + +* Prevent installing PodDisruptionBudget for `replicaCount: 1` or `autoscaling.minReplicas: 1`. + [#896](https://github.com/Kong/charts/pull/896) +* The admission webhook now will be triggered on Secrets creation for KIC 2.12.1+. + [#907](https://github.com/Kong/charts/pull/907) +* Container security context defaults now comply with the restricted pod + security standard. This includes an enforced run as user ID set to 1000. UID + 1000 is used for official Kong images other than Alpine images (which use UID + 100) and for KIC images 3.0.0+ (older images use UID 65532). Images that do + not use UID 1000 can still run with this user, as static image files are + world-accessible and runtime-created files are created in temporary + directories created for the run as user. + [#911](https://github.com/Kong/charts/pull/911) +* Allow using templates (via `tpl`) when specifying `proxy.nameOverride`. + [#914](https://github.com/Kong/charts/pull/914) + +## 2.29.0 + +### Improvements +* Make it possible to set the admission webhook's `timeoutSeconds`. + [#894](https://github.com/Kong/charts/pull/894) + +## 2.28.1 + +### Fixed + +* The admission webhook now includes Gateway API resources and Ingress + resources for controller versions 2.12+. This version introduces new + validations for Kong's regex path implementation. + [#892](https://github.com/Kong/charts/pull/892) + +## 2.28.0 + +### Improvements + +* Bump default `kong` image tag to 3.4. + [#883](https://github.com/Kong/charts/pull/883) +* Bump default ingress controller image tag to 2.12. +* Added validation rule for `latency` upstream load balancing algorithm to + CRDs. [Upgrade your CRDs](https://github.com/Kong/charts/blob/main/charts/kong/UPGRADE.md#updates-to-crds) + when installing this release. + +## 2.27.0 + +### Improvements + +* Listens now all support `.address` configuration. This was an existing + setting that was not applied properly for some listens. + [#881](https://github.com/Kong/charts/pull/881) + +## 2.26.5 + +### Fixed + +* Kuma ServiceAccount Token hints and volumes are also available in migrations + Pods. + [#877](https://github.com/Kong/charts/pull/877) + +## 2.26.4 + +### Fixed + +* updated `admin_api_uri` to `admin_gui_api_url` as per [kong documentation](https://docs.konghq.com/gateway/3.4.x/reference/configuration/#admin_api_uri). + +## 2.26.3 + +### Fixed + +* Enabled Service and Ingress in Kong Manager for non enterprise users. + +## 2.26.2 + +### Fixed + +* Add missing CRD KongConsumerGroup and extend status subresource for CRDs + +## 2.26.1 + +### Fixed + +* Fix parsing enterprise tags (like e.g. `3.4.0.0`) + [#857](https://github.com/Kong/charts/pull/857) + +## 2.26.0 + +### Breaking changes + +2.26 changes the default proxy readiness endpoint for newer Kong versions. This +causes an issue in a narrow edge case. If all of the following are true: + +* You use Kong 3.3 or newer. +* You use controller 2.10 or older. +* You run the controller and proxy in separate Deployments. + +you are affected and should review [the 2.26 upgrade instructions](https://github.com/Kong/charts/blob/main/charts/kong/UPGRADE.md#2260). + +### Improvements + +* Use the Kong 3.3 `/status/ready` endpoint for readiness probes by default if + available. If not available, use the old `/status` default. + [#844](https://github.com/Kong/charts/pull/844) +* Add ArgoCD `Sync` and `BeforeHookCreation` [hook policies](https://argo-cd.readthedocs.io/en/stable/user-guide/resource_hooks/) + to the the init and pre-upgrade migrations Jobs. +* Add controller's RBAC rules for `KongConsumerGroups` CRD. + [#850](https://github.com/Kong/charts/pull/850) +* Updated controller version to 2.11. + +## 2.25.0 + +- Generate the `adminApiService.name` value from `.Release.Name` rather than + hardcoding to `kong` + [#839](https://github.com/Kong/charts/pull/839) + +## 2.24.0 + +### Improvements + +* Running `tpl` against user-supplied labels and annotations used in Deployment + [#814](https://github.com/Kong/charts/pull/814) + + Example: + ```yaml + podLabels: + version: "{{ .Values.image.tag }}" # Will render dynamically when overridden downstream + ``` + +* Fail to render templates when PodSecurityPolicy was requested but cluster doesn't + serve its API. + [#823](https://github.com/Kong/charts/pull/823) +* Add support for multiple hosts and tls configurations for Kong proxy `Ingress`. + [#813](https://github.com/Kong/charts/pull/813) +* Bump postgres default tag to `13.11.0-debian-11-r20` which includes arm64 images. + [#834](https://github.com/Kong/charts/pull/834) + +### Fixed + +* Fix Ingress and HPA API versions during capabilities checking + [#827](https://github.com/Kong/charts/pull/827) + +## 2.23.0 + +### Improvements + +* Add custom label configuration option for Kong proxy `Ingress`. + [#812](https://github.com/Kong/charts/pull/812) +* Bump default `kong/kubernetes-ingress-controller` image tag to 2.10. + Bump default `kong` image tag to 3.3. + [#815](https://github.com/Kong/charts/pull/815) + +## 2.22.0 + +### Improvements + +* Removed redundant RBAC permissions for non-existing subresources `secrets/status` + and `endpoints/status`. + [#798](https://github.com/Kong/charts/pull/798) +* For Kong Ingress Controller in version >= 2.10, RBAC permissions for `Endpoints` + are not configured anymore (because it uses `EndpointSlices`). + [#798](https://github.com/Kong/charts/pull/798) +* Added support for setting `certificates.cluster.commonName`. This allows a custom + certificate `CommonName` to be provided when deploying Kong Gateway in hybrid + mode using Cert Manager [#804](https://github.com/Kong/charts/pull/804) + +## 2.21.0 + +### Improvements + +* Added support for `startupProbe` on Kong pods. This can be configured via + `.Values.startupProbe`. To maintain backward compatibility, it is disabled by default. + [#792](https://github.com/Kong/charts/pull/792) +* Customize Admission Webhook namespaceSelectors and compose them from values. + [#794](https://github.com/Kong/charts/pull/794) +* Added `CustomResourceDefinition` `list` and `watch` permissions to controller's ClusterRole. + [#796](https://github.com/Kong/charts/pull/796) + +## 2.20.2 + +### Fixed + +* Automatic license provisioning for Gateways managed by Ingress Controllers in Konnect mode + is disabled by default. + To enable it, set `.Values.ingressController.konnect.license.enabled=true`. + [#793](https://github.com/Kong/charts/pull/793) + +## 2.20.1 + +### Fixed + +* Fix correct timestamp format and remove `isCA` in certificates + [#791](https://github.com/Kong/charts/pull/791) + +## 2.20.0 + +### Improvements + +* Added support for automatic license provisioning for Gateways managed by + Ingress Controllers in Konnect mode (`.Values.ingressController.konnect.enabled=true`). + [#787](https://github.com/Kong/charts/pull/787) + +## 2.19.1 + +### Fixed + +* Fix `webhook-cert` being mounted regardless if `.Values.ingressController.enabled` + is set. + [#779](https://github.com/Kong/charts/pull/779) + +## 2.19.0 + +### Improvements + +* Security context enforces read-only root filesystem by default. This is not + expected to affect most configurations, but [will affect custom plugins that + write to the container filesystem](https://github.com/Kong/charts/blob/main/charts/kong/UPGRADE.md#2170). + [#770](https://github.com/Kong/charts/pull/770) + +## 2.18.0 + +### Improvements + +* Added support for the Admin API service TLS client verification. + [#780](https://github.com/Kong/charts/pull/780 + +## 2.17.1 + +### Fixed + +* The `-redhat` suffix on official KIC images is no longer considered part of + the semver string for version checks. + [#779](https://github.com/Kong/charts/pull/779) + +## 2.17.0 + +### Improvements + +* Added support for controller's gateway discovery. + With `ingressController.gatewayDiscovery.enabled` set to `true` Kong Ingress Controller + will enable gateway discovery using an Admin API service. + For more information on this please see [the corresponding README.md section][kic_gateway_discovery_readme]. + This feature is only available when deploying chart with Kong Ingress Controller in version 2.9 or higher. + [#747](https://github.com/Kong/charts/pull/747) +* Added experimental support for the ingress controller's Konnect sync feature via `ingressController.konnect.*` values. + This feature is only available when deploying chart with Kong Ingress Controller in version 2.9 or higher and + requires `ingressController.gatewayDiscovery.enabled` set to `true`. + [#746](https://github.com/Kong/charts/pull/746) +* Added support for annotations on the admission webhook ValidatingWebhookConfiguration. + [#760](https://github.com/Kong/charts/pull/760) +* Added support for `subject` and `privateKey` properties on certificates. + [#762](https://github.com/Kong/charts/pull/762) +* Added support for loadBalancerClass in LoadBalancer type services. + [#767](https://github.com/Kong/charts/pull/767) +* Added support for `GRPCRoute`s. + [#772](https://github.com/Kong/charts/pull/772) +* Default Kong version is bumped to 3.2. + [#773](https://github.com/Kong/charts/pull/773) +* Added support for admissionhook to include labels. + [#768](https://github.com/Kong/charts/pull/768) + +### Under the hood + +* Add kube-linter to the CI pipeline to ensure produced manifests comply + with community best practices. + [#751](https://github.com/Kong/charts/pull/751) + +[kic_gateway_discovery_readme]: ./README.md#the-gatewaydiscovery-section + +## 2.16.5 + +### Fixed + +* Fix autoscaling version detection. + [#752](https://github.com/Kong/charts/pull/752) +* Don't include a clear-stale-pid initContainer when kong gateway is not + enabled in the deployment. + [#749](https://github.com/Kong/charts/pull/749) + +## 2.16.4 + +### Fixed + +* HorizontalPodAutoscaler's API version is detected properly. + [#744](https://github.com/Kong/charts/pull/744) + +## 2.16.3 + +### Fixed + +* Fix template issue preventing custom dblessconfig volume from being mounted. + [#741](https://github.com/Kong/charts/pull/741) + +## 2.16.2 + +### Fixed + +* The admission webhook is disabled when the ingress controller is disabled, as + the admission webhook requires a service provided by the ingress controller. + +## 2.16.1 + +### Fixed + +* serviceAccount projected volume is properly provisioned for GKE clusters >= 1.20. + [#735](https://github.com/Kong/charts/pull/735) + +## 2.16.0 + +### Improvements + +* Let users specify their own labels and annotations for generated PodSecurityPolicy. + [#721](https://github.com/Kong/charts/pull/721) +* Enable the admission webhook by default. This can reject configuration, but + is not expected to be a meaningfully breaking change. Existing configuration + is not affected, and any new changes that the webhook would reject would also + be rejected by Kong. + [#727](https://github.com/Kong/charts/pull/727) +* Replaced static secret with projected volume in deployment. + [#722](https://github.com/Kong/charts/pull/722) +* Reject invalid log config values. + [#733](https://github.com/Kong/charts/pull/733) +* Update custom resource definitions to latest v2.8.1 from + kong/kubernetes-ingress-controller + [#730](https://github.com/Kong/charts/pull/730) +* Respect setting `.Values.deployment.serviceAccount.automountServiceAccountToken` in + migrations Jobs. This was already the case for the Deployment. + [#729](https://github.com/Kong/charts/pull/729) + +## 2.15.3 + +### Fixed + +* Changed `ingressController.readinessProbe` to use `/readyz` to prevent pods from becoming ready and serving 404s prior to the `ingress-controller` first syncing config to the `proxy` [#716](https://github.com/Kong/charts/pull/716). +* Fixed incorrect `if` block order in volume mount templates. + +## 2.15.2 + +### Fixed + +* Do not attempt to mount DB-less config if none provided by chart. + +## 2.15.1 + +### Fixed + +* Remove unnecessary failure condition from [#695](https://github.com/Kong/charts/pull/695). + +## 2.15.0 + +### Improvements + +* Add the `dblessConfig.secret` key to the values file, allowing the user to + supply a Secret for their dbless config file. + [#695](https://github.com/Kong/charts/pull/695) +* Add support for version `v1beta1` of the Gateway API when generating RBAC rules. +* Add support for version `v1beta1` of the Gateway API when generating RBAC rules. + ([#706](https://github.com/Kong/charts/pull/706)) +* Prevent supplying duplicate plugin inclusion to `KONG_PLUGINS` env variable. + ([#711](https://github.com/Kong/charts/pull/711)) + +### Fixed + +* Removed appProtocol to fix AKS load balancer + ([#705](https://github.com/Kong/charts/pull/705)) +* Fix lookup for CA certificate secret for admission webhook. + ([#704](https://github.com/Kong/charts/pull/704)) + +## 2.14.0 + +Note: KIC 2.8 does include several updates to CRDs, but only for documentation and validation. +You can [upgrade CRDs](https://github.com/Kong/charts/blob/main/charts/kong/UPGRADE.md#updates-to-crds), +but doing so is not required. + +### Improvements + +* Default Kong and KIC versions bumped to 3.1 and 2.8. +* UDP proxy (udpProxy) assumes the UDP protocol by default for stream entries (udpProxy.stream). + This can be still overridden to TCP by specifying the protocol explicitly, but it is not recommended to do so. + [#682](https://github.com/Kong/charts/pull/682) +* Supported `autoscaling/v2` API + ([#679](https://github.com/Kong/charts/pull/679)) +* Add support for specifying the minium number of seconds for which newly created pods should be ready without + any of its container crashing, for it to be considered available. (`deployment.minReadySeconds`) + ([#688](https://github.com/Kong/charts/pull/688)) +* Increased the default memory requests and limits for the Kong pod to 2G + ([#690](https://github.com/Kong/charts/pull/690)) +* Add a rule for `KongIngress` to the ValidatingWebhookConfiguration. + ([#702](https://github.com/Kong/charts/pull/702)) + +### Fixed + +* Removed `PodSecurityPolicy` if the API is not supported in k8s cluster + to be compatible to k8s 1.25+. + [#680](https://github.com/Kong/charts/pull/680) + + +## 2.13.1 + +### Improvements + +* Updated default controller version to [KIC 2.7](https://github.com/Kong/kubernetes-ingress-controller/blob/main/CHANGELOG.md#270). + +## 2.13.0 + +### Improvements + +* Added cert-manager issuer support for proxy default and cluster mtls certificates + ([#592](https://github.com/Kong/charts/pull/592)) +* Updated CRDs with the new ordering field for KongPlugins, the new + IngressClassParameters resource, and assorted field description updates. + These [require a manual update](https://github.com/Kong/charts/blob/main/charts/kong/UPGRADE.md#updates-to-crds). +* Updated default tags to Kong 3.0 and KIC 2.6. + +## 2.12.0 + +### Improvements + +* Added ClusterRole for cluster-scoped resources when using watchNamespaces. + [#611](https://github.com/Kong/charts/issues/611) +* Added `extraObjects` to create additional k8s resources as part of the helm release. + [#652](https://github.com/Kong/charts/issues/652) + +## 2.11.0 + +### Fixed + +* Fixed Deployment missing if in case of empty tolerations + [#630](https://github.com/Kong/charts/issues/630) +* Use stdout and stderr by default for all logs. Several were writing to prefix + directory files. + [#634](https://github.com/Kong/charts/issues/634) +* Remove `terminationGracePeriodSeconds` from KIC's container spec since this + field is only applicable for pods, not containers. + [#640](https://github.com/Kong/charts/issues/640) + +### Improvements + +* Bump controller version to 2.5. + [#642](https://github.com/Kong/charts/issues/642) +* Added `fullnameOverride` to override the normal resource name string. + [#635](https://github.com/Kong/charts/issues/635) +* Added size limits for emptyDir mounts. + [#632](https://github.com/Kong/charts/issues/632) + +## 2.10.2 + +### Fixed + +* Kuma now also mounts ServiceAccount tokens on releases without a controller + container. + +## 2.10.1 + +### Fixed + +* Updated manual ServiceAccount Secret mount format for compatibility with + Kuma. + +## 2.10.0 + +### Added + +* Added option to disable test job pods. + [#598](https://github.com/Kong/charts/issues/598) +* Changed default admission failure policy from `Fail` to `Ignore`. + [#612](https://github.com/Kong/charts/issues/612) +* ServiceAccount tokens are now only mounted in the controller container to + limit attack surface. + [#619](https://github.com/Kong/charts/issues/619) + +## 2.9.1 + +### Fixed + +* Fixed another unwanted newline chomp that broke GatewayClass + permissions. + +## 2.9.0 + +* Added terminationDelaySeconds for Ingress Controller. + ([597](https://github.com/Kong/charts/pull/597)) +* Made KNative permissions conditional on CRD availability. + +### Fixed + +* Removed KNative permission from the Gateway permissions set. + +## 2.8.2 + +### Fixed + +* Fixed an unwanted newline chomp in fix PR #595. + ([594](https://github.com/Kong/charts/pull/594)) + +## 2.8.1 + +### Fixed + +* Fixed the stream default type, which should have been an empty array, not an + empty map. This had no effect on chart behavior, but resulted in warning + messages when user values.yamls contained non-empty stream configuration. + ([594](https://github.com/Kong/charts/pull/594)) +* Gateway API permissions are no longer created if Gateway API CRDs are not + installed on the cluster. This would block installs by non-super admin users. + ([595](https://github.com/Kong/charts/pull/595)) + +## 2.8.0 + +### Breaking changes + +2.8 requires manual removal of existing IngressClass resources and updates the +Postgres sub-chart version. Further details are available [in the upgrade guide](https://github.com/Kong/charts/blob/main/charts/kong/UPGRADE.md#280). + +The chart honors `ingressController.installCRDs: false` again. Remove it from +your values.yaml if it is currently present. Unless your install user [lacks +permissions to read +CRDs](https://github.com/Kong/charts/blob/main/charts/kong/README.md#removing-c +luster-scoped-permissions), which would have prevented you from installing +earlier chart versions, you should omit this setting and let the templates +detect whether you use the legacy CRD installation method automatically. + +### Improvements + +* Added Ingress for cluster sync. + ([583](https://github.com/Kong/charts/pull/583)) +* Added controller support for custom environment variables. + ([568](https://github.com/Kong/charts/pull/568)) +* Ingress `pathType` field is now configurable. + ([564](https://github.com/Kong/charts/pull/564)) +* Added IngressClass resources to RBAC roles. + ([563](https://github.com/Kong/charts/pull/563)) +* Ingresses now support wildcard hostnames. + ([559](https://github.com/Kong/charts/pull/559)) +* Enables the option to add sidecar containers to the migration containers. + ([540](https://github.com/Kong/charts/pull/540)) +* Update the IngressClass controller string to match the value used upstream. + ([557](https://github.com/Kong/charts/pull/557)) +* Added support for user-defined controller volume mounts. + ([560](https://github.com/Kong/charts/pull/560)) +* Added support for autoscaling `behavior`. + ([561](https://github.com/Kong/charts/pull/561)) +* Improved support and documentation for installations that [lack + cluster-scoped permissions](https://github.com/Kong/charts/blob/main/charts/kong/README.md#removing-cluster-scoped-permissions). + ([565](https://github.com/Kong/charts/pull/565)) +* Updated podDisruptionBudget from `policy/v1beta1` to `policy/v1`. + ([574](https://github.com/Kong/charts/pull/574)) +* Updated controller version to 2.3. + +### Fixed + +* Removed CREATE from ValidatingWebhookConfiguration objectSelector for Secrets to align with changes in Kong/kubernetes-ingress-controller. + ([#542](https://github.com/Kong/charts/pull/542)) +* Fixed traffic routing from Istio's envoy proxy to Kong proxy when using Istio's AuthorizationPolicy. + ([#550](https://github.com/Kong/charts/pull/550)) +* Fixed creation of non-default IngressClasses + ([#552](https://github.com/Kong/charts/pull/552)) +* Fixed: wait_for_db no longer tries to instantiate the keyring in Kong Enterprise + ([#556](https://github.com/Kong/charts/pull/556)) + +## 2.7.0 + +2.7.0 includes CRD updates, which [must be applied manually](https://github.com/Kong/charts/blob/main/charts/kong/UPGRADE.md#270). + +### Breaking Changes + +* There are upstream changes to the Postgres sub-chart that change many + values.yaml keys. The default `postgresqlUsername` and `postgresqlDatabase` + keys used in this chart's values.yaml are now `auth.username` and + `auth.database`. If you set other Postgres sub-chart values, consult the + [upstream README](https://github.com/bitnami/charts/tree/master/bitnami/postgresql) + and [upgrade guide](https://docs.bitnami.com/kubernetes/infrastructure/postgresql/administration/upgrade/#to-1100) + to see what you need to change. + +### Improvements + +* Added Gateway API resources to RBAC rules. + ([#536](https://github.com/Kong/charts/pull/536)) +* Replaced `sleep 15` in `preStop` command with `--wait=15` argument to `kong quit`. + ([#531](https://github.com/Kong/charts/pull/531)) +* Added support for non `KONG_` prefixed custom environment variables + ([#530](https://github.com/Kong/charts/pull/530)) +* Updated to latest CRDs from upstream. + +## 2.6.5 + +### Fixed + +* Generated IngressClass resources persist across updates properly. + ([#518](https://github.com/Kong/charts/pull/518)) + +## 2.6.4 + +### Improvements + +* Updated default tags to Kong 2.7, Kong Enterprise 2.7.0.0, and Kong Ingress + Controller 2.1. + +### Fixed + +* Corrected a misnamed field in podDisruptionBudget. + ([#519](https://github.com/Kong/charts/pull/519)) + +## 2.6.3 + +### Improvements + +* Increased example resources for the Kong container. + ([#511](https://github.com/Kong/charts/pull/511)) + +### Fixed + +* Corrected an invalid label match condition for the admission webhook. + ([#513](https://github.com/Kong/charts/pull/513)) + +## 2.6.2 + +### Improvements + +* Added `app` and `version` labels to pods. + ([#504](https://github.com/Kong/charts/pull/504)) +* Reworked leftover socket file cleanup to avoid similar problems of the same + class. + ([#508](https://github.com/Kong/charts/pull/508)) + +### Fixed + +* SecurityContext and resources applied to PID cleanup initContainer also. + ([#503](https://github.com/Kong/charts/pull/503)) +* Disabled the admission webhook on Helm Secrets, fixing an issue where it + prevented Helm from updating release metadata. + ([#500](https://github.com/Kong/charts/pull/500)) +* initContainers that use the Kong image use the same imagePullPolicy as the + main Kong container. + ([#501](https://github.com/Kong/charts/pull/501)) +* Applied mesh sidecar annotations to the Pod, not the Deployment. + ([#507](https://github.com/Kong/charts/pull/507)) + +## 2.6.1 + +### Fixed + +* Disabled IngressClass creation on Kubernetes versions that do not support it. +* Added missing resources (Secrets, KongClusterPlugins) to the admission + controller configuration. + ([#492](https://github.com/Kong/charts/pull/492)) + +## 2.6.0 + +**Note:** chart versions 2.3.0 through 2.5.0 contained an incorrect +KongIngress CRD. The `proxy.path` field was missing. Helm will not fix this +automatically on upgrade. You can fix it by running: + +``` +kubectl apply -f https://raw.githubusercontent.com/Kong/charts/main/charts/kong/crds/custom-resource-definitions.yaml +``` + +### Improvements + +* Added an initContainer to clear leftover PID file in the event of a Kong + container crash, allowing the container to restart. + ([#480](https://github.com/Kong/charts/pull/480)) +* Added deployment.hostNetwork to enable host network access. + ([#486](https://github.com/Kong/charts/pull/486)) + +### Fixed + +* NOTES.txt documentation link now uses up-to-date location. +* Ingress availability check tightened to require the Ingress API specifically + in `networking.k8s.io/v1`. + ([#484](https://github.com/Kong/charts/pull/484)) +* Flipped backwards logic for creating an IngressClass when no IngressClass was + present. + ([#485](https://github.com/Kong/charts/pull/485)) +* Removed unnecessary hardcoded controller container argument. + ([#481](https://github.com/Kong/charts/pull/481)) +* Restored missing `proxy.path` field to KongIngress CRD. + +## 2.5.0 + +### Improvements + +* Default Kong proxy version updated to 2.6. + +### Fixed + +* Properly disable KongClusterPlugin when watchNamespaces is set. + ([#475](https://github.com/Kong/charts/pull/475)) + +## 2.4.0 + +### Breaking Changes + +* KIC now defaults to version 2.0. If you use a database, you must first + perform a temporary intermediate upgrade to disable KIC before upgrading it + to 2.0 and re-enabling it. See the [upgrade guide](https://github.com/Kong/charts/blob/main/charts/kong/UPGRADE.md#disable-ingress-controller-prior-to-2x-upgrade-when-using-postgresql) + for detailed instructions. +* ServiceAccount are now always created by default unless explicitly disabled. + ServiceAccount customization has [moved under the `deployment` section of + configuration](https://github.com/Kong/charts/blob/main/charts/kong/UPGRADE.md#changed-serviceaccount-configuration-location) + to reflect this. This accomodates configurations that need a ServiceAccount + but that do not use the ingress controller. + ([#455](https://github.com/Kong/charts/pull/455)) + +### Improvements + +* Migration jobs support a configurable backoffLimit. + ([#442](https://github.com/Kong/charts/pull/442)) +* Generated Ingresses now use `networking.k8s.io/v1` when available. + ([#446](https://github.com/Kong/charts/pull/446)) + +### Fixed + +* 5-digit UDP ports now work properly. + ([#443](https://github.com/Kong/charts/pull/443)) +* Fixed port name used for NLB annotation example. + ([#458](https://github.com/Kong/charts/pull/458)) +* Fixed a compatibility issue with Helm's `--set-file` feature and + user-provided DB-less configuration ConfigMaps. + ([#465](https://github.com/Kong/charts/pull/465)) + +## 2.3.0 + +### Breaking Changes + +* Upgraded CRDs to V1 from the previous deprecated v1beta1. + [#391](https://github.com/kong/charts/issues/391) + ACTION REQUIRED: This is a breaking change as it makes + this chart incompatible with Kubernetes clusters older + than v1.16.x. Upgrade your cluster to a version greater + than or equal to v1.16 before installing. + Note that technically it will remain possible to deploy + on older clusters by managing the CRDs manually ahead of + time (e.g. intentionally deploying the legacy CRDs) but + these configurations will be considered unsupported. + [upgrade](https://kubernetes.io/docs/tasks/administer-cluster/cluster-upgrade/) + ACTION REQUIRED: For existing deployments Helm avoids managing + CRDs so when upgrading from a previous release you will need + to apply the new V1 versions of the CRDs (in `crds/`) manually. + [hip-0011](https://github.com/helm/community/blob/main/hips/hip-0011.md) + ([#415](https://github.com/Kong/charts/pull/415)) +* Added support for controller metrics to the Prometheus resources. This + requires KIC 2.x. The chart automatically detects if your controller image is + compatible, but only if your tag is semver-compliant. If you are using an + image without a semver-compliant tag (such as `next`) you _must_ set the + `ingressController.image.effectiveSemver` value to a semver string + appropriate for your image (for example, if your image is 2.0.0-based, you + would set it to `2.0.0`. + ([#430](https://github.com/Kong/charts/pull/430)) + +### Improvements + +* Updated default Kong versions to 2.5 (OSS) and 2.5.0.0 (Enterprise). +* Added user-configured initContainer support to Jobs. + ([#408](https://github.com/Kong/charts/pull/408)) +* Upgraded RBAC resources to v1 from v1beta1 for compatibility with Kubernetes + 1.22 and newer. This breaks compatibility with Kubernetes 1.7 and older, but + these Kubernetes versions were never supported, so this change is not + breaking. Added additional permissions to support KIC 2.x. + ([#420](https://github.com/Kong/charts/pull/420)) + ([#419](https://github.com/Kong/charts/pull/419)) +* Added `ingressController.watchNamespaces[]` to values.yaml. When set, the + controller will only watch the listed namespaces (instead of all namespaces, + the default), and will create Roles for each namespace (instead of a + ClusterRole). This feature requires KIC 2.x. + ([#420](https://github.com/Kong/charts/pull/420)) +* Added support for [dnsPolicy and + dnsConfig](https://kubernetes.io/docs/tasks/administer-cluster/nodelocaldns/). + ([#425](https://github.com/Kong/charts/pull/425)) +* Use migration commands directly in upgrade/install Jobs instead of invoking + them via a shell. This adds support for some additional features in Kong + images that only apply when the container command starts with `kong`. + ([#429](https://github.com/Kong/charts/pull/429)) + +### Fixed +* Fixed an incorrect template for DaemonSet releases. + ([#426](https://github.com/Kong/charts/pull/426)) + +## 2.2.0 + +### Breaking changes + +* Removed default `maxUnavailable` setting for pod disruption budget + configuration. This is necessary to allow usage of the `minUnavailable` + setting, but means that there is no longer any default availability + constraint. If you set `podDisruptionBudget.enabled=true` in your values and + did not previously set any `podDisruptionBudget.maxUnavailable` value, you + must add `podDisruptionBudget.maxUnavailable="50%"` to your values. + +### Improvements + +* Added host alias injection to override DNS and/or add DNS entries not + available from the DNS resolver. + ([#366](https://github.com/Kong/charts/pull/366)) +* Added support for custom labels. + ([#370](https://github.com/Kong/charts/pull/370)) +* Only add paths to Ingresses if configured, for OpenShift 4.x compatibility. + ([#375](https://github.com/Kong/charts/pull/375)) +* Kong containers no longer the image ENTRYPOINT. This allows the stock image + bootstrap scripts to run normally. + ([#377](https://github.com/Kong/charts/pull/377)) +* Added security context settings for containers. + ([#387](https://github.com/Kong/charts/pull/387)) +* Bumped Kong and controller image defaults to the latest versions. + ([#378](https://github.com/Kong/charts/pull/378)) +* Added support for user-provided admission webhook certificates. + ([#385](https://github.com/Kong/charts/pull/385)) +* Disable service account tokens when it is unnecessary. + ([#389](https://github.com/Kong/charts/pull/389)) + +### Fixed + +* Admission webhook port is now listed under the controller container, where + the admission webhook runs. + ([#384](https://github.com/Kong/charts/pull/384)) + +### Documentation + +* Removed a duplicate key from example values. + ([#360](https://github.com/Kong/charts/pull/360)) +* Clarified Enterprise free mode usage. + ([#362](https://github.com/Kong/charts/pull/362)) +* Expand EKS Service annotation examples for proxy. + ([#376](https://github.com/Kong/charts/pull/375)) + +## 2.1.0 + +### Improvements + +* Added support for user-defined volumes, volume mounts, and init containers. + ([#317](https://github.com/Kong/charts/pull/317)) +* Tolerations are now applied to migration Job Pods also. + ([#341](https://github.com/Kong/charts/pull/341)) +* Added support for using a DaemonSet instead of Deployment. + ([#347](https://github.com/Kong/charts/pull/347)) +* Updated default image versions and completed migration off Bintray + repositories. + ([#349](https://github.com/Kong/charts/pull/349)) +* PDB ignores migration Job Pods. + ([#352](https://github.com/Kong/charts/pull/352)) + +### Documentation + +* Clarified service monitor usage information. + ([#345](https://github.com/Kong/charts/pull/345)) + +## 2.0.0 + +### Breaking changes + +* Helm 2 is no longer supported. You **must** [migrate your Kong chart releases + to Helm 3](https://helm.sh/docs/topics/v2_v3_migration/) before updating to + this release. +* Deprecated [Portal auth settings](https://github.com/Kong/charts/blob/kong-1.15.0/charts/kong/UPGRADE.md#removal-of-dedicated-portal-authentication-configuration-parameters) + are no longer supported. +* The deprecated [`runMigrations` setting](https://github.com/Kong/charts/blob/kong-1.15.0/charts/kong/UPGRADE.md#changes-to-migration-job-configuration) + is no longer supported. +* Deprecated [admin API Service configuration](https://github.com/Kong/charts/blob/kong-1.15.0/charts/kong/UPGRADE.md#changes-to-kong-service-configuration) + is no longer supported. +* Deprecated [multi-host proxy configuration](https://github.com/Kong/charts/blob/kong-1.15.0/charts/kong/UPGRADE.md#removal-of-multi-host-proxy-ingress) + is no longer supported. + +`helm upgrade` with the previous version (1.15.0) will print a warning message +if you still use any of the removed values.yaml configuration. If you do not +see any warnings after the upgrade completes, you are already using the modern +equivalents of these settings and can proceed with upgrading to 2.0.0-rc1. + +### Improvements + +* Admission webhook certificates persist after their initial creation. This + prevents an unnecessary restart of Kong Pods on upgrades that do not actually + modify the deployment. + ([#256](https://github.com/Kong/charts/pull/256)) +* `ingressController.installCRDs` now defaults to `false`, simplifying + installation on Helm 3. Installs now default to using Helm 3's CRD management + system, and do not require changes to values or install flags to install + successfully. + ([#305](https://github.com/Kong/charts/pull/305)) +* Added support for Pod `topologySpreadConstraints`. + ([#308](https://github.com/Kong/charts/pull/308)) +* Kong Ingress Controller image now pulled from Docker Hub (due to Bintray being + discontinued). Changed the default Docker image repository for the ingress + controller. + +### Fixed + +* Generated admission webhook certificates now include SANs for compatibility + with Go 1.15 controller builds. + ([#312](https://github.com/Kong/charts/pull/312)). + +### Documentation + +* Clarified use of `terminationGracePeriodSeconds`. + ([#302](https://github.com/Kong/charts/pull/302)) + +## 1.15.0 + +1.15.0 is an interim release before the planned release of 2.0.0. There were +several feature changes we wanted to release prior to the removal of deprecated +functionality for 2.0. The original planned deprecations covered in the [1.14.0 +changelog](#1140) are still planned for 2.0.0. + +### Improvements + +* The default Kong version is now 2.3 and the default Kong Enterprise version + is now 2.3.2.0. +* Added configurable `terminationGracePeriodSeconds` for the pre-stop lifecycle + hook. + ([#271](https://github.com/Kong/charts/pull/271)). +* Initial migration database wait init containers no longer have a default + image configuration in values.yaml. When no image is specified, the chart + will use the Kong image. The standard Kong images include bash, and can run + the database wait script without downloading a separate image. Configuring a + wait image is now only necessary if you use a custom Kong image that lacks + bash. + ([#285](https://github.com/Kong/charts/pull/285)). +* Init containers for database availability and migration completeness can now + be disabled. They cause compatibility issues with many service meshes. + ([#285](https://github.com/Kong/charts/pull/285)). +* Removed the default migration Job annotation that disabled Kuma's mesh proxy. + The latest version of Kuma no longer prevents Jobs from completing. + ([#285](https://github.com/Kong/charts/pull/285)). +* Services now support user-configurable labels, and the Prometheus + ServiceMonitor label is included on the proxy Service by default. Users that + disable the proxy Service and add this label to another Service to collect + metrics. + ([#290](https://github.com/Kong/charts/pull/290)). +* Migration Jobs now allow resource quota configuration. Init containers + inherit their resource quotas from their associated Kong container. + ([#294](https://github.com/Kong/charts/pull/294)). + +### Fixed + +* The database readiness wait script ConfigMap and associated mounts are no + longer created if that feature is not in use. + ([#285](https://github.com/Kong/charts/pull/285)). +* Removed a duplicated field from CRDs. + ([#281](https://github.com/Kong/charts/pull/281)). + +## 1.14.5 + +### Fixed + +* Removed `http2` from default status listen TLS parameters. It only supports a + limited subset of the extra listen parameters, and does not allow `http2`. + +## 1.14.4 + +### Fixed + +* Status listens now include parameters in the default values.yaml. The absence + of these defaults caused a template rendering error when the TLS listen was + enabled. + +### Documentation + +* Updated status listen comments to reflect TLS listen availability on Kong + 2.1+. + +## 1.14.3 + +### Fixed + +* Fix issues with legacy proxy Ingress object template. + +## 1.14.2 + +### Fixed + +* Corrected invalid default value for `enterprise.smtp.smtp_auth`. + +## 1.14.1 + +### Fixed + +* Moved several Kong container settings into the appropriate template block. + Previously these were rendered whether or not the Kong container was enabled, + which unintentionally applied them to the controller container. + +## 1.14.0 + +### Breaking changes + +1.14 is the last planned 1.x version of the Kong chart. 2.x will remove support +for Helm 2.x and all deprecated configuration. The chart prints a warning when +upgrading or installing if it detects any configuration still using an old +format. + +* All Ingress and Service resources now use the same template. This ensures + that all chart Ingresses and Services support the same configuration. The + proxy previously used a unique Ingress configuration, which is now + deprecated. If you use the proxy Ingress, [see the instructions in + UPGRADE.md](https://github.com/Kong/charts/blob/kong-1.14.0/charts/kong/UPGRADE.md#removal-of-multi-host-proxy-ingress) + to update your configuration. No changes are required for other Service and + Ingress configurations. + ([#251](https://github.com/Kong/charts/pull/251)). +* The chart now uses the standard Kong status endpoint instead of custom + configuration, allowing users to specify their own custom configuration. The + status endpoint is no available in versions older than Kong 1.4.0 or Kong + Enterprise 1.5.0; if you use an older version, you will need to [add and load + the old custom configuration](https://github.com/Kong/charts/blob/main/charts/kong/UPGRADE.md#default-custom-server-block-replaced-with-status-listen). + + If you use a newer version and include Kong container readinessProbe and/or + livenessProbe configuration in your values.yaml, you must change the port + from `metrics` to `status`. + ([#255](https://github.com/Kong/charts/pull/255)). + +### Fixed + +* Correct an issue with migrations Job toggles. + ([#231](https://github.com/Kong/charts/pull/231)) + +## 1.13.0 + +### Improvements + +* Updated default Kong Enterprise version to 2.2.1.0-alpine. +* Updated default Kong Ingress Controller version to 1.1. +* Add `namespace` to values.yaml to override release namespace if desired. + ([#231](https://github.com/Kong/charts/pull/231)) + +### Fixed + +* Migration Jobs now use the same nodeSelector configuration as the main Kong + Deployment. + ([#238](https://github.com/Kong/charts/pull/238)) +* Disabled custom Kong template mount if Kong is not enabled. + ([#240](https://github.com/Kong/charts/pull/240)) +* Changed YAML string to a YAML boolean. + ([#240](https://github.com/Kong/charts/pull/240)) + +### Documentation + +* Clarify requirements for using horizontal pod autoscalers. + ([#236](https://github.com/Kong/charts/pull/236)) + +## 1.12.0 + +### Improvements + +* Increased default worker count to 2 to avoid issues with latency during + blocking tasks, such as DB-less config updates. This change increases memory + usage, but the increase should not be a concern for any but the smallest + deployments (deployments with memory limits below 512MB). +* Updated default Kong version to 2.2. + ([#221](https://github.com/Kong/charts/pull/221)) +* Updated default Kong Enterprise version to 2.1.4.1. +* Added a means to mount extra ConfigMap and Secret resources. + ([#208](https://github.com/Kong/charts/pull/208)) +* Added configurable annotations for migration Jobs. + ([#219](https://github.com/Kong/charts/pull/219)) +* Added template for deprecation warnings to automate formatting and avoid + excess newlines. + +### Fixed + +* Upgrades no longer force auto-scaling Deployments back to the replica count. + ([#222](https://github.com/Kong/charts/pull/222)) + +## 1.11.0 + +### Breaking changes + +* Kong Ingress Controller 1.0 removes support for several deprecated flags and + the KongCredential custom resource. Please see the [controller changelog](https://github.com/Kong/kubernetes-ingress-controller/blob/main/CHANGELOG.md#breaking-changes) + for details. Note that Helm 3 will not remove the KongCredential CRD by + default: you should delete it manually after converting KongCredentials to + [credential Secrets](https://github.com/Kong/kubernetes-ingress-controller/blob/next/docs/guides/using-consumer-credential-resource.md#provision-a-consumer). + If you manage CRDs using Helm (check to see if your KongCredential CRD has a + `app.kubernetes.io/managed-by: Helm` label), perform the credential Secret + conversion **before** upgrading to chart 1.11.0 to avoid losing credential + configuration. +* The chart no longer uses the `extensions` API for PodSecurityPolicy, and now + uses the modern `policy` API. This breaks compatibility with Kubernetes + versions 1.11 and older. + ([#195](https://github.com/Kong/charts/pull/195)) + +### Improvements + +* Updated default controller version to 1.0. +* The chart now adds namespace information to manifests explicitly. This + simplifies workflows that use `helm template`. + ([#193](https://github.com/Kong/charts/pull/193)) + +### Fixed +* Changes to annotation block generation prevent incorrect YAML indentation + when specifying annotations via command line arguments to Helm commands. + ([#200](https://github.com/Kong/charts/pull/200)) + +## 1.10.0 + +### Breaking changes + +* Kong Ingress Controller 0.10.0 comes with breaking changes to global + `KongPlugin`s and to resources without an ingress class defined. Refer to the + [`UPGRADE.md notes for chart 1.10.0`](https://github.com/Kong/charts/blob/main/charts/kong/UPGRADE.md#1100) + for details. + +### Improvements + +* Updated default controller version to 0.10.0. + +### Fixed + +* Removed the `status` field from the `TCPIngress` CRD. + ([#188](https://github.com/Kong/charts/pull/188)) + +## 1.9.1 + +### Documentation + +* Clarified documentation for [breaking changes in 1.9.0](#190) to indicate + that any values.yaml that sets `waitImage.repository` requires changes, + including those that set the old default. +* Updated Enterprise examples to use latest Enterprise image version. + +## 1.9.0 + +### Breaking changes + +1.9.0 now uses a bash-based pre-migration database availability check. If you +set `waitImage.repository` in values.yaml, either to the previous default +(`busybox`) or to a custom image, you must change it to an image that includes +a `bash` executable. + +Once you have `waitImage.repository` set to an image with bash, [perform an +initial chart version upgrade with migrations disabled](https://github.com/Kong/charts/blob/main/charts/kong/UPGRADE.md#changes-to-wait-for-postgres-image) +before re-enabling migrations, updating your Kong image version, and performing +a second release upgrade. + +### Improvements + +* Added support for sidecar injection. + ([#174](https://github.com/Kong/charts/pull/174)) +* Changed to a bash-based pre-migration database availability check. + ([#179](https://github.com/Kong/charts/pull/179)) +* Changed to a bash-based pre-migration database availability check. + ([#179](https://github.com/Kong/charts/pull/179)) +* Updated default Kong Enterprise version to 2.1.3.0. + +### Fixed + +* Added missing cluster telemetry service and fixed missing cluster service + port. + ([#185](https://github.com/Kong/charts/pull/185)) + +### Documentation + +* Added an example Enterprise controller-managed DB-less values.yaml. + ([#175](https://github.com/Kong/charts/pull/175)) + +## 1.8.0 + +**Kong Enterprise users:** please review documentation for the [Kong Enterprise +2.1.x beta +release](https://docs.konghq.com/enterprise/2.1.x/release-notes/#coming-soon) +and [hybrid mode on Kong +Enterprise](https://docs.konghq.com/enterprise/2.1.x/deployment/hybrid-mode/#kubernetes-support) +as well. Version 1.8 of the Kong Helm chart adds support for hybrid mode, which +is currently only available in the 2.1.x beta. Production systems should +continue to use the Kong Enterprise 1.5.x stable releases, which do not support +hybrid mode. + +### Improvements + +* Update default Kong version to 2.1. +* Update Kong Enterprise images to 1.5.0.4 (kong-enterprise-edition) and + 2.0.4.2 (kong-enterprise-k8s). +* Updated default controller version to 0.9.1. + ([#150](https://github.com/Kong/charts/pull/150)) +* Added support for ServiceMonitor targetLabels (for use with the Prometheus + Operator). + ([#162](https://github.com/Kong/charts/pull/162)) +* Automatically handle the [new port_maps + setting](https://github.com/Kong/kong/pull/5861) for the proxy service. + ([#169](https://github.com/Kong/charts/pull/169)) +* Add support for [hybrid mode + deployments](https://docs.konghq.com/latest/hybrid-mode/). + ([#160](https://github.com/Kong/charts/pull/160)) + + +### Fixed + +* Fixed an issue with improperly-rendered listen strings. + ([#155](https://github.com/Kong/charts/pull/155)) + +### Documentation + +* Improved inline documentation of `env` in values.yaml. + ([#163](https://github.com/Kong/charts/pull/163)) + +## 1.7.0 + +### Improvements + +* Added support for + [CRD-only](https://github.com/Kong/charts/blob/1.7.0/charts/kong/README.md#crds-only) + and [controller-only releases](https://github.com/Kong/charts/blob/next/charts/kong/README.md#standalone-controller-nodes). + ([#136](https://github.com/Kong/charts/pull/136)) + +### Documentation + +* Added a set of [example + values.yamls](https://github.com/Kong/charts/tree/main/charts/kong/example-values) + for various configurations of Kong and Kong Enterprise. + ([#134](https://github.com/Kong/charts/pull/134)) + +## 1.6.1 + +This release contains no changes other than the version. This is to address an +issue with our release automation. + +## 1.6.0 + +### Improvements + +* Updated default controller version to 0.9.0. + ([#132](https://github.com/Kong/charts/pull/132)) +* Updated default Enterprise versions to 2.0.4.1 and 1.5.0.2. + ([#130](https://github.com/Kong/charts/pull/130)) +* Added ability to override chart lifecycle. + ([#116](https://github.com/Kong/charts/pull/116)) +* Added ability to apply user-defined labels to pods. + ([#121](https://github.com/Kong/charts/pull/121)) +* Filtered serviceMonitor to disable metrics collection from non-proxy + services. + ([#112](https://github.com/Kong/charts/pull/112)) +* Set admin API to listen on localhost only if possible. + ([#125](https://github.com/Kong/charts/pull/125)) +* Add `auth_type` and `ssl` settings to `smtp` block. + ([#127](https://github.com/Kong/charts/pull/127)) +* Remove UID from default securityContext. + ([#138](https://github.com/Kong/charts/pull/138)) + +### Documentation + +* Corrected invalid default serviceMonitor.interval value. + ([#110](https://github.com/Kong/charts/pull/110)) +* Removed duplicate `installCRDs` documentation. + ([#115](https://github.com/Kong/charts/pull/115)) +* Simplified example license Secret creation command. + ([#131](https://github.com/Kong/charts/pull/131)) + +## 1.5.0 + +### Improvements + +* Added support for annotating the ServiceAccount. + ([#97](https://github.com/Kong/charts/pull/97)) +* Updated controller templates to use environment variables for default + configuration. + ([#99](https://github.com/Kong/charts/pull/99)) +* Added support for stream listens. + ([#103](https://github.com/Kong/charts/pull/103)) +* Moved migration configuration under a `migrations` block with support for + enabling upgrade jobs independently and adding annotations. + ([#102](https://github.com/Kong/charts/pull/102)) +* Added support for the [status listen](https://github.com/Kong/kong/pull/4977). + ([#107](https://github.com/Kong/charts/pull/107)) +* :warning: Exposed PodSecurityPolicy spec in values.yaml and added default + configuration to enforce a read-only root filesystem. **Kong Enterprise + versions prior to 1.5.0 require the root filesystem be read-write. If you use + an older version and enforce PodSecurityPolicy, you must set + `.Values.podSecurityPolicy.spec.readOnlyRootFilesystem: false`.** + ([#104](https://github.com/Kong/charts/pull/104)) + +### Fixed + +* Fixed old init-migrations jobs blocking upgrades. + ([#102](https://github.com/Kong/charts/pull/102)) + +### Documentation + +* Fixed discrepancy between image version in values.yaml and README.md. + ([#96](https://github.com/Kong/charts/pull/96)) +* Added example Enterprise image tags to values.yaml. + ([#100](https://github.com/Kong/charts/pull/100)) +* Added deprecation warnings in CHANGELOG.md. + ([#91](https://github.com/Kong/charts/pull/91)) +* Improved RBAC documentation to clarify process and use new controller + functionality. + ([#95](https://github.com/Kong/charts/pull/95)) +* Added documentation for managing multi-release clusters with varied node + roles (e.g. admin-only, Portal-only, etc.). + ([#102](https://github.com/Kong/charts/pull/102)) + +## 1.4.1 + +### Documentation + +* Fixed an issue with the 1.4.1 upgrade steps. + +## 1.4.0 + +### Improvements + +* :warning: Service and listen configuration now use a unified configuration + format. **The previous configuration format for the admin API service is + deprecated and will be removed in a future release.** Listen configuration + now supports specifying parameters. Kubernetes service creation can now be + enabled or disabled for all Kong services. Users should review the + [1.4.0 upgrade guide](https://github.com/Kong/charts/blob/next/charts/kong/UPGRADE.md#changes-to-kong-service-configuration) + for details on how to update their values.yaml. + ([#72](https://github.com/Kong/charts/pull/72)) +* Updated the default controller version to 0.8. This adds new + KongClusterPlugin and TCPIngress CRDs and RBAC permissions for them. Users + should also note that `strip_path` now defaults to disabled, which will + likely break existing configuration. See [the controller + changelog](https://github.com/Kong/kubernetes-ingress-controller/blob/main/CHANGELOG.md#080---20200325) + and [upgrade-guide](https://github.com/Kong/charts/blob/next/charts/kong/UPGRADE.md#strip_path-now-defaults-to-false-for-controller-managed-routes) + for full details. + ([#77](https://github.com/Kong/charts/pull/77)) +* Added support for user-supplied ingress controller CLI arguments. + ([#79](https://github.com/Kong/charts/pull/79)) +* Added support for annotating the chart's deployment. + ([#81](https://github.com/Kong/charts/pull/81)) +* Switched to the Bitnami Postgres chart, as the chart in Helm's repository has + [moved + there](https://github.com/helm/charts/tree/master/stable/postgresql#this-helm-chart-is-deprecated). + ([#82](https://github.com/Kong/charts/pull/82)) + +### Fixed + +* Corrected the app version in Chart.yaml. + ([#86](https://github.com/Kong/charts/pull/86)) + +### Documentation + +* Fixed incorrect default value for `installCRDs`. + ([#78](https://github.com/Kong/charts/pull/78)) +* Added detailed upgrade guide covering breaking changes and deprecations. + ([#74](https://github.com/Kong/charts/pull/74)) +* Improved installation steps for Helm 2 and Helm 3. + ([#83](https://github.com/Kong/charts/pull/83)) + ([#84](https://github.com/Kong/charts/pull/84)) +* Remove outdated `ingressController.replicaCount` setting. + ([#87](https://github.com/Kong/charts/pull/87)) + +## 1.3.1 + +### Fixed + +* Added missing newline to NOTES.txt template. + ([#66](https://github.com/Kong/charts/pull/66)) + +### Documentation + +* Instruct users to create secrets for both the kong-enterprise-k8s and + kong-enterprise-edition Docker registries. + ([#65](https://github.com/Kong/charts/pull/65)) +* Updated maintainer information. + +## 1.3.0 + +### Improvements + +* Custom plugin mounts now support subdirectories. These are necessary for + plugins that include their own migrations. Note that Kong versions prior to + 2.0.1 [have a bug](https://github.com/Kong/kong/pull/5509) that prevents them + from running these migrations. ([#24](https://github.com/Kong/charts/pull/24)) +* LoadBalancer services will now respect their NodePort. + ([#48](https://github.com/Kong/charts/pull/41)) +* The proxy TLS listen now enables HTTP/2 (and, by extension, gRPC). + ([#47](https://github.com/Kong/charts/pull/47)) +* Added support for `priorityClassName` to the Kong deployment. + ([#56](https://github.com/Kong/charts/pull/56)) +* Bumped default Kong version to 2.0 and controller version to 0.7.1. + ([#60](https://github.com/Kong/charts/pull/60)) +* :warning: Removed dedicated Portal auth settings, which are unnecessary in + modern versions. **The `enterprise.portal.portal_auth` and + `enterprise.portal.session_conf_secret` settings in values.yaml are + deprecated and will be removed in a future release.** See the [upgrade + guide](https://github.com/Kong/charts/blob/main/charts/kong/UPGRADE.md#removal-of-dedicated-portal-authentication-configuration-parameters) + for instructions on migrating them to environment variables. + ([#55](https://github.com/Kong/charts/pull/55)) + +### Fixed + +* Fixed typo in HorizontalPodAutoscaler template. + ([#45](https://github.com/Kong/charts/pull/45)) + +### Documentation + +* Added contributing guidelines. ([#41](https://github.com/Kong/charts/pull/41)) +* Added README section for Helm 2 versus Helm 3 considerations. + ([#34](https://github.com/Kong/charts/pull/41)) +* Added documentation for `proxy.annotations` to README.md. + ([#57](https://github.com/Kong/charts/pull/57)) +* Added FAQ entry for init-migrations job conflicts on upgrades. + ([#59](https://github.com/Kong/charts/pull/59) +* Move changelog out of README.md into CHANGELOG.md. + ([#60](https://github.com/Kong/charts/pull/60) +* Improved formatting for 1.2.0 changelog. + +## 1.2.0 + +### Improvements +* Added support for HorizontalPodAutoscaler. + ([#12](https://github.com/Kong/charts/pull/12)) +* Environment variables are now consistently sorted alphabetically. + ([#29](https://github.com/Kong/charts/pull/29)) + +### Fixed +* Removed temporary ServiceAccount template, which caused upgrades to break the + existing ServiceAccount's credentials. Moved template and instructions for + use to FAQs, as the temporary user is only needed in rare scenarios. + ([#31](https://github.com/Kong/charts/pull/31)) +* Fix an issue where the wait-for-postgres job did not know which port to use + in some scenarios. ([#28](https://github.com/Kong/charts/pull/28)) + +### Documentation +* Added warning regarding volume mounts. + ([#25](https://github.com/Kong/charts/pull/25)) + +## 1.1.1 + +### Fixed + +* Add missing `smtp_admin_emails` and `smtp_mock = off` to SMTP enabled block in + `kong.env`. + +### CI changes + +* Remove version bump requirement in preparation for new release model. + +## 1.1.0 + +> https://github.com/Kong/charts/pull/4 + +### Improvements + +* Significantly refactor the `env`/EnvVar templating system to determine the + complete set of environment variables (both user-defined variables and + variables generated from other sections of values.yaml) and resolve conflicts + before rendering. User-provided values are now guaranteed to take precedence + over generated values. Previously, precedence relied on a Kubernetes + implementation quirk that was not consistent across all Kubernetes providers. +* Combine templates for license, session configuration, etc. that generate + `secretKeyRef` values into a single generic template. + +## 1.0.3 + +- Fix invalid namespace for pre-migrations and Role. +- Fix whitespaces formatting in README. + +## 1.0.2 + +- Helm 3 support: CRDs are declared in crds directory. Backward compatible support for helm 2. + +## 1.0.1 + +Fixed invalid namespace variable name causing ServiceAccount and Role to be generated in other namespace than desired. + +## 1.0.0 + +There are not code changes between `1.0.0` and `0.36.5`. +From this version onwards, charts are hosted at https://charts.konghq.com. + +The `0.x` versions of the chart are available in Helm's +[Charts](https://github.com/helm/charts) repository are are now considered +deprecated. + +## 0.36.5 + +> PR https://github.com/helm/charts/pull/20099 + +### Improvements + +- Allow `grpc` protocol for KongPlugins + +## 0.36.4 + +> PR https://github.com/helm/charts/pull/20051 + +### Fixed + +- Issue: [`Ingress Controller errors when chart is redeployed with Admission + Webhook enabled`](https://github.com/helm/charts/issues/20050) + +## 0.36.3 + +> PR https://github.com/helm/charts/pull/19992 + +### Fixed + +- Fix spacing in ServiceMonitor when label is specified in config + +## 0.36.2 + +> PR https://github.com/helm/charts/pull/19955 + +### Fixed + +- Set `sideEffects` and `admissionReviewVersions` for Admission Webhook +- timeouts for liveness and readiness probes has been changed from `1s` to `5s` + +## 0.36.1 + +> PR https://github.com/helm/charts/pull/19946 + +### Fixed + +- Added missing watch permission to custom resources + +## 0.36.0 + +> PR https://github.com/helm/charts/pull/19916 + +### Upgrade Instructions + +- When upgrading from <0.35.0, in-place chart upgrades will fail. + It is necessary to delete the helm release with `helm del --purge $RELEASE` and redeploy from scratch. + Note that this will cause downtime for the kong proxy. + +### Improvements + +- Fixed Deployment's label selector that prevented in-place chart upgrades. + +## 0.35.1 + +> PR https://github.com/helm/charts/pull/19914 + +### Improvements + +- Update CRDs to Ingress Controller 0.7 +- Optimize readiness and liveness probes for more responsive health checks +- Fixed incorrect space in NOTES.txt + +## 0.35.0 + +> PR [#19856](https://github.com/helm/charts/pull/19856) + +### Improvements + +- Labels on all resources have been updated to adhere to the Helm Chart + guideline here: + https://v2.helm.sh/docs/developing_charts/#syncing-your-chart-repository + +## 0.34.2 + +> PR [#19854](https://github.com/helm/charts/pull/19854) + +This release contains no user-visible changes + +### Under the hood + + - Various tests have been consolidated to speed up CI. + +## 0.34.1 + +> PR [#19887](https://github.com/helm/charts/pull/19887) + +### Fixed + +- Correct indentation for Job securityContexts. + +## 0.34.0 + +> PR [#19885](https://github.com/helm/charts/pull/19885) + +### New features + +- Update default version of Ingress Controller to 0.7.0 + +## 0.33.1 + +> PR [#19852](https://github.com/helm/charts/pull/19852) + +### Fixed + +- Correct an issue with white space handling within `final_env` helper. + +## 0.33.0 + +> PR [#19840](https://github.com/helm/charts/pull/19840) + +### Dependencies + +- Postgres sub-chart has been bumped up to 8.1.2 + +### Fixed + +- Removed podDisruption budge for Ingress Controller. Ingress Controller and + Kong run in the same pod so this was no longer applicable +- Migration job now receives the same environment variable and configuration + as that of the Kong pod. +- If Kong is configured to run with Postgres, the Kong pods now always wait + for Postgres to start. Previously this was done only when the sub-chart + Postgres was deployed. +- A hard-coded container name is used for kong: `proxy`. Previously this + was auto-generated by Helm. This deterministic naming allows for simpler + scripts and documentation. + +### Under the hood + +Following changes have no end user visible effects: + +- All Custom Resource Definitions have been consolidated into a single + template file +- All RBAC resources have been consolidated into a single template file +- `wait-for-postgres` container has been refactored and de-duplicated + +## 0.32.1 + +### Improvements + +- This is a doc only release. No code changes have been done. +- Post installation steps have been simplified and now point to a getting + started page +- Misc updates to README: + - Document missing variables + - Remove outdated variables + - Revamp and rewrite major portions of the README + - Added a table of content to make the content navigable + +## 0.32.0 + +### Improvements + +- Create and mount emptyDir volumes for `/tmp` and `/kong_prefix` to allow + for read-only root filesystem securityContexts and PodSecurityPolicys. +- Use read-only mounts for custom plugin volumes. +- Update stock PodSecurityPolicy to allow emptyDir access. +- Override the standard `/usr/local/kong` prefix to the mounted emptyDir + at `/kong_prefix` in `.Values.env`. +- Add securityContext injection points to template. By default, + it sets Kong pods to run with UID 1000. + +### Fixes + +- Correct behavior for the Vitals toggle. + Vitals defaults to on in all current Kong Enterprise releases, and + the existing template only created the Vitals environment variable + if `.Values.enterprise.enabled == true`. Inverted template to create + it (and set it to "off") if that setting is instead disabled. +- Correct an issue where custom plugin configurations would block Kong + from starting. + +## 0.31.0 + +### Breaking changes + +- Admin Service is disabled by default (`admin.enabled`) +- Default for `proxy.type` has been changed to `LoadBalancer` + +### New features + +- Update default version of Kong to 1.4 +- Update default version of Ingress Controller to 0.6.2 +- Add support to disable kong-admin service via `admin.enabled` flag. + +## 0.31.2 + +### Fixes + +- Do not remove white space between documents when rendering + `migrations-pre-upgrade.yaml` + +## 0.30.1 + +### New Features + +- Add support for specifying Proxy service ClusterIP + +## 0.30.0 + +### Breaking changes + +- `admin_gui_auth_conf_secret` is now required for Kong Manager + authentication methods other than `basic-auth`. + Users defining values for `admin_gui_auth_conf` should migrate them to + an externally-defined secret with a key of `admin_gui_auth_conf` and + reference the secret name in `admin_gui_auth_conf_secret`. + +## 0.29.0 + +### New Features + +- Add support for specifying Ingress Controller environment variables. + +## 0.28.0 + +### New Features + +- Added support for the Validating Admission Webhook with the Ingress Controller. + +## 0.27.2 + +### Fixes + +- Do not create a ServiceAccount if it is not necessary. +- If a configuration change requires creating a ServiceAccount, + create a temporary ServiceAccount to allow pre-upgrade tasks to + complete before the regular ServiceAccount is created. + +## 0.27.1 + +### Documentation updates +- Retroactive changelog update for 0.24 breaking changes. + +## 0.27.0 + +### Breaking changes + +- DB-less mode is enabled by default. +- Kong is installed as an Ingress Controller for the cluster by default. + +## 0.25.0 + +### New features + +- Add support for PodSecurityPolicy +- Require creation of a ServiceAccount + +## 0.24.0 + +### Breaking changes + +- The configuration format for ingresses in values.yaml has changed. +Previously, all ingresses accepted an array of hostnames, and would create +ingress rules for each. Ingress configuration for services other than the proxy +now accepts a single hostname, which allows simpler TLS configuration and +automatic population of `admin_api_uri` and similar settings. Configuration for +the proxy ingress is unchanged, but its documentation now accurately reflects +the TLS configuration needed. diff --git a/charts/kong/kong/2.41.0/Chart.lock b/charts/kong/kong/2.41.0/Chart.lock new file mode 100644 index 0000000000..88cd736b96 --- /dev/null +++ b/charts/kong/kong/2.41.0/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: postgresql + repository: https://charts.bitnami.com/bitnami + version: 11.9.13 +digest: sha256:051285066cef2799e39e2953c4abd405c36510a09e9e1bd1833a29224daffddb +generated: "2022-12-19T11:56:46.951582785-08:00" diff --git a/charts/kong/kong/2.41.0/Chart.yaml b/charts/kong/kong/2.41.0/Chart.yaml new file mode 100644 index 0000000000..00058ceee1 --- /dev/null +++ b/charts/kong/kong/2.41.0/Chart.yaml @@ -0,0 +1,21 @@ +annotations: + catalog.cattle.io/certified: partner + catalog.cattle.io/display-name: Kong Gateway + catalog.cattle.io/release-name: kong +apiVersion: v2 +appVersion: "3.6" +dependencies: +- condition: postgresql.enabled + name: postgresql + repository: file://./charts/postgresql + version: 11.9.13 +description: The Cloud-Native Ingress and API-management +home: https://konghq.com/ +icon: file://assets/icons/kong.png +maintainers: +- email: team-k8s@konghq.com + name: team-k8s-bot +name: kong +sources: +- https://github.com/Kong/charts/tree/main/charts/kong +version: 2.41.0 diff --git a/charts/kong/kong/2.41.0/FAQs.md b/charts/kong/kong/2.41.0/FAQs.md new file mode 100644 index 0000000000..847cb63d11 --- /dev/null +++ b/charts/kong/kong/2.41.0/FAQs.md @@ -0,0 +1,139 @@ +# Frequently Asked Questions (FAQs) + +Despite the title, this is more a list of common problems. + +#### Kong cannot connect to a fresh Postgres install and fails to start + +If Kong is reporting that it cannot connect to Postgres because of an invalid +password on a fresh install, you likely have a leftover PersistentVolume from a +previous install using the same name. You should delete your install, delete +the associated PersistentVolumeClaim, and install again. + +Postgres PVCs [are not deleted when the chart install is +deleted](https://docs.bitnami.com/kubernetes/faq/troubleshooting/troubleshooting-helm-chart-issues/#persistence-volumes-pvs-retained-from-previous-releases), +and will be reused by subsequent installs if still present. Since the `kong` +user password is written to disk during database initialization only, that old +user's password is expected, not the new user's. + +PVC names use the pattern `data--postgresql-`. If +you named your install `foo` and did not increase the Postgres replica count, +you will have a single `data-foo-postgresql-0` PVC that needs to be deleted: + +``` +kubectl delete pvc data-foo-postgresql-0 +``` + +If you use a workflow that frequently deletes and re-creates installs, you +should make sure to delete PVCs when you delete the release: + +``` +helm delete foo; kubectl delete pvc data-foo-postgresql-0 +``` + +#### Upgrading a release fails due to missing ServiceAccount + +When upgrading a release, some configuration changes result in this error: + +``` +Error creating: pods "releasename-kong-pre-upgrade-migrations-" is forbidden: error looking up service account releasename-kong: serviceaccount "releasename-kong" not found +``` + +Enabling the ingress controller or PodSecurityPolicy requires that the Kong +chart also create a ServiceAccount. When upgrading from a configuration that +previously had neither of these features enabled, the pre-upgrade-migrations +Job attempts to use this ServiceAccount before it is created. It is [not +possible to easily handle this case automatically](https://github.com/Kong/charts/pull/31). + +Users encountering this issue should temporarily modify their +[pre-upgrade-migrations template](https://github.com/Kong/charts/blob/main/charts/kong/templates/migrations-pre-upgrade.yaml), +adding the following at the bottom: + +``` +{{ if or .Values.podSecurityPolicy.enabled (and .Values.ingressController.enabled .Values.ingressController.serviceAccount.create) -}} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "kong.serviceAccountName" . }} + namespace: {{ template "kong.namespace" . }} + annotations: + "helm.sh/hook": pre-upgrade + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + labels: + {{- include "kong.metaLabels" . | nindent 4 }} +{{- end -}} +``` + +Upgrading with this in place will create a temporary service account before +creating the actual service account. After this initial upgrade, users must +revert to the original pre-upgrade migrations template, as leaving the +temporary ServiceAccount template in place will [cause permissions issues on +subsequent upgrades](https://github.com/Kong/charts/issues/30). + +#### Running "helm upgrade" fails because of old init-migrations Job + +When running `helm upgrade`, the upgrade fails and Helm reports an error +similar to the following: + +``` +Error: UPGRADE FAILED: cannot patch "RELEASE-NAME-kong-init-migrations" with +kind Job: Job.batch "RELEASE-NAME-kong-init-migrations" is invalid ... field +is immutable +``` + +This occurs if a `RELEASE-NAME-kong-init-migrations` Job is left over from a +previous `helm install` or `helm upgrade`. Deleting it with +`kubectl delete job RELEASE-NAME-kong-init-migrations` will allow the upgrade +to proceed. Chart versions greater than 1.5.0 delete the job automatically. + +#### DB-backed instances do not start when deployed within a service mesh + +Service meshes, such as Istio and Kuma, if deployed in a mode that injects +a sidecar to Kong, don't make the mesh available to `InitContainer`s, +because the sidecar starts _after_ all `InitContainer`s finish. + +By default, this chart uses init containers to ensure that the database is +online and has migrations applied before starting Kong. This provides for a +smoother startup, but isn't compatible with service mesh sidecar requirements +if Kong is to access the database through the mesh. + +Setting `waitImage.enabled=false` in values.yaml disables these init containers +and resolves this issue. However, during the initial install, your Kong +Deployment will enter the CrashLoopBackOff state while waiting for migrations +to complete. It will eventually exit this state and enter Running as long as +there are no issues finishing migrations, usually within 2 minutes. + +If your Deployment is stuck in CrashLoopBackoff for longer, check the init +migrations Job logs to see if it is unable to connect to the database or unable +to complete migrations for some other reason. Resolve any issues you find, +delete the release, and attempt to install again. + +#### Kong fails to start after `helm upgrade` when Postgres is used + +As of Kong chart 2.8, this issue is no longer present. 2.8 updates the Postgres +sub-chart to a version that checks for existing password Secrets and leaves +them as-is rather than overwriting them. + +You may be running into this issue: https://github.com/helm/charts/issues/12575. +This issue is caused due to: https://github.com/helm/helm/issues/3053. + +The problem that happens is that Postgres database has the old password but +the new secret has a different password, which is used by Kong, and password +based authentication fails. + +The solution to the problem is to specify a password to the `postgresql` chart. +This is to ensure that the password is not generated randomly but is set to +the same one that is user-provided on each upgrade. + +The Postgres chart provides [two options](https://github.com/bitnami/charts/tree/master/bitnami/postgresql#postgresql-common-parameters) +for setting a password: + +- `auth.password` sets a password directly in values.yaml, in cleartext. This + is fine if you are using the instance for testing and have no security + concerns. +- `auth.existingSecret` specifies a Secret that contains [specific keys](https://github.com/bitnami/charts/blob/a6146a1ed392c8683c30b21e3fef905d86b0d2d6/bitnami/postgresql/values.yaml#L134-L143). + This should be used if you need to properly secure the Postgres instance. + +If you have already upgraded, the old password is lost. You will need to +delete the Helm release and the Postgres PersistentVolumeClaim before +re-installing with a non-random password. diff --git a/charts/kong/kong/2.41.0/README.md b/charts/kong/kong/2.41.0/README.md new file mode 100644 index 0000000000..fa495a31bd --- /dev/null +++ b/charts/kong/kong/2.41.0/README.md @@ -0,0 +1,1240 @@ +## Kong for Kubernetes + +[Kong for Kubernetes](https://github.com/Kong/kubernetes-ingress-controller) +is an open-source Ingress Controller for Kubernetes that offers +API management capabilities with a plugin architecture. + +This chart bootstraps all the components needed to run Kong on a +[Kubernetes](http://kubernetes.io) cluster using the +[Helm](https://helm.sh) package manager. + +## TL;DR; + +```bash +helm repo add kong https://charts.konghq.com +helm repo update + +helm install kong/kong --generate-name +``` + +## Table of contents + +- [Prerequisites](#prerequisites) +- [Install](#install) +- [Uninstall](#uninstall) +- [FAQs](#faqs) +- [Kong Enterprise](#kong-enterprise) +- [Deployment Options](#deployment-options) + - [Database](#database) + - [DB-less deployment](#db-less-deployment) + - [Using the Postgres sub-chart](#using-the-postgres-sub-chart) + - [Postgres sub-chart considerations for OpenShift](#postgres-sub-chart-considerations-for-openshift) + - [Runtime package](#runtime-package) + - [Configuration method](#configuration-method) + - [Separate admin and proxy nodes](#separate-admin-and-proxy-nodes) + - [Standalone controller nodes](#standalone-controller-nodes) + - [Hybrid mode](#hybrid-mode) + - [Certificates](#certificates) + - [Control plane node configuration](#control-plane-node-configuration) + - [Data plane node configuration](#data-plane-node-configuration) + - [Cert Manager Integration](#cert-manager-integration) + - [CRD management](#crd-management) + - [InitContainers](#initcontainers) + - [HostAliases](#hostaliases) + - [Sidecar Containers](#sidecar-containers) + - [Migration Sidecar Containers](#migration-sidecar-containers) + - [User Defined Volumes](#user-defined-volumes) + - [User Defined Volume Mounts](#user-defined-volume-mounts) + - [Removing cluster-scoped permissions](#removing-cluster-scoped-permissions) + - [Using a DaemonSet](#using-a-daemonset) + - [Using dnsPolicy and dnsConfig](#using-dnspolicy-and-dnsconfig) + - [Example configurations](#example-configurations) +- [Configuration](#configuration) + - [Kong parameters](#kong-parameters) + - [Kong Service Parameters](#kong-service-parameters) + - [Admin Service mTLS](#admin-service-mtls) + - [Stream listens](#stream-listens) + - [Ingress Controller Parameters](#ingress-controller-parameters) + - [The `env` section](#the-env-section) + - [The `customEnv` section](#the-customenv-section) + - [General Parameters](#general-parameters) + - [The `env` section](#the-env-section-1) + - [The `customEnv` section](#the-customenv-section-1) + - [The `extraLabels` section](#the-extralabels-section) +- [Kong Enterprise Parameters](#kong-enterprise-parameters) + - [Overview](#overview) + - [Prerequisites](#prerequisites-1) + - [Kong Enterprise License](#kong-enterprise-license) + - [Kong Enterprise Docker registry access](#kong-enterprise-docker-registry-access) + - [Service location hints](#service-location-hints) + - [RBAC](#rbac) + - [Sessions](#sessions) + - [Email/SMTP](#emailsmtp) +- [Prometheus Operator integration](#prometheus-operator-integration) +- [Argo CD considerations](#argo-cd-considerations) +- [Changelog](https://github.com/Kong/charts/blob/main/charts/kong/CHANGELOG.md) +- [Upgrading](https://github.com/Kong/charts/blob/main/charts/kong/UPGRADE.md) +- [Seeking help](#seeking-help) + +## Prerequisites + +- Kubernetes 1.17+. Older chart releases support older Kubernetes versions. + Refer to the [supported version matrix](https://docs.konghq.com/kubernetes-ingress-controller/latest/references/version-compatibility/#kubernetes) + and the [chart changelog](https://github.com/Kong/charts/blob/main/charts/kong/CHANGELOG.md) + for information about the default chart controller versions and Kubernetes + versions supported by controller releases. +- PV provisioner support in the underlying infrastructure if persistence + is needed for Kong datastore. + +## Install + +To install Kong: + +```bash +helm repo add kong https://charts.konghq.com +helm repo update + +helm install kong/kong --generate-name +``` + +## Uninstall + +To uninstall/delete a Helm release `my-release`: + +```bash +helm delete my-release +``` + +The command removes all the Kubernetes components associated with the +chart and deletes the release. + +> **Tip**: List all releases using `helm list` + +## FAQs + +Please read the +[FAQs](https://github.com/Kong/charts/blob/main/charts/kong/FAQs.md) +document. + +## Kong Enterprise + +If using Kong Enterprise, several additional steps are necessary before +installing the chart: + +- Set `enterprise.enabled` to `true` in `values.yaml` file. +- Update values.yaml to use a Kong Enterprise image. +- Satisfy the two prerequisites below for + [Enterprise License](#kong-enterprise-license) and + [Enterprise Docker Registry](#kong-enterprise-docker-registry-access). +- (Optional) [set a `password` environment variable](#rbac) to create the + initial super-admin. Though not required, this is recommended for users that + wish to use RBAC, as it cannot be done after initial setup. + +Once you have these set, it is possible to install Kong Enterprise. + +Please read through +[Kong Enterprise considerations](#kong-enterprise-parameters) +to understand all settings that are enterprise specific. + +## Deployment Options + +Kong is a highly configurable piece of software that can be deployed +in a number of different ways, depending on your use-case. + +All combinations of various runtimes, databases and configuration methods are +supported by this Helm chart. +The recommended approach is to use the Ingress Controller based configuration +along-with DB-less mode. + +Following sections detail on various high-level architecture options available: + +### Database + +Kong can run with or without a database (DB-less). By default, this chart +installs Kong without a database. + +You can set the database the `env.database` parameter. For more details, please +read the [env](#the-env-section) section. + +#### DB-less deployment + +When deploying Kong in DB-less mode(`env.database: "off"`) +and without the Ingress Controller(`ingressController.enabled: false`), +you have to provide a [declarative configuration](https://docs.konghq.com/gateway-oss/latest/db-less-and-declarative-config/#the-declarative-configuration-format) for Kong to run. +You can provide an existing ConfigMap +(`dblessConfig.configMap`) or Secret (`dblessConfig.secret`) or place the whole +configuration into `values.yaml` (`dblessConfig.config`) parameter. See the +example configuration in the default values.yaml for more details. You can use +`--set-file dblessConfig.config=/path/to/declarative-config.yaml` in Helm +commands to substitute in a complete declarative config file. + +Note that externally supplied ConfigMaps are not hashed or tracked in deployment annotations. +Subsequent ConfigMap updates will require user-initiated new deployment rollouts +to apply the new configuration. You should run `kubectl rollout restart deploy` +after updating externally supplied ConfigMap content. + +#### Using the Postgres sub-chart + +The chart can optionally spawn a Postgres instance using [Bitnami's Postgres +chart](https://github.com/bitnami/charts/blob/master/bitnami/postgresql/README.md) +as a sub-chart. Set `postgresql.enabled=true` to enable the sub-chart. Enabling +this will auto-populate Postgres connection settings in Kong's environment. + +The Postgres sub-chart is best used to quickly provision temporary environments +without installing and configuring your database separately. For longer-lived +environments, we recommend you manage your database outside the Kong Helm +release. + +##### Postgres sub-chart considerations for OpenShift + +Due to the default `securityContexts` in the postgres sub-chart, you will need to add the following values to the `postgresql` section to get postgres running on OpenShift: + +```yaml + volumePermissions: + enabled: false + securityContext: + runAsUser: "auto" + primary: + containerSecurityContext: + enabled: false + podSecurityContext: + enabled: false +``` + +### Runtime package + +There are three different packages of Kong that are available: + +- **Kong Gateway**\ + This is the [Open-Source](https://github.com/kong/kong) offering. It is a + full-blown API Gateway and Ingress solution with a wide-array of functionality. + When Kong Gateway is combined with the Ingress based configuration method, + you get Kong for Kubernetes. This is the default deployment for this Helm + Chart. +- **Kong Enterprise K8S**\ + This package builds up on top of the Open-Source Gateway and bundles in all + the Enterprise-only plugins as well. + When Kong Enterprise K8S is combined with the Ingress based + configuration method, you get Kong for Kubernetes Enterprise. + This package also comes with 24x7 support from Kong Inc. +- **Kong Enterprise**\ + This is the full-blown Enterprise package which packs with itself all the + Enterprise functionality like Manager, Portal, Vitals, etc. + This package can't be run in DB-less mode. + +The package to run can be changed via `image.repository` and `image.tag` +parameters. If you would like to run the Enterprise package, please read +the [Kong Enterprise Parameters](#kong-enterprise-parameters) section. + +### Configuration method + +Kong can be configured via two methods: +- **Ingress and CRDs**\ + The configuration for Kong is done via `kubectl` and Kubernetes-native APIs. + This is also known as Kong Ingress Controller or Kong for Kubernetes and is + the default deployment pattern for this Helm Chart. The configuration + for Kong is managed via Ingress and a few + [Custom Resources](https://docs.konghq.com/kubernetes-ingress-controller/latest/concepts/custom-resources). + For more details, please read the + [documentation](https://docs.konghq.com/kubernetes-ingress-controller/) + on Kong Ingress Controller. + To configure and fine-tune the controller, please read the + [Ingress Controller Parameters](#ingress-controller-parameters) section. +- **Admin API**\ + This is the traditional method of running and configuring Kong. + By default, the Admin API of Kong is not exposed as a Service. This + can be controlled via `admin.enabled` and `env.admin_listen` parameters. + +### Separate admin and proxy nodes + +*Note: although this section is titled "Separate admin and proxy nodes", this +split release technique is generally applicable to any deployment with +different types of Kong nodes. Separating Admin API and proxy nodes is one of +the more common use cases for splitting across multiple releases, but you can +also split releases for split proxy and Developer Portal nodes, multiple groups +of proxy nodes with separate listen configurations for network segmentation, etc. +However, it does not apply to hybrid mode, as only the control plane release +interacts with the database.* + +Users may wish to split their Kong deployment into multiple instances that only +run some of Kong's services (i.e. you run `helm install` once for every +instance type you wish to create). + +To disable Kong services on an instance, you should set `SVC.enabled`, +`SVC.http.enabled`, `SVC.tls.enabled`, and `SVC.ingress.enabled` all to +`false`, where `SVC` is `proxy`, `admin`, `manager`, `portal`, or `portalapi`. + +The standard chart upgrade automation process assumes that there is only a +single Kong release in the Kong cluster, and runs both `migrations up` and +`migrations finish` jobs. To handle clusters split across multiple releases, +you should: +1. Upgrade one of the releases with `helm upgrade RELEASENAME -f values.yaml + --set migrations.preUpgrade=true --set migrations.postUpgrade=false`. +2. Upgrade all but one of the remaining releases with `helm upgrade RELEASENAME + -f values.yaml --set migrations.preUpgrade=false --set + migrations.postUpgrade=false`. +3. Upgrade the final release with `helm upgrade RELEASENAME -f values.yaml + --set migrations.preUpgrade=false --set migrations.postUpgrade=true`. + +This ensures that all instances are using the new Kong package before running +`kong migrations finish`. + +Users should note that Helm supports supplying multiple values.yaml files, +allowing you to separate shared configuration from instance-specific +configuration. For example, you may have a shared values.yaml that contains +environment variables and other common settings, and then several +instance-specific values.yamls that contain service configuration only. You can +then create releases with: + +```bash +helm install proxy-only -f shared-values.yaml -f only-proxy.yaml kong/kong +helm install admin-only -f shared-values.yaml -f only-admin.yaml kong/kong +``` + +### Standalone controller nodes + +The chart can deploy releases that contain the controller only, with no Kong +container, by setting `deployment.kong.enabled: false` in values.yaml. There +are several controller settings that must be populated manually in this +scenario and several settings that are useful when using multiple controllers: + +* `ingressController.env.kong_admin_url` must be set to the Kong Admin API URL. + If the Admin API is exposed by a service in the cluster, this should look + something like `https://my-release-kong-admin.kong-namespace.svc:8444` +* `ingressController.env.publish_service` must be set to the Kong proxy + service, e.g. `namespace/my-release-kong-proxy`. +* `ingressController.ingressClass` should be set to a different value for each + instance of the controller. +* `ingressController.env.kong_admin_filter_tag` should be set to a different value + for each instance of the controller. +* If using Kong Enterprise, `ingressController.env.kong_workspace` can + optionally create configuration in a workspace other than `default`. + +Standalone controllers require a database-backed Kong instance, as DB-less mode +requires that a single controller generate a complete Kong configuration. + +### Hybrid mode + +Kong supports [hybrid mode +deployments](https://docs.konghq.com/2.0.x/hybrid-mode/) as of Kong 2.0.0 and +[Kong Enterprise 2.1.0](https://docs.konghq.com/enterprise/2.1.x/deployment/hybrid-mode/). +These deployments split Kong nodes into control plane (CP) nodes, which provide +the admin API and interact with the database, and data plane (DP) nodes, which +provide the proxy and receive configuration from control plane nodes. + +You can deploy hybrid mode Kong clusters by [creating separate releases for each node +type](#separate-admin-and-proxy-nodes), i.e. use separate control and data +plane values.yamls that are then installed separately. The [control +plane](#control-plane-node-configuration) and [data +plane](#data-plane-node-configuration) configuration sections below cover the +values.yaml specifics for each. + +Cluster certificates are not generated automatically. You must [create a +certificate and key pair](#certificates) for intra-cluster communication. + +When upgrading the Kong version, you must [upgrade the control plane release +first and then upgrade the data plane release](https://docs.konghq.com/gateway/latest/plan-and-deploy/hybrid-mode/#version-compatibility). + +#### Certificates + +> This example shows how to use Kong Hybrid mode with `cluster_mtls: shared`. +> For an example of `cluster_mtls: pki` see the [hybrid-cert-manager example](https://github.com/Kong/charts/blob/main/charts/kong/example-values/hybrid-cert-manager/) + +Hybrid mode uses TLS to secure the CP/DP node communication channel, and +requires certificates for it. You can generate these either using `kong hybrid +gen_cert` on a local Kong installation or using OpenSSL: + +```bash +openssl req -new -x509 -nodes -newkey ec:<(openssl ecparam -name secp384r1) \ + -keyout /tmp/cluster.key -out /tmp/cluster.crt \ + -days 1095 -subj "/CN=kong_clustering" +``` + +You must then place these certificates in a Secret: + +```bash +kubectl create secret tls kong-cluster-cert --cert=/tmp/cluster.crt --key=/tmp/cluster.key +``` + +#### Control plane node configuration + +You must configure the control plane nodes to mount the certificate secret on +the container filesystem is serve it from the cluster listen. In values.yaml: + +```yaml +secretVolumes: +- kong-cluster-cert +``` + +```yaml +env: + role: control_plane + cluster_cert: /etc/secrets/kong-cluster-cert/tls.crt + cluster_cert_key: /etc/secrets/kong-cluster-cert/tls.key +``` + +Furthermore, you must enable the cluster listen and Kubernetes Service, and +should typically disable the proxy: + +```yaml +cluster: + enabled: true + tls: + enabled: true + servicePort: 8005 + containerPort: 8005 + +proxy: + enabled: false +``` + +Enterprise users with Vitals enabled must also enable the cluster telemetry +service: + +```yaml +clustertelemetry: + enabled: true + tls: + enabled: true + servicePort: 8006 + containerPort: 8006 +``` + +If using the ingress controller, you must also specify the DP proxy service as +its publish target to keep Ingress status information up to date: + +``` +ingressController: + env: + publish_service: hybrid/example-release-data-kong-proxy +``` + +Replace `hybrid` with your DP nodes' namespace and `example-release-data` with +the name of the DP release. + +#### Data plane node configuration + +Data plane configuration also requires the certificate and `role` +configuration, and the database should always be set to `off`. You must also +trust the cluster certificate and indicate what hostname/port Kong should use +to find control plane nodes. + +Though not strictly required, you should disable the admin service (it will not +work on DP nodes anyway, but should be disabled to avoid creating an invalid +Service resource). + +```yaml +secretVolumes: +- kong-cluster-cert +``` + +```yaml +admin: + enabled: false +``` + +```yaml +env: + role: data_plane + database: "off" + cluster_cert: /etc/secrets/kong-cluster-cert/tls.crt + cluster_cert_key: /etc/secrets/kong-cluster-cert/tls.key + lua_ssl_trusted_certificate: /etc/secrets/kong-cluster-cert/tls.crt + cluster_control_plane: control-plane-release-name-kong-cluster.hybrid.svc.cluster.local:8005 + cluster_telemetry_endpoint: control-plane-release-name-kong-clustertelemetry.hybrid.svc.cluster.local:8006 # Enterprise-only +``` + +Note that the `cluster_control_plane` value will differ depending on your +environment. `control-plane-release-name` will change to your CP release name, +`hybrid` will change to whatever namespace it resides in. See [Kubernetes' +documentation on Service +DNS](https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/) +for more detail. + +If you use multiple Helm releases to manage different data plane configurations +attached to the same control plane, setting the `deployment.hostname` field +will help you keep track of which is which in the `/clustering/data-plane` +endpoint. + +### Cert Manager Integration + +By default, Kong will create self-signed certificates on start for its TLS +listens if you do not provide your own. The chart can create +[cert-manager](https://cert-manager.io/docs/) Certificates for its Services and +configure them for you. To use this integration, install cert-manager, create +an issuer, set `certificates.enabled: true` in values.yaml, and set your issuer +name in `certificates.issuer` or `certificates.clusterIssuer` depending on the +issuer type. + +If you do not have an issuer available, you can install the example [self-signed ClusterIssuer](https://cert-manager.io/docs/configuration/selfsigned/#bootstrapping-ca-issuers) +and set `certificates.clusterIssuer: selfsigned-issuer` for testing. You +should, however, migrate to an issuer using a CA your clients trust for actual +usage. + +The `proxy`, `admin`, `portal`, and `cluster` subsections under `certificates` +let you choose hostnames, override issuers, set `subject` or set `privateKey` on a per-certificate basis for the +proxy, admin API and Manager, Portal and Portal API, and hybrid mode mTLS +services, respectively. + +To use hybrid mode, the control and data plane releases must use the same +issuer for their cluster certificates. + +### CRD management + +Earlier versions of this chart (<2.0) created CRDs associated with the ingress +controller as part of the release. This raised two challenges: + +- Multiple release of the chart would conflict with one another, as each would + attempt to create its own set of CRDs. +- Because deleting a CRD also deletes any custom resources associated with it, + deleting a release of the chart could destroy user configuration without + providing any means to restore it. + +Helm 3 introduced a simplified CRD management method that was safer, but +requires some manual work when a chart added or modified CRDs: CRDs are created +on install if they are not already present, but are not modified during +release upgrades or deletes. Our chart release upgrade instructions call out +when manual action is necessary to update CRDs. This CRD handling strategy is +recommended for most users. + +Some users may wish to manage their CRDs automatically. If you manage your CRDs +this way, we _strongly_ recommend that you back up all associated custom +resources in the event you need to recover from unintended CRD deletion. + +While Helm 3's CRD management system is recommended, there is no simple means +of migrating away from release-managed CRDs if you previously installed your +release with the old system (you would need to back up your existing custom +resources, delete your release, reinstall, and restore your custom resources +after). As such, the chart detects if you currently use release-managed CRDs +and continues to use the old CRD templates when using chart version 2.0+. If +you do (your resources will have a `meta.helm.sh/release-name` annotation), we +_strongly_ recommend that you back up all associated custom resources in the +event you need to recover from unintended CRD deletion. + +### InitContainers + +The chart is able to deploy initContainers along with Kong. This can be very +useful when there's a requirement for custom initialization. The +`deployment.initContainers` field in values.yaml takes an array of objects that +get appended as-is to the existing `spec.template.initContainers` array in the +kong deployment resource. + +### HostAliases + +The chart is able to inject host aliases into containers. This can be very useful +when it's required to resolve additional domain name which can't be looked-up +directly from dns server. The `deployment.hostAliases` field in values.yaml +takes an array of objects that set to `spec.template.hostAliases` field in the +kong deployment resource. + +### Sidecar Containers + +The chart can deploy additional containers along with the Kong and Ingress +Controller containers, sometimes referred to as "sidecar containers". This can +be useful to include network proxies or logging services along with Kong. The +`deployment.sidecarContainers` field in values.yaml takes an array of objects +that get appended as-is to the existing `spec.template.spec.containers` array +in the Kong deployment resource. + +### Migration Sidecar Containers + +In the same way sidecar containers are attached to the Kong and Ingress +Controller containers the chart can add sidecars to the containers that runs +the migrations. The +`migrations.sidecarContainers` field in values.yaml takes an array of objects +that get appended as-is to the existing `spec.template.spec.containers` array +in the pre-upgrade-migrations, post-upgrade-migrations and migration resrouces. +Keep in mind the containers should be finite and they should be terminated +with the migration containers, otherwise the migration could get the status +as finished and the deployment of the chart will reach the timeout. + +### User Defined Volumes + +The chart can deploy additional volumes along with Kong. This can be useful to +include additional volumes which required during iniatilization phase +(InitContainer). The `deployment.userDefinedVolumes` field in values.yaml +takes an array of objects that get appended as-is to the existing +`spec.template.spec.volumes` array in the kong deployment resource. + +### User Defined Volume Mounts + +The chart can mount user-defined volumes. The +`deployment.userDefinedVolumeMounts` and +`ingressController.userDefinedVolumeMounts` fields in values.yaml take an array +of object that get appended as-is to the existing +`spec.template.spec.containers[].volumeMounts` and +`spec.template.spec.initContainers[].volumeMounts` array in the kong deployment +resource. + +### Removing cluster-scoped permissions + +You can limit the controller's access to allow it to only watch specific +namespaces for namespaced resources. By default, the controller watches all +namespaces. Limiting access requires several changes to configuration: + +- Set `ingressController.watchNamespaces` to a list of namespaces you want to + watch. The chart will automatically generate roles for each namespace and + assign them to the controller's service account. +- Optionally set `ingressController.installCRDs=false` if your user role (the + role you use when running `helm install`, not the controller service + account's role) does not have access to get CRDs. By default, the chart + attempts to look up the controller CRDs for [a legacy behavior + check](#crd-management). + +### Using a DaemonSet + +Setting `deployment.daemonset: true` deploys Kong using a [DaemonSet +controller](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/) +instead of a Deployment controller. This runs a Kong Pod on every kubelet in +the Kubernetes cluster. For such configuration it may be desirable to configure +Pods to use the network of the host they run on instead of a dedicated network +namespace. The benefit of this approach is that the Kong can bind ports directly +to Kubernetes nodes' network interfaces, without the extra network translation +imposed by NodePort Services. It can be achieved by setting `deployment.hostNetwork: true`. + +### Using dnsPolicy and dnsConfig + +The chart able to inject custom DNS configuration into containers. This can be useful when you have EKS cluster with [NodeLocal DNSCache](https://kubernetes.io/docs/tasks/administer-cluster/nodelocaldns/) configured and attach AWS security groups directly to pod using [security groups for pods feature](https://docs.aws.amazon.com/eks/latest/userguide/security-groups-for-pods.html). + +### Example configurations + +Several example values.yaml are available in the +[example-values](https://github.com/Kong/charts/blob/main/charts/kong/example-values/) +directory. + +## Configuration + +### Kong parameters + +| Parameter | Description | Default | +| ---------------------------------- | ------------------------------------------------------------------------------------- | ------------------- | +| image.repository | Kong image | `kong` | +| image.tag | Kong image version | `3.5` | +| image.effectiveSemver | Semantic version to use for version-dependent features (if `tag` is not a semver) | | +| image.pullPolicy | Image pull policy | `IfNotPresent` | +| image.pullSecrets | Image pull secrets | `null` | +| replicaCount | Kong instance count. It has no effect when `autoscaling.enabled` is set to true | `1` | +| plugins | Install custom plugins into Kong via ConfigMaps or Secrets | `{}` | +| env | Additional [Kong configurations](https://getkong.org/docs/latest/configuration/) | | +| customEnv | Custom Environment variables without `KONG_` prefix | | +| envFrom | Populate environment variables from ConfigMap or Secret keys | | +| migrations.preUpgrade | Run "kong migrations up" jobs | `true` | +| migrations.postUpgrade | Run "kong migrations finish" jobs | `true` | +| migrations.annotations | Annotations for migration job pods | `{"sidecar.istio.io/inject": "false" | +| migrations.jobAnnotations | Additional annotations for migration jobs | `{}` | +| migrations.backoffLimit | Override the system backoffLimit | `{}` | +| waitImage.enabled | Spawn init containers that wait for the database before starting Kong | `true` | +| waitImage.repository | Image used to wait for database to become ready. Uses the Kong image if none set | | +| waitImage.tag | Tag for image used to wait for database to become ready | | +| waitImage.pullPolicy | Wait image pull policy | `IfNotPresent` | +| postgresql.enabled | Spin up a new postgres instance for Kong | `false` | +| dblessConfig.configMap | Name of an existing ConfigMap containing the `kong.yml` file. This must have the key `kong.yml`.| `` | +| dblessConfig.config | Yaml configuration file for the dbless (declarative) configuration of Kong | see in `values.yaml` | + +#### Kong Service Parameters + +The various `SVC.*` parameters below are common to the various Kong services +(the admin API, proxy, Kong Manager, the Developer Portal, and the Developer +Portal API) and define their listener configuration, K8S Service properties, +and K8S Ingress properties. Defaults are listed only if consistent across the +individual services: see values.yaml for their individual default values. + +`SVC` below can be substituted with each of: +* `proxy` +* `udpProxy` +* `admin` +* `manager` +* `portal` +* `portalapi` +* `cluster` +* `clustertelemetry` +* `status` + +`status` is intended for internal use within the cluster. Unlike other +services it cannot be exposed externally, and cannot create a Kubernetes +service or ingress. It supports the settings under `SVC.http` and `SVC.tls` +only. + +`cluster` is used on hybrid mode control plane nodes. It does not support the +`SVC.http.*` settings (cluster communications must be TLS-only) or the +`SVC.ingress.*` settings (cluster communication requires TLS client +authentication, which cannot pass through an ingress proxy). `clustertelemetry` +is similar, and used when Vitals is enabled on Kong Enterprise control plane +nodes. + +`udpProxy` is used for UDP stream listens (Kubernetes does not yet support +mixed TCP/UDP LoadBalancer Services). It _does not_ support the `http`, `tls`, +or `ingress` sections, as it is used only for stream listens. + +| Parameter | Description | Default | +|-----------------------------------|-------------------------------------------------------------------------------------------|--------------------------| +| SVC.enabled | Create Service resource for SVC (admin, proxy, manager, etc.) | | +| SVC.http.enabled | Enables http on the service | | +| SVC.http.servicePort | Service port to use for http | | +| SVC.http.containerPort | Container port to use for http | | +| SVC.http.nodePort | Node port to use for http | | +| SVC.http.hostPort | Host port to use for http | | +| SVC.http.parameters | Array of additional listen parameters | `[]` | +| SVC.http.appProtocol | `appProtocol` to be set in a Service's port. If left empty, no `appProtocol` will be set. | | +| SVC.tls.enabled | Enables TLS on the service | | +| SVC.tls.containerPort | Container port to use for TLS | | +| SVC.tls.servicePort | Service port to use for TLS | | +| SVC.tls.nodePort | Node port to use for TLS | | +| SVC.tls.hostPort | Host port to use for TLS | | +| SVC.tls.overrideServiceTargetPort | Override service port to use for TLS without touching Kong containerPort | | +| SVC.tls.parameters | Array of additional listen parameters | `["http2"]` | +| SVC.tls.appProtocol | `appProtocol` to be set in a Service's port. If left empty, no `appProtocol` will be set. | | +| SVC.type | k8s service type. Options: NodePort, ClusterIP, LoadBalancer | | +| SVC.clusterIP | k8s service clusterIP | | +| SVC.loadBalancerClass | loadBalancerClass to use for LoadBalancer provisionning | | +| SVC.loadBalancerSourceRanges | Limit service access to CIDRs if set and service type is `LoadBalancer` | `[]` | +| SVC.loadBalancerIP | Reuse an existing ingress static IP for the service | | +| SVC.externalIPs | IPs for which nodes in the cluster will also accept traffic for the servic | `[]` | +| SVC.externalTrafficPolicy | k8s service's externalTrafficPolicy. Options: Cluster, Local | | +| SVC.ingress.enabled | Enable ingress resource creation (works with SVC.type=ClusterIP) | `false` | +| SVC.ingress.ingressClassName | Set the ingressClassName to associate this Ingress with an IngressClass | | +| SVC.ingress.hostname | Ingress hostname | `""` | +| SVC.ingress.path | Ingress path. | `/` | +| SVC.ingress.pathType | Ingress pathType. One of `ImplementationSpecific`, `Exact` or `Prefix` | `ImplementationSpecific` | +| SVC.ingress.hosts | Slice of hosts configurations, including `hostname`, `path` and `pathType` keys | `[]` | +| SVC.ingress.tls | Name of secret resource or slice of `secretName` and `hosts` keys | | +| SVC.ingress.annotations | Ingress annotations. See documentation for your ingress controller for details | `{}` | +| SVC.ingress.labels | Ingress labels. Additional custom labels to add to the ingress. | `{}` | +| SVC.annotations | Service annotations | `{}` | +| SVC.labels | Service labels | `{}` | + +#### Admin Service mTLS + +On top of the common parameters listed above, the `admin` service supports parameters for mTLS client verification. +If any of `admin.tls.client.caBundle` or `admin.tls.client.secretName` are set, the admin service will be configured to +require mTLS client verification. If both are set, `admin.tls.client.caBundle` will take precedence. + +| Parameter | Description | Default | +|-----------------------------|---------------------------------------------------------------------------------------------|---------| +| admin.tls.client.caBundle | CA certificate to use for TLS verification of the Admin API client (PEM-encoded). | `""` | +| admin.tls.client.secretName | CA certificate secret name - must contain a `tls.crt` key with the PEM-encoded certificate. | `""` | + +#### Stream listens + +The proxy configuration additionally supports creating stream listens. These +are configured using an array of objects under `proxy.stream` and `udpProxy.stream`: + +| Parameter | Description | Default | +| ---------------------------------- | ------------------------------------------------------------------------------------- | ------------------- | +| protocol | The listen protocol, either "TCP" or "UDP" | | +| containerPort | Container port to use for a stream listen | | +| servicePort | Service port to use for a stream listen | | +| nodePort | Node port to use for a stream listen | | +| hostPort | Host port to use for a stream listen | | +| parameters | Array of additional listen parameters | `[]` | + +### Ingress Controller Parameters + +All of the following properties are nested under the `ingressController` +section of `values.yaml` file: + +| Parameter | Description | Default | +|--------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------| +| enabled | Deploy the ingress controller, rbac and crd | true | +| image.repository | Docker image with the ingress controller | kong/kubernetes-ingress-controller | +| image.tag | Version of the ingress controller | `3.3` | +| image.effectiveSemver | Version of the ingress controller used for version-specific features when image.tag is not a valid semantic version | | +| readinessProbe | Kong ingress controllers readiness probe | | +| livenessProbe | Kong ingress controllers liveness probe | | +| installCRDs | Legacy toggle for Helm 2-style CRD management. Should not be set [unless necessary due to cluster permissions](#removing-cluster-scoped-permissions). | false | +| env | Specify Kong Ingress Controller configuration via environment variables | | +| customEnv | Specify custom environment variables (without the CONTROLLER_ prefix) | | +| envFrom | Populate environment variables from ConfigMap or Secret keys | | +| ingressClass | The name of this controller's ingressClass | kong | +| ingressClassAnnotations | The ingress-class value for controller | kong | +| args | List of ingress-controller cli arguments | [] | +| watchNamespaces | List of namespaces to watch. Watches all namespaces if empty | [] | +| admissionWebhook.enabled | Whether to enable the validating admission webhook | true | +| admissionWebhook.failurePolicy | How unrecognized errors from the admission endpoint are handled (Ignore or Fail) | Ignore | +| admissionWebhook.filterSecrets | Limit the webhook to only Secrets with the appropriate KIC validation labels. | false | +| admissionWebhook.port | The port the ingress controller will listen on for admission webhooks | 8080 | +| admissionWebhook.address | The address the ingress controller will listen on for admission webhooks, if not 0.0.0.0 | | +| admissionWebhook.annotations | Annotations for the Validation Webhook Configuration | | +| admissionWebhook.certificate.provided | Use a provided certificate. When set to false, the chart will automatically generate a certificate. | false | +| admissionWebhook.certificate.secretName | Name of the TLS secret for the provided webhook certificate | | +| admissionWebhook.certificate.caBundle | PEM encoded CA bundle which will be used to validate the provided webhook certificate | | +| admissionWebhook.namespaceSelector | Add namespaceSelector to the webhook. Please go to [Kubernetes doc for the specs](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#matching-requests-namespaceselector) | | +| admissionWebhook.timeoutSeconds | Kubernetes `apiserver`'s timeout when running this webhook. Default: 10 seconds. | | +| userDefinedVolumes | Create volumes. Please go to Kubernetes doc for the spec of the volumes | | +| userDefinedVolumeMounts | Create volumeMounts. Please go to Kubernetes doc for the spec of the volumeMounts | | +| terminationGracePeriodSeconds | Sets the [termination grace period](https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#hook-handler-execution) for Deployment pod | 30 | +| gatewayDiscovery.enabled | Enables Kong instance service discovery (for more details see [gatewayDiscovery section][gd_section]) | false | +| gatewayDiscovery.generateAdminApiService | Generate the admin API service name based on the release name (for more details see [gatewayDiscovery section][gd_section]) | false | +| gatewayDiscovery.adminApiService.namespace | The namespace of the Kong admin API service (for more details see [gatewayDiscovery section][gd_section]) | `.Release.Namespace` | +| gatewayDiscovery.adminApiService.name | The name of the Kong admin API service (for more details see [gatewayDiscovery section][gd_section]) | "" | +| konnect.enabled | Enable synchronisation of data plane configuration with Konnect Runtime Group | false | +| konnect.runtimeGroupID | Deprecated: Konnect Runtime Group's unique identifier. | | +| konnect.controlPlaneID | Konnect Control Plane's unique identifier. | | +| konnect.apiHostname | Konnect API hostname. Defaults to a production US-region. | us.kic.api.konghq.com | +| konnect.tlsClientCertSecretName | Name of the secret that contains Konnect Runtime Group's client TLS certificate. | konnect-client-tls | +| konnect.license.enabled | Enable automatic license provisioning for Gateways managed by Ingress Controller in Konnect mode. | false | +| adminApi.tls.client.enabled | Enable TLS client verification for the Admin API. By default, Helm will generate certificates automatically. | false | +| adminApi.tls.client.certProvided | Use user-provided certificates. If set to false, Helm will generate certificates. | false | +| adminApi.tls.client.secretName | Client TLS certificate/key pair secret name. Can be also set when `certProvided` is false to enforce a generated secret's name. | "" | +| adminApi.tls.client.caSecretName | CA TLS certificate/key pair secret name. Can be also set when `certProvided` is false to enforce a generated secret's name. | "" | + +[gd_section]: #the-gatewayDiscovery-section + +#### The `env` section +For a complete list of all configuration values you can set in the +`env` section, please read the Kong Ingress Controller's +[configuration document](https://docs.konghq.com/kubernetes-ingress-controller/latest/reference/cli-arguments/). + +#### The `customEnv` section + +The `customEnv` section can be used to configure all environment variables other than Ingress Controller configuration. +Any key value put under this section translates to environment variables. +Every key is upper-cased before setting the environment variable. + +An example: + +```yaml +kong: + ingressController: + customEnv: + TZ: "Europe/Berlin" +``` + +#### The `gatewayDiscovery` section + +Kong Ingress Controller v2.9 has introduced gateway discovery which allows +the controller to discover Gateway instances that it should configure using +an Admin API Kubernetes service. + +Using this feature requires a split release installation of Gateways and Ingress Controller. +For exemplar `values.yaml` files which use this feature please see: [examples README.md](./example-values/README.md). +or use the [`ingress` chart](../ingress/README.md) which can handle this for you. + +##### Configuration + +You'll be able to configure this feature through configuration section under +`ingressController.gatewayDiscovery`: + +- If `ingressController.gatewayDiscovery.enabled` is set to `false`: the ingress controller + will control a pre-determined set of Gateway instances based on Admin API URLs + (provided under the hood via `CONTROLLER_KONG_ADMIN_URL` environment variable). + +- If `ingressController.gatewayDiscovery.enabled` is set to `true`: the ingress controller + will dynamically locate Gateway instances by watching the specified Kubernetes + service. + (provided under the hood via `CONTROLLER_KONG_ADMIN_SVC` environment variable). + + The following admin API Service flags have to be present in order for gateway + discovery to work: + + - `ingressController.gatewayDiscovery.adminApiService.name` + - `ingressController.gatewayDiscovery.adminApiService.namespace` + + If you set `ingressController.gatewayDiscovery.generateAdminApiService` to `true`, + the chart will generate values for `name` and `namespace` based on the current release name and + namespace. This is useful when consuming the `kong` chart as a subchart. + +Additionally, you can control the addresses that are generated for your Gateways +via the `--gateway-discovery-dns-strategy` CLI flag that can be set on the Ingress Controller +(or an equivalent environment variable: `CONTROLLER_GATEWAY_DISCOVERY_DNS_STRATEGY`). +It accepts 3 values which change the way that Gateway addresses are generated: +- `service` - for service scoped pod DNS names: `pod-ip-address.service-name.my-namespace.svc.cluster-domain.example` +- `pod` - for namespace scope pod DNS names: `pod-ip-address.my-namespace.pod.cluster-domain.example` +- `ip` (default, retains behavior introduced in v2.9) - for regular IP addresses + +When using `gatewayDiscovery`, you should consider configuring the Admin service to use mTLS client verification to make +this interface secure. +Without that, anyone who can access the Admin API from inside the cluster can configure the Gateway instances. + +On the controller release side, that can be achieved by setting `ingressController.adminApi.tls.client.enabled` to `true`. +By default, Helm will generate a certificate Secret named `-admin-api-keypair` and +a CA Secret named `-admin-api-ca-keypair` for you. + +To provide your own cert, set `ingressController.adminApi.tls.client.certProvided` to +`true`, `ingressController.adminApi.tls.client.secretName` to the name of the Secret containing your client cert, and `ingressController.adminApi.tls.client.caSecretName` to the name of the Secret containing your CA cert. + +On the Gateway release side, set either `admin.tls.client.secretName` to the name of your CA Secret or set `admin.tls.client.caBundle` to the CA certificate string. + +### General Parameters + +| Parameter | Description | Default | +| ---------------------------------- | ------------------------------------------------------------------------------------- | ------------------- | +| namespace | Namespace to deploy chart resources | | +| deployment.kong.enabled | Enable or disable deploying Kong | `true` | +| deployment.revisionHistoryLimit | The number of `ReplicaSet`s to retain. | `10` | +| deployment.minReadySeconds | Minimum number of seconds for which newly created pods should be ready without any of its container crashing, for it to be considered available. | | +| deployment.initContainers | Create initContainers. Please go to Kubernetes doc for the spec of the initContainers | | +| deployment.daemonset | Use a DaemonSet instead of a Deployment | `false` | +| deployment.hostname | Set the Deployment's `.spec.template.hostname`. Kong reports this as its hostname. | | +| deployment.hostNetwork | Enable hostNetwork, which binds to the ports to the host | `false` | +| deployment.userDefinedVolumes | Create volumes. Please go to Kubernetes doc for the spec of the volumes | | +| deployment.userDefinedVolumeMounts | Create volumeMounts. Please go to Kubernetes doc for the spec of the volumeMounts | | +| deployment.serviceAccount.create | Create Service Account for the Deployment / Daemonset and the migrations | `true` | +| deployment.serviceAccount.automountServiceAccountToken | Enable ServiceAccount token automount in Kong deployment | `false` | +| deployment.serviceAccount.name | Name of the Service Account, a default one will be generated if left blank. | "" | +| deployment.serviceAccount.annotations | Annotations for the Service Account | {} | +| deployment.test.enabled | Enable creation of test resources for use with "helm test" | `false` | +| autoscaling.enabled | Set this to `true` to enable autoscaling | `false` | +| autoscaling.minReplicas | Set minimum number of replicas | `2` | +| autoscaling.maxReplicas | Set maximum number of replicas | `5` | +| autoscaling.behavior | Sets the [behavior for scaling up and down](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/#configurable-scaling-behavior) | `{}` | +| autoscaling.targetCPUUtilizationPercentage | Target Percentage for when autoscaling takes affect. Only used if cluster does not support `autoscaling/v2` or `autoscaling/v2beta2` | `80` | +| autoscaling.metrics | metrics used for autoscaling for clusters that supports `autoscaling/v2` or `autoscaling/v2beta2` | See [values.yaml](values.yaml) | +| updateStrategy | update strategy for deployment | `{}` | +| readinessProbe | Kong readiness probe | | +| livenessProbe | Kong liveness probe | | +| startupProbe | Kong startup probe | | +| lifecycle | Proxy container lifecycle hooks | see `values.yaml` | +| terminationGracePeriodSeconds | Sets the [termination grace period](https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#hook-handler-execution) for Deployment pods | 30 | +| affinity | Node/pod affinities | | +| topologySpreadConstraints | Control how Pods are spread across cluster among failure-domains | | +| nodeSelector | Node labels for pod assignment | `{}` | +| deploymentAnnotations | Annotations to add to deployment | see `values.yaml` | +| podAnnotations | Annotations to add to each pod | see `values.yaml` | +| podLabels | Labels to add to each pod | `{}` | +| resources | Pod resource requests & limits | `{}` | +| tolerations | List of node taints to tolerate | `[]` | +| dnsPolicy | Pod dnsPolicy | | +| dnsConfig | Pod dnsConfig | | +| podDisruptionBudget.enabled | Enable PodDisruptionBudget for Kong | `false` | +| podDisruptionBudget.maxUnavailable | Represents the minimum number of Pods that can be unavailable (integer or percentage) | `50%` | +| podDisruptionBudget.minAvailable | Represents the number of Pods that must be available (integer or percentage) | | +| podSecurityPolicy.enabled | Enable podSecurityPolicy for Kong | `false` | +| podSecurityPolicy.labels | Labels to add to podSecurityPolicy for Kong | `{}` | +| podSecurityPolicy.annotations | Annotations to add to podSecurityPolicy for Kong | `{}` | +| podSecurityPolicy.spec | Collection of [PodSecurityPolicy settings](https://kubernetes.io/docs/concepts/policy/pod-security-policy/#what-is-a-pod-security-policy) | | +| priorityClassName | Set pod scheduling priority class for Kong pods | `""` | +| secretVolumes | Mount given secrets as a volume in Kong container to override default certs and keys. | `[]` | +| securityContext | Set the securityContext for Kong Pods | `{}` | +| containerSecurityContext | Set the securityContext for Containers | See values.yaml | +| serviceMonitor.enabled | Create ServiceMonitor for Prometheus Operator | `false` | +| serviceMonitor.interval | Scraping interval | `30s` | +| serviceMonitor.namespace | Where to create ServiceMonitor | | +| serviceMonitor.labels | ServiceMonitor labels | `{}` | +| serviceMonitor.targetLabels | ServiceMonitor targetLabels | `{}` | +| serviceMonitor.honorLabels | ServiceMonitor honorLabels | `{}` | +| serviceMonitor.metricRelabelings | ServiceMonitor metricRelabelings | `{}` | +| serviceMonitor.relabelings | ServiceMonitor relabelings | `[]` | +| extraConfigMaps | ConfigMaps to add to mounted volumes | `[]` | +| extraSecrets | Secrets to add to mounted volumes | `[]` | +| nameOverride | Replaces "kong" in resource names, like "RELEASENAME-nameOverride" instead of "RELEASENAME-kong" | `""` | +| fullnameOverride | Overrides the entire resource name string | `""` | +| extraObjects | Create additional k8s resources | `[]` | +**Note:** If you are using `deployment.hostNetwork` to bind to lower ports ( < 1024), which may be the desired option (ports 80 and 433), you also +need to tweak the `containerSecurityContext` configuration as in the example: + +```yaml +containerSecurityContext: # run as root to bind to lower ports + capabilities: + add: [NET_BIND_SERVICE] + runAsGroup: 0 + runAsNonRoot: false + runAsUser: 0 +``` + +**Note:** The default `podAnnotations` values disable inbound proxying for Kuma +and Istio. This is appropriate when using Kong as a gateway for external +traffic inbound into the cluster. + +If you want to use Kong as an internal proxy within the cluster network, you +should enable inbound the inbound mesh proxies: + +```yaml +# Enable inbound mesh proxying for Kuma and Istio +podAnnotations: + kuma.io/gateway: disabled + traffic.sidecar.istio.io/includeInboundPorts: "*" +``` + +#### The `env` section + +The `env` section can be used to configured all properties of Kong. +Any key value put under this section translates to environment variables +used to control Kong's configuration. Every key is prefixed with `KONG_` +and upper-cased before setting the environment variable. + +Furthermore, all `kong.env` parameters can also accept a mapping instead of a +value to ensure the parameters can be set through configmaps and secrets. + +An example: + +```yaml +kong: + env: # load PG password from a secret dynamically + pg_user: kong + pg_password: + valueFrom: + secretKeyRef: + key: kong + name: postgres + nginx_worker_processes: "2" +``` + +For complete list of Kong configurations please check the +[Kong configuration docs](https://docs.konghq.com/latest/configuration). + +> **Tip**: You can use the default [values.yaml](values.yaml) + +#### The `customEnv` section + +The `customEnv` section can be used to configure all custom properties of other than Kong. +Any key value put under this section translates to environment variables +that can be used in Kong's plugin configurations. Every key is upper-cased before setting the environment variable. + +An example: + +```yaml +kong: + customEnv: + api_token: + valueFrom: + secretKeyRef: + key: token + name: api_key + client_name: testClient +``` + +#### The `extraLabels` section + +The `extraLabels` section can be used to configure some extra labels that will be added to each Kubernetes object generated. + +For example, you can add the `acme.com/some-key: some-value` label to each Kubernetes object by putting the following in your Helm values: + +```yaml +extraLabels: + acme.com/some-key: some-value +``` + +## Kong Enterprise Parameters + +### Overview + +Kong Enterprise requires some additional configuration not needed when using +Kong Open-Source. To use Kong Enterprise, at the minimum, +you need to do the following: + +- Set `enterprise.enabled` to `true` in `values.yaml` file. +- Update values.yaml to use a Kong Enterprise image. +- Satisfy the two prerequisites below for Enterprise License and + Enterprise Docker Registry. +- (Optional) [set a `password` environment variable](#rbac) to create the + initial super-admin. Though not required, this is recommended for users that + wish to use RBAC, as it cannot be done after initial setup. + +Once you have these set, it is possible to install Kong Enterprise, +but please make sure to review the below sections for other settings that +you should consider configuring before installing Kong. + +Some of the more important configuration is grouped in sections +under the `.enterprise` key in values.yaml, though most enterprise-specific +configuration can be placed under the `.env` key. + +### Prerequisites + +#### Kong Enterprise License + +Kong Enterprise 2.3+ can run with or without a license. If you wish to run 2.3+ +without a license, you can skip this step and leave `enterprise.license_secret` +unset. In this case only a limited subset of features will be available. +Earlier versions require a license. + +If you have paid for a license, but you do not have a copy of yours, please +contact Kong Support. Once you have it, you will need to store it in a Secret: + +```bash +kubectl create secret generic kong-enterprise-license --from-file=license=./license.json +``` + +Set the secret name in `values.yaml`, in the `.enterprise.license_secret` key. +Please ensure the above secret is created in the same namespace in which +Kong is going to be deployed. + +#### Kong Enterprise Docker registry access + +Kong Enterprise versions 2.2 and earlier use a private Docker registry and +require a pull secret. **If you use 2.3 or newer, you can skip this step.** + +You should have received credentials to log into docker hub after +purchasing Kong Enterprise. After logging in, you can retrieve your API key +from \ \> Edit Profile \> API Key. Use this to create registry +secrets: + +```bash +kubectl create secret docker-registry kong-enterprise-edition-docker \ + --docker-server=hub.docker.io \ + --docker-username= \ + --docker-password= +secret/kong-enterprise-edition-docker created +``` + +Set the secret names in `values.yaml` in the `image.pullSecrets` section. +Again, please ensure the above secret is created in the same namespace in which +Kong is going to be deployed. + +### Service location hints + +Kong Enterprise add two GUIs, Kong Manager and the Kong Developer Portal, that +must know where other Kong services (namely the admin and files APIs) can be +accessed in order to function properly. Kong's default behavior for attempting +to locate these absent configuration is unlikely to work in common Kubernetes +environments. Because of this, you should set each of `admin_gui_url`, +`admin_gui_api_url`, `proxy_url`, `portal_api_url`, `portal_gui_host`, and +`portal_gui_protocol` under the `.env` key in values.yaml to locations where +each of their respective services can be accessed to ensure that Kong services +can locate one another and properly set CORS headers. See the +[Property Reference documentation](https://docs.konghq.com/enterprise/latest/property-reference/) +for more details on these settings. + +### RBAC + +You can create a default RBAC superuser when initially running `helm install` +by setting a `password` environment variable under `env` in values.yaml. It +should be a reference to a secret key containing your desired password. This +will create a `kong_admin` admin whose token and basic-auth password match the +value in the secret. For example: + +```yaml +env: + password: + valueFrom: + secretKeyRef: + name: kong-enterprise-superuser-password + key: password +``` + +If using the ingress controller, it needs access to the token as well, by +specifying `kong_admin_token` in its environment variables: + +```yaml +ingressController: + env: + kong_admin_token: + valueFrom: + secretKeyRef: + name: kong-enterprise-superuser-password + key: password +``` + +Although the above examples both use the initial super-admin, we recommend +[creating a less-privileged RBAC user](https://docs.konghq.com/enterprise/latest/kong-manager/administration/rbac/add-user/) +for the controller after installing. It needs at least workspace admin +privileges in its workspace (`default` by default, settable by adding a +`workspace` variable under `ingressController.env`). Once you create the +controller user, add its token to a secret and update your `kong_admin_token` +variable to use it. Remove the `password` variable from Kong's environment +variables and the secret containing the super-admin token after. + +### Sessions + +Login sessions for Kong Manager and the Developer Portal make use of +[the Kong Sessions plugin](https://docs.konghq.com/enterprise/latest/kong-manager/authentication/sessions). +When configured via values.yaml, their configuration must be stored in Secrets, +as it contains an HMAC key. + +Kong Manager's session configuration must be configured via values.yaml, +whereas this is optional for the Developer Portal on versions 0.36+. Providing +Portal session configuration in values.yaml provides the default session +configuration, which can be overridden on a per-workspace basis. + +```bash +cat admin_gui_session_conf +``` + +```json +{"cookie_name":"admin_session","cookie_samesite":"off","secret":"admin-secret-CHANGEME","cookie_secure":true,"storage":"kong"} +``` + +```bash +cat portal_session_conf +``` + +```json +{"cookie_name":"portal_session","cookie_samesite":"off","secret":"portal-secret-CHANGEME","cookie_secure":true,"storage":"kong"} +``` + +```bash +kubectl create secret generic kong-session-config --from-file=admin_gui_session_conf --from-file=portal_session_conf +``` + +```bash +secret/kong-session-config created +``` + +The exact plugin settings may vary in your environment. The `secret` should +always be changed for both configurations. + +After creating your secret, set its name in values.yaml in +`.enterprise.rbac.session_conf_secret`. If you create a Portal configuration, +add it at `env.portal_session_conf` using a secretKeyRef. + +### Email/SMTP + +Email is used to send invitations for +[Kong Admins](https://docs.konghq.com/enterprise/latest/kong-manager/networking/email) +and [Developers](https://docs.konghq.com/enterprise/latest/developer-portal/configuration/smtp). + +Email invitations rely on setting a number of SMTP settings at once. For +convenience, these are grouped under the `.enterprise.smtp` key in values.yaml. +Setting `.enterprise.smtp.disabled: true` will set `KONG_SMTP_MOCK=on` and +allow Admin/Developer invites to proceed without sending email. Note, however, +that these have limited functionality without sending email. + +If your SMTP server requires authentication, you must provide the `username` +and `smtp_password_secret` keys under `.enterprise.smtp.auth`. +`smtp_password_secret` must be a Secret containing an `smtp_password` key whose +value is your SMTP password. + +By default, SMTP uses `AUTH` `PLAIN` when you provide credentials. If your provider requires `AUTH LOGIN`, set `smtp_auth_type: login`. + +## Prometheus Operator integration + +The chart can configure a ServiceMonitor resource to instruct the [Prometheus +Operator](https://github.com/prometheus-operator/prometheus-operator) to +collect metrics from Kong Pods. To enable this, set +`serviceMonitor.enabled=true` in `values.yaml`. + +Kong exposes memory usage and connection counts by default. You can enable +traffic metrics for routes and services by configuring the [Prometheus +plugin](https://docs.konghq.com/hub/kong-inc/prometheus/). + +The ServiceMonitor requires an `enable-metrics: "true"` label on one of the +chart's Services to collect data. By default, this label is set on the proxy +Service. It should only be set on a single chart Service to avoid duplicate +data. If you disable the proxy Service (e.g. on a hybrid control plane instance +or Portal-only instance) and still wish to collect memory usage metrics, add +this label to another Service, e.g. on the admin API Service: + +``` +admin: + labels: + enable-metrics: "true" +``` + +## Argo CD Considerations + +The built-in database subchart (`postgresql.enabled` in values) is not +supported when installing the chart via Argo CD. + +Argo CD does not support the full Helm lifecycle. There is no distinction +between the initial install and upgrades. Both operations are a "sync" in Argo +terms. This affects when migration Jobs execute in database-backed Kong +installs. + +The chart sets the `Sync` and `BeforeHookCreation` deletion +[hook policies](https://argo-cd.readthedocs.io/en/stable/user-guide/resource_hooks/) +on the `init-migrations` and `pre-upgrade-migrations` Jobs. + +The `pre-upgrade-migrations` Job normally uses Helm's `pre-upgrade` policy. Argo +translates this to its `PreSync` policy, which would create the Job before all +sync phase resources. Doing this before various sync phase resources (such as +the ServiceAccount) are in place would prevent the Job from running +successfully. Overriding this with Argo's `Sync` policy starts the Job at the +same time as the upgraded Deployment Pods. The new Pods may fail to start +temporarily, but will eventually start normally once migrations complete. + +## Seeking help + +If you run into an issue, bug or have a question, please reach out to the Kong +community via [Kong Nation](https://discuss.konghq.com). +Please do not open issues in [this](https://github.com/helm/charts) repository +as the maintainers will not be notified and won't respond. diff --git a/charts/kong/kong/2.41.0/UPGRADE.md b/charts/kong/kong/2.41.0/UPGRADE.md new file mode 100644 index 0000000000..893527759a --- /dev/null +++ b/charts/kong/kong/2.41.0/UPGRADE.md @@ -0,0 +1,807 @@ +# Upgrade considerations + +New versions of the Kong chart may add significant new functionality or +deprecate/entirely remove old functionality. This document covers how and why +users should update their chart configuration to take advantage of new features +or migrate away from deprecated features. + +In general, breaking changes deprecate their old features before removing them +entirely. While support for the old functionality remains, the chart will show +a warning about the outdated configuration when running `helm +install/status/upgrade`. + +Note that not all versions contain breaking changes. If a version is not +present in the table of contents, it requires no version-specific changes when +upgrading from a previous version. + +## Table of contents + +- [Upgrade considerations for all versions](#upgrade-considerations-for-all-versions) +- [2.26.0](#2260) +- [2.19.0](#2190) +- [2.13.0](#2130) +- [2.8.0](#280) +- [2.7.0](#270) +- [2.4.0](#240) +- [2.3.0](#230) +- [2.2.0](#220) +- [2.1.0](#210) +- [2.0.0](#200) +- [1.14.0](#1140) +- [1.11.0](#1110) +- [1.10.0](#1100) +- [1.9.0](#190) +- [1.6.0](#160) +- [1.5.0](#150) +- [1.4.0](#140) +- [1.3.0](#130) + +## Upgrade considerations for all versions + +The chart automates the +[upgrade migration process](https://github.com/Kong/kong/blob/master/UPGRADE.md). +When running `helm upgrade`, the chart spawns an initial job to run `kong +migrations up` and then spawns new Kong pods with the updated version. Once +these pods become ready, they begin processing traffic and old pods are +terminated. Once this is complete, the chart spawns another job to run `kong +migrations finish`. + +If you split your Kong deployment across multiple Helm releases (to create +proxy-only and admin-only nodes, for example), you must +[set which migration jobs run based on your upgrade order](https://github.com/Kong/charts/blob/main/charts/kong/README.md#separate-admin-and-proxy-nodes). +However, this does not apply to hybrid mode, which can run both migrations but +requires [upgrading the control plane version +first](https://docs.konghq.com/gateway/latest/plan-and-deploy/hybrid-mode/#version-compatibility). + +While the migrations themselves are automated, the chart does not automatically +ensure that you follow the recommended upgrade path. If you are upgrading from +more than one minor Kong version back, check the [upgrade path +recommendations for Kong open source](https://github.com/Kong/kong/blob/master/UPGRADE.md#3-suggested-upgrade-path) +or [Kong Enterprise](https://docs.konghq.com/enterprise/latest/deployment/migrations/). + +Although not required, users should upgrade their chart version and Kong +version indepedently. In the even of any issues, this will help clarify whether +the issue stems from changes in Kubernetes resources or changes in Kong. + +Users may encounter an error when upgrading which displays a large block of +text ending with `field is immutable`. This is typically due to a bug with the +`init-migrations` job, which was not removed automatically prior to 1.5.0. +If you encounter this error, deleting any existing `init-migrations` jobs will +clear it. + +### Updates to CRDs + +Helm installs CRDs at initial install but [does not update them +after](https://github.com/helm/community/blob/main/hips/hip-0011.md). Some +chart releases include updates to CRDs that must be applied to successfully +upgrade. Because Helm does not handle these updates, you must manually apply +them before upgrading your release. + +``` kubectl apply -f +https://raw.githubusercontent.com/Kong/charts/kong-/charts/kong/crds/custom-resource-definitions.yaml +``` + +For example, if your release is 2.6.4, you would apply +`https://raw.githubusercontent.com/Kong/charts/kong-2.6.4/charts/kong/crds/custom-resource-definitions.yaml`. + +## 2.26.0 + +If you are using controller version 2.10 or lower and proxy version 3.3 or +higher in separate Deployments (such as when using the `ingress` chart), proxy +Pods will not become ready unless you override the default readiness endpoint: + +``` +readinessProbe: + httpGet: + path: /status +``` + +This section goes under the `gateway` section when using the `ingress` chart. + +2.26 changes the default proxy readiness endpoint to the `/status/ready` +endpoint introduced in Kong 3.3. This endpoint reports true when Kong has +configuration available, whereas the previous `/status` endpoint returned true +immediately after start, and could result in proxy instances attempting to +serve requests before they had configuration. + +The chart has logic to fall back to the older endpoint if the proxy and +controller versions do not work well with the new endpoint. However, the chart +detection cannot determine the controller version when the controller is in a +separate Deployment, and will always use the new endpoint if the Kong image +version is 3.3 or higher. + +Kong recommends Kong 3.3 and higher users update to controller 2.11 at their +earliest convenience to take advantage of the improved readiness behavior. + +## 2.19.0 + +2.19 sets a default [security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) +that declares a read-only root filesystem for Kong containers. The base Kong and KIC +images are compatible with this setting. The chart mounts temporary writeable +emptyDir filesystems for locations that require writeable files (`/tmp` and +`/kong_prefix/`). + +This setting limit attack surface and should be compatible with most +installations. However, if you use custom plugins that write to disk, you must +either mount a writeable emptyDir for them or override the new defaults by +setting: + +``` +containerSecurityContext: + readOnlyRootFilesystem: false +``` + +in your values.yaml. + +## 2.13.0 + +2.13.0 includes updated CRDs. You must [apply these manually](#updates-to-crds) +before upgrading an existing release. + +2.13 changes the default Kong tag to 3.0 and the default KIC tag to 2.6. We +recommend that you set these versions (`image.tag` and +`ingressController.image.tag`) in your values.yaml to allow updating the chart +without also updating the container versions. If you do update to these +container image versions, you should first review the Kong 3.0 breaking changes +(see the [open +source](https://github.com/Kong/kong/blob/master/CHANGELOG.md#300) and +[Enterprise](https://docs.konghq.com/gateway/changelog/#3000) Kong changelogs) +and the [ingress controller upgrade guide for Kong +3.x](https://docs.konghq.com/kubernetes-ingress-controller/2.6.x/guides/upgrade-kong-3x). + +Kong 3.0 requires KIC version 2.6 at minimum. It will not work with any +previous versions. Changes to regular expression paths in Kong 3.x furthermore +require changes to Ingresses that use regular expression paths in rules. + +## 2.8.0 + +### IngressClass controller name change requires manual delete + +2.8 updates the chart-managed IngressClass's controller name to match the +controller name used elsewhere in Kong's documenation. Controller names are +immutable, so Helm cannot actually update existing IngressClass resources. + +Prior to your upgrade, you must delete the existing IngressClass. Helm will +create a new IngressClass with the new controller name during the upgrade: + +``` +kubectl delete ingressclass +helm upgrade RELEASE_NAME kong/kong ... +``` + +Removing the IngressClass will not affect configuration: the controller +IngressClass implementation is still in progress, and it will still ingest +resources whose `ingress.class` annotation or `ingressClassName` value matches +the the `CONTROLLER_INGRESS_CLASS` value in the controller environment even if +no matching IngressClass exists. + +### Postgres subchart version update + +2.8 updates the Postgres subchart version from 8.6.8 to 11.1.15. This changes +a number of values.yaml keys and the default Postgres version. The previous +default Postgres version was [11.7.0-debian-10-r37](https://github.com/bitnami/charts/blob/590c6b0f4e07161614453b12efe71f22e0c00a46/bitnami/postgresql/values.yaml#L18). + +To use the new version on an existing install, you should [follow Bitnami's +instructions for updating values.yaml keys and upgrading their chart]() as well +as [the Postgres upgrade instructions](https://www.postgresql.org/docs/current/upgrading.html). + +You can alternately use the new chart without upgrading Postgres by setting +`postgresql.image.tag=11.7.0-debian-10-r37` or use the old version of the +chart. Helm documentation is unclear on whether ignoring a subchart version +change for a release is possible, so we recommend [dumping the +database](https://www.postgresql.org/docs/current/backup-dump.html) and +creating a separate release if you wish to continue using 8.6.8: + +``` +helm install my-release -f values.yaml --version 8.6.8 bitnami/postgresql +``` + +Afterwords, you will upgrade your Kong chart release with +`postgresql.enabled=false` and `env.pg_host` and `env.pg_password` set to the +appropriate hostname and Secret reference for your new release (these are set +automatically when the subchart is enabled, but will not be set automatically +with a separate release). + +## 2.7.0 + +2.7 updates CRDs to the version released in KIC 2.1.0. Helm does not upgrade +CRDs automatically; you must `kubectl apply -f https://raw.githubusercontent.com/Kong/charts/kong-2.7.0/charts/kong/crds/custom-resource-definitions.yaml` +manually before upgrading. + +You should not apply the updated CRDs until you are prepared to upgrade to KIC +2.1 or higher, and [must have first upgraded to 2.0](https://github.com/Kong/kubernetes-ingress-controller/blob/v2.1.1/CHANGELOG.md#breaking-changes) +and applied the [previous version of the CRDs](https://raw.githubusercontent.com/Kong/charts/kong-2.6.4/charts/kong/crds/custom-resource-definitions.yaml). + +## 2.4.0 + +### Disable ingress controller prior to 2.x upgrade when using PostgreSQL + +Chart version 2.4 is the first Kong chart version that defaults to the 2.x +series of ingress controller releases. 2.x uses a different leader election +system than 1.x. If both versions are running simultaneously, both controller +versions will attempt to interact with the admin API, potentially setting +inconsistent configuration in the database when PostgreSQL is the backend. + +If you are configured with the following: + +- ingressController.enabled=true +- postgresql.enabled=true + +and do not override the ingress controller version, you must perform the +upgrade in multiple steps: + +First, pin the controller version and upgrade to chart 2.4.0: + +```console +helm upgrade --wait \ + --set ingressController.image.tag= \ + --version 2.4.0 \ + --namespace \ + kong/kong +``` + +Second, temporarily disable the ingress controller: + +```console +helm upgrade --wait \ + --set ingressController.enabled=false \ + --set deployment.serviceaccount.create=true \ + --version 2.4.0 \ + --namespace \ + kong/kong +``` + +Finally, re-enable the ingress controller at the new version: + +```console +helm upgrade --wait \ + --set ingressController.enabled=true \ + --set ingressController.image.tag= \ + --version 2.4.0 \ + --namespace \ + kong/kong +``` + +While the controller is disabled, changes to Kubernetes configuration (Ingress +resources, KongPlugin resources, Service Endpoints, etc.) will not update Kong +proxy configuration. We recommend you establish an active maintenance window +under which to perform this upgrade and inform users and stakeholders so as to +avoid unexpected disruption. + +### Changed ServiceAccount configuration location + +2.4.0 moved ServiceAccount configuration from +`ingressController.serviceAccount` to `deployment.serviceAccount` to accomodate +configurations that required a ServiceAccount but did not use the controller. + +The chart now creates a ServiceAccount by default. When enabled, upgrade +migration hooks require the ServiceAccount, but Helm will not create it before +the hooks run, and the migration jobs will fail. To avoid this, first perform +an initial chart upgrade that does not update the Kong image version and sets +`migrations.preUpgrade=false` and `migrations.postUpgrade=false`. This will +create the account for future upgrades, and you can re-enable migrations and +upgrade your Kong version after. + +If you disable ServiceAccount or override its name, you must move your +configuration under `deployment.serviceAccount`. The chart will warn you if it +detects non-default configuration in the original location when you upgrade. +You can use `helm upgrade --dry-run` to see if you are affected before actually +upgrading. + +## 2.3.0 + +### Updated CRDs and CRD API version + +2.3.0 adds new and updated CRDs for KIC 2.x. These CRDs are compatible with +KIC 1.x also. The CRD API version is now v1, replacing the deprecated v1beta1, +to support Kubernetes 1.22 and onward. API version v1 requires Kubernetes 1.16 +and newer. + +Helm 2-style CRD management will upgrade CRDs automatically. You can check to +see if you are using Helm 2-style management by running: + +``` +kubectl get crd kongconsumers.configuration.konghq.com -o yaml | grep "meta.helm.sh/release-name" +``` + +If you see output, you are using Helm 2-style CRD management. + +Helm 3-style CRD management (the default) does not upgrade CRDs automatically. +You must apply the changes manually by running: + +``` +kubectl apply -f https://raw.githubusercontent.com/Kong/charts/kong-2.2.0/charts/kong/crds/custom-resource-definitions.yaml +``` + +Although not recommended, you can remain on an older Kubernetes version and not +upgrade your CRDs if you are using Helm 3-style CRD management. However, you +will not be able to run KIC 2.x, and these configurations are considered +unsupported. + +### Ingress controller feature detection + +2.3.0 includes some features that are enabled by default, but require KIC 2.x. +KIC 2.x is not yet the default ingress controller version because there are +currently only preview releases for it. To maintain compatibility with KIC 1.x, +the chart automatically detects the KIC image version and disables incompatible +features. This feature detection requires a semver image tag, and the chart +cannot render successfully if the image tag is not semver-compliant. + +Standard KIC images do use semver-compliant tags, and you do not need to make +any configuration changes if you use one. If you use a non-semver tag, such as +`next`, you must set the new `ingressController.image.effectiveSemver` field to +your approximate semver version. For example, if your `next` tag is for an +unreleased `2.1.0` KIC version, you should set `effectiveSemver: 2.1.0`. + +## 2.2.0 + +### Changes to pod disruption budget defaults + +Prior to 2.2.0, the default values.yaml included +`podDisruptionBudget.maxUnavailable: 50%`. This prevented setting +`podDisruptionBudget.minUnavailable` at all. To allow use of +`podDisruptionBudget.minUnavailable`, we have removed the +`podDisruptionBudget.maxUnavailable` default. If you previously relied on this +default (you set `podDisruptionBudget.enabled: true` but did not set +`podDisruptionBudget.maxUnavailable`), you now must explicitly set +`podDisruptionBudget.maxUnavailable: 50%` in your values.yaml. + +## 2.1.0 + +### Migration off Bintray + +Bintray, the Docker registry previously used for several images used by this +chart, is [sunsetting May 1, +2021](https://jfrog.com/blog/into-the-sunset-bintray-jcenter-gocenter-and-chartcenter/). + +The chart default `values.yaml` now uses the new Docker Hub repositories for all +affected images. You should check your release `values.yaml` files to confirm that +they do not still reference Bintray repositories. If they do, update them to +use the Docker Hub repositories now in the default `values.yaml`. + +## 2.0.0 + +### Support for Helm 2 dropped + +2.0.0 takes advantage of template functionality that is only available in Helm +3 and reworks values defaults to target Helm 3 CRD handling, and requires Helm +3 as such. If you are not already using Helm 3, you must migrate to it before +updating to 2.0.0 or later: + +https://helm.sh/docs/topics/v2_v3_migration/ + +If desired, you can migrate your Kong chart releases without migrating charts' +releases. + +### Support for deprecated 1.x features removed + +Several previous 1.x chart releases reworked sections of values.yaml while +maintaining support for the older version of those settings. 2.x drops support +for the older versions of these settings entirely: + +* [Portal auth settings](#removal-of-dedicated-portal-authentication-configuration-parameters) +* [The `runMigrations` setting](#changes-to-migration-job-configuration) +* [Single-stack admin API Service configuration](#changes-to-kong-service-configuration) +* [Multi-host proxy configuration](#removal-of-multi-host-proxy-ingress) + +Each deprecated setting is accompanied by a warning that appears at the end of +`helm upgrade` output on a 1.x release: + +``` +WARNING: You are currently using legacy ... +``` + +If you do not see any such warnings when upgrading a release using chart +1.15.0, you are not using deprecated configuration and are ready to upgrade to +2.0.0. If you do see these warnings, follow the linked instructions to migrate +to the current settings format. + +## 1.14.0 + +### Removal of multi-host proxy Ingress + +Most of the chart's Ingress templates support a single hostname and TLS Secret. +The proxy Ingress template originally differed, and allowed multiple hostnames +and TLS configurations. As of chart 1.14.0, we have deprecated the unique proxy +Ingress configuration; it is now identical to all other Kong services. If you +do not need to configure multiple Ingress rules for your proxy, you will +change: + +```yaml +ingress: + hosts: ["proxy.kong.example"] + tls: + - hosts: + - proxy.kong.example + secretName: example-tls-secret + path: / +``` +to: + +```yaml +ingress: + tls: example-tls-secret + hostname: proxy.kong.example + path: / +``` +We plan to remove support for the multi-host configuration entirely in version +2.0 of the chart. If you currently use multiple hosts, we recommend that you +either: +- Define Ingresses for each application, e.g. if you proxy applicationA at + `foo.kong.example` and applicationB at `bar.kong.example`, you deploy those + applications with their own Ingress resources that target the proxy. +- Define a multi-host Ingress manually. Before upgrading, save your current + proxy Ingress, delete labels from the saved copy, and set + `proxy.ingress.enabled=false`. After upgrading, create your Ingress from the + saved copy and edit it directly to add new rules. + +We expect that most users do not need a built-in multi-host proxy Ingress or +even a proxy Ingress at all: the old configuration predates the Kong Ingress +Controller and is most useful if you place Kong behind some other controller. +If you are interested in preserving this functionality, please [discuss your +use case with us](https://github.com/Kong/charts/issues/73). If there is +sufficient interest, we will explore options for continuing to support the +original proxy Ingress configuration format. + +### Default custom server block replaced with status listen + +Earlier versions of the chart included [a custom server block](https://github.com/Kong/charts/blob/kong-1.13.0/charts/kong/templates/config-custom-server-blocks.yaml) +to provide `/status` and `/metrics` endpoints. This server block simplified +RBAC-enabled Enterprise deployments by providing access to these endpoints +outside the (protected) admin API. + +Current versions (Kong 1.4.0+ and Kong Enterprise 1.5.0+) have a built-in +status listen that provides the same functionality, and chart 1.14.0 uses it +for readiness/liveness probes and the Prometheus service monitor. + +If you are using a version that supports the new status endpoint, you do not +need to make any changes to your values unless you include `readinessProbe` and +`livenessProbe` in them. If you do, you must change the port from `metrics` to +`status`. + +If you are using an older version that does not support the status listen, you +will need to: +- Create the server block ConfigMap independent of the chart. You will need to + set the ConfigMap name and namespace manually and remove the labels block. +- Add an `extraConfigMaps` values entry for your ConfigMap. +- Set `env.nginx_http_include` to `/path/to/your/mount/servers.conf`. +- Add the [old readiness/liveness probe blocks](https://github.com/Kong/charts/blob/kong-1.13.0/charts/kong/values.yaml#L437-L458) + to your values.yaml. +- If you use the Prometheus service monitor, edit it after installing the chart + and set `targetPort` to `9542`. This cannot be set from values.yaml, but Helm + 3 will preserve the change on subsequent upgrades. + +## 1.11.0 + +### `KongCredential` custom resources no longer supported + +1.11.0 updates the default Kong Ingress Controller version to 1.0. Controller +1.0 removes support for the deprecated KongCredential resource. Before +upgrading to chart 1.11.0, you must convert existing KongCredential resources +to [credential Secrets](https://github.com/Kong/kubernetes-ingress-controller/blob/next/docs/guides/using-consumer-credential-resource.md#provision-a-consumer). + +Custom resource management varies depending on your exact chart configuration. +By default, Helm 3 only creates CRDs in the `crds` directory if they are not +already present, and does not modify or remove them after. If you use this +management method, you should create a manifest file that contains [only the +KongCredential CRD](https://github.com/Kong/charts/blob/kong-1.10.0/charts/kong/crds/custom-resource-definitions.yaml#L35-L68) +and then [delete it](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#delete-a-customresourcedefinition). + +Helm 2 and Helm 3 both allow managing CRDs via the chart. In Helm 2, this is +required; in Helm 3, it is optional. When using this method, only a single +release will actually manage the CRD. Check to see which release has +`ingressController.installCRDs: true` to determine which does so if you have +multiple releases. When using this management method, upgrading a release to +chart 1.11.0 will delete the KongCredential CRD during the upgrade, which will +_delete any existing KongCredential resources_. To avoid losing configuration, +check to see if your CRD is managed: + +``` +kubectl get crd kongcredentials.configuration.konghq.com -o yaml | grep "app.kubernetes.io/managed-by: Helm" +``` + +If that command returns output, your CRD is managed and you must convert to +credential Secrets before upgrading (you should do so regardless, but are not +at risk of losing data, and can downgrade to an older chart version if you have +issues). + +### Changes to CRDs + +Controller 1.0 [introduces a status field](https://github.com/Kong/kubernetes-ingress-controller/blob/main/CHANGELOG.md#added) +for its custom resources. By default, Helm 3 does not apply updates to custom +resource definitions if those definitions are already present on the Kubernetes +API server (and they will be if you are upgrading a release from a previous +chart version). To update your custom resources: + +``` +kubectl apply -f https://raw.githubusercontent.com/Kong/charts/main/charts/kong/crds/custom-resource-definitions.yaml +``` + +### Deprecated controller flags/environment variables and annotations removed + +Kong Ingress Controller 0.x versions had a number of deprecated +flags/environment variables and annotations. Version 1.0 removes support for +these, and you must update your configuration to use their modern equivalents +before upgrading to chart 1.11.0. + +The [controller changelog](https://github.com/Kong/kubernetes-ingress-controller/blob/master/CHANGELOG.md#breaking-changes) +provides links to lists of deprecated configuration and their replacements. + +## 1.10.0 + +### `KongClusterPlugin` replaces global `KongPlugin`s + +Kong Ingress Controller 0.10.0 no longer supports `KongPlugin`s with a `global: true` label. See the [KIC changelog for 0.10.0](https://github.com/Kong/kubernetes-ingress-controller/blob/main/CHANGELOG.md#0100---20200915) for migration hints. + +### Dropping support for resources not specifying an ingress class + +Kong Ingress Controller 0.10.0 drops support for certain kinds of resources without a `kubernetes.io/ingress.class` annotation. See the [KIC changelog for 0.10.0](https://github.com/Kong/kubernetes-ingress-controller/blob/main/CHANGELOG.md#0100---20200915) for the exact list of those kinds, and for possible migration paths. + +## 1.9.0 + +### New image for Enterprise controller-managed DB-less deployments + +As of Kong Enterprise 2.1.3.0, there is no longer a separate image +(`kong-enterprise-k8s`) for controller-managed DB-less deployments. All Kong +Enterprise deployments now use the `kong-enterprise-edition` image. + +Existing users of the `kong-enterprise-k8s` image can use the latest +`kong-enterprise-edition` image as a drop-in replacement for the +`kong-enterprise-k8s` image. You will also need to [create a Docker registry +secret](https://github.com/Kong/charts/blob/main/charts/kong/README.md#kong-enterprise-docker-registry-access) +for the `kong-enterprise-edition` registry and add it to `image.pullSecrets` in +values.yaml if you do not have one already. + +### Changes to wait-for-postgres image + +Prior to 1.9.0, the chart launched a busybox initContainer for migration Pods +to check Postgres' reachability [using +netcat](https://github.com/Kong/charts/blob/kong-1.8.0/charts/kong/templates/_helpers.tpl#L626). + +As of 1.9.0, the chart uses a [bash +script](https://github.com/Kong/charts/blob/kong-1.9.0/charts/kong/templates/wait-for-postgres-script.yaml) +to perform the same connectivity check. The default `waitImage.repository` +value is now `bash` rather than `busybox`. Double-check your values.yaml to +confirm that you do not set `waitImage.repository` and `waitImage.tag` to the +old defaults: if you do, remove that configuration before upgrading. + +The Helm upgrade cycle requires this script be available for upgrade jobs. On +existing installations, you must first perform an initial `helm upgrade --set +migrations.preUpgrade=false --migrations.postUpgrade=false` to chart 1.9.0. +Perform this initial upgrade without making changes to your Kong image version: +if you are upgrading Kong along with the chart, perform a separate upgrade +after with the migration jobs re-enabled. + +If you do not override `waitImage.repository` in your releases, you do not need +to make any other configuration changes when upgrading to 1.9.0. + +If you do override `waitImage.repository` to use a custom image, you must +switch to a custom image that provides a `bash` executable. Note that busybox +images, or images derived from it, do _not_ include a `bash` executable. We +recommend switching to an image derived from the public bash Docker image or a +base operating system image that provides a `bash` executable. + +## 1.6.0 + +### Changes to Custom Resource Definitions + +The KongPlugin and KongClusterPlugin resources have changed. Helm 3's CRD +management system does not modify CRDs during `helm upgrade`, and these must be +updated manually: + +``` +kubectl apply -f https://raw.githubusercontent.com/Kong/charts/kong-1.6.0/charts/kong/crds/custom-resource-definitions.yaml +``` + +Existing plugin resources do not require changes; the CRD update only adds new +fields. + +### Removal of default security context UID setting + +Versions of Kong prior to 2.0 and Kong Enterprise prior to 1.3 use Docker +images that required setting a UID via Kubernetes in some environments +(primarily OpenShift). This is no longer necessary with modern Docker images +and can cause issues depending on other environment settings, so it was +removed. + +Most users should not need to take any action, but if you encounter permissions +errors when upgrading (`kubectl describe pod PODNAME` should contain any), you +can restore it by adding the following to your values.yaml: + +``` +securityContext: + runAsUser: 1000 +``` + +## 1.5.0 + +### PodSecurityPolicy defaults to read-only root filesystem + +1.5.0 defaults to using a read-only root container filesystem if +`podSecurityPolicy.enabled: true` is set in values.yaml. This improves +security, but is incompatible with Kong Enterprise versions prior to 1.5. If +you use an older version and enable PodSecurityPolicy, you must set +`podSecurityPolicy.spec.readOnlyRootFilesystem: false`. + +Kong open-source and Kong for Kubernetes Enterprise are compatible with a +read-only root filesystem on all versions. + +### Changes to migration job configuration + +Previously, all migration jobs were enabled/disabled through a single +`runMigrations` setting. 1.5.0 splits these into toggles for each of the +individual upgrade migrations: + +``` +migrations: + preUpgrade: true + postUpgrade: true +``` + +Initial migration jobs are now only run during `helm install` and are deleted +automatically when users first run `helm upgrade`. + +Users should replace `runMigrations` with the above block from the latest +values.yaml. + +The new format addresses several needs: +* The initial migrations job are only created during the initial install, + preventing [conflicts on upgrades](https://github.com/Kong/charts/blob/main/charts/kong/FAQs.md#running-helm-upgrade-fails-because-of-old-init-migrations-job). +* The upgrade migrations jobs can be disabled as need for managing + [multi-release clusters](https://github.com/Kong/charts/blob/main/charts/kong/README.md#separate-admin-and-proxy-nodes). + This enables management of clusters that have nodes with different roles, + e.g. nodes that only run the proxy and nodes that only run the admin API. +* Migration jobs now allow specifying annotations, and provide a default set + of annotations that disable some service mesh sidecars. Because sidecar + containers do not terminate, they [prevent the jobs from completing](https://github.com/kubernetes/kubernetes/issues/25908). + +## 1.4.0 + +### Changes to default Postgres permissions + +The [Postgres sub-chart](https://github.com/bitnami/charts/tree/master/bitnami/postgresql) +used by this chart has modified the way their chart handles file permissions. +This is not an issue for new installations, but prevents Postgres from starting +if its PVC was created with an older version. If affected, your Postgres pod +logs will show: + +``` +postgresql 19:16:04.03 INFO ==> ** Starting PostgreSQL ** +2020-03-27 19:16:04.053 GMT [1] FATAL: data directory "/bitnami/postgresql/data" has group or world access +2020-03-27 19:16:04.053 GMT [1] DETAIL: Permissions should be u=rwx (0700). +``` + +You can restore the old permission handling behavior by adding two settings to +the `postgresql` block in values.yaml: + +```yaml +postgresql: + enabled: true + postgresqlDataDir: /bitnami/postgresql/data + volumePermissions: + enabled: true +``` + +For background, see https://github.com/helm/charts/issues/13651 + +### `strip_path` now defaults to `false` for controller-managed routes + +1.4.0 defaults to version 0.8 of the ingress controller, which changes the +default value of the `strip_path` route setting from `true` to `false`. To +understand how this works in practice, compare the upstream path for these +requests when `strip_path` is toggled: + +| Ingress path | `strip_path` | Request path | Upstream path | +|--------------|--------------|--------------|---------------| +| /foo/bar | true | /foo/bar/baz | /baz | +| /foo/bar | false | /foo/bar/baz | /foo/bar/baz | + +This change brings the controller in line with the Kubernetes Ingress +specification, which expects that controllers will not modify the request +before passing it upstream unless explicitly configured to do so. + +To preserve your existing route handling, you should add this annotation to +your ingress resources: + +``` +konghq.com/strip-path: "true" +``` + +This is a new annotation that is equivalent to the `route.strip_path` setting +in KongIngress resources. Note that if you have already set this to `false`, +you should leave it as-is and not add an annotation to the ingress. + +### Changes to Kong service configuration + +1.4.0 reworks the templates and configuration used to generate Kong +configuration and Kuberenetes resources for Kong's services (the admin API, +proxy, Developer Portal, etc.). For the admin API, this requires breaking +changes to the configuration format in values.yaml. Prior to 1.4.0, the admin +API allowed a single listen only, which could be toggled between HTTPS and +HTTP: + +```yaml +admin: + enabled: false # create Service + useTLS: true + servicePort: 8444 + containerPort: 8444 +``` +In 1.4.0+, the admin API allows enabling or disabling the HTTP and TLS listens +independently. The equivalent of the above configuration is: + +```yaml +admin: + enabled: false # create Service + http: + enabled: false # create HTTP listen + servicePort: 8001 + containerPort: 8001 + parameters: [] + + tls: + enabled: true # create HTTPS listen + servicePort: 8444 + containerPort: 8444 + parameters: + - http2 +``` +All Kong services now support `SERVICE.enabled` parameters: these allow +disabling the creation of a Kubernetes Service resource for that Kong service, +which is useful in configurations where nodes have different roles, e.g. where +some nodes only handle proxy traffic and some only handle admin API traffic. To +disable a Kong service completely, you should also set `SERVICE.http.enabled: +false` and `SERVICE.tls.enabled: false`. Disabling creation of the Service +resource only leaves the Kong service enabled, but only accessible within its +pod. The admin API is configured with only Service creation disabled to allow +the ingress controller to access it without allowing access from other pods. + +Services now also include a new `parameters` section that allows setting +additional listen options, e.g. the `reuseport` and `backlog=16384` parameters +from the [default 2.0.0 proxy +listen](https://github.com/Kong/kong/blob/2.0.0/kong.conf.default#L186). For +compatibility with older Kong versions, the chart defaults do not enable most +of the newer parameters, only HTTP/2 support. Users of versions 1.3.0 and newer +can safely add the new parameters. + +## 1.3.0 + +### Removal of dedicated Portal authentication configuration parameters + +1.3.0 deprecates the `enterprise.portal.portal_auth` and +`enterprise.portal.session_conf_secret` settings in values.yaml in favor of +placing equivalent configuration under `env`. These settings are less important +in Kong Enterprise 0.36+, as they can both be set per workspace in Kong +Manager. + +These settings provide the default settings for Portal instances: when the +"Authentication plugin" and "Session Config" dropdowns at +https://manager.kong.example/WORKSPACE/portal/settings/ are set to "Default", +the settings from `KONG_PORTAL_AUTH` and `KONG_PORTAL_SESSION_CONF` are used. +If these environment variables are not set, the defaults are to use +`basic-auth` and `{}` (which applies the [session plugin default +configuration](https://docs.konghq.com/hub/kong-inc/session/)). + +If you set nonstandard defaults and wish to keep using these settings, or use +Kong Enterprise 0.35 (which did not provide a means to set per-workspace +session configuration) you should convert them to environment variables. For +example, if you currently have: + +```yaml +portal: + enabled: true + portal_auth: basic-auth + session_conf_secret: portal-session +``` +You should remove the `portal_auth` and `session_conf_secret` entries and +replace them with their equivalents under the `env` block: + +```yaml +env: + portal_auth: basic-auth + portal_session_conf: + valueFrom: + secretKeyRef: + name: portal-session + key: portal_session_conf +``` diff --git a/charts/kong/kong/2.41.0/app-readme.md b/charts/kong/kong/2.41.0/app-readme.md new file mode 100644 index 0000000000..19d811f902 --- /dev/null +++ b/charts/kong/kong/2.41.0/app-readme.md @@ -0,0 +1,7 @@ +# Kong for Kubernetes + +[Kong](https://konghq.com) makes connecting APIs and microservices across hybrid or multi-cloud environments easier and faster than ever. We power trillions of API transactions for leading organizations globally through our end-to-end API platform. + +Kong Gateway is the world’s most popular open source API gateway, built for multi-cloud and hybrid, and optimized for microservices and distributed architectures. It is built on top of a lightweight proxy to deliver unparalleled latency, performance and scalability for all your microservice applications regardless of where they run. It allows you to exercise granular control over your traffic with Kong’s plugin architecture + +The Kong Enterprise Service Control Platform brokers an organization’s information across all services. Built on top of Kong’s battle-tested open source core, Kong Enterprise enables customers to simplify management of APIs and microservices across hybrid-cloud and multi-cloud deployments. With Kong Enterprise, customers can proactively identify anomalies and threats, automate tasks, and improve visibility across their entire organization. diff --git a/charts/kong/kong/2.41.0/charts/postgresql/.helmignore b/charts/kong/kong/2.41.0/charts/postgresql/.helmignore new file mode 100644 index 0000000000..f0c1319444 --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/.helmignore @@ -0,0 +1,21 @@ +# 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 diff --git a/charts/kong/kong/2.41.0/charts/postgresql/Chart.lock b/charts/kong/kong/2.41.0/charts/postgresql/Chart.lock new file mode 100644 index 0000000000..123dedb6ba --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: common + repository: https://charts.bitnami.com/bitnami + version: 2.0.4 +digest: sha256:ec5726c5d8f1e474cc6c9ca90c18efc35f4dbd15ccaf2df148764947d5ad6a6c +generated: "2022-10-25T14:40:27.273494162Z" diff --git a/charts/kong/kong/2.41.0/charts/postgresql/Chart.yaml b/charts/kong/kong/2.41.0/charts/postgresql/Chart.yaml new file mode 100644 index 0000000000..109e6b2dd3 --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/Chart.yaml @@ -0,0 +1,30 @@ +annotations: + category: Database +apiVersion: v2 +appVersion: 14.5.0 +dependencies: +- name: common + repository: https://charts.bitnami.com/bitnami + tags: + - bitnami-common + version: 2.x.x +description: PostgreSQL (Postgres) is an open source object-relational database known + for reliability and data integrity. ACID-compliant, it supports foreign keys, joins, + views, triggers and stored procedures. +home: https://github.com/bitnami/charts/tree/main/bitnami/postgresql +icon: https://bitnami.com/assets/stacks/postgresql/img/postgresql-stack-220x234.png +keywords: +- postgresql +- postgres +- database +- sql +- replication +- cluster +maintainers: +- name: Bitnami + url: https://github.com/bitnami/charts +name: postgresql +sources: +- https://github.com/bitnami/containers/tree/main/bitnami/postgresql +- https://www.postgresql.org/ +version: 11.9.13 diff --git a/charts/kong/kong/2.41.0/charts/postgresql/README.md b/charts/kong/kong/2.41.0/charts/postgresql/README.md new file mode 100644 index 0000000000..28eed1c57f --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/README.md @@ -0,0 +1,683 @@ + + +# PostgreSQL packaged by Bitnami + +PostgreSQL (Postgres) is an open source object-relational database known for reliability and data integrity. ACID-compliant, it supports foreign keys, joins, views, triggers and stored procedures. + +[Overview of PostgreSQL](http://www.postgresql.org) + +Trademarks: This software listing is packaged by Bitnami. The respective trademarks mentioned in the offering are owned by the respective companies, and use of them does not imply any affiliation or endorsement. + +## TL;DR + +```bash +helm repo add my-repo https://charts.bitnami.com/bitnami +helm install my-release my-repo/postgresql +``` + +## Introduction + +This chart bootstraps a [PostgreSQL](https://github.com/bitnami/containers/tree/main/bitnami/postgresql) deployment on a [Kubernetes](https://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + +For HA, please see [this repo](https://github.com/bitnami/charts/tree/main/bitnami/postgresql-ha) + +Bitnami charts can be used with [Kubeapps](https://kubeapps.dev/) for deployment and management of Helm Charts in clusters. + +## Prerequisites + +- Kubernetes 1.19+ +- Helm 3.2.0+ +- PV provisioner support in the underlying infrastructure + +## Installing the Chart + +To install the chart with the release name `my-release`: + +```bash +helm install my-release my-repo/postgresql +``` + +The command deploys PostgreSQL on the Kubernetes cluster in the default configuration. The [Parameters](#parameters) section lists the parameters that can be configured during installation. + +> **Tip**: List all releases using `helm list` + +## Uninstalling the Chart + +To uninstall/delete the `my-release` deployment: + +```console +helm delete my-release +``` + +The command removes all the Kubernetes components but PVC's associated with the chart and deletes the release. + +To delete the PVC's associated with `my-release`: + +```bash +kubectl delete pvc -l release=my-release +``` + +> **Note**: Deleting the PVC's will delete postgresql data as well. Please be cautious before doing it. + +## Parameters + +### Global parameters + +| Name | Description | Value | +| ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----- | +| `global.imageRegistry` | Global Docker image registry | `""` | +| `global.imagePullSecrets` | Global Docker registry secret names as an array | `[]` | +| `global.storageClass` | Global StorageClass for Persistent Volume(s) | `""` | +| `global.postgresql.auth.postgresPassword` | Password for the "postgres" admin user (overrides `auth.postgresPassword`) | `""` | +| `global.postgresql.auth.username` | Name for a custom user to create (overrides `auth.username`) | `""` | +| `global.postgresql.auth.password` | Password for the custom user to create (overrides `auth.password`) | `""` | +| `global.postgresql.auth.database` | Name for a custom database to create (overrides `auth.database`) | `""` | +| `global.postgresql.auth.existingSecret` | Name of existing secret to use for PostgreSQL credentials (overrides `auth.existingSecret`). | `""` | +| `global.postgresql.auth.secretKeys.adminPasswordKey` | Name of key in existing secret to use for PostgreSQL credentials (overrides `auth.secretKeys.adminPasswordKey`). Only used when `global.postgresql.auth.existingSecret` is set. | `""` | +| `global.postgresql.auth.secretKeys.userPasswordKey` | Name of key in existing secret to use for PostgreSQL credentials (overrides `auth.secretKeys.userPasswordKey`). Only used when `global.postgresql.auth.existingSecret` is set. | `""` | +| `global.postgresql.auth.secretKeys.replicationPasswordKey` | Name of key in existing secret to use for PostgreSQL credentials (overrides `auth.secretKeys.replicationPasswordKey`). Only used when `global.postgresql.auth.existingSecret` is set. | `""` | +| `global.postgresql.service.ports.postgresql` | PostgreSQL service port (overrides `service.ports.postgresql`) | `""` | + + +### Common parameters + +| Name | Description | Value | +| ------------------------ | -------------------------------------------------------------------------------------------- | --------------- | +| `kubeVersion` | Override Kubernetes version | `""` | +| `nameOverride` | String to partially override common.names.fullname template (will maintain the release name) | `""` | +| `fullnameOverride` | String to fully override common.names.fullname template | `""` | +| `clusterDomain` | Kubernetes Cluster Domain | `cluster.local` | +| `extraDeploy` | Array of extra objects to deploy with the release (evaluated as a template) | `[]` | +| `commonLabels` | Add labels to all the deployed resources | `{}` | +| `commonAnnotations` | Add annotations to all the deployed resources | `{}` | +| `diagnosticMode.enabled` | Enable diagnostic mode (all probes will be disabled and the command will be overridden) | `false` | +| `diagnosticMode.command` | Command to override all containers in the statefulset | `["sleep"]` | +| `diagnosticMode.args` | Args to override all containers in the statefulset | `["infinity"]` | + + +### PostgreSQL common parameters + +| Name | Description | Value | +| ---------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | +| `image.registry` | PostgreSQL image registry | `docker.io` | +| `image.repository` | PostgreSQL image repository | `bitnami/postgresql` | +| `image.tag` | PostgreSQL image tag (immutable tags are recommended) | `14.5.0-debian-11-r35` | +| `image.digest` | PostgreSQL image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag | `""` | +| `image.pullPolicy` | PostgreSQL image pull policy | `IfNotPresent` | +| `image.pullSecrets` | Specify image pull secrets | `[]` | +| `image.debug` | Specify if debug values should be set | `false` | +| `auth.enablePostgresUser` | Assign a password to the "postgres" admin user. Otherwise, remote access will be blocked for this user | `true` | +| `auth.postgresPassword` | Password for the "postgres" admin user. Ignored if `auth.existingSecret` with key `postgres-password` is provided | `""` | +| `auth.username` | Name for a custom user to create | `""` | +| `auth.password` | Password for the custom user to create. Ignored if `auth.existingSecret` with key `password` is provided | `""` | +| `auth.database` | Name for a custom database to create | `""` | +| `auth.replicationUsername` | Name of the replication user | `repl_user` | +| `auth.replicationPassword` | Password for the replication user. Ignored if `auth.existingSecret` with key `replication-password` is provided | `""` | +| `auth.existingSecret` | Name of existing secret to use for PostgreSQL credentials. `auth.postgresPassword`, `auth.password`, and `auth.replicationPassword` will be ignored and picked up from this secret. The secret might also contains the key `ldap-password` if LDAP is enabled. `ldap.bind_password` will be ignored and picked from this secret in this case. | `""` | +| `auth.secretKeys.adminPasswordKey` | Name of key in existing secret to use for PostgreSQL credentials. Only used when `auth.existingSecret` is set. | `postgres-password` | +| `auth.secretKeys.userPasswordKey` | Name of key in existing secret to use for PostgreSQL credentials. Only used when `auth.existingSecret` is set. | `password` | +| `auth.secretKeys.replicationPasswordKey` | Name of key in existing secret to use for PostgreSQL credentials. Only used when `auth.existingSecret` is set. | `replication-password` | +| `auth.usePasswordFiles` | Mount credentials as a files instead of using an environment variable | `false` | +| `architecture` | PostgreSQL architecture (`standalone` or `replication`) | `standalone` | +| `replication.synchronousCommit` | Set synchronous commit mode. Allowed values: `on`, `remote_apply`, `remote_write`, `local` and `off` | `off` | +| `replication.numSynchronousReplicas` | Number of replicas that will have synchronous replication. Note: Cannot be greater than `readReplicas.replicaCount`. | `0` | +| `replication.applicationName` | Cluster application name. Useful for advanced replication settings | `my_application` | +| `containerPorts.postgresql` | PostgreSQL container port | `5432` | +| `audit.logHostname` | Log client hostnames | `false` | +| `audit.logConnections` | Add client log-in operations to the log file | `false` | +| `audit.logDisconnections` | Add client log-outs operations to the log file | `false` | +| `audit.pgAuditLog` | Add operations to log using the pgAudit extension | `""` | +| `audit.pgAuditLogCatalog` | Log catalog using pgAudit | `off` | +| `audit.clientMinMessages` | Message log level to share with the user | `error` | +| `audit.logLinePrefix` | Template for log line prefix (default if not set) | `""` | +| `audit.logTimezone` | Timezone for the log timestamps | `""` | +| `ldap.enabled` | Enable LDAP support | `false` | +| `ldap.server` | IP address or name of the LDAP server. | `""` | +| `ldap.port` | Port number on the LDAP server to connect to | `""` | +| `ldap.prefix` | String to prepend to the user name when forming the DN to bind | `""` | +| `ldap.suffix` | String to append to the user name when forming the DN to bind | `""` | +| `ldap.basedn` | Root DN to begin the search for the user in | `""` | +| `ldap.binddn` | DN of user to bind to LDAP | `""` | +| `ldap.bindpw` | Password for the user to bind to LDAP | `""` | +| `ldap.searchAttribute` | Attribute to match against the user name in the search | `""` | +| `ldap.searchFilter` | The search filter to use when doing search+bind authentication | `""` | +| `ldap.scheme` | Set to `ldaps` to use LDAPS | `""` | +| `ldap.tls.enabled` | Se to true to enable TLS encryption | `false` | +| `ldap.uri` | LDAP URL beginning in the form `ldap[s]://host[:port]/basedn`. If provided, all the other LDAP parameters will be ignored. | `""` | +| `postgresqlDataDir` | PostgreSQL data dir folder | `/bitnami/postgresql/data` | +| `postgresqlSharedPreloadLibraries` | Shared preload libraries (comma-separated list) | `pgaudit` | +| `shmVolume.enabled` | Enable emptyDir volume for /dev/shm for PostgreSQL pod(s) | `true` | +| `shmVolume.sizeLimit` | Set this to enable a size limit on the shm tmpfs | `""` | +| `tls.enabled` | Enable TLS traffic support | `false` | +| `tls.autoGenerated` | Generate automatically self-signed TLS certificates | `false` | +| `tls.preferServerCiphers` | Whether to use the server's TLS cipher preferences rather than the client's | `true` | +| `tls.certificatesSecret` | Name of an existing secret that contains the certificates | `""` | +| `tls.certFilename` | Certificate filename | `""` | +| `tls.certKeyFilename` | Certificate key filename | `""` | +| `tls.certCAFilename` | CA Certificate filename | `""` | +| `tls.crlFilename` | File containing a Certificate Revocation List | `""` | + + +### PostgreSQL Primary parameters + +| Name | Description | Value | +| -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | --------------------- | +| `primary.name` | Name of the primary database (eg primary, master, leader, ...) | `primary` | +| `primary.configuration` | PostgreSQL Primary main configuration to be injected as ConfigMap | `""` | +| `primary.pgHbaConfiguration` | PostgreSQL Primary client authentication configuration | `""` | +| `primary.existingConfigmap` | Name of an existing ConfigMap with PostgreSQL Primary configuration | `""` | +| `primary.extendedConfiguration` | Extended PostgreSQL Primary configuration (appended to main or default configuration) | `""` | +| `primary.existingExtendedConfigmap` | Name of an existing ConfigMap with PostgreSQL Primary extended configuration | `""` | +| `primary.initdb.args` | PostgreSQL initdb extra arguments | `""` | +| `primary.initdb.postgresqlWalDir` | Specify a custom location for the PostgreSQL transaction log | `""` | +| `primary.initdb.scripts` | Dictionary of initdb scripts | `{}` | +| `primary.initdb.scriptsConfigMap` | ConfigMap with scripts to be run at first boot | `""` | +| `primary.initdb.scriptsSecret` | Secret with scripts to be run at first boot (in case it contains sensitive information) | `""` | +| `primary.initdb.user` | Specify the PostgreSQL username to execute the initdb scripts | `""` | +| `primary.initdb.password` | Specify the PostgreSQL password to execute the initdb scripts | `""` | +| `primary.standby.enabled` | Whether to enable current cluster's primary as standby server of another cluster or not | `false` | +| `primary.standby.primaryHost` | The Host of replication primary in the other cluster | `""` | +| `primary.standby.primaryPort` | The Port of replication primary in the other cluster | `""` | +| `primary.extraEnvVars` | Array with extra environment variables to add to PostgreSQL Primary nodes | `[]` | +| `primary.extraEnvVarsCM` | Name of existing ConfigMap containing extra env vars for PostgreSQL Primary nodes | `""` | +| `primary.extraEnvVarsSecret` | Name of existing Secret containing extra env vars for PostgreSQL Primary nodes | `""` | +| `primary.command` | Override default container command (useful when using custom images) | `[]` | +| `primary.args` | Override default container args (useful when using custom images) | `[]` | +| `primary.livenessProbe.enabled` | Enable livenessProbe on PostgreSQL Primary containers | `true` | +| `primary.livenessProbe.initialDelaySeconds` | Initial delay seconds for livenessProbe | `30` | +| `primary.livenessProbe.periodSeconds` | Period seconds for livenessProbe | `10` | +| `primary.livenessProbe.timeoutSeconds` | Timeout seconds for livenessProbe | `5` | +| `primary.livenessProbe.failureThreshold` | Failure threshold for livenessProbe | `6` | +| `primary.livenessProbe.successThreshold` | Success threshold for livenessProbe | `1` | +| `primary.readinessProbe.enabled` | Enable readinessProbe on PostgreSQL Primary containers | `true` | +| `primary.readinessProbe.initialDelaySeconds` | Initial delay seconds for readinessProbe | `5` | +| `primary.readinessProbe.periodSeconds` | Period seconds for readinessProbe | `10` | +| `primary.readinessProbe.timeoutSeconds` | Timeout seconds for readinessProbe | `5` | +| `primary.readinessProbe.failureThreshold` | Failure threshold for readinessProbe | `6` | +| `primary.readinessProbe.successThreshold` | Success threshold for readinessProbe | `1` | +| `primary.startupProbe.enabled` | Enable startupProbe on PostgreSQL Primary containers | `false` | +| `primary.startupProbe.initialDelaySeconds` | Initial delay seconds for startupProbe | `30` | +| `primary.startupProbe.periodSeconds` | Period seconds for startupProbe | `10` | +| `primary.startupProbe.timeoutSeconds` | Timeout seconds for startupProbe | `1` | +| `primary.startupProbe.failureThreshold` | Failure threshold for startupProbe | `15` | +| `primary.startupProbe.successThreshold` | Success threshold for startupProbe | `1` | +| `primary.customLivenessProbe` | Custom livenessProbe that overrides the default one | `{}` | +| `primary.customReadinessProbe` | Custom readinessProbe that overrides the default one | `{}` | +| `primary.customStartupProbe` | Custom startupProbe that overrides the default one | `{}` | +| `primary.lifecycleHooks` | for the PostgreSQL Primary container to automate configuration before or after startup | `{}` | +| `primary.resources.limits` | The resources limits for the PostgreSQL Primary containers | `{}` | +| `primary.resources.requests.memory` | The requested memory for the PostgreSQL Primary containers | `256Mi` | +| `primary.resources.requests.cpu` | The requested cpu for the PostgreSQL Primary containers | `250m` | +| `primary.podSecurityContext.enabled` | Enable security context | `true` | +| `primary.podSecurityContext.fsGroup` | Group ID for the pod | `1001` | +| `primary.containerSecurityContext.enabled` | Enable container security context | `true` | +| `primary.containerSecurityContext.runAsUser` | User ID for the container | `1001` | +| `primary.hostAliases` | PostgreSQL primary pods host aliases | `[]` | +| `primary.hostNetwork` | Specify if host network should be enabled for PostgreSQL pod (postgresql primary) | `false` | +| `primary.hostIPC` | Specify if host IPC should be enabled for PostgreSQL pod (postgresql primary) | `false` | +| `primary.labels` | Map of labels to add to the statefulset (postgresql primary) | `{}` | +| `primary.annotations` | Annotations for PostgreSQL primary pods | `{}` | +| `primary.podLabels` | Map of labels to add to the pods (postgresql primary) | `{}` | +| `primary.podAnnotations` | Map of annotations to add to the pods (postgresql primary) | `{}` | +| `primary.podAffinityPreset` | PostgreSQL primary pod affinity preset. Ignored if `primary.affinity` is set. Allowed values: `soft` or `hard` | `""` | +| `primary.podAntiAffinityPreset` | PostgreSQL primary pod anti-affinity preset. Ignored if `primary.affinity` is set. Allowed values: `soft` or `hard` | `soft` | +| `primary.nodeAffinityPreset.type` | PostgreSQL primary node affinity preset type. Ignored if `primary.affinity` is set. Allowed values: `soft` or `hard` | `""` | +| `primary.nodeAffinityPreset.key` | PostgreSQL primary node label key to match Ignored if `primary.affinity` is set. | `""` | +| `primary.nodeAffinityPreset.values` | PostgreSQL primary node label values to match. Ignored if `primary.affinity` is set. | `[]` | +| `primary.affinity` | Affinity for PostgreSQL primary pods assignment | `{}` | +| `primary.nodeSelector` | Node labels for PostgreSQL primary pods assignment | `{}` | +| `primary.tolerations` | Tolerations for PostgreSQL primary pods assignment | `[]` | +| `primary.topologySpreadConstraints` | Topology Spread Constraints for pod assignment spread across your cluster among failure-domains. Evaluated as a template | `[]` | +| `primary.priorityClassName` | Priority Class to use for each pod (postgresql primary) | `""` | +| `primary.schedulerName` | Use an alternate scheduler, e.g. "stork". | `""` | +| `primary.terminationGracePeriodSeconds` | Seconds PostgreSQL primary pod needs to terminate gracefully | `""` | +| `primary.updateStrategy.type` | PostgreSQL Primary statefulset strategy type | `RollingUpdate` | +| `primary.updateStrategy.rollingUpdate` | PostgreSQL Primary statefulset rolling update configuration parameters | `{}` | +| `primary.extraVolumeMounts` | Optionally specify extra list of additional volumeMounts for the PostgreSQL Primary container(s) | `[]` | +| `primary.extraVolumes` | Optionally specify extra list of additional volumes for the PostgreSQL Primary pod(s) | `[]` | +| `primary.sidecars` | Add additional sidecar containers to the PostgreSQL Primary pod(s) | `[]` | +| `primary.initContainers` | Add additional init containers to the PostgreSQL Primary pod(s) | `[]` | +| `primary.extraPodSpec` | Optionally specify extra PodSpec for the PostgreSQL Primary pod(s) | `{}` | +| `primary.service.type` | Kubernetes Service type | `ClusterIP` | +| `primary.service.ports.postgresql` | PostgreSQL service port | `5432` | +| `primary.service.nodePorts.postgresql` | Node port for PostgreSQL | `""` | +| `primary.service.clusterIP` | Static clusterIP or None for headless services | `""` | +| `primary.service.annotations` | Annotations for PostgreSQL primary service | `{}` | +| `primary.service.loadBalancerIP` | Load balancer IP if service type is `LoadBalancer` | `""` | +| `primary.service.externalTrafficPolicy` | Enable client source IP preservation | `Cluster` | +| `primary.service.loadBalancerSourceRanges` | Addresses that are allowed when service is LoadBalancer | `[]` | +| `primary.service.extraPorts` | Extra ports to expose in the PostgreSQL primary service | `[]` | +| `primary.service.sessionAffinity` | Session Affinity for Kubernetes service, can be "None" or "ClientIP" | `None` | +| `primary.service.sessionAffinityConfig` | Additional settings for the sessionAffinity | `{}` | +| `primary.persistence.enabled` | Enable PostgreSQL Primary data persistence using PVC | `true` | +| `primary.persistence.existingClaim` | Name of an existing PVC to use | `""` | +| `primary.persistence.mountPath` | The path the volume will be mounted at | `/bitnami/postgresql` | +| `primary.persistence.subPath` | The subdirectory of the volume to mount to | `""` | +| `primary.persistence.storageClass` | PVC Storage Class for PostgreSQL Primary data volume | `""` | +| `primary.persistence.accessModes` | PVC Access Mode for PostgreSQL volume | `["ReadWriteOnce"]` | +| `primary.persistence.size` | PVC Storage Request for PostgreSQL volume | `8Gi` | +| `primary.persistence.annotations` | Annotations for the PVC | `{}` | +| `primary.persistence.labels` | Labels for the PVC | `{}` | +| `primary.persistence.selector` | Selector to match an existing Persistent Volume (this value is evaluated as a template) | `{}` | +| `primary.persistence.dataSource` | Custom PVC data source | `{}` | + + +### PostgreSQL read only replica parameters (only used when `architecture` is set to `replication`) + +| Name | Description | Value | +| ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | --------------------- | +| `readReplicas.name` | Name of the read replicas database (eg secondary, slave, ...) | `read` | +| `readReplicas.replicaCount` | Number of PostgreSQL read only replicas | `1` | +| `readReplicas.extendedConfiguration` | Extended PostgreSQL read only replicas configuration (appended to main or default configuration) | `""` | +| `readReplicas.extraEnvVars` | Array with extra environment variables to add to PostgreSQL read only nodes | `[]` | +| `readReplicas.extraEnvVarsCM` | Name of existing ConfigMap containing extra env vars for PostgreSQL read only nodes | `""` | +| `readReplicas.extraEnvVarsSecret` | Name of existing Secret containing extra env vars for PostgreSQL read only nodes | `""` | +| `readReplicas.command` | Override default container command (useful when using custom images) | `[]` | +| `readReplicas.args` | Override default container args (useful when using custom images) | `[]` | +| `readReplicas.livenessProbe.enabled` | Enable livenessProbe on PostgreSQL read only containers | `true` | +| `readReplicas.livenessProbe.initialDelaySeconds` | Initial delay seconds for livenessProbe | `30` | +| `readReplicas.livenessProbe.periodSeconds` | Period seconds for livenessProbe | `10` | +| `readReplicas.livenessProbe.timeoutSeconds` | Timeout seconds for livenessProbe | `5` | +| `readReplicas.livenessProbe.failureThreshold` | Failure threshold for livenessProbe | `6` | +| `readReplicas.livenessProbe.successThreshold` | Success threshold for livenessProbe | `1` | +| `readReplicas.readinessProbe.enabled` | Enable readinessProbe on PostgreSQL read only containers | `true` | +| `readReplicas.readinessProbe.initialDelaySeconds` | Initial delay seconds for readinessProbe | `5` | +| `readReplicas.readinessProbe.periodSeconds` | Period seconds for readinessProbe | `10` | +| `readReplicas.readinessProbe.timeoutSeconds` | Timeout seconds for readinessProbe | `5` | +| `readReplicas.readinessProbe.failureThreshold` | Failure threshold for readinessProbe | `6` | +| `readReplicas.readinessProbe.successThreshold` | Success threshold for readinessProbe | `1` | +| `readReplicas.startupProbe.enabled` | Enable startupProbe on PostgreSQL read only containers | `false` | +| `readReplicas.startupProbe.initialDelaySeconds` | Initial delay seconds for startupProbe | `30` | +| `readReplicas.startupProbe.periodSeconds` | Period seconds for startupProbe | `10` | +| `readReplicas.startupProbe.timeoutSeconds` | Timeout seconds for startupProbe | `1` | +| `readReplicas.startupProbe.failureThreshold` | Failure threshold for startupProbe | `15` | +| `readReplicas.startupProbe.successThreshold` | Success threshold for startupProbe | `1` | +| `readReplicas.customLivenessProbe` | Custom livenessProbe that overrides the default one | `{}` | +| `readReplicas.customReadinessProbe` | Custom readinessProbe that overrides the default one | `{}` | +| `readReplicas.customStartupProbe` | Custom startupProbe that overrides the default one | `{}` | +| `readReplicas.lifecycleHooks` | for the PostgreSQL read only container to automate configuration before or after startup | `{}` | +| `readReplicas.resources.limits` | The resources limits for the PostgreSQL read only containers | `{}` | +| `readReplicas.resources.requests.memory` | The requested memory for the PostgreSQL read only containers | `256Mi` | +| `readReplicas.resources.requests.cpu` | The requested cpu for the PostgreSQL read only containers | `250m` | +| `readReplicas.podSecurityContext.enabled` | Enable security context | `true` | +| `readReplicas.podSecurityContext.fsGroup` | Group ID for the pod | `1001` | +| `readReplicas.containerSecurityContext.enabled` | Enable container security context | `true` | +| `readReplicas.containerSecurityContext.runAsUser` | User ID for the container | `1001` | +| `readReplicas.hostAliases` | PostgreSQL read only pods host aliases | `[]` | +| `readReplicas.hostNetwork` | Specify if host network should be enabled for PostgreSQL pod (PostgreSQL read only) | `false` | +| `readReplicas.hostIPC` | Specify if host IPC should be enabled for PostgreSQL pod (postgresql primary) | `false` | +| `readReplicas.labels` | Map of labels to add to the statefulset (PostgreSQL read only) | `{}` | +| `readReplicas.annotations` | Annotations for PostgreSQL read only pods | `{}` | +| `readReplicas.podLabels` | Map of labels to add to the pods (PostgreSQL read only) | `{}` | +| `readReplicas.podAnnotations` | Map of annotations to add to the pods (PostgreSQL read only) | `{}` | +| `readReplicas.podAffinityPreset` | PostgreSQL read only pod affinity preset. Ignored if `primary.affinity` is set. Allowed values: `soft` or `hard` | `""` | +| `readReplicas.podAntiAffinityPreset` | PostgreSQL read only pod anti-affinity preset. Ignored if `primary.affinity` is set. Allowed values: `soft` or `hard` | `soft` | +| `readReplicas.nodeAffinityPreset.type` | PostgreSQL read only node affinity preset type. Ignored if `primary.affinity` is set. Allowed values: `soft` or `hard` | `""` | +| `readReplicas.nodeAffinityPreset.key` | PostgreSQL read only node label key to match Ignored if `primary.affinity` is set. | `""` | +| `readReplicas.nodeAffinityPreset.values` | PostgreSQL read only node label values to match. Ignored if `primary.affinity` is set. | `[]` | +| `readReplicas.affinity` | Affinity for PostgreSQL read only pods assignment | `{}` | +| `readReplicas.nodeSelector` | Node labels for PostgreSQL read only pods assignment | `{}` | +| `readReplicas.tolerations` | Tolerations for PostgreSQL read only pods assignment | `[]` | +| `readReplicas.topologySpreadConstraints` | Topology Spread Constraints for pod assignment spread across your cluster among failure-domains. Evaluated as a template | `[]` | +| `readReplicas.priorityClassName` | Priority Class to use for each pod (PostgreSQL read only) | `""` | +| `readReplicas.schedulerName` | Use an alternate scheduler, e.g. "stork". | `""` | +| `readReplicas.terminationGracePeriodSeconds` | Seconds PostgreSQL read only pod needs to terminate gracefully | `""` | +| `readReplicas.updateStrategy.type` | PostgreSQL read only statefulset strategy type | `RollingUpdate` | +| `readReplicas.updateStrategy.rollingUpdate` | PostgreSQL read only statefulset rolling update configuration parameters | `{}` | +| `readReplicas.extraVolumeMounts` | Optionally specify extra list of additional volumeMounts for the PostgreSQL read only container(s) | `[]` | +| `readReplicas.extraVolumes` | Optionally specify extra list of additional volumes for the PostgreSQL read only pod(s) | `[]` | +| `readReplicas.sidecars` | Add additional sidecar containers to the PostgreSQL read only pod(s) | `[]` | +| `readReplicas.initContainers` | Add additional init containers to the PostgreSQL read only pod(s) | `[]` | +| `readReplicas.extraPodSpec` | Optionally specify extra PodSpec for the PostgreSQL read only pod(s) | `{}` | +| `readReplicas.service.type` | Kubernetes Service type | `ClusterIP` | +| `readReplicas.service.ports.postgresql` | PostgreSQL service port | `5432` | +| `readReplicas.service.nodePorts.postgresql` | Node port for PostgreSQL | `""` | +| `readReplicas.service.clusterIP` | Static clusterIP or None for headless services | `""` | +| `readReplicas.service.annotations` | Annotations for PostgreSQL read only service | `{}` | +| `readReplicas.service.loadBalancerIP` | Load balancer IP if service type is `LoadBalancer` | `""` | +| `readReplicas.service.externalTrafficPolicy` | Enable client source IP preservation | `Cluster` | +| `readReplicas.service.loadBalancerSourceRanges` | Addresses that are allowed when service is LoadBalancer | `[]` | +| `readReplicas.service.extraPorts` | Extra ports to expose in the PostgreSQL read only service | `[]` | +| `readReplicas.service.sessionAffinity` | Session Affinity for Kubernetes service, can be "None" or "ClientIP" | `None` | +| `readReplicas.service.sessionAffinityConfig` | Additional settings for the sessionAffinity | `{}` | +| `readReplicas.persistence.enabled` | Enable PostgreSQL read only data persistence using PVC | `true` | +| `readReplicas.persistence.existingClaim` | Name of an existing PVC to use | `""` | +| `readReplicas.persistence.mountPath` | The path the volume will be mounted at | `/bitnami/postgresql` | +| `readReplicas.persistence.subPath` | The subdirectory of the volume to mount to | `""` | +| `readReplicas.persistence.storageClass` | PVC Storage Class for PostgreSQL read only data volume | `""` | +| `readReplicas.persistence.accessModes` | PVC Access Mode for PostgreSQL volume | `["ReadWriteOnce"]` | +| `readReplicas.persistence.size` | PVC Storage Request for PostgreSQL volume | `8Gi` | +| `readReplicas.persistence.annotations` | Annotations for the PVC | `{}` | +| `readReplicas.persistence.labels` | Labels for the PVC | `{}` | +| `readReplicas.persistence.selector` | Selector to match an existing Persistent Volume (this value is evaluated as a template) | `{}` | +| `readReplicas.persistence.dataSource` | Custom PVC data source | `{}` | + + +### NetworkPolicy parameters + +| Name | Description | Value | +| ------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | +| `networkPolicy.enabled` | Enable network policies | `false` | +| `networkPolicy.metrics.enabled` | Enable network policies for metrics (prometheus) | `false` | +| `networkPolicy.metrics.namespaceSelector` | Monitoring namespace selector labels. These labels will be used to identify the prometheus' namespace. | `{}` | +| `networkPolicy.metrics.podSelector` | Monitoring pod selector labels. These labels will be used to identify the Prometheus pods. | `{}` | +| `networkPolicy.ingressRules.primaryAccessOnlyFrom.enabled` | Enable ingress rule that makes PostgreSQL primary node only accessible from a particular origin. | `false` | +| `networkPolicy.ingressRules.primaryAccessOnlyFrom.namespaceSelector` | Namespace selector label that is allowed to access the PostgreSQL primary node. This label will be used to identified the allowed namespace(s). | `{}` | +| `networkPolicy.ingressRules.primaryAccessOnlyFrom.podSelector` | Pods selector label that is allowed to access the PostgreSQL primary node. This label will be used to identified the allowed pod(s). | `{}` | +| `networkPolicy.ingressRules.primaryAccessOnlyFrom.customRules` | Custom network policy for the PostgreSQL primary node. | `{}` | +| `networkPolicy.ingressRules.readReplicasAccessOnlyFrom.enabled` | Enable ingress rule that makes PostgreSQL read-only nodes only accessible from a particular origin. | `false` | +| `networkPolicy.ingressRules.readReplicasAccessOnlyFrom.namespaceSelector` | Namespace selector label that is allowed to access the PostgreSQL read-only nodes. This label will be used to identified the allowed namespace(s). | `{}` | +| `networkPolicy.ingressRules.readReplicasAccessOnlyFrom.podSelector` | Pods selector label that is allowed to access the PostgreSQL read-only nodes. This label will be used to identified the allowed pod(s). | `{}` | +| `networkPolicy.ingressRules.readReplicasAccessOnlyFrom.customRules` | Custom network policy for the PostgreSQL read-only nodes. | `{}` | +| `networkPolicy.egressRules.denyConnectionsToExternal` | Enable egress rule that denies outgoing traffic outside the cluster, except for DNS (port 53). | `false` | +| `networkPolicy.egressRules.customRules` | Custom network policy rule | `{}` | + + +### Volume Permissions parameters + +| Name | Description | Value | +| ------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | +| `volumePermissions.enabled` | Enable init container that changes the owner and group of the persistent volume | `false` | +| `volumePermissions.image.registry` | Init container volume-permissions image registry | `docker.io` | +| `volumePermissions.image.repository` | Init container volume-permissions image repository | `bitnami/bitnami-shell` | +| `volumePermissions.image.tag` | Init container volume-permissions image tag (immutable tags are recommended) | `11-debian-11-r45` | +| `volumePermissions.image.digest` | Init container volume-permissions image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag | `""` | +| `volumePermissions.image.pullPolicy` | Init container volume-permissions image pull policy | `IfNotPresent` | +| `volumePermissions.image.pullSecrets` | Init container volume-permissions image pull secrets | `[]` | +| `volumePermissions.resources.limits` | Init container volume-permissions resource limits | `{}` | +| `volumePermissions.resources.requests` | Init container volume-permissions resource requests | `{}` | +| `volumePermissions.containerSecurityContext.runAsUser` | User ID for the init container | `0` | + + +### Other Parameters + +| Name | Description | Value | +| --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ------- | +| `serviceAccount.create` | Enable creation of ServiceAccount for PostgreSQL pod | `false` | +| `serviceAccount.name` | The name of the ServiceAccount to use. | `""` | +| `serviceAccount.automountServiceAccountToken` | Allows auto mount of ServiceAccountToken on the serviceAccount created | `true` | +| `serviceAccount.annotations` | Additional custom annotations for the ServiceAccount | `{}` | +| `rbac.create` | Create Role and RoleBinding (required for PSP to work) | `false` | +| `rbac.rules` | Custom RBAC rules to set | `[]` | +| `psp.create` | Whether to create a PodSecurityPolicy. WARNING: PodSecurityPolicy is deprecated in Kubernetes v1.21 or later, unavailable in v1.25 or later | `false` | + + +### Metrics Parameters + +| Name | Description | Value | +| ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | --------------------------- | +| `metrics.enabled` | Start a prometheus exporter | `false` | +| `metrics.image.registry` | PostgreSQL Prometheus Exporter image registry | `docker.io` | +| `metrics.image.repository` | PostgreSQL Prometheus Exporter image repository | `bitnami/postgres-exporter` | +| `metrics.image.tag` | PostgreSQL Prometheus Exporter image tag (immutable tags are recommended) | `0.11.1-debian-11-r22` | +| `metrics.image.digest` | PostgreSQL image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag | `""` | +| `metrics.image.pullPolicy` | PostgreSQL Prometheus Exporter image pull policy | `IfNotPresent` | +| `metrics.image.pullSecrets` | Specify image pull secrets | `[]` | +| `metrics.customMetrics` | Define additional custom metrics | `{}` | +| `metrics.extraEnvVars` | Extra environment variables to add to PostgreSQL Prometheus exporter | `[]` | +| `metrics.containerSecurityContext.enabled` | Enable PostgreSQL Prometheus exporter containers' Security Context | `true` | +| `metrics.containerSecurityContext.runAsUser` | Set PostgreSQL Prometheus exporter containers' Security Context runAsUser | `1001` | +| `metrics.containerSecurityContext.runAsNonRoot` | Set PostgreSQL Prometheus exporter containers' Security Context runAsNonRoot | `true` | +| `metrics.livenessProbe.enabled` | Enable livenessProbe on PostgreSQL Prometheus exporter containers | `true` | +| `metrics.livenessProbe.initialDelaySeconds` | Initial delay seconds for livenessProbe | `5` | +| `metrics.livenessProbe.periodSeconds` | Period seconds for livenessProbe | `10` | +| `metrics.livenessProbe.timeoutSeconds` | Timeout seconds for livenessProbe | `5` | +| `metrics.livenessProbe.failureThreshold` | Failure threshold for livenessProbe | `6` | +| `metrics.livenessProbe.successThreshold` | Success threshold for livenessProbe | `1` | +| `metrics.readinessProbe.enabled` | Enable readinessProbe on PostgreSQL Prometheus exporter containers | `true` | +| `metrics.readinessProbe.initialDelaySeconds` | Initial delay seconds for readinessProbe | `5` | +| `metrics.readinessProbe.periodSeconds` | Period seconds for readinessProbe | `10` | +| `metrics.readinessProbe.timeoutSeconds` | Timeout seconds for readinessProbe | `5` | +| `metrics.readinessProbe.failureThreshold` | Failure threshold for readinessProbe | `6` | +| `metrics.readinessProbe.successThreshold` | Success threshold for readinessProbe | `1` | +| `metrics.startupProbe.enabled` | Enable startupProbe on PostgreSQL Prometheus exporter containers | `false` | +| `metrics.startupProbe.initialDelaySeconds` | Initial delay seconds for startupProbe | `10` | +| `metrics.startupProbe.periodSeconds` | Period seconds for startupProbe | `10` | +| `metrics.startupProbe.timeoutSeconds` | Timeout seconds for startupProbe | `1` | +| `metrics.startupProbe.failureThreshold` | Failure threshold for startupProbe | `15` | +| `metrics.startupProbe.successThreshold` | Success threshold for startupProbe | `1` | +| `metrics.customLivenessProbe` | Custom livenessProbe that overrides the default one | `{}` | +| `metrics.customReadinessProbe` | Custom readinessProbe that overrides the default one | `{}` | +| `metrics.customStartupProbe` | Custom startupProbe that overrides the default one | `{}` | +| `metrics.containerPorts.metrics` | PostgreSQL Prometheus exporter metrics container port | `9187` | +| `metrics.resources.limits` | The resources limits for the PostgreSQL Prometheus exporter container | `{}` | +| `metrics.resources.requests` | The requested resources for the PostgreSQL Prometheus exporter container | `{}` | +| `metrics.service.ports.metrics` | PostgreSQL Prometheus Exporter service port | `9187` | +| `metrics.service.clusterIP` | Static clusterIP or None for headless services | `""` | +| `metrics.service.sessionAffinity` | Control where client requests go, to the same pod or round-robin | `None` | +| `metrics.service.annotations` | Annotations for Prometheus to auto-discover the metrics endpoint | `{}` | +| `metrics.serviceMonitor.enabled` | Create ServiceMonitor Resource for scraping metrics using Prometheus Operator | `false` | +| `metrics.serviceMonitor.namespace` | Namespace for the ServiceMonitor Resource (defaults to the Release Namespace) | `""` | +| `metrics.serviceMonitor.interval` | Interval at which metrics should be scraped. | `""` | +| `metrics.serviceMonitor.scrapeTimeout` | Timeout after which the scrape is ended | `""` | +| `metrics.serviceMonitor.labels` | Additional labels that can be used so ServiceMonitor will be discovered by Prometheus | `{}` | +| `metrics.serviceMonitor.selector` | Prometheus instance selector labels | `{}` | +| `metrics.serviceMonitor.relabelings` | RelabelConfigs to apply to samples before scraping | `[]` | +| `metrics.serviceMonitor.metricRelabelings` | MetricRelabelConfigs to apply to samples before ingestion | `[]` | +| `metrics.serviceMonitor.honorLabels` | Specify honorLabels parameter to add the scrape endpoint | `false` | +| `metrics.serviceMonitor.jobLabel` | The name of the label on the target service to use as the job name in prometheus. | `""` | +| `metrics.prometheusRule.enabled` | Create a PrometheusRule for Prometheus Operator | `false` | +| `metrics.prometheusRule.namespace` | Namespace for the PrometheusRule Resource (defaults to the Release Namespace) | `""` | +| `metrics.prometheusRule.labels` | Additional labels that can be used so PrometheusRule will be discovered by Prometheus | `{}` | +| `metrics.prometheusRule.rules` | PrometheusRule definitions | `[]` | + + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, + +```bash +$ helm install my-release \ + --set auth.postgresPassword=secretpassword + my-repo/postgresql +``` + +The above command sets the PostgreSQL `postgres` account password to `secretpassword`. + +> NOTE: Once this chart is deployed, it is not possible to change the application's access credentials, such as usernames or passwords, using Helm. To change these application credentials after deployment, delete any persistent volumes (PVs) used by the chart and re-deploy it, or use the application's built-in administrative tools if available. + +> **Warning** Setting a password will be ignored on new installation in case when previous Posgresql release was deleted through the helm command. In that case, old PVC will have an old password, and setting it through helm won't take effect. Deleting persistent volumes (PVs) will solve the issue. Refer to [issue 2061](https://github.com/bitnami/charts/issues/2061) for more details + +Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example, + +```bash +helm install my-release -f values.yaml my-repo/postgresql +``` + +> **Tip**: You can use the default [values.yaml](values.yaml) + +## Configuration and installation details + +### [Rolling VS Immutable tags](https://docs.bitnami.com/containers/how-to/understand-rolling-tags-containers/) + +It is strongly recommended to use immutable tags in a production environment. This ensures your deployment does not change automatically if the same tag is updated with a different image. + +Bitnami will release a new chart updating its containers if a new version of the main container, significant changes, or critical vulnerabilities exist. + +### Customizing primary and read replica services in a replicated configuration + +At the top level, there is a service object which defines the services for both primary and readReplicas. For deeper customization, there are service objects for both the primary and read types individually. This allows you to override the values in the top level service object so that the primary and read can be of different service types and with different clusterIPs / nodePorts. Also in the case you want the primary and read to be of type nodePort, you will need to set the nodePorts to different values to prevent a collision. The values that are deeper in the primary.service or readReplicas.service objects will take precedence over the top level service object. + +### Use a different PostgreSQL version + +To modify the application version used in this chart, specify a different version of the image using the `image.tag` parameter and/or a different repository using the `image.repository` parameter. Refer to the [chart documentation for more information on these parameters and how to use them with images from a private registry](https://docs.bitnami.com/kubernetes/infrastructure/postgresql/configuration/change-image-version/). + +### postgresql.conf / pg_hba.conf files as configMap + +This helm chart also supports to customize the PostgreSQL configuration file. You can add additional PostgreSQL configuration parameters using the `primary.extendedConfiguration`/`readReplicas.extendedConfiguration` parameters as a string. Alternatively, to replace the entire default configuration use `primary.configuration`. + +You can also add a custom pg_hba.conf using the `primary.pgHbaConfiguration` parameter. + +In addition to these options, you can also set an external ConfigMap with all the configuration files. This is done by setting the `primary.existingConfigmap` parameter. Note that this will override the two previous options. + +### Initialize a fresh instance + +The [Bitnami PostgreSQL](https://github.com/bitnami/containers/tree/main/bitnami/postgresql) image allows you to use your custom scripts to initialize a fresh instance. In order to execute the scripts, you can specify custom scripts using the `primary.initdb.scripts` parameter as a string. + +In addition, you can also set an external ConfigMap with all the initialization scripts. This is done by setting the `primary.initdb.scriptsConfigMap` parameter. Note that this will override the two previous options. If your initialization scripts contain sensitive information such as credentials or passwords, you can use the `primary.initdb.scriptsSecret` parameter. + +The allowed extensions are `.sh`, `.sql` and `.sql.gz`. + +### Securing traffic using TLS + +TLS support can be enabled in the chart by specifying the `tls.` parameters while creating a release. The following parameters should be configured to properly enable the TLS support in the chart: + +- `tls.enabled`: Enable TLS support. Defaults to `false` +- `tls.certificatesSecret`: Name of an existing secret that contains the certificates. No defaults. +- `tls.certFilename`: Certificate filename. No defaults. +- `tls.certKeyFilename`: Certificate key filename. No defaults. + +For example: + +- First, create the secret with the cetificates files: + + ```console + kubectl create secret generic certificates-tls-secret --from-file=./cert.crt --from-file=./cert.key --from-file=./ca.crt + ``` + +- Then, use the following parameters: + + ```console + volumePermissions.enabled=true + tls.enabled=true + tls.certificatesSecret="certificates-tls-secret" + tls.certFilename="cert.crt" + tls.certKeyFilename="cert.key" + ``` + + > Note TLS and VolumePermissions: PostgreSQL requires certain permissions on sensitive files (such as certificate keys) to start up. Due to an on-going [issue](https://github.com/kubernetes/kubernetes/issues/57923) regarding kubernetes permissions and the use of `containerSecurityContext.runAsUser`, you must enable `volumePermissions` to ensure everything works as expected. + +### Sidecars + +If you need additional containers to run within the same pod as PostgreSQL (e.g. an additional metrics or logging exporter), you can do so via the `sidecars` config parameter. Simply define your container according to the Kubernetes container spec. + +```yaml +# For the PostgreSQL primary +primary: + sidecars: + - name: your-image-name + image: your-image + imagePullPolicy: Always + ports: + - name: portname + containerPort: 1234 +# For the PostgreSQL replicas +readReplicas: + sidecars: + - name: your-image-name + image: your-image + imagePullPolicy: Always + ports: + - name: portname + containerPort: 1234 +``` + +### Metrics + +The chart optionally can start a metrics exporter for [prometheus](https://prometheus.io). The metrics endpoint (port 9187) is not exposed and it is expected that the metrics are collected from inside the k8s cluster using something similar as the described in the [example Prometheus scrape configuration](https://github.com/prometheus/prometheus/blob/master/documentation/examples/prometheus-kubernetes.yml). + +The exporter allows to create custom metrics from additional SQL queries. See the Chart's `values.yaml` for an example and consult the [exporters documentation](https://github.com/wrouesnel/postgres_exporter#adding-new-metrics-via-a-config-file) for more details. + +### Use of global variables + +In more complex scenarios, we may have the following tree of dependencies + +``` + +--------------+ + | | + +------------+ Chart 1 +-----------+ + | | | | + | --------+------+ | + | | | + | | | + | | | + | | | + v v v ++-------+------+ +--------+------+ +--------+------+ +| | | | | | +| PostgreSQL | | Sub-chart 1 | | Sub-chart 2 | +| | | | | | ++--------------+ +---------------+ +---------------+ +``` + +The three charts below depend on the parent chart Chart 1. However, subcharts 1 and 2 may need to connect to PostgreSQL as well. In order to do so, subcharts 1 and 2 need to know the PostgreSQL credentials, so one option for deploying could be deploy Chart 1 with the following parameters: + +``` +postgresql.auth.username=testuser +subchart1.postgresql.auth.username=testuser +subchart2.postgresql.auth.username=testuser +postgresql.auth.password=testpass +subchart1.postgresql.auth.password=testpass +subchart2.postgresql.auth.password=testpass +postgresql.auth.database=testdb +subchart1.postgresql.auth.database=testdb +subchart2.postgresql.auth.database=testdb +``` + +If the number of dependent sub-charts increases, installing the chart with parameters can become increasingly difficult. An alternative would be to set the credentials using global variables as follows: + +``` +global.postgresql.auth.username=testuser +global.postgresql.auth.password=testpass +global.postgresql.auth.database=testdb +``` + +This way, the credentials will be available in all of the subcharts. + +## Persistence + +The [Bitnami PostgreSQL](https://github.com/bitnami/containers/tree/main/bitnami/postgresql) image stores the PostgreSQL data and configurations at the `/bitnami/postgresql` path of the container. + +Persistent Volume Claims are used to keep the data across deployments. This is known to work in GCE, AWS, and minikube. +See the [Parameters](#parameters) section to configure the PVC or to disable persistence. + +If you already have data in it, you will fail to sync to standby nodes for all commits, details can refer to the [code present in the container repository](https://github.com/bitnami/containers/tree/main/bitnami/postgresql). If you need to use those data, please covert them to sql and import after `helm install` finished. + +## NetworkPolicy + +To enable network policy for PostgreSQL, 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 `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: + +```bash +kubectl annotate namespace default "net.beta.kubernetes.io/network-policy={\"ingress\":{\"isolation\":\"DefaultDeny\"}}" +``` + +With NetworkPolicy enabled, traffic will be limited to just port 5432. + +For more precise policy, set `networkPolicy.allowExternal=false`. This will only allow pods with the generated client label to connect to PostgreSQL. +This label will be displayed in the output of a successful install. + +## Differences between Bitnami PostgreSQL image and [Docker Official](https://hub.docker.com/_/postgres) image + +- The Docker Official PostgreSQL image does not support replication. If you pass any replication environment variable, this would be ignored. The only environment variables supported by the Docker Official image are POSTGRES_USER, POSTGRES_DB, POSTGRES_PASSWORD, POSTGRES_INITDB_ARGS, POSTGRES_INITDB_WALDIR and PGDATA. All the remaining environment variables are specific to the Bitnami PostgreSQL image. +- The Bitnami PostgreSQL image is non-root by default. This requires that you run the pod with `securityContext` and updates the permissions of the volume with an `initContainer`. A key benefit of this configuration is that the pod follows security best practices and is prepared to run on Kubernetes distributions with hard security constraints like OpenShift. +- For OpenShift, one may either define the runAsUser and fsGroup accordingly, or try this more dynamic option: volumePermissions.securityContext.runAsUser="auto",securityContext.enabled=false,containerSecurityContext.enabled=false,shmVolume.chmod.enabled=false + +### Setting Pod's affinity + +This chart allows you to set your custom affinity using the `XXX.affinity` parameter(s). Find more information about Pod's affinity in the [kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity). + +As an alternative, you can use of the preset configurations for pod affinity, pod anti-affinity, and node affinity available at the [bitnami/common](https://github.com/bitnami/charts/tree/main/bitnami/common#affinities) chart. To do so, set the `XXX.podAffinityPreset`, `XXX.podAntiAffinityPreset`, or `XXX.nodeAffinityPreset` parameters. + +## Troubleshooting + +Find more information about how to deal with common errors related to Bitnami's Helm charts in [this troubleshooting guide](https://docs.bitnami.com/general/how-to/troubleshoot-helm-chart-issues). + +## Upgrading + +Refer to the [chart documentation for more information about how to upgrade from previous releases](https://docs.bitnami.com/kubernetes/infrastructure/postgresql/administration/upgrade/). + +## License + +Copyright © 2022 Bitnami + +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. \ No newline at end of file diff --git a/charts/kong/kong/2.41.0/charts/postgresql/charts/common/.helmignore b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/.helmignore new file mode 100644 index 0000000000..50af031725 --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/.helmignore @@ -0,0 +1,22 @@ +# 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/ diff --git a/charts/kong/kong/2.41.0/charts/postgresql/charts/common/Chart.yaml b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/Chart.yaml new file mode 100644 index 0000000000..4721c32c33 --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/Chart.yaml @@ -0,0 +1,23 @@ +annotations: + category: Infrastructure +apiVersion: v2 +appVersion: 2.0.4 +description: A Library Helm Chart for grouping common logic between bitnami charts. + This chart is not deployable by itself. +home: https://github.com/bitnami/charts/tree/main/bitnami/common +icon: https://bitnami.com/downloads/logos/bitnami-mark.png +keywords: +- common +- helper +- template +- function +- bitnami +maintainers: +- name: Bitnami + url: https://github.com/bitnami/charts +name: common +sources: +- https://github.com/bitnami/charts +- https://www.bitnami.com/ +type: library +version: 2.0.4 diff --git a/charts/kong/kong/2.41.0/charts/postgresql/charts/common/README.md b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/README.md new file mode 100644 index 0000000000..a2ecd6044c --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/README.md @@ -0,0 +1,350 @@ +# Bitnami Common Library Chart + +A [Helm Library Chart](https://helm.sh/docs/topics/library_charts/#helm) for grouping common logic between bitnami charts. + +## TL;DR + +```yaml +dependencies: + - name: common + version: 1.x.x + repository: https://charts.bitnami.com/bitnami +``` + +```bash +$ helm dependency update +``` + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "common.names.fullname" . }} +data: + myvalue: "Hello World" +``` + +## Introduction + +This chart provides a common template helpers which can be used to develop new charts using [Helm](https://helm.sh) package manager. + +Bitnami charts can be used with [Kubeapps](https://kubeapps.dev/) for deployment and management of Helm Charts in clusters. + +## Prerequisites + +- Kubernetes 1.19+ +- Helm 3.2.0+ + +## Parameters + +The following table lists the helpers available in the library which are scoped in different sections. + +### Affinities + +| Helper identifier | Description | Expected Input | +|-------------------------------|------------------------------------------------------|------------------------------------------------| +| `common.affinities.nodes.soft` | Return a soft nodeAffinity definition | `dict "key" "FOO" "values" (list "BAR" "BAZ")` | +| `common.affinities.nodes.hard` | Return a hard nodeAffinity definition | `dict "key" "FOO" "values" (list "BAR" "BAZ")` | +| `common.affinities.pods.soft` | Return a soft podAffinity/podAntiAffinity definition | `dict "component" "FOO" "context" $` | +| `common.affinities.pods.hard` | Return a hard podAffinity/podAntiAffinity definition | `dict "component" "FOO" "context" $` | + +### Capabilities + +| Helper identifier | Description | Expected Input | +|------------------------------------------------|------------------------------------------------------------------------------------------------|-------------------| +| `common.capabilities.kubeVersion` | Return the target Kubernetes version (using client default if .Values.kubeVersion is not set). | `.` Chart context | +| `common.capabilities.cronjob.apiVersion` | Return the appropriate apiVersion for cronjob. | `.` Chart context | +| `common.capabilities.deployment.apiVersion` | Return the appropriate apiVersion for deployment. | `.` Chart context | +| `common.capabilities.statefulset.apiVersion` | Return the appropriate apiVersion for statefulset. | `.` Chart context | +| `common.capabilities.ingress.apiVersion` | Return the appropriate apiVersion for ingress. | `.` Chart context | +| `common.capabilities.rbac.apiVersion` | Return the appropriate apiVersion for RBAC resources. | `.` Chart context | +| `common.capabilities.crd.apiVersion` | Return the appropriate apiVersion for CRDs. | `.` Chart context | +| `common.capabilities.policy.apiVersion` | Return the appropriate apiVersion for podsecuritypolicy. | `.` Chart context | +| `common.capabilities.networkPolicy.apiVersion` | Return the appropriate apiVersion for networkpolicy. | `.` Chart context | +| `common.capabilities.apiService.apiVersion` | Return the appropriate apiVersion for APIService. | `.` Chart context | +| `common.capabilities.hpa.apiVersion` | Return the appropriate apiVersion for Horizontal Pod Autoscaler | `.` Chart context | +| `common.capabilities.supportsHelmVersion` | Returns true if the used Helm version is 3.3+ | `.` Chart context | + +### Errors + +| Helper identifier | Description | Expected Input | +|-----------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------| +| `common.errors.upgrade.passwords.empty` | It will ensure required passwords are given when we are upgrading a chart. If `validationErrors` is not empty it will throw an error and will stop the upgrade action. | `dict "validationErrors" (list $validationError00 $validationError01) "context" $` | + +### Images + +| Helper identifier | Description | Expected Input | +|-----------------------------|------------------------------------------------------|---------------------------------------------------------------------------------------------------------| +| `common.images.image` | Return the proper and full image name | `dict "imageRoot" .Values.path.to.the.image "global" $`, see [ImageRoot](#imageroot) for the structure. | +| `common.images.pullSecrets` | Return the proper Docker Image Registry Secret Names (deprecated: use common.images.renderPullSecrets instead) | `dict "images" (list .Values.path.to.the.image1, .Values.path.to.the.image2) "global" .Values.global` | +| `common.images.renderPullSecrets` | Return the proper Docker Image Registry Secret Names (evaluates values as templates) | `dict "images" (list .Values.path.to.the.image1, .Values.path.to.the.image2) "context" $` | + +### Ingress + +| Helper identifier | Description | Expected Input | +|-------------------------------------------|-------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `common.ingress.backend` | Generate a proper Ingress backend entry depending on the API version | `dict "serviceName" "foo" "servicePort" "bar"`, see the [Ingress deprecation notice](https://kubernetes.io/blog/2019/07/18/api-deprecations-in-1-16/) for the syntax differences | +| `common.ingress.supportsPathType` | Prints "true" if the pathType field is supported | `.` Chart context | +| `common.ingress.supportsIngressClassname` | Prints "true" if the ingressClassname field is supported | `.` Chart context | +| `common.ingress.certManagerRequest` | Prints "true" if required cert-manager annotations for TLS signed certificates are set in the Ingress annotations | `dict "annotations" .Values.path.to.the.ingress.annotations` | + +### Labels + +| Helper identifier | Description | Expected Input | +|-----------------------------|-----------------------------------------------------------------------------|-------------------| +| `common.labels.standard` | Return Kubernetes standard labels | `.` Chart context | +| `common.labels.matchLabels` | Labels to use on `deploy.spec.selector.matchLabels` and `svc.spec.selector` | `.` Chart context | + +### Names + +| Helper identifier | Description | Expected Input | +|-----------------------------------|-----------------------------------------------------------------------|-------------------| +| `common.names.name` | Expand the name of the chart or use `.Values.nameOverride` | `.` Chart context | +| `common.names.fullname` | Create a default fully qualified app name. | `.` Chart context | +| `common.names.namespace` | Allow the release namespace to be overridden | `.` Chart context | +| `common.names.fullname.namespace` | Create a fully qualified app name adding the installation's namespace | `.` Chart context | +| `common.names.chart` | Chart name plus version | `.` Chart context | + +### Secrets + +| Helper identifier | Description | Expected Input | +|---------------------------|--------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `common.secrets.name` | Generate the name of the secret. | `dict "existingSecret" .Values.path.to.the.existingSecret "defaultNameSuffix" "mySuffix" "context" $` see [ExistingSecret](#existingsecret) for the structure. | +| `common.secrets.key` | Generate secret key. | `dict "existingSecret" .Values.path.to.the.existingSecret "key" "keyName"` see [ExistingSecret](#existingsecret) for the structure. | +| `common.passwords.manage` | Generate secret password or retrieve one if already created. | `dict "secret" "secret-name" "key" "keyName" "providedValues" (list "path.to.password1" "path.to.password2") "length" 10 "strong" false "chartName" "chartName" "context" $`, length, strong and chartNAme fields are optional. | +| `common.secrets.exists` | Returns whether a previous generated secret already exists. | `dict "secret" "secret-name" "context" $` | + +### Storage + +| Helper identifier | Description | Expected Input | +|-------------------------------|---------------------------------------|---------------------------------------------------------------------------------------------------------------------| +| `common.storage.class` | Return the proper Storage Class | `dict "persistence" .Values.path.to.the.persistence "global" $`, see [Persistence](#persistence) for the structure. | + +### TplValues + +| Helper identifier | Description | Expected Input | +|---------------------------|----------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------| +| `common.tplvalues.render` | Renders a value that contains template | `dict "value" .Values.path.to.the.Value "context" $`, value is the value should rendered as template, context frequently is the chart context `$` or `.` | + +### Utils + +| Helper identifier | Description | Expected Input | +|--------------------------------|------------------------------------------------------------------------------------------|------------------------------------------------------------------------| +| `common.utils.fieldToEnvVar` | Build environment variable name given a field. | `dict "field" "my-password"` | +| `common.utils.secret.getvalue` | Print instructions to get a secret value. | `dict "secret" "secret-name" "field" "secret-value-field" "context" $` | +| `common.utils.getValueFromKey` | Gets a value from `.Values` object given its key path | `dict "key" "path.to.key" "context" $` | +| `common.utils.getKeyFromList` | Returns first `.Values` key with a defined value or first of the list if all non-defined | `dict "keys" (list "path.to.key1" "path.to.key2") "context" $` | + +### Validations + +| Helper identifier | Description | Expected Input | +|--------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `common.validations.values.single.empty` | Validate a value must not be empty. | `dict "valueKey" "path.to.value" "secret" "secret.name" "field" "my-password" "subchart" "subchart" "context" $` secret, field and subchart are optional. In case they are given, the helper will generate a how to get instruction. See [ValidateValue](#validatevalue) | +| `common.validations.values.multiple.empty` | Validate a multiple values must not be empty. It returns a shared error for all the values. | `dict "required" (list $validateValueConf00 $validateValueConf01) "context" $`. See [ValidateValue](#validatevalue) | +| `common.validations.values.mariadb.passwords` | This helper will ensure required password for MariaDB are not empty. It returns a shared error for all the values. | `dict "secret" "mariadb-secret" "subchart" "true" "context" $` subchart field is optional and could be true or false it depends on where you will use mariadb chart and the helper. | +| `common.validations.values.mysql.passwords` | This helper will ensure required password for MySQL are not empty. It returns a shared error for all the values. | `dict "secret" "mysql-secret" "subchart" "true" "context" $` subchart field is optional and could be true or false it depends on where you will use mysql chart and the helper. | +| `common.validations.values.postgresql.passwords` | This helper will ensure required password for PostgreSQL are not empty. It returns a shared error for all the values. | `dict "secret" "postgresql-secret" "subchart" "true" "context" $` subchart field is optional and could be true or false it depends on where you will use postgresql chart and the helper. | +| `common.validations.values.redis.passwords` | This helper will ensure required password for Redis® are not empty. It returns a shared error for all the values. | `dict "secret" "redis-secret" "subchart" "true" "context" $` subchart field is optional and could be true or false it depends on where you will use redis chart and the helper. | +| `common.validations.values.cassandra.passwords` | This helper will ensure required password for Cassandra are not empty. It returns a shared error for all the values. | `dict "secret" "cassandra-secret" "subchart" "true" "context" $` subchart field is optional and could be true or false it depends on where you will use cassandra chart and the helper. | +| `common.validations.values.mongodb.passwords` | This helper will ensure required password for MongoDB® are not empty. It returns a shared error for all the values. | `dict "secret" "mongodb-secret" "subchart" "true" "context" $` subchart field is optional and could be true or false it depends on where you will use mongodb chart and the helper. | + +### Warnings + +| Helper identifier | Description | Expected Input | +|------------------------------|----------------------------------|------------------------------------------------------------| +| `common.warnings.rollingTag` | Warning about using rolling tag. | `ImageRoot` see [ImageRoot](#imageroot) for the structure. | + +## Special input schemas + +### ImageRoot + +```yaml +registry: + type: string + description: Docker registry where the image is located + example: docker.io + +repository: + type: string + description: Repository and image name + example: bitnami/nginx + +tag: + type: string + description: image tag + example: 1.16.1-debian-10-r63 + +pullPolicy: + type: string + description: Specify a imagePullPolicy. Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' + +pullSecrets: + type: array + items: + type: string + description: Optionally specify an array of imagePullSecrets (evaluated as templates). + +debug: + type: boolean + description: Set to true if you would like to see extra information on logs + example: false + +## An instance would be: +# registry: docker.io +# repository: bitnami/nginx +# tag: 1.16.1-debian-10-r63 +# pullPolicy: IfNotPresent +# debug: false +``` + +### Persistence + +```yaml +enabled: + type: boolean + description: Whether enable persistence. + example: true + +storageClass: + type: string + description: Ghost data Persistent Volume Storage Class, If set to "-", storageClassName: "" which disables dynamic provisioning. + example: "-" + +accessMode: + type: string + description: Access mode for the Persistent Volume Storage. + example: ReadWriteOnce + +size: + type: string + description: Size the Persistent Volume Storage. + example: 8Gi + +path: + type: string + description: Path to be persisted. + example: /bitnami + +## An instance would be: +# enabled: true +# storageClass: "-" +# accessMode: ReadWriteOnce +# size: 8Gi +# path: /bitnami +``` + +### ExistingSecret + +```yaml +name: + type: string + description: Name of the existing secret. + example: mySecret +keyMapping: + description: Mapping between the expected key name and the name of the key in the existing secret. + type: object + +## An instance would be: +# name: mySecret +# keyMapping: +# password: myPasswordKey +``` + +#### Example of use + +When we store sensitive data for a deployment in a secret, some times we want to give to users the possibility of using theirs existing secrets. + +```yaml +# templates/secret.yaml +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "common.names.fullname" . }} + labels: + app: {{ include "common.names.fullname" . }} +type: Opaque +data: + password: {{ .Values.password | b64enc | quote }} + +# templates/dpl.yaml +--- +... + env: + - name: PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "common.secrets.name" (dict "existingSecret" .Values.existingSecret "context" $) }} + key: {{ include "common.secrets.key" (dict "existingSecret" .Values.existingSecret "key" "password") }} +... + +# values.yaml +--- +name: mySecret +keyMapping: + password: myPasswordKey +``` + +### ValidateValue + +#### NOTES.txt + +```console +{{- $validateValueConf00 := (dict "valueKey" "path.to.value00" "secret" "secretName" "field" "password-00") -}} +{{- $validateValueConf01 := (dict "valueKey" "path.to.value01" "secret" "secretName" "field" "password-01") -}} + +{{ include "common.validations.values.multiple.empty" (dict "required" (list $validateValueConf00 $validateValueConf01) "context" $) }} +``` + +If we force those values to be empty we will see some alerts + +```console +$ helm install test mychart --set path.to.value00="",path.to.value01="" + 'path.to.value00' must not be empty, please add '--set path.to.value00=$PASSWORD_00' to the command. To get the current value: + + export PASSWORD_00=$(kubectl get secret --namespace default secretName -o jsonpath="{.data.password-00}" | base64 -d) + + 'path.to.value01' must not be empty, please add '--set path.to.value01=$PASSWORD_01' to the command. To get the current value: + + export PASSWORD_01=$(kubectl get secret --namespace default secretName -o jsonpath="{.data.password-01}" | base64 -d) +``` + +## Upgrading + +### To 1.0.0 + +[On November 13, 2020, Helm v2 support was formally finished](https://github.com/helm/charts#status-of-the-project), this major version is the result of the required changes applied to the Helm Chart to be able to incorporate the different features added in Helm v3 and to be consistent with the Helm project itself regarding the Helm v2 EOL. + +**What changes were introduced in this major version?** + +- Previous versions of this Helm Chart use `apiVersion: v1` (installable by both Helm 2 and 3), this Helm Chart was updated to `apiVersion: v2` (installable by Helm 3 only). [Here](https://helm.sh/docs/topics/charts/#the-apiversion-field) you can find more information about the `apiVersion` field. +- Use `type: library`. [Here](https://v3.helm.sh/docs/faq/#library-chart-support) you can find more information. +- The different fields present in the *Chart.yaml* file has been ordered alphabetically in a homogeneous way for all the Bitnami Helm Charts + +**Considerations when upgrading to this version** + +- If you want to upgrade to this version from a previous one installed with Helm v3, you shouldn't face any issues +- If you want to upgrade to this version using Helm v2, this scenario is not supported as this version doesn't support Helm v2 anymore +- If you installed the previous version with Helm v2 and wants to upgrade to this version with Helm v3, please refer to the [official Helm documentation](https://helm.sh/docs/topics/v2_v3_migration/#migration-use-cases) about migrating from Helm v2 to v3 + +**Useful links** + +- https://docs.bitnami.com/tutorials/resolve-helm2-helm3-post-migration-issues/ +- https://helm.sh/docs/topics/v2_v3_migration/ +- https://helm.sh/blog/migrate-from-helm-v2-to-helm-v3/ + +## License + +Copyright © 2022 Bitnami + +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/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_affinities.tpl b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_affinities.tpl new file mode 100644 index 0000000000..2387be2620 --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_affinities.tpl @@ -0,0 +1,102 @@ +{{/* vim: set filetype=mustache: */}} + +{{/* +Return a soft nodeAffinity definition +{{ include "common.affinities.nodes.soft" (dict "key" "FOO" "values" (list "BAR" "BAZ")) -}} +*/}} +{{- define "common.affinities.nodes.soft" -}} +preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: {{ .key }} + operator: In + values: + {{- range .values }} + - {{ . | quote }} + {{- end }} + weight: 1 +{{- end -}} + +{{/* +Return a hard nodeAffinity definition +{{ include "common.affinities.nodes.hard" (dict "key" "FOO" "values" (list "BAR" "BAZ")) -}} +*/}} +{{- define "common.affinities.nodes.hard" -}} +requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: {{ .key }} + operator: In + values: + {{- range .values }} + - {{ . | quote }} + {{- end }} +{{- end -}} + +{{/* +Return a nodeAffinity definition +{{ include "common.affinities.nodes" (dict "type" "soft" "key" "FOO" "values" (list "BAR" "BAZ")) -}} +*/}} +{{- define "common.affinities.nodes" -}} + {{- if eq .type "soft" }} + {{- include "common.affinities.nodes.soft" . -}} + {{- else if eq .type "hard" }} + {{- include "common.affinities.nodes.hard" . -}} + {{- end -}} +{{- end -}} + +{{/* +Return a soft podAffinity/podAntiAffinity definition +{{ include "common.affinities.pods.soft" (dict "component" "FOO" "extraMatchLabels" .Values.extraMatchLabels "context" $) -}} +*/}} +{{- define "common.affinities.pods.soft" -}} +{{- $component := default "" .component -}} +{{- $extraMatchLabels := default (dict) .extraMatchLabels -}} +preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: {{- (include "common.labels.matchLabels" .context) | nindent 10 }} + {{- if not (empty $component) }} + {{ printf "app.kubernetes.io/component: %s" $component }} + {{- end }} + {{- range $key, $value := $extraMatchLabels }} + {{ $key }}: {{ $value | quote }} + {{- end }} + namespaces: + - {{ include "common.names.namespace" .context | quote }} + topologyKey: kubernetes.io/hostname + weight: 1 +{{- end -}} + +{{/* +Return a hard podAffinity/podAntiAffinity definition +{{ include "common.affinities.pods.hard" (dict "component" "FOO" "extraMatchLabels" .Values.extraMatchLabels "context" $) -}} +*/}} +{{- define "common.affinities.pods.hard" -}} +{{- $component := default "" .component -}} +{{- $extraMatchLabels := default (dict) .extraMatchLabels -}} +requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: {{- (include "common.labels.matchLabels" .context) | nindent 8 }} + {{- if not (empty $component) }} + {{ printf "app.kubernetes.io/component: %s" $component }} + {{- end }} + {{- range $key, $value := $extraMatchLabels }} + {{ $key }}: {{ $value | quote }} + {{- end }} + namespaces: + - {{ include "common.names.namespace" .context | quote }} + topologyKey: kubernetes.io/hostname +{{- end -}} + +{{/* +Return a podAffinity/podAntiAffinity definition +{{ include "common.affinities.pods" (dict "type" "soft" "key" "FOO" "values" (list "BAR" "BAZ")) -}} +*/}} +{{- define "common.affinities.pods" -}} + {{- if eq .type "soft" }} + {{- include "common.affinities.pods.soft" . -}} + {{- else if eq .type "hard" }} + {{- include "common.affinities.pods.hard" . -}} + {{- end -}} +{{- end -}} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_capabilities.tpl b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_capabilities.tpl new file mode 100644 index 0000000000..9d9b760044 --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_capabilities.tpl @@ -0,0 +1,154 @@ +{{/* vim: set filetype=mustache: */}} + +{{/* +Return the target Kubernetes version +*/}} +{{- define "common.capabilities.kubeVersion" -}} +{{- if .Values.global }} + {{- if .Values.global.kubeVersion }} + {{- .Values.global.kubeVersion -}} + {{- else }} + {{- default .Capabilities.KubeVersion.Version .Values.kubeVersion -}} + {{- end -}} +{{- else }} +{{- default .Capabilities.KubeVersion.Version .Values.kubeVersion -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for poddisruptionbudget. +*/}} +{{- define "common.capabilities.policy.apiVersion" -}} +{{- if semverCompare "<1.21-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "policy/v1beta1" -}} +{{- else -}} +{{- print "policy/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for networkpolicy. +*/}} +{{- define "common.capabilities.networkPolicy.apiVersion" -}} +{{- if semverCompare "<1.7-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "extensions/v1beta1" -}} +{{- else -}} +{{- print "networking.k8s.io/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for cronjob. +*/}} +{{- define "common.capabilities.cronjob.apiVersion" -}} +{{- if semverCompare "<1.21-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "batch/v1beta1" -}} +{{- else -}} +{{- print "batch/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for deployment. +*/}} +{{- define "common.capabilities.deployment.apiVersion" -}} +{{- if semverCompare "<1.14-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "extensions/v1beta1" -}} +{{- else -}} +{{- print "apps/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for statefulset. +*/}} +{{- define "common.capabilities.statefulset.apiVersion" -}} +{{- if semverCompare "<1.14-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "apps/v1beta1" -}} +{{- else -}} +{{- print "apps/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for ingress. +*/}} +{{- define "common.capabilities.ingress.apiVersion" -}} +{{- if .Values.ingress -}} +{{- if .Values.ingress.apiVersion -}} +{{- .Values.ingress.apiVersion -}} +{{- else if semverCompare "<1.14-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "extensions/v1beta1" -}} +{{- else if semverCompare "<1.19-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "networking.k8s.io/v1beta1" -}} +{{- else -}} +{{- print "networking.k8s.io/v1" -}} +{{- end }} +{{- else if semverCompare "<1.14-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "extensions/v1beta1" -}} +{{- else if semverCompare "<1.19-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "networking.k8s.io/v1beta1" -}} +{{- else -}} +{{- print "networking.k8s.io/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for RBAC resources. +*/}} +{{- define "common.capabilities.rbac.apiVersion" -}} +{{- if semverCompare "<1.17-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "rbac.authorization.k8s.io/v1beta1" -}} +{{- else -}} +{{- print "rbac.authorization.k8s.io/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for CRDs. +*/}} +{{- define "common.capabilities.crd.apiVersion" -}} +{{- if semverCompare "<1.19-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "apiextensions.k8s.io/v1beta1" -}} +{{- else -}} +{{- print "apiextensions.k8s.io/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for APIService. +*/}} +{{- define "common.capabilities.apiService.apiVersion" -}} +{{- if semverCompare "<1.10-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "apiregistration.k8s.io/v1beta1" -}} +{{- else -}} +{{- print "apiregistration.k8s.io/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for Horizontal Pod Autoscaler. +*/}} +{{- define "common.capabilities.hpa.apiVersion" -}} +{{- if semverCompare "<1.23-0" (include "common.capabilities.kubeVersion" .context) -}} +{{- if .beta2 -}} +{{- print "autoscaling/v2beta2" -}} +{{- else -}} +{{- print "autoscaling/v2beta1" -}} +{{- end -}} +{{- else -}} +{{- print "autoscaling/v2" -}} +{{- end -}} +{{- end -}} + +{{/* +Returns true if the used Helm version is 3.3+. +A way to check the used Helm version was not introduced until version 3.3.0 with .Capabilities.HelmVersion, which contains an additional "{}}" structure. +This check is introduced as a regexMatch instead of {{ if .Capabilities.HelmVersion }} because checking for the key HelmVersion in <3.3 results in a "interface not found" error. +**To be removed when the catalog's minimun Helm version is 3.3** +*/}} +{{- define "common.capabilities.supportsHelmVersion" -}} +{{- if regexMatch "{(v[0-9])*[^}]*}}$" (.Capabilities | toString ) }} + {{- true -}} +{{- end -}} +{{- end -}} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_errors.tpl b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_errors.tpl new file mode 100644 index 0000000000..a79cc2e322 --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_errors.tpl @@ -0,0 +1,23 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Through error when upgrading using empty passwords values that must not be empty. + +Usage: +{{- $validationError00 := include "common.validations.values.single.empty" (dict "valueKey" "path.to.password00" "secret" "secretName" "field" "password-00") -}} +{{- $validationError01 := include "common.validations.values.single.empty" (dict "valueKey" "path.to.password01" "secret" "secretName" "field" "password-01") -}} +{{ include "common.errors.upgrade.passwords.empty" (dict "validationErrors" (list $validationError00 $validationError01) "context" $) }} + +Required password params: + - validationErrors - String - Required. List of validation strings to be return, if it is empty it won't throw error. + - context - Context - Required. Parent context. +*/}} +{{- define "common.errors.upgrade.passwords.empty" -}} + {{- $validationErrors := join "" .validationErrors -}} + {{- if and $validationErrors .context.Release.IsUpgrade -}} + {{- $errorString := "\nPASSWORDS ERROR: You must provide your current passwords when upgrading the release." -}} + {{- $errorString = print $errorString "\n Note that even after reinstallation, old credentials may be needed as they may be kept in persistent volume claims." -}} + {{- $errorString = print $errorString "\n Further information can be obtained at https://docs.bitnami.com/general/how-to/troubleshoot-helm-chart-issues/#credential-errors-while-upgrading-chart-releases" -}} + {{- $errorString = print $errorString "\n%s" -}} + {{- printf $errorString $validationErrors | fail -}} + {{- end -}} +{{- end -}} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_images.tpl b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_images.tpl new file mode 100644 index 0000000000..46c659e792 --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_images.tpl @@ -0,0 +1,76 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Return the proper image name +{{ include "common.images.image" ( dict "imageRoot" .Values.path.to.the.image "global" $) }} +*/}} +{{- define "common.images.image" -}} +{{- $registryName := .imageRoot.registry -}} +{{- $repositoryName := .imageRoot.repository -}} +{{- $separator := ":" -}} +{{- $termination := .imageRoot.tag | toString -}} +{{- if .global }} + {{- if .global.imageRegistry }} + {{- $registryName = .global.imageRegistry -}} + {{- end -}} +{{- end -}} +{{- if .imageRoot.digest }} + {{- $separator = "@" -}} + {{- $termination = .imageRoot.digest | toString -}} +{{- end -}} +{{- printf "%s/%s%s%s" $registryName $repositoryName $separator $termination -}} +{{- end -}} + +{{/* +Return the proper Docker Image Registry Secret Names (deprecated: use common.images.renderPullSecrets instead) +{{ include "common.images.pullSecrets" ( dict "images" (list .Values.path.to.the.image1, .Values.path.to.the.image2) "global" .Values.global) }} +*/}} +{{- define "common.images.pullSecrets" -}} + {{- $pullSecrets := list }} + + {{- if .global }} + {{- range .global.imagePullSecrets -}} + {{- $pullSecrets = append $pullSecrets . -}} + {{- end -}} + {{- end -}} + + {{- range .images -}} + {{- range .pullSecrets -}} + {{- $pullSecrets = append $pullSecrets . -}} + {{- end -}} + {{- end -}} + + {{- if (not (empty $pullSecrets)) }} +imagePullSecrets: + {{- range $pullSecrets }} + - name: {{ . }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Return the proper Docker Image Registry Secret Names evaluating values as templates +{{ include "common.images.renderPullSecrets" ( dict "images" (list .Values.path.to.the.image1, .Values.path.to.the.image2) "context" $) }} +*/}} +{{- define "common.images.renderPullSecrets" -}} + {{- $pullSecrets := list }} + {{- $context := .context }} + + {{- if $context.Values.global }} + {{- range $context.Values.global.imagePullSecrets -}} + {{- $pullSecrets = append $pullSecrets (include "common.tplvalues.render" (dict "value" . "context" $context)) -}} + {{- end -}} + {{- end -}} + + {{- range .images -}} + {{- range .pullSecrets -}} + {{- $pullSecrets = append $pullSecrets (include "common.tplvalues.render" (dict "value" . "context" $context)) -}} + {{- end -}} + {{- end -}} + + {{- if (not (empty $pullSecrets)) }} +imagePullSecrets: + {{- range $pullSecrets }} + - name: {{ . }} + {{- end }} + {{- end }} +{{- end -}} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_ingress.tpl b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_ingress.tpl new file mode 100644 index 0000000000..831da9caa2 --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_ingress.tpl @@ -0,0 +1,68 @@ +{{/* vim: set filetype=mustache: */}} + +{{/* +Generate backend entry that is compatible with all Kubernetes API versions. + +Usage: +{{ include "common.ingress.backend" (dict "serviceName" "backendName" "servicePort" "backendPort" "context" $) }} + +Params: + - serviceName - String. Name of an existing service backend + - servicePort - String/Int. Port name (or number) of the service. It will be translated to different yaml depending if it is a string or an integer. + - context - Dict - Required. The context for the template evaluation. +*/}} +{{- define "common.ingress.backend" -}} +{{- $apiVersion := (include "common.capabilities.ingress.apiVersion" .context) -}} +{{- if or (eq $apiVersion "extensions/v1beta1") (eq $apiVersion "networking.k8s.io/v1beta1") -}} +serviceName: {{ .serviceName }} +servicePort: {{ .servicePort }} +{{- else -}} +service: + name: {{ .serviceName }} + port: + {{- if typeIs "string" .servicePort }} + name: {{ .servicePort }} + {{- else if or (typeIs "int" .servicePort) (typeIs "float64" .servicePort) }} + number: {{ .servicePort | int }} + {{- end }} +{{- end -}} +{{- end -}} + +{{/* +Print "true" if the API pathType field is supported +Usage: +{{ include "common.ingress.supportsPathType" . }} +*/}} +{{- define "common.ingress.supportsPathType" -}} +{{- if (semverCompare "<1.18-0" (include "common.capabilities.kubeVersion" .)) -}} +{{- print "false" -}} +{{- else -}} +{{- print "true" -}} +{{- end -}} +{{- end -}} + +{{/* +Returns true if the ingressClassname field is supported +Usage: +{{ include "common.ingress.supportsIngressClassname" . }} +*/}} +{{- define "common.ingress.supportsIngressClassname" -}} +{{- if semverCompare "<1.18-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "false" -}} +{{- else -}} +{{- print "true" -}} +{{- end -}} +{{- end -}} + +{{/* +Return true if cert-manager required annotations for TLS signed +certificates are set in the Ingress annotations +Ref: https://cert-manager.io/docs/usage/ingress/#supported-annotations +Usage: +{{ include "common.ingress.certManagerRequest" ( dict "annotations" .Values.path.to.the.ingress.annotations ) }} +*/}} +{{- define "common.ingress.certManagerRequest" -}} +{{ if or (hasKey .annotations "cert-manager.io/cluster-issuer") (hasKey .annotations "cert-manager.io/issuer") (hasKey .annotations "kubernetes.io/tls-acme") }} + {{- true -}} +{{- end -}} +{{- end -}} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_labels.tpl b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_labels.tpl new file mode 100644 index 0000000000..252066c7e2 --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_labels.tpl @@ -0,0 +1,18 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Kubernetes standard labels +*/}} +{{- define "common.labels.standard" -}} +app.kubernetes.io/name: {{ include "common.names.name" . }} +helm.sh/chart: {{ include "common.names.chart" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end -}} + +{{/* +Labels to use on deploy.spec.selector.matchLabels and svc.spec.selector +*/}} +{{- define "common.labels.matchLabels" -}} +app.kubernetes.io/name: {{ include "common.names.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end -}} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_names.tpl b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_names.tpl new file mode 100644 index 0000000000..1bdac8b776 --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_names.tpl @@ -0,0 +1,70 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "common.names.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "common.names.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "common.names.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create a default fully qualified dependency name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +Usage: +{{ include "common.names.dependency.fullname" (dict "chartName" "dependency-chart-name" "chartValues" .Values.dependency-chart "context" $) }} +*/}} +{{- define "common.names.dependency.fullname" -}} +{{- if .chartValues.fullnameOverride -}} +{{- .chartValues.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .chartName .chartValues.nameOverride -}} +{{- if contains $name .context.Release.Name -}} +{{- .context.Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .context.Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Allow the release namespace to be overridden for multi-namespace deployments in combined charts. +*/}} +{{- define "common.names.namespace" -}} +{{- if .Values.namespaceOverride -}} +{{- .Values.namespaceOverride -}} +{{- else -}} +{{- .Release.Namespace -}} +{{- end -}} +{{- end -}} + +{{/* +Create a fully qualified app name adding the installation's namespace. +*/}} +{{- define "common.names.fullname.namespace" -}} +{{- printf "%s-%s" (include "common.names.fullname" .) (include "common.names.namespace" .) | trunc 63 | trimSuffix "-" -}} +{{- end -}} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_secrets.tpl b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_secrets.tpl new file mode 100644 index 0000000000..fa18f73a4f --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_secrets.tpl @@ -0,0 +1,140 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Generate secret name. + +Usage: +{{ include "common.secrets.name" (dict "existingSecret" .Values.path.to.the.existingSecret "defaultNameSuffix" "mySuffix" "context" $) }} + +Params: + - existingSecret - ExistingSecret/String - Optional. The path to the existing secrets in the values.yaml given by the user + to be used instead of the default one. Allows for it to be of type String (just the secret name) for backwards compatibility. + +info: https://github.com/bitnami/charts/tree/main/bitnami/common#existingsecret + - defaultNameSuffix - String - Optional. It is used only if we have several secrets in the same deployment. + - context - Dict - Required. The context for the template evaluation. +*/}} +{{- define "common.secrets.name" -}} +{{- $name := (include "common.names.fullname" .context) -}} + +{{- if .defaultNameSuffix -}} +{{- $name = printf "%s-%s" $name .defaultNameSuffix | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- with .existingSecret -}} +{{- if not (typeIs "string" .) -}} +{{- with .name -}} +{{- $name = . -}} +{{- end -}} +{{- else -}} +{{- $name = . -}} +{{- end -}} +{{- end -}} + +{{- printf "%s" $name -}} +{{- end -}} + +{{/* +Generate secret key. + +Usage: +{{ include "common.secrets.key" (dict "existingSecret" .Values.path.to.the.existingSecret "key" "keyName") }} + +Params: + - existingSecret - ExistingSecret/String - Optional. The path to the existing secrets in the values.yaml given by the user + to be used instead of the default one. Allows for it to be of type String (just the secret name) for backwards compatibility. + +info: https://github.com/bitnami/charts/tree/main/bitnami/common#existingsecret + - key - String - Required. Name of the key in the secret. +*/}} +{{- define "common.secrets.key" -}} +{{- $key := .key -}} + +{{- if .existingSecret -}} + {{- if not (typeIs "string" .existingSecret) -}} + {{- if .existingSecret.keyMapping -}} + {{- $key = index .existingSecret.keyMapping $.key -}} + {{- end -}} + {{- end }} +{{- end -}} + +{{- printf "%s" $key -}} +{{- end -}} + +{{/* +Generate secret password or retrieve one if already created. + +Usage: +{{ include "common.secrets.passwords.manage" (dict "secret" "secret-name" "key" "keyName" "providedValues" (list "path.to.password1" "path.to.password2") "length" 10 "strong" false "chartName" "chartName" "context" $) }} + +Params: + - secret - String - Required - Name of the 'Secret' resource where the password is stored. + - key - String - Required - Name of the key in the secret. + - providedValues - List - Required - The path to the validating value in the values.yaml, e.g: "mysql.password". Will pick first parameter with a defined value. + - length - int - Optional - Length of the generated random password. + - strong - Boolean - Optional - Whether to add symbols to the generated random password. + - chartName - String - Optional - Name of the chart used when said chart is deployed as a subchart. + - context - Context - Required - Parent context. + +The order in which this function returns a secret password: + 1. Already existing 'Secret' resource + (If a 'Secret' resource is found under the name provided to the 'secret' parameter to this function and that 'Secret' resource contains a key with the name passed as the 'key' parameter to this function then the value of this existing secret password will be returned) + 2. Password provided via the values.yaml + (If one of the keys passed to the 'providedValues' parameter to this function is a valid path to a key in the values.yaml and has a value, the value of the first key with a value will be returned) + 3. Randomly generated secret password + (A new random secret password with the length specified in the 'length' parameter will be generated and returned) + +*/}} +{{- define "common.secrets.passwords.manage" -}} + +{{- $password := "" }} +{{- $subchart := "" }} +{{- $chartName := default "" .chartName }} +{{- $passwordLength := default 10 .length }} +{{- $providedPasswordKey := include "common.utils.getKeyFromList" (dict "keys" .providedValues "context" $.context) }} +{{- $providedPasswordValue := include "common.utils.getValueFromKey" (dict "key" $providedPasswordKey "context" $.context) }} +{{- $secretData := (lookup "v1" "Secret" $.context.Release.Namespace .secret).data }} +{{- if $secretData }} + {{- if hasKey $secretData .key }} + {{- $password = index $secretData .key | quote }} + {{- else }} + {{- printf "\nPASSWORDS ERROR: The secret \"%s\" does not contain the key \"%s\"\n" .secret .key | fail -}} + {{- end -}} +{{- else if $providedPasswordValue }} + {{- $password = $providedPasswordValue | toString | b64enc | quote }} +{{- else }} + + {{- if .context.Values.enabled }} + {{- $subchart = $chartName }} + {{- end -}} + + {{- $requiredPassword := dict "valueKey" $providedPasswordKey "secret" .secret "field" .key "subchart" $subchart "context" $.context -}} + {{- $requiredPasswordError := include "common.validations.values.single.empty" $requiredPassword -}} + {{- $passwordValidationErrors := list $requiredPasswordError -}} + {{- include "common.errors.upgrade.passwords.empty" (dict "validationErrors" $passwordValidationErrors "context" $.context) -}} + + {{- if .strong }} + {{- $subStr := list (lower (randAlpha 1)) (randNumeric 1) (upper (randAlpha 1)) | join "_" }} + {{- $password = randAscii $passwordLength }} + {{- $password = regexReplaceAllLiteral "\\W" $password "@" | substr 5 $passwordLength }} + {{- $password = printf "%s%s" $subStr $password | toString | shuffle | b64enc | quote }} + {{- else }} + {{- $password = randAlphaNum $passwordLength | b64enc | quote }} + {{- end }} +{{- end -}} +{{- printf "%s" $password -}} +{{- end -}} + +{{/* +Returns whether a previous generated secret already exists + +Usage: +{{ include "common.secrets.exists" (dict "secret" "secret-name" "context" $) }} + +Params: + - secret - String - Required - Name of the 'Secret' resource where the password is stored. + - context - Context - Required - Parent context. +*/}} +{{- define "common.secrets.exists" -}} +{{- $secret := (lookup "v1" "Secret" $.context.Release.Namespace .secret) }} +{{- if $secret }} + {{- true -}} +{{- end -}} +{{- end -}} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_storage.tpl b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_storage.tpl new file mode 100644 index 0000000000..60e2a844f6 --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_storage.tpl @@ -0,0 +1,23 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Return the proper Storage Class +{{ include "common.storage.class" ( dict "persistence" .Values.path.to.the.persistence "global" $) }} +*/}} +{{- define "common.storage.class" -}} + +{{- $storageClass := .persistence.storageClass -}} +{{- if .global -}} + {{- if .global.storageClass -}} + {{- $storageClass = .global.storageClass -}} + {{- end -}} +{{- end -}} + +{{- if $storageClass -}} + {{- if (eq "-" $storageClass) -}} + {{- printf "storageClassName: \"\"" -}} + {{- else }} + {{- printf "storageClassName: %s" $storageClass -}} + {{- end -}} +{{- end -}} + +{{- end -}} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_tplvalues.tpl b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_tplvalues.tpl new file mode 100644 index 0000000000..2db166851b --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_tplvalues.tpl @@ -0,0 +1,13 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Renders a value that contains template. +Usage: +{{ include "common.tplvalues.render" ( dict "value" .Values.path.to.the.Value "context" $) }} +*/}} +{{- define "common.tplvalues.render" -}} + {{- if typeIs "string" .value }} + {{- tpl .value .context }} + {{- else }} + {{- tpl (.value | toYaml) .context }} + {{- end }} +{{- end -}} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_utils.tpl b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_utils.tpl new file mode 100644 index 0000000000..8c22b2a383 --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_utils.tpl @@ -0,0 +1,62 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Print instructions to get a secret value. +Usage: +{{ include "common.utils.secret.getvalue" (dict "secret" "secret-name" "field" "secret-value-field" "context" $) }} +*/}} +{{- define "common.utils.secret.getvalue" -}} +{{- $varname := include "common.utils.fieldToEnvVar" . -}} +export {{ $varname }}=$(kubectl get secret --namespace {{ .context.Release.Namespace | quote }} {{ .secret }} -o jsonpath="{.data.{{ .field }}}" | base64 -d) +{{- end -}} + +{{/* +Build env var name given a field +Usage: +{{ include "common.utils.fieldToEnvVar" dict "field" "my-password" }} +*/}} +{{- define "common.utils.fieldToEnvVar" -}} + {{- $fieldNameSplit := splitList "-" .field -}} + {{- $upperCaseFieldNameSplit := list -}} + + {{- range $fieldNameSplit -}} + {{- $upperCaseFieldNameSplit = append $upperCaseFieldNameSplit ( upper . ) -}} + {{- end -}} + + {{ join "_" $upperCaseFieldNameSplit }} +{{- end -}} + +{{/* +Gets a value from .Values given +Usage: +{{ include "common.utils.getValueFromKey" (dict "key" "path.to.key" "context" $) }} +*/}} +{{- define "common.utils.getValueFromKey" -}} +{{- $splitKey := splitList "." .key -}} +{{- $value := "" -}} +{{- $latestObj := $.context.Values -}} +{{- range $splitKey -}} + {{- if not $latestObj -}} + {{- printf "please review the entire path of '%s' exists in values" $.key | fail -}} + {{- end -}} + {{- $value = ( index $latestObj . ) -}} + {{- $latestObj = $value -}} +{{- end -}} +{{- printf "%v" (default "" $value) -}} +{{- end -}} + +{{/* +Returns first .Values key with a defined value or first of the list if all non-defined +Usage: +{{ include "common.utils.getKeyFromList" (dict "keys" (list "path.to.key1" "path.to.key2") "context" $) }} +*/}} +{{- define "common.utils.getKeyFromList" -}} +{{- $key := first .keys -}} +{{- $reverseKeys := reverse .keys }} +{{- range $reverseKeys }} + {{- $value := include "common.utils.getValueFromKey" (dict "key" . "context" $.context ) }} + {{- if $value -}} + {{- $key = . }} + {{- end -}} +{{- end -}} +{{- printf "%s" $key -}} +{{- end -}} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_warnings.tpl b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_warnings.tpl new file mode 100644 index 0000000000..ae10fa41ee --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/_warnings.tpl @@ -0,0 +1,14 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Warning about using rolling tag. +Usage: +{{ include "common.warnings.rollingTag" .Values.path.to.the.imageRoot }} +*/}} +{{- define "common.warnings.rollingTag" -}} + +{{- if and (contains "bitnami/" .repository) (not (.tag | toString | regexFind "-r\\d+$|sha256:")) }} +WARNING: Rolling tag detected ({{ .repository }}:{{ .tag }}), please note that it is strongly recommended to avoid using rolling tags in a production environment. ++info https://docs.bitnami.com/containers/how-to/understand-rolling-tags-containers/ +{{- end }} + +{{- end -}} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/validations/_cassandra.tpl b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/validations/_cassandra.tpl new file mode 100644 index 0000000000..ded1ae3bca --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/validations/_cassandra.tpl @@ -0,0 +1,72 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Validate Cassandra required passwords are not empty. + +Usage: +{{ include "common.validations.values.cassandra.passwords" (dict "secret" "secretName" "subchart" false "context" $) }} +Params: + - secret - String - Required. Name of the secret where Cassandra values are stored, e.g: "cassandra-passwords-secret" + - subchart - Boolean - Optional. Whether Cassandra is used as subchart or not. Default: false +*/}} +{{- define "common.validations.values.cassandra.passwords" -}} + {{- $existingSecret := include "common.cassandra.values.existingSecret" . -}} + {{- $enabled := include "common.cassandra.values.enabled" . -}} + {{- $dbUserPrefix := include "common.cassandra.values.key.dbUser" . -}} + {{- $valueKeyPassword := printf "%s.password" $dbUserPrefix -}} + + {{- if and (or (not $existingSecret) (eq $existingSecret "\"\"")) (eq $enabled "true") -}} + {{- $requiredPasswords := list -}} + + {{- $requiredPassword := dict "valueKey" $valueKeyPassword "secret" .secret "field" "cassandra-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredPassword -}} + + {{- include "common.validations.values.multiple.empty" (dict "required" $requiredPasswords "context" .context) -}} + + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for existingSecret. + +Usage: +{{ include "common.cassandra.values.existingSecret" (dict "context" $) }} +Params: + - subchart - Boolean - Optional. Whether Cassandra is used as subchart or not. Default: false +*/}} +{{- define "common.cassandra.values.existingSecret" -}} + {{- if .subchart -}} + {{- .context.Values.cassandra.dbUser.existingSecret | quote -}} + {{- else -}} + {{- .context.Values.dbUser.existingSecret | quote -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled cassandra. + +Usage: +{{ include "common.cassandra.values.enabled" (dict "context" $) }} +*/}} +{{- define "common.cassandra.values.enabled" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.cassandra.enabled -}} + {{- else -}} + {{- printf "%v" (not .context.Values.enabled) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for the key dbUser + +Usage: +{{ include "common.cassandra.values.key.dbUser" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether Cassandra is used as subchart or not. Default: false +*/}} +{{- define "common.cassandra.values.key.dbUser" -}} + {{- if .subchart -}} + cassandra.dbUser + {{- else -}} + dbUser + {{- end -}} +{{- end -}} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/validations/_mariadb.tpl b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/validations/_mariadb.tpl new file mode 100644 index 0000000000..b6906ff77b --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/validations/_mariadb.tpl @@ -0,0 +1,103 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Validate MariaDB required passwords are not empty. + +Usage: +{{ include "common.validations.values.mariadb.passwords" (dict "secret" "secretName" "subchart" false "context" $) }} +Params: + - secret - String - Required. Name of the secret where MariaDB values are stored, e.g: "mysql-passwords-secret" + - subchart - Boolean - Optional. Whether MariaDB is used as subchart or not. Default: false +*/}} +{{- define "common.validations.values.mariadb.passwords" -}} + {{- $existingSecret := include "common.mariadb.values.auth.existingSecret" . -}} + {{- $enabled := include "common.mariadb.values.enabled" . -}} + {{- $architecture := include "common.mariadb.values.architecture" . -}} + {{- $authPrefix := include "common.mariadb.values.key.auth" . -}} + {{- $valueKeyRootPassword := printf "%s.rootPassword" $authPrefix -}} + {{- $valueKeyUsername := printf "%s.username" $authPrefix -}} + {{- $valueKeyPassword := printf "%s.password" $authPrefix -}} + {{- $valueKeyReplicationPassword := printf "%s.replicationPassword" $authPrefix -}} + + {{- if and (or (not $existingSecret) (eq $existingSecret "\"\"")) (eq $enabled "true") -}} + {{- $requiredPasswords := list -}} + + {{- $requiredRootPassword := dict "valueKey" $valueKeyRootPassword "secret" .secret "field" "mariadb-root-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredRootPassword -}} + + {{- $valueUsername := include "common.utils.getValueFromKey" (dict "key" $valueKeyUsername "context" .context) }} + {{- if not (empty $valueUsername) -}} + {{- $requiredPassword := dict "valueKey" $valueKeyPassword "secret" .secret "field" "mariadb-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredPassword -}} + {{- end -}} + + {{- if (eq $architecture "replication") -}} + {{- $requiredReplicationPassword := dict "valueKey" $valueKeyReplicationPassword "secret" .secret "field" "mariadb-replication-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredReplicationPassword -}} + {{- end -}} + + {{- include "common.validations.values.multiple.empty" (dict "required" $requiredPasswords "context" .context) -}} + + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for existingSecret. + +Usage: +{{ include "common.mariadb.values.auth.existingSecret" (dict "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MariaDB is used as subchart or not. Default: false +*/}} +{{- define "common.mariadb.values.auth.existingSecret" -}} + {{- if .subchart -}} + {{- .context.Values.mariadb.auth.existingSecret | quote -}} + {{- else -}} + {{- .context.Values.auth.existingSecret | quote -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled mariadb. + +Usage: +{{ include "common.mariadb.values.enabled" (dict "context" $) }} +*/}} +{{- define "common.mariadb.values.enabled" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.mariadb.enabled -}} + {{- else -}} + {{- printf "%v" (not .context.Values.enabled) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for architecture + +Usage: +{{ include "common.mariadb.values.architecture" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MariaDB is used as subchart or not. Default: false +*/}} +{{- define "common.mariadb.values.architecture" -}} + {{- if .subchart -}} + {{- .context.Values.mariadb.architecture -}} + {{- else -}} + {{- .context.Values.architecture -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for the key auth + +Usage: +{{ include "common.mariadb.values.key.auth" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MariaDB is used as subchart or not. Default: false +*/}} +{{- define "common.mariadb.values.key.auth" -}} + {{- if .subchart -}} + mariadb.auth + {{- else -}} + auth + {{- end -}} +{{- end -}} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/validations/_mongodb.tpl b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/validations/_mongodb.tpl new file mode 100644 index 0000000000..f820ec1070 --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/validations/_mongodb.tpl @@ -0,0 +1,108 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Validate MongoDB® required passwords are not empty. + +Usage: +{{ include "common.validations.values.mongodb.passwords" (dict "secret" "secretName" "subchart" false "context" $) }} +Params: + - secret - String - Required. Name of the secret where MongoDB® values are stored, e.g: "mongodb-passwords-secret" + - subchart - Boolean - Optional. Whether MongoDB® is used as subchart or not. Default: false +*/}} +{{- define "common.validations.values.mongodb.passwords" -}} + {{- $existingSecret := include "common.mongodb.values.auth.existingSecret" . -}} + {{- $enabled := include "common.mongodb.values.enabled" . -}} + {{- $authPrefix := include "common.mongodb.values.key.auth" . -}} + {{- $architecture := include "common.mongodb.values.architecture" . -}} + {{- $valueKeyRootPassword := printf "%s.rootPassword" $authPrefix -}} + {{- $valueKeyUsername := printf "%s.username" $authPrefix -}} + {{- $valueKeyDatabase := printf "%s.database" $authPrefix -}} + {{- $valueKeyPassword := printf "%s.password" $authPrefix -}} + {{- $valueKeyReplicaSetKey := printf "%s.replicaSetKey" $authPrefix -}} + {{- $valueKeyAuthEnabled := printf "%s.enabled" $authPrefix -}} + + {{- $authEnabled := include "common.utils.getValueFromKey" (dict "key" $valueKeyAuthEnabled "context" .context) -}} + + {{- if and (or (not $existingSecret) (eq $existingSecret "\"\"")) (eq $enabled "true") (eq $authEnabled "true") -}} + {{- $requiredPasswords := list -}} + + {{- $requiredRootPassword := dict "valueKey" $valueKeyRootPassword "secret" .secret "field" "mongodb-root-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredRootPassword -}} + + {{- $valueUsername := include "common.utils.getValueFromKey" (dict "key" $valueKeyUsername "context" .context) }} + {{- $valueDatabase := include "common.utils.getValueFromKey" (dict "key" $valueKeyDatabase "context" .context) }} + {{- if and $valueUsername $valueDatabase -}} + {{- $requiredPassword := dict "valueKey" $valueKeyPassword "secret" .secret "field" "mongodb-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredPassword -}} + {{- end -}} + + {{- if (eq $architecture "replicaset") -}} + {{- $requiredReplicaSetKey := dict "valueKey" $valueKeyReplicaSetKey "secret" .secret "field" "mongodb-replica-set-key" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredReplicaSetKey -}} + {{- end -}} + + {{- include "common.validations.values.multiple.empty" (dict "required" $requiredPasswords "context" .context) -}} + + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for existingSecret. + +Usage: +{{ include "common.mongodb.values.auth.existingSecret" (dict "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MongoDb is used as subchart or not. Default: false +*/}} +{{- define "common.mongodb.values.auth.existingSecret" -}} + {{- if .subchart -}} + {{- .context.Values.mongodb.auth.existingSecret | quote -}} + {{- else -}} + {{- .context.Values.auth.existingSecret | quote -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled mongodb. + +Usage: +{{ include "common.mongodb.values.enabled" (dict "context" $) }} +*/}} +{{- define "common.mongodb.values.enabled" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.mongodb.enabled -}} + {{- else -}} + {{- printf "%v" (not .context.Values.enabled) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for the key auth + +Usage: +{{ include "common.mongodb.values.key.auth" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MongoDB® is used as subchart or not. Default: false +*/}} +{{- define "common.mongodb.values.key.auth" -}} + {{- if .subchart -}} + mongodb.auth + {{- else -}} + auth + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for architecture + +Usage: +{{ include "common.mongodb.values.architecture" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MongoDB® is used as subchart or not. Default: false +*/}} +{{- define "common.mongodb.values.architecture" -}} + {{- if .subchart -}} + {{- .context.Values.mongodb.architecture -}} + {{- else -}} + {{- .context.Values.architecture -}} + {{- end -}} +{{- end -}} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/validations/_mysql.tpl b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/validations/_mysql.tpl new file mode 100644 index 0000000000..74472a0617 --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/validations/_mysql.tpl @@ -0,0 +1,103 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Validate MySQL required passwords are not empty. + +Usage: +{{ include "common.validations.values.mysql.passwords" (dict "secret" "secretName" "subchart" false "context" $) }} +Params: + - secret - String - Required. Name of the secret where MySQL values are stored, e.g: "mysql-passwords-secret" + - subchart - Boolean - Optional. Whether MySQL is used as subchart or not. Default: false +*/}} +{{- define "common.validations.values.mysql.passwords" -}} + {{- $existingSecret := include "common.mysql.values.auth.existingSecret" . -}} + {{- $enabled := include "common.mysql.values.enabled" . -}} + {{- $architecture := include "common.mysql.values.architecture" . -}} + {{- $authPrefix := include "common.mysql.values.key.auth" . -}} + {{- $valueKeyRootPassword := printf "%s.rootPassword" $authPrefix -}} + {{- $valueKeyUsername := printf "%s.username" $authPrefix -}} + {{- $valueKeyPassword := printf "%s.password" $authPrefix -}} + {{- $valueKeyReplicationPassword := printf "%s.replicationPassword" $authPrefix -}} + + {{- if and (or (not $existingSecret) (eq $existingSecret "\"\"")) (eq $enabled "true") -}} + {{- $requiredPasswords := list -}} + + {{- $requiredRootPassword := dict "valueKey" $valueKeyRootPassword "secret" .secret "field" "mysql-root-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredRootPassword -}} + + {{- $valueUsername := include "common.utils.getValueFromKey" (dict "key" $valueKeyUsername "context" .context) }} + {{- if not (empty $valueUsername) -}} + {{- $requiredPassword := dict "valueKey" $valueKeyPassword "secret" .secret "field" "mysql-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredPassword -}} + {{- end -}} + + {{- if (eq $architecture "replication") -}} + {{- $requiredReplicationPassword := dict "valueKey" $valueKeyReplicationPassword "secret" .secret "field" "mysql-replication-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredReplicationPassword -}} + {{- end -}} + + {{- include "common.validations.values.multiple.empty" (dict "required" $requiredPasswords "context" .context) -}} + + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for existingSecret. + +Usage: +{{ include "common.mysql.values.auth.existingSecret" (dict "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MySQL is used as subchart or not. Default: false +*/}} +{{- define "common.mysql.values.auth.existingSecret" -}} + {{- if .subchart -}} + {{- .context.Values.mysql.auth.existingSecret | quote -}} + {{- else -}} + {{- .context.Values.auth.existingSecret | quote -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled mysql. + +Usage: +{{ include "common.mysql.values.enabled" (dict "context" $) }} +*/}} +{{- define "common.mysql.values.enabled" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.mysql.enabled -}} + {{- else -}} + {{- printf "%v" (not .context.Values.enabled) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for architecture + +Usage: +{{ include "common.mysql.values.architecture" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MySQL is used as subchart or not. Default: false +*/}} +{{- define "common.mysql.values.architecture" -}} + {{- if .subchart -}} + {{- .context.Values.mysql.architecture -}} + {{- else -}} + {{- .context.Values.architecture -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for the key auth + +Usage: +{{ include "common.mysql.values.key.auth" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MySQL is used as subchart or not. Default: false +*/}} +{{- define "common.mysql.values.key.auth" -}} + {{- if .subchart -}} + mysql.auth + {{- else -}} + auth + {{- end -}} +{{- end -}} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/validations/_postgresql.tpl b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/validations/_postgresql.tpl new file mode 100644 index 0000000000..164ec0d012 --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/validations/_postgresql.tpl @@ -0,0 +1,129 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Validate PostgreSQL required passwords are not empty. + +Usage: +{{ include "common.validations.values.postgresql.passwords" (dict "secret" "secretName" "subchart" false "context" $) }} +Params: + - secret - String - Required. Name of the secret where postgresql values are stored, e.g: "postgresql-passwords-secret" + - subchart - Boolean - Optional. Whether postgresql is used as subchart or not. Default: false +*/}} +{{- define "common.validations.values.postgresql.passwords" -}} + {{- $existingSecret := include "common.postgresql.values.existingSecret" . -}} + {{- $enabled := include "common.postgresql.values.enabled" . -}} + {{- $valueKeyPostgresqlPassword := include "common.postgresql.values.key.postgressPassword" . -}} + {{- $valueKeyPostgresqlReplicationEnabled := include "common.postgresql.values.key.replicationPassword" . -}} + {{- if and (or (not $existingSecret) (eq $existingSecret "\"\"")) (eq $enabled "true") -}} + {{- $requiredPasswords := list -}} + {{- $requiredPostgresqlPassword := dict "valueKey" $valueKeyPostgresqlPassword "secret" .secret "field" "postgresql-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredPostgresqlPassword -}} + + {{- $enabledReplication := include "common.postgresql.values.enabled.replication" . -}} + {{- if (eq $enabledReplication "true") -}} + {{- $requiredPostgresqlReplicationPassword := dict "valueKey" $valueKeyPostgresqlReplicationEnabled "secret" .secret "field" "postgresql-replication-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredPostgresqlReplicationPassword -}} + {{- end -}} + + {{- include "common.validations.values.multiple.empty" (dict "required" $requiredPasswords "context" .context) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to decide whether evaluate global values. + +Usage: +{{ include "common.postgresql.values.use.global" (dict "key" "key-of-global" "context" $) }} +Params: + - key - String - Required. Field to be evaluated within global, e.g: "existingSecret" +*/}} +{{- define "common.postgresql.values.use.global" -}} + {{- if .context.Values.global -}} + {{- if .context.Values.global.postgresql -}} + {{- index .context.Values.global.postgresql .key | quote -}} + {{- end -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for existingSecret. + +Usage: +{{ include "common.postgresql.values.existingSecret" (dict "context" $) }} +*/}} +{{- define "common.postgresql.values.existingSecret" -}} + {{- $globalValue := include "common.postgresql.values.use.global" (dict "key" "existingSecret" "context" .context) -}} + + {{- if .subchart -}} + {{- default (.context.Values.postgresql.existingSecret | quote) $globalValue -}} + {{- else -}} + {{- default (.context.Values.existingSecret | quote) $globalValue -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled postgresql. + +Usage: +{{ include "common.postgresql.values.enabled" (dict "context" $) }} +*/}} +{{- define "common.postgresql.values.enabled" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.postgresql.enabled -}} + {{- else -}} + {{- printf "%v" (not .context.Values.enabled) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for the key postgressPassword. + +Usage: +{{ include "common.postgresql.values.key.postgressPassword" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether postgresql is used as subchart or not. Default: false +*/}} +{{- define "common.postgresql.values.key.postgressPassword" -}} + {{- $globalValue := include "common.postgresql.values.use.global" (dict "key" "postgresqlUsername" "context" .context) -}} + + {{- if not $globalValue -}} + {{- if .subchart -}} + postgresql.postgresqlPassword + {{- else -}} + postgresqlPassword + {{- end -}} + {{- else -}} + global.postgresql.postgresqlPassword + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled.replication. + +Usage: +{{ include "common.postgresql.values.enabled.replication" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether postgresql is used as subchart or not. Default: false +*/}} +{{- define "common.postgresql.values.enabled.replication" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.postgresql.replication.enabled -}} + {{- else -}} + {{- printf "%v" .context.Values.replication.enabled -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for the key replication.password. + +Usage: +{{ include "common.postgresql.values.key.replicationPassword" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether postgresql is used as subchart or not. Default: false +*/}} +{{- define "common.postgresql.values.key.replicationPassword" -}} + {{- if .subchart -}} + postgresql.replication.password + {{- else -}} + replication.password + {{- end -}} +{{- end -}} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/validations/_redis.tpl b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/validations/_redis.tpl new file mode 100644 index 0000000000..dcccfc1aed --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/validations/_redis.tpl @@ -0,0 +1,76 @@ + +{{/* vim: set filetype=mustache: */}} +{{/* +Validate Redis® required passwords are not empty. + +Usage: +{{ include "common.validations.values.redis.passwords" (dict "secret" "secretName" "subchart" false "context" $) }} +Params: + - secret - String - Required. Name of the secret where redis values are stored, e.g: "redis-passwords-secret" + - subchart - Boolean - Optional. Whether redis is used as subchart or not. Default: false +*/}} +{{- define "common.validations.values.redis.passwords" -}} + {{- $enabled := include "common.redis.values.enabled" . -}} + {{- $valueKeyPrefix := include "common.redis.values.keys.prefix" . -}} + {{- $standarizedVersion := include "common.redis.values.standarized.version" . }} + + {{- $existingSecret := ternary (printf "%s%s" $valueKeyPrefix "auth.existingSecret") (printf "%s%s" $valueKeyPrefix "existingSecret") (eq $standarizedVersion "true") }} + {{- $existingSecretValue := include "common.utils.getValueFromKey" (dict "key" $existingSecret "context" .context) }} + + {{- $valueKeyRedisPassword := ternary (printf "%s%s" $valueKeyPrefix "auth.password") (printf "%s%s" $valueKeyPrefix "password") (eq $standarizedVersion "true") }} + {{- $valueKeyRedisUseAuth := ternary (printf "%s%s" $valueKeyPrefix "auth.enabled") (printf "%s%s" $valueKeyPrefix "usePassword") (eq $standarizedVersion "true") }} + + {{- if and (or (not $existingSecret) (eq $existingSecret "\"\"")) (eq $enabled "true") -}} + {{- $requiredPasswords := list -}} + + {{- $useAuth := include "common.utils.getValueFromKey" (dict "key" $valueKeyRedisUseAuth "context" .context) -}} + {{- if eq $useAuth "true" -}} + {{- $requiredRedisPassword := dict "valueKey" $valueKeyRedisPassword "secret" .secret "field" "redis-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredRedisPassword -}} + {{- end -}} + + {{- include "common.validations.values.multiple.empty" (dict "required" $requiredPasswords "context" .context) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled redis. + +Usage: +{{ include "common.redis.values.enabled" (dict "context" $) }} +*/}} +{{- define "common.redis.values.enabled" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.redis.enabled -}} + {{- else -}} + {{- printf "%v" (not .context.Values.enabled) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right prefix path for the values + +Usage: +{{ include "common.redis.values.key.prefix" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether redis is used as subchart or not. Default: false +*/}} +{{- define "common.redis.values.keys.prefix" -}} + {{- if .subchart -}}redis.{{- else -}}{{- end -}} +{{- end -}} + +{{/* +Checks whether the redis chart's includes the standarizations (version >= 14) + +Usage: +{{ include "common.redis.values.standarized.version" (dict "context" $) }} +*/}} +{{- define "common.redis.values.standarized.version" -}} + + {{- $standarizedAuth := printf "%s%s" (include "common.redis.values.keys.prefix" .) "auth" -}} + {{- $standarizedAuthValues := include "common.utils.getValueFromKey" (dict "key" $standarizedAuth "context" .context) }} + + {{- if $standarizedAuthValues -}} + {{- true -}} + {{- end -}} +{{- end -}} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/validations/_validations.tpl b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/validations/_validations.tpl new file mode 100644 index 0000000000..9a814cf40d --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/templates/validations/_validations.tpl @@ -0,0 +1,46 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Validate values must not be empty. + +Usage: +{{- $validateValueConf00 := (dict "valueKey" "path.to.value" "secret" "secretName" "field" "password-00") -}} +{{- $validateValueConf01 := (dict "valueKey" "path.to.value" "secret" "secretName" "field" "password-01") -}} +{{ include "common.validations.values.empty" (dict "required" (list $validateValueConf00 $validateValueConf01) "context" $) }} + +Validate value params: + - valueKey - String - Required. The path to the validating value in the values.yaml, e.g: "mysql.password" + - secret - String - Optional. Name of the secret where the validating value is generated/stored, e.g: "mysql-passwords-secret" + - field - String - Optional. Name of the field in the secret data, e.g: "mysql-password" +*/}} +{{- define "common.validations.values.multiple.empty" -}} + {{- range .required -}} + {{- include "common.validations.values.single.empty" (dict "valueKey" .valueKey "secret" .secret "field" .field "context" $.context) -}} + {{- end -}} +{{- end -}} + +{{/* +Validate a value must not be empty. + +Usage: +{{ include "common.validations.value.empty" (dict "valueKey" "mariadb.password" "secret" "secretName" "field" "my-password" "subchart" "subchart" "context" $) }} + +Validate value params: + - valueKey - String - Required. The path to the validating value in the values.yaml, e.g: "mysql.password" + - secret - String - Optional. Name of the secret where the validating value is generated/stored, e.g: "mysql-passwords-secret" + - field - String - Optional. Name of the field in the secret data, e.g: "mysql-password" + - subchart - String - Optional - Name of the subchart that the validated password is part of. +*/}} +{{- define "common.validations.values.single.empty" -}} + {{- $value := include "common.utils.getValueFromKey" (dict "key" .valueKey "context" .context) }} + {{- $subchart := ternary "" (printf "%s." .subchart) (empty .subchart) }} + + {{- if not $value -}} + {{- $varname := "my-value" -}} + {{- $getCurrentValue := "" -}} + {{- if and .secret .field -}} + {{- $varname = include "common.utils.fieldToEnvVar" . -}} + {{- $getCurrentValue = printf " To get the current value:\n\n %s\n" (include "common.utils.secret.getvalue" .) -}} + {{- end -}} + {{- printf "\n '%s' must not be empty, please add '--set %s%s=$%s' to the command.%s" .valueKey $subchart .valueKey $varname $getCurrentValue -}} + {{- end -}} +{{- end -}} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/charts/common/values.yaml b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/values.yaml new file mode 100644 index 0000000000..f2df68e5e6 --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/charts/common/values.yaml @@ -0,0 +1,5 @@ +## bitnami/common +## It is required by CI/CD tools and processes. +## @skip exampleValue +## +exampleValue: common-chart diff --git a/charts/kong/kong/2.41.0/charts/postgresql/templates/NOTES.txt b/charts/kong/kong/2.41.0/charts/postgresql/templates/NOTES.txt new file mode 100644 index 0000000000..e0474d4b64 --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/templates/NOTES.txt @@ -0,0 +1,89 @@ +CHART NAME: {{ .Chart.Name }} +CHART VERSION: {{ .Chart.Version }} +APP VERSION: {{ .Chart.AppVersion }} + +** Please be patient while the chart is being deployed ** + +{{- if .Values.diagnosticMode.enabled }} +The chart has been deployed in diagnostic mode. All probes have been disabled and the command has been overwritten with: + + command: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.command "context" $) | nindent 4 }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.args "context" $) | nindent 4 }} + +Get the list of pods by executing: + + kubectl get pods --namespace {{ .Release.Namespace }} -l app.kubernetes.io/instance={{ .Release.Name }} + +Access the pod you want to debug by executing + + kubectl exec --namespace {{ .Release.Namespace }} -ti -- /opt/bitnami/scripts/postgresql/entrypoint.sh /bin/bash + +In order to replicate the container startup scripts execute this command: + + /opt/bitnami/scripts/postgresql/entrypoint.sh /opt/bitnami/scripts/postgresql/run.sh + +{{- else }} + +PostgreSQL can be accessed via port {{ include "postgresql.service.port" . }} on the following DNS names from within your cluster: + + {{ include "postgresql.primary.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local - Read/Write connection + +{{- if eq .Values.architecture "replication" }} + + {{ include "postgresql.readReplica.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local - Read only connection + +{{- end }} + +{{- $customUser := include "postgresql.username" . }} +{{- if and (not (empty $customUser)) (ne $customUser "postgres") .Values.auth.enablePostgresUser }} + +To get the password for "postgres" run: + + export POSTGRES_ADMIN_PASSWORD=$(kubectl get secret --namespace {{ .Release.Namespace }} {{ include "postgresql.secretName" . }} -o jsonpath="{.data.postgres-password}" | base64 -d) + +To get the password for "{{ $customUser }}" run: + + export POSTGRES_PASSWORD=$(kubectl get secret --namespace {{ .Release.Namespace }} {{ include "postgresql.secretName" . }} -o jsonpath="{.data.password}" | base64 -d) + +{{- else }} + +To get the password for "{{ default "postgres" $customUser }}" run: + + export POSTGRES_PASSWORD=$(kubectl get secret --namespace {{ .Release.Namespace }} {{ include "postgresql.secretName" . }} -o jsonpath="{.data.{{ ternary "password" "postgres-password" (and (not (empty $customUser)) (ne $customUser "postgres")) }}}" | base64 -d) + +{{- end }} + +To connect to your database run the following command: + + kubectl run {{ include "common.names.fullname" . }}-client --rm --tty -i --restart='Never' --namespace {{ .Release.Namespace }} --image {{ include "postgresql.image" . }} --env="PGPASSWORD=$POSTGRES_PASSWORD" \ + --command -- psql --host {{ include "postgresql.primary.fullname" . }} -U {{ default "postgres" $customUser }} -d {{- if include "postgresql.database" . }} {{ include "postgresql.database" . }}{{- else }} postgres{{- end }} -p {{ include "postgresql.service.port" . }} + + > NOTE: If you access the container using bash, make sure that you execute "/opt/bitnami/scripts/postgresql/entrypoint.sh /bin/bash" in order to avoid the error "psql: local user with ID {{ .Values.primary.containerSecurityContext.runAsUser }}} does not exist" + +To connect to your database from outside the cluster execute the following commands: + +{{- if contains "NodePort" .Values.primary.service.type }} + + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "postgresql.primary.fullname" . }}) + PGPASSWORD="$POSTGRES_PASSWORD" psql --host $NODE_IP --port $NODE_PORT -U {{ default "postgres" $customUser }} -d {{- if include "postgresql.database" . }} {{ include "postgresql.database" . }}{{- else }} postgres{{- end }} + +{{- else if contains "LoadBalancer" .Values.primary.service.type }} + + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + Watch the status with: 'kubectl get svc --namespace {{ .Release.Namespace }} -w {{ include "postgresql.primary.fullname" . }}' + + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "postgresql.primary.fullname" . }} --template "{{ "{{ range (index .status.loadBalancer.ingress 0) }}{{ . }}{{ end }}" }}") + PGPASSWORD="$POSTGRES_PASSWORD" psql --host $SERVICE_IP --port {{ include "postgresql.service.port" . }} -U {{ default "postgres" $customUser }} -d {{- if include "postgresql.database" . }} {{ include "postgresql.database" . }}{{- else }} postgres{{- end }} + +{{- else if contains "ClusterIP" .Values.primary.service.type }} + + kubectl port-forward --namespace {{ .Release.Namespace }} svc/{{ include "postgresql.primary.fullname" . }} {{ include "postgresql.service.port" . }}:{{ include "postgresql.service.port" . }} & + PGPASSWORD="$POSTGRES_PASSWORD" psql --host 127.0.0.1 -U {{ default "postgres" $customUser }} -d {{- if include "postgresql.database" . }} {{ include "postgresql.database" . }}{{- else }} postgres{{- end }} -p {{ include "postgresql.service.port" . }} + +{{- end }} +{{- end }} + +{{- include "postgresql.validateValues" . -}} +{{- include "common.warnings.rollingTag" .Values.image -}} +{{- include "common.warnings.rollingTag" .Values.volumePermissions.image }} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/templates/_helpers.tpl b/charts/kong/kong/2.41.0/charts/postgresql/templates/_helpers.tpl new file mode 100644 index 0000000000..fe123f5f5d --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/templates/_helpers.tpl @@ -0,0 +1,399 @@ +{{/* vim: set filetype=mustache: */}} + +{{/* +Create a default fully qualified app name for PostgreSQL Primary objects +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "postgresql.primary.fullname" -}} +{{- if eq .Values.architecture "replication" }} + {{- printf "%s-%s" (include "common.names.fullname" .) .Values.primary.name | trunc 63 | trimSuffix "-" -}} +{{- else -}} + {{- include "common.names.fullname" . -}} +{{- end -}} +{{- end -}} + +{{/* +Create a default fully qualified app name for PostgreSQL read-only replicas objects +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "postgresql.readReplica.fullname" -}} +{{- printf "%s-%s" (include "common.names.fullname" .) .Values.readReplicas.name | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create the default FQDN for PostgreSQL primary headless service +We truncate at 63 chars because of the DNS naming spec. +*/}} +{{- define "postgresql.primary.svc.headless" -}} +{{- printf "%s-hl" (include "postgresql.primary.fullname" .) | trunc 63 | trimSuffix "-" }} +{{- end -}} + +{{/* +Create the default FQDN for PostgreSQL read-only replicas headless service +We truncate at 63 chars because of the DNS naming spec. +*/}} +{{- define "postgresql.readReplica.svc.headless" -}} +{{- printf "%s-hl" (include "postgresql.readReplica.fullname" .) | trunc 63 | trimSuffix "-" }} +{{- end -}} + +{{/* +Return the proper PostgreSQL image name +*/}} +{{- define "postgresql.image" -}} +{{ include "common.images.image" (dict "imageRoot" .Values.image "global" .Values.global) }} +{{- end -}} + +{{/* +Return the proper PostgreSQL metrics image name +*/}} +{{- define "postgresql.metrics.image" -}} +{{ include "common.images.image" (dict "imageRoot" .Values.metrics.image "global" .Values.global) }} +{{- end -}} + +{{/* +Return the proper image name (for the init container volume-permissions image) +*/}} +{{- define "postgresql.volumePermissions.image" -}} +{{ include "common.images.image" (dict "imageRoot" .Values.volumePermissions.image "global" .Values.global) }} +{{- end -}} + +{{/* +Return the proper Docker Image Registry Secret Names +*/}} +{{- define "postgresql.imagePullSecrets" -}} +{{ include "common.images.pullSecrets" (dict "images" (list .Values.image .Values.metrics.image .Values.volumePermissions.image) "global" .Values.global) }} +{{- end -}} + +{{/* +Return the name for a custom user to create +*/}} +{{- define "postgresql.username" -}} +{{- if .Values.global.postgresql.auth.username }} + {{- .Values.global.postgresql.auth.username -}} +{{- else -}} + {{- .Values.auth.username -}} +{{- end -}} +{{- end -}} + +{{/* +Return the name for a custom database to create +*/}} +{{- define "postgresql.database" -}} +{{- if .Values.global.postgresql.auth.database }} + {{- .Values.global.postgresql.auth.database -}} +{{- else if .Values.auth.database -}} + {{- .Values.auth.database -}} +{{- end -}} +{{- end -}} + +{{/* +Get the password secret. +*/}} +{{- define "postgresql.secretName" -}} +{{- if .Values.global.postgresql.auth.existingSecret }} + {{- printf "%s" (tpl .Values.global.postgresql.auth.existingSecret $) -}} +{{- else if .Values.auth.existingSecret -}} + {{- printf "%s" (tpl .Values.auth.existingSecret $) -}} +{{- else -}} + {{- printf "%s" (include "common.names.fullname" .) -}} +{{- end -}} +{{- end -}} + +{{/* +Get the replication-password key. +*/}} +{{- define "postgresql.replicationPasswordKey" -}} +{{- if or .Values.global.postgresql.auth.existingSecret .Values.auth.existingSecret }} + {{- if .Values.global.postgresql.auth.secretKeys.replicationPasswordKey }} + {{- printf "%s" (tpl .Values.global.postgresql.auth.secretKeys.replicationPasswordKey $) -}} + {{- else if .Values.auth.secretKeys.replicationPasswordKey -}} + {{- printf "%s" (tpl .Values.auth.secretKeys.replicationPasswordKey $) -}} + {{- else -}} + {{- "replication-password" -}} + {{- end -}} +{{- else -}} + {{- "replication-password" -}} +{{- end -}} +{{- end -}} + +{{/* +Get the admin-password key. +*/}} +{{- define "postgresql.adminPasswordKey" -}} +{{- if or .Values.global.postgresql.auth.existingSecret .Values.auth.existingSecret }} + {{- if .Values.global.postgresql.auth.secretKeys.adminPasswordKey }} + {{- printf "%s" (tpl .Values.global.postgresql.auth.secretKeys.adminPasswordKey $) -}} + {{- else if .Values.auth.secretKeys.adminPasswordKey -}} + {{- printf "%s" (tpl .Values.auth.secretKeys.adminPasswordKey $) -}} + {{- end -}} +{{- else -}} + {{- "postgres-password" -}} +{{- end -}} +{{- end -}} + +{{/* +Get the user-password key. +*/}} +{{- define "postgresql.userPasswordKey" -}} +{{- if or .Values.global.postgresql.auth.existingSecret .Values.auth.existingSecret }} + {{- if or (empty (include "postgresql.username" .)) (eq (include "postgresql.username" .) "postgres") }} + {{- printf "%s" (include "postgresql.adminPasswordKey" .) -}} + {{- else -}} + {{- if .Values.global.postgresql.auth.secretKeys.userPasswordKey }} + {{- printf "%s" (tpl .Values.global.postgresql.auth.secretKeys.userPasswordKey $) -}} + {{- else if .Values.auth.secretKeys.userPasswordKey -}} + {{- printf "%s" (tpl .Values.auth.secretKeys.userPasswordKey $) -}} + {{- end -}} + {{- end -}} +{{- else -}} + {{- ternary "password" "postgres-password" (and (not (empty (include "postgresql.username" .))) (ne (include "postgresql.username" .) "postgres")) -}} +{{- end -}} +{{- end -}} + +{{/* +Return true if a secret object should be created +*/}} +{{- define "postgresql.createSecret" -}} +{{- if not (or .Values.global.postgresql.auth.existingSecret .Values.auth.existingSecret) -}} + {{- true -}} +{{- end -}} +{{- end -}} + +{{/* +Return PostgreSQL service port +*/}} +{{- define "postgresql.service.port" -}} +{{- if .Values.global.postgresql.service.ports.postgresql }} + {{- .Values.global.postgresql.service.ports.postgresql -}} +{{- else -}} + {{- .Values.primary.service.ports.postgresql -}} +{{- end -}} +{{- end -}} + +{{/* +Return PostgreSQL service port +*/}} +{{- define "postgresql.readReplica.service.port" -}} +{{- if .Values.global.postgresql.service.ports.postgresql }} + {{- .Values.global.postgresql.service.ports.postgresql -}} +{{- else -}} + {{- .Values.readReplicas.service.ports.postgresql -}} +{{- end -}} +{{- end -}} + +{{/* +Get the PostgreSQL primary configuration ConfigMap name. +*/}} +{{- define "postgresql.primary.configmapName" -}} +{{- if .Values.primary.existingConfigmap -}} + {{- printf "%s" (tpl .Values.primary.existingConfigmap $) -}} +{{- else -}} + {{- printf "%s-configuration" (include "postgresql.primary.fullname" .) -}} +{{- end -}} +{{- end -}} + +{{/* +Return true if a configmap object should be created for PostgreSQL primary with the configuration +*/}} +{{- define "postgresql.primary.createConfigmap" -}} +{{- if and (or .Values.primary.configuration .Values.primary.pgHbaConfiguration) (not .Values.primary.existingConfigmap) }} + {{- true -}} +{{- else -}} +{{- end -}} +{{- end -}} + +{{/* +Get the PostgreSQL primary extended configuration ConfigMap name. +*/}} +{{- define "postgresql.primary.extendedConfigmapName" -}} +{{- if .Values.primary.existingExtendedConfigmap -}} + {{- printf "%s" (tpl .Values.primary.existingExtendedConfigmap $) -}} +{{- else -}} + {{- printf "%s-extended-configuration" (include "postgresql.primary.fullname" .) -}} +{{- end -}} +{{- end -}} + +{{/* +Get the PostgreSQL read replica extended configuration ConfigMap name. +*/}} +{{- define "postgresql.readReplicas.extendedConfigmapName" -}} + {{- printf "%s-extended-configuration" (include "postgresql.readReplica.fullname" .) -}} +{{- end -}} + +{{/* +Return true if a configmap object should be created for PostgreSQL primary with the extended configuration +*/}} +{{- define "postgresql.primary.createExtendedConfigmap" -}} +{{- if and .Values.primary.extendedConfiguration (not .Values.primary.existingExtendedConfigmap) }} + {{- true -}} +{{- else -}} +{{- end -}} +{{- end -}} + +{{/* +Return true if a configmap object should be created for PostgreSQL read replica with the extended configuration +*/}} +{{- define "postgresql.readReplicas.createExtendedConfigmap" -}} +{{- if .Values.readReplicas.extendedConfiguration }} + {{- true -}} +{{- else -}} +{{- end -}} +{{- end -}} + +{{/* + Create the name of the service account to use + */}} +{{- define "postgresql.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "common.names.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Return true if a configmap should be mounted with PostgreSQL configuration +*/}} +{{- define "postgresql.mountConfigurationCM" -}} +{{- if or .Values.primary.configuration .Values.primary.pgHbaConfiguration .Values.primary.existingConfigmap }} + {{- true -}} +{{- end -}} +{{- end -}} + +{{/* +Get the initialization scripts ConfigMap name. +*/}} +{{- define "postgresql.initdb.scriptsCM" -}} +{{- if .Values.primary.initdb.scriptsConfigMap -}} + {{- printf "%s" (tpl .Values.primary.initdb.scriptsConfigMap $) -}} +{{- else -}} + {{- printf "%s-init-scripts" (include "postgresql.primary.fullname" .) -}} +{{- end -}} +{{- end -}} + +{/* +Return true if TLS is enabled for LDAP connection +*/}} +{{- define "postgresql.ldap.tls.enabled" -}} +{{- if and (kindIs "string" .Values.ldap.tls) (not (empty .Values.ldap.tls)) }} + {{- true -}} +{{- else if and (kindIs "map" .Values.ldap.tls) .Values.ldap.tls.enabled }} + {{- true -}} +{{- end -}} +{{- end -}} + +{{/* +Get the readiness probe command +*/}} +{{- define "postgresql.readinessProbeCommand" -}} +{{- $customUser := include "postgresql.username" . }} +- | +{{- if (include "postgresql.database" .) }} + exec pg_isready -U {{ default "postgres" $customUser | quote }} -d "dbname={{ include "postgresql.database" . }} {{- if .Values.tls.enabled }} sslcert={{ include "postgresql.tlsCert" . }} sslkey={{ include "postgresql.tlsCertKey" . }}{{- end }}" -h 127.0.0.1 -p {{ .Values.containerPorts.postgresql }} +{{- else }} + exec pg_isready -U {{ default "postgres" $customUser | quote }} {{- if .Values.tls.enabled }} -d "sslcert={{ include "postgresql.tlsCert" . }} sslkey={{ include "postgresql.tlsCertKey" . }}"{{- end }} -h 127.0.0.1 -p {{ .Values.containerPorts.postgresql }} +{{- end }} +{{- if contains "bitnami/" .Values.image.repository }} + [ -f /opt/bitnami/postgresql/tmp/.initialized ] || [ -f /bitnami/postgresql/.initialized ] +{{- end -}} +{{- end -}} + +{{/* +Compile all warnings into a single message, and call fail. +*/}} +{{- define "postgresql.validateValues" -}} +{{- $messages := list -}} +{{- $messages := append $messages (include "postgresql.validateValues.ldapConfigurationMethod" .) -}} +{{- $messages := append $messages (include "postgresql.validateValues.psp" .) -}} +{{- $messages := without $messages "" -}} +{{- $message := join "\n" $messages -}} + +{{- if $message -}} +{{- printf "\nVALUES VALIDATION:\n%s" $message | fail -}} +{{- end -}} +{{- end -}} + +{{/* +Validate values of Postgresql - If ldap.url is used then you don't need the other settings for ldap +*/}} +{{- define "postgresql.validateValues.ldapConfigurationMethod" -}} +{{- if and .Values.ldap.enabled (and (not (empty .Values.ldap.url)) (not (empty .Values.ldap.server))) }} +postgresql: ldap.url, ldap.server + You cannot set both `ldap.url` and `ldap.server` at the same time. + Please provide a unique way to configure LDAP. + More info at https://www.postgresql.org/docs/current/auth-ldap.html +{{- end -}} +{{- end -}} + +{{/* +Validate values of Postgresql - If PSP is enabled RBAC should be enabled too +*/}} +{{- define "postgresql.validateValues.psp" -}} +{{- if and .Values.psp.create (not .Values.rbac.create) }} +postgresql: psp.create, rbac.create + RBAC should be enabled if PSP is enabled in order for PSP to work. + More info at https://kubernetes.io/docs/concepts/policy/pod-security-policy/#authorizing-policies +{{- end -}} +{{- end -}} + +{{/* +Return the path to the cert file. +*/}} +{{- define "postgresql.tlsCert" -}} +{{- if .Values.tls.autoGenerated }} + {{- printf "/opt/bitnami/postgresql/certs/tls.crt" -}} +{{- else -}} + {{- required "Certificate filename is required when TLS in enabled" .Values.tls.certFilename | printf "/opt/bitnami/postgresql/certs/%s" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the path to the cert key file. +*/}} +{{- define "postgresql.tlsCertKey" -}} +{{- if .Values.tls.autoGenerated }} + {{- printf "/opt/bitnami/postgresql/certs/tls.key" -}} +{{- else -}} +{{- required "Certificate Key filename is required when TLS in enabled" .Values.tls.certKeyFilename | printf "/opt/bitnami/postgresql/certs/%s" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the path to the CA cert file. +*/}} +{{- define "postgresql.tlsCACert" -}} +{{- if .Values.tls.autoGenerated }} + {{- printf "/opt/bitnami/postgresql/certs/ca.crt" -}} +{{- else -}} + {{- printf "/opt/bitnami/postgresql/certs/%s" .Values.tls.certCAFilename -}} +{{- end -}} +{{- end -}} + +{{/* +Return the path to the CRL file. +*/}} +{{- define "postgresql.tlsCRL" -}} +{{- if .Values.tls.crlFilename -}} +{{- printf "/opt/bitnami/postgresql/certs/%s" .Values.tls.crlFilename -}} +{{- end -}} +{{- end -}} + +{{/* +Return true if a TLS credentials secret object should be created +*/}} +{{- define "postgresql.createTlsSecret" -}} +{{- if and .Values.tls.autoGenerated (not .Values.tls.certificatesSecret) }} + {{- true -}} +{{- end -}} +{{- end -}} + +{{/* +Return the path to the CA cert file. +*/}} +{{- define "postgresql.tlsSecretName" -}} +{{- if .Values.tls.autoGenerated }} + {{- printf "%s-crt" (include "common.names.fullname" .) -}} +{{- else -}} + {{ required "A secret containing TLS certificates is required when TLS is enabled" .Values.tls.certificatesSecret }} +{{- end -}} +{{- end -}} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/templates/extra-list.yaml b/charts/kong/kong/2.41.0/charts/postgresql/templates/extra-list.yaml new file mode 100644 index 0000000000..9ac65f9e16 --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/templates/extra-list.yaml @@ -0,0 +1,4 @@ +{{- range .Values.extraDeploy }} +--- +{{ include "common.tplvalues.render" (dict "value" . "context" $) }} +{{- end }} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/templates/networkpolicy-egress.yaml b/charts/kong/kong/2.41.0/charts/postgresql/templates/networkpolicy-egress.yaml new file mode 100644 index 0000000000..e8621474b2 --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/templates/networkpolicy-egress.yaml @@ -0,0 +1,32 @@ +{{- if and .Values.networkPolicy.enabled (or .Values.networkPolicy.egressRules.denyConnectionsToExternal .Values.networkPolicy.egressRules.customRules) }} +apiVersion: {{ include "common.capabilities.networkPolicy.apiVersion" . }} +kind: NetworkPolicy +metadata: + name: {{ printf "%s-egress" (include "common.names.fullname" .) }} + namespace: {{ .Release.Namespace }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + podSelector: + matchLabels: {{- include "common.labels.matchLabels" . | nindent 6 }} + policyTypes: + - Egress + egress: + {{- if .Values.networkPolicy.egressRules.denyConnectionsToExternal }} + - ports: + - port: 53 + protocol: UDP + - port: 53 + protocol: TCP + - to: + - namespaceSelector: {} + {{- end }} + {{- if .Values.networkPolicy.egressRules.customRules }} + {{- include "common.tplvalues.render" (dict "value" .Values.networkPolicy.egressRules.customRules "context" $) | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/templates/primary/configmap.yaml b/charts/kong/kong/2.41.0/charts/postgresql/templates/primary/configmap.yaml new file mode 100644 index 0000000000..d654a2257b --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/templates/primary/configmap.yaml @@ -0,0 +1,24 @@ +{{- if (include "postgresql.primary.createConfigmap" .) }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ printf "%s-configuration" (include "postgresql.primary.fullname" .) }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: primary + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +data: + {{- if .Values.primary.configuration }} + postgresql.conf: |- + {{- include "common.tplvalues.render" ( dict "value" .Values.primary.configuration "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.primary.pgHbaConfiguration }} + pg_hba.conf: | + {{- include "common.tplvalues.render" ( dict "value" .Values.primary.pgHbaConfiguration "context" $ ) | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/templates/primary/extended-configmap.yaml b/charts/kong/kong/2.41.0/charts/postgresql/templates/primary/extended-configmap.yaml new file mode 100644 index 0000000000..d129bd3b2f --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/templates/primary/extended-configmap.yaml @@ -0,0 +1,18 @@ +{{- if (include "postgresql.primary.createExtendedConfigmap" .) }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ printf "%s-extended-configuration" (include "postgresql.primary.fullname" .) }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: primary + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +data: + override.conf: |- + {{- include "common.tplvalues.render" ( dict "value" .Values.primary.extendedConfiguration "context" $ ) | nindent 4 }} +{{- end }} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/templates/primary/initialization-configmap.yaml b/charts/kong/kong/2.41.0/charts/postgresql/templates/primary/initialization-configmap.yaml new file mode 100644 index 0000000000..d3d26cb8cb --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/templates/primary/initialization-configmap.yaml @@ -0,0 +1,15 @@ +{{- if and .Values.primary.initdb.scripts (not .Values.primary.initdb.scriptsConfigMap) }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ printf "%s-init-scripts" (include "postgresql.primary.fullname" .) }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +data: {{- include "common.tplvalues.render" (dict "value" .Values.primary.initdb.scripts "context" .) | nindent 2 }} +{{- end }} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/templates/primary/metrics-configmap.yaml b/charts/kong/kong/2.41.0/charts/postgresql/templates/primary/metrics-configmap.yaml new file mode 100644 index 0000000000..8ad2f35fce --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/templates/primary/metrics-configmap.yaml @@ -0,0 +1,16 @@ +{{- if and .Values.metrics.enabled .Values.metrics.customMetrics }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ printf "%s-metrics" (include "postgresql.primary.fullname" .) }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +data: + custom-metrics.yaml: {{ toYaml .Values.metrics.customMetrics | quote }} +{{- end }} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/templates/primary/metrics-svc.yaml b/charts/kong/kong/2.41.0/charts/postgresql/templates/primary/metrics-svc.yaml new file mode 100644 index 0000000000..75a1b81be6 --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/templates/primary/metrics-svc.yaml @@ -0,0 +1,31 @@ +{{- if .Values.metrics.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ printf "%s-metrics" (include "postgresql.primary.fullname" .) }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: metrics + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + annotations: + {{- if .Values.commonAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.metrics.service.annotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.service.annotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + type: ClusterIP + sessionAffinity: {{ .Values.metrics.service.sessionAffinity }} + {{- if .Values.metrics.service.clusterIP }} + clusterIP: {{ .Values.metrics.service.clusterIP }} + {{- end }} + ports: + - name: http-metrics + port: {{ .Values.metrics.service.ports.metrics }} + targetPort: http-metrics + selector: {{- include "common.labels.matchLabels" . | nindent 4 }} + app.kubernetes.io/component: primary +{{- end }} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/templates/primary/networkpolicy.yaml b/charts/kong/kong/2.41.0/charts/postgresql/templates/primary/networkpolicy.yaml new file mode 100644 index 0000000000..ce0052d48a --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/templates/primary/networkpolicy.yaml @@ -0,0 +1,57 @@ +{{- if and .Values.networkPolicy.enabled (or .Values.networkPolicy.metrics.enabled .Values.networkPolicy.ingressRules.primaryAccessOnlyFrom.enabled) }} +apiVersion: {{ include "common.capabilities.networkPolicy.apiVersion" . }} +kind: NetworkPolicy +metadata: + name: {{ printf "%s-ingress" (include "postgresql.primary.fullname" .) }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: primary + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + podSelector: + matchLabels: {{- include "common.labels.matchLabels" . | nindent 6 }} + app.kubernetes.io/component: primary + ingress: + {{- if and .Values.metrics.enabled .Values.networkPolicy.metrics.enabled (or .Values.networkPolicy.metrics.namespaceSelector .Values.networkPolicy.metrics.podSelector) }} + - from: + {{- if .Values.networkPolicy.metrics.namespaceSelector }} + - namespaceSelector: + matchLabels: {{- include "common.tplvalues.render" (dict "value" .Values.networkPolicy.metrics.namespaceSelector "context" $) | nindent 14 }} + {{- end }} + {{- if .Values.networkPolicy.metrics.podSelector }} + - podSelector: + matchLabels: {{- include "common.tplvalues.render" (dict "value" .Values.networkPolicy.metrics.podSelector "context" $) | nindent 14 }} + {{- end }} + ports: + - port: {{ .Values.metrics.containerPorts.metrics }} + {{- end }} + {{- if and .Values.networkPolicy.ingressRules.primaryAccessOnlyFrom.enabled (or .Values.networkPolicy.ingressRules.primaryAccessOnlyFrom.namespaceSelector .Values.networkPolicy.ingressRules.primaryAccessOnlyFrom.podSelector) }} + - from: + {{- if .Values.networkPolicy.ingressRules.primaryAccessOnlyFrom.namespaceSelector }} + - namespaceSelector: + matchLabels: {{- include "common.tplvalues.render" (dict "value" .Values.networkPolicy.ingressRules.primaryAccessOnlyFrom.namespaceSelector "context" $) | nindent 14 }} + {{- end }} + {{- if .Values.networkPolicy.ingressRules.primaryAccessOnlyFrom.podSelector }} + - podSelector: + matchLabels: {{- include "common.tplvalues.render" (dict "value" .Values.networkPolicy.ingressRules.primaryAccessOnlyFrom.podSelector "context" $) | nindent 14 }} + {{- end }} + ports: + - port: {{ .Values.containerPorts.postgresql }} + {{- end }} + {{- if and .Values.networkPolicy.ingressRules.primaryAccessOnlyFrom.enabled (eq .Values.architecture "replication") }} + - from: + - podSelector: + matchLabels: {{- include "common.labels.matchLabels" . | nindent 14 }} + app.kubernetes.io/component: read + ports: + - port: {{ .Values.containerPorts.postgresql }} + {{- end }} + {{- if .Values.networkPolicy.ingressRules.primaryAccessOnlyFrom.customRules }} + {{- include "common.tplvalues.render" (dict "value" .Values.networkPolicy.ingressRules.primaryAccessOnlyFrom.customRules "context" $) | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/templates/primary/servicemonitor.yaml b/charts/kong/kong/2.41.0/charts/postgresql/templates/primary/servicemonitor.yaml new file mode 100644 index 0000000000..c4a19fe053 --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/templates/primary/servicemonitor.yaml @@ -0,0 +1,48 @@ +{{- if and .Values.metrics.enabled .Values.metrics.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "postgresql.primary.fullname" . }} + namespace: {{ default .Release.Namespace .Values.metrics.serviceMonitor.namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: metrics + {{- if .Values.metrics.serviceMonitor.labels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.serviceMonitor.labels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + {{- if .Values.metrics.serviceMonitor.jobLabel }} + jobLabel: {{ .Values.metrics.serviceMonitor.jobLabel }} + {{- end }} + selector: + matchLabels: {{- include "common.labels.matchLabels" . | nindent 6 }} + {{- if .Values.metrics.serviceMonitor.selector }} + {{- include "common.tplvalues.render" (dict "value" .Values.metrics.serviceMonitor.selector "context" $) | nindent 6 }} + {{- end }} + app.kubernetes.io/component: metrics + endpoints: + - port: http-metrics + {{- if .Values.metrics.serviceMonitor.interval }} + interval: {{ .Values.metrics.serviceMonitor.interval }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.metrics.serviceMonitor.scrapeTimeout }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.relabelings }} + relabelings: {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.serviceMonitor.relabelings "context" $) | nindent 6 }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.metricRelabelings }} + metricRelabelings: {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.serviceMonitor.metricRelabelings "context" $) | nindent 6 }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.honorLabels }} + honorLabels: {{ .Values.metrics.serviceMonitor.honorLabels }} + {{- end }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace | quote }} +{{- end }} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/templates/primary/statefulset.yaml b/charts/kong/kong/2.41.0/charts/postgresql/templates/primary/statefulset.yaml new file mode 100644 index 0000000000..3fd77f4afb --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/templates/primary/statefulset.yaml @@ -0,0 +1,634 @@ +{{- $customUser := include "postgresql.username" . }} +apiVersion: {{ include "common.capabilities.statefulset.apiVersion" . }} +kind: StatefulSet +metadata: + name: {{ include "postgresql.primary.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: primary + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.primary.labels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.primary.labels "context" $ ) | nindent 4 }} + {{- end }} + annotations: + {{- if .Values.commonAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.primary.annotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.primary.annotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + replicas: 1 + serviceName: {{ include "postgresql.primary.svc.headless" . }} + {{- if .Values.primary.updateStrategy }} + updateStrategy: {{- toYaml .Values.primary.updateStrategy | nindent 4 }} + {{- end }} + selector: + matchLabels: {{- include "common.labels.matchLabels" . | nindent 6 }} + app.kubernetes.io/component: primary + template: + metadata: + name: {{ include "postgresql.primary.fullname" . }} + labels: {{- include "common.labels.standard" . | nindent 8 }} + app.kubernetes.io/component: primary + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 8 }} + {{- end }} + {{- if .Values.primary.podLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.primary.podLabels "context" $ ) | nindent 8 }} + {{- end }} + annotations: + {{- if (include "postgresql.primary.createConfigmap" .) }} + checksum/configuration: {{ include (print $.Template.BasePath "/primary/configmap.yaml") . | sha256sum }} + {{- end }} + {{- if (include "postgresql.primary.createExtendedConfigmap" .) }} + checksum/extended-configuration: {{ include (print $.Template.BasePath "/primary/extended-configmap.yaml") . | sha256sum }} + {{- end }} + {{- if .Values.primary.podAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.primary.podAnnotations "context" $ ) | nindent 8 }} + {{- end }} + spec: + {{- if .Values.primary.extraPodSpec }} + {{- include "common.tplvalues.render" (dict "value" .Values.primary.extraPodSpec "context" $) | nindent 6 }} + {{- end }} + serviceAccountName: {{ include "postgresql.serviceAccountName" . }} + {{- include "postgresql.imagePullSecrets" . | nindent 6 }} + {{- if .Values.primary.hostAliases }} + hostAliases: {{- include "common.tplvalues.render" (dict "value" .Values.primary.hostAliases "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.primary.affinity }} + affinity: {{- include "common.tplvalues.render" (dict "value" .Values.primary.affinity "context" $) | nindent 8 }} + {{- else }} + affinity: + podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.primary.podAffinityPreset "component" "primary" "context" $) | nindent 10 }} + podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.primary.podAntiAffinityPreset "component" "primary" "context" $) | nindent 10 }} + nodeAffinity: {{- include "common.affinities.nodes" (dict "type" .Values.primary.nodeAffinityPreset.type "key" .Values.primary.nodeAffinityPreset.key "values" .Values.primary.nodeAffinityPreset.values) | nindent 10 }} + {{- end }} + {{- if .Values.primary.nodeSelector }} + nodeSelector: {{- include "common.tplvalues.render" (dict "value" .Values.primary.nodeSelector "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.primary.tolerations }} + tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.primary.tolerations "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.primary.topologySpreadConstraints }} + topologySpreadConstraints: {{- include "common.tplvalues.render" (dict "value" .Values.primary.topologySpreadConstraints "context" .) | nindent 8 }} + {{- end }} + {{- if .Values.primary.priorityClassName }} + priorityClassName: {{ .Values.primary.priorityClassName }} + {{- end }} + {{- if .Values.primary.schedulerName }} + schedulerName: {{ .Values.primary.schedulerName | quote }} + {{- end }} + {{- if .Values.primary.terminationGracePeriodSeconds }} + terminationGracePeriodSeconds: {{ .Values.primary.terminationGracePeriodSeconds }} + {{- end }} + {{- if .Values.primary.podSecurityContext.enabled }} + securityContext: {{- omit .Values.primary.podSecurityContext "enabled" | toYaml | nindent 8 }} + {{- end }} + hostNetwork: {{ .Values.primary.hostNetwork }} + hostIPC: {{ .Values.primary.hostIPC }} + initContainers: + {{- if and .Values.tls.enabled (not .Values.volumePermissions.enabled) }} + - name: copy-certs + image: {{ include "postgresql.volumePermissions.image" . }} + imagePullPolicy: {{ .Values.volumePermissions.image.pullPolicy | quote }} + {{- if .Values.primary.resources }} + resources: {{- toYaml .Values.primary.resources | nindent 12 }} + {{- end }} + # We don't require a privileged container in this case + {{- if .Values.primary.containerSecurityContext.enabled }} + securityContext: {{- omit .Values.primary.containerSecurityContext "enabled" | toYaml | nindent 12 }} + {{- end }} + command: + - /bin/sh + - -ec + - | + cp /tmp/certs/* /opt/bitnami/postgresql/certs/ + chmod 600 {{ include "postgresql.tlsCertKey" . }} + volumeMounts: + - name: raw-certificates + mountPath: /tmp/certs + - name: postgresql-certificates + mountPath: /opt/bitnami/postgresql/certs + {{- else if and .Values.volumePermissions.enabled (or .Values.primary.persistence.enabled .Values.shmVolume.enabled) }} + - name: init-chmod-data + image: {{ include "postgresql.volumePermissions.image" . }} + imagePullPolicy: {{ .Values.volumePermissions.image.pullPolicy | quote }} + {{- if .Values.volumePermissions.resources }} + resources: {{- toYaml .Values.volumePermissions.resources | nindent 12 }} + {{- end }} + command: + - /bin/sh + - -ec + - | + {{- if .Values.primary.persistence.enabled }} + {{- if eq ( toString ( .Values.volumePermissions.containerSecurityContext.runAsUser )) "auto" }} + chown `id -u`:`id -G | cut -d " " -f2` {{ .Values.primary.persistence.mountPath }} + {{- else }} + chown {{ .Values.primary.containerSecurityContext.runAsUser }}:{{ .Values.primary.podSecurityContext.fsGroup }} {{ .Values.primary.persistence.mountPath }} + {{- end }} + mkdir -p {{ .Values.primary.persistence.mountPath }}/data {{- if (include "postgresql.mountConfigurationCM" .) }} {{ .Values.primary.persistence.mountPath }}/conf {{- end }} + chmod 700 {{ .Values.primary.persistence.mountPath }}/data {{- if (include "postgresql.mountConfigurationCM" .) }} {{ .Values.primary.persistence.mountPath }}/conf {{- end }} + find {{ .Values.primary.persistence.mountPath }} -mindepth 1 -maxdepth 1 {{- if not (include "postgresql.mountConfigurationCM" .) }} -not -name "conf" {{- end }} -not -name ".snapshot" -not -name "lost+found" | \ + {{- if eq ( toString ( .Values.volumePermissions.containerSecurityContext.runAsUser )) "auto" }} + xargs -r chown -R `id -u`:`id -G | cut -d " " -f2` + {{- else }} + xargs -r chown -R {{ .Values.primary.containerSecurityContext.runAsUser }}:{{ .Values.primary.podSecurityContext.fsGroup }} + {{- end }} + {{- end }} + {{- if .Values.shmVolume.enabled }} + chmod -R 777 /dev/shm + {{- end }} + {{- if .Values.tls.enabled }} + cp /tmp/certs/* /opt/bitnami/postgresql/certs/ + {{- if eq ( toString ( .Values.volumePermissions.containerSecurityContext.runAsUser )) "auto" }} + chown -R `id -u`:`id -G | cut -d " " -f2` /opt/bitnami/postgresql/certs/ + {{- else }} + chown -R {{ .Values.primary.containerSecurityContext.runAsUser }}:{{ .Values.primary.podSecurityContext.fsGroup }} /opt/bitnami/postgresql/certs/ + {{- end }} + chmod 600 {{ include "postgresql.tlsCertKey" . }} + {{- end }} + {{- if eq ( toString ( .Values.volumePermissions.containerSecurityContext.runAsUser )) "auto" }} + securityContext: {{- omit .Values.volumePermissions.containerSecurityContext "runAsUser" | toYaml | nindent 12 }} + {{- else }} + securityContext: {{- .Values.volumePermissions.containerSecurityContext | toYaml | nindent 12 }} + {{- end }} + volumeMounts: + {{- if .Values.primary.persistence.enabled }} + - name: data + mountPath: {{ .Values.primary.persistence.mountPath }} + {{- if .Values.primary.persistence.subPath }} + subPath: {{ .Values.primary.persistence.subPath }} + {{- end }} + {{- end }} + {{- if .Values.shmVolume.enabled }} + - name: dshm + mountPath: /dev/shm + {{- end }} + {{- if .Values.tls.enabled }} + - name: raw-certificates + mountPath: /tmp/certs + - name: postgresql-certificates + mountPath: /opt/bitnami/postgresql/certs + {{- end }} + {{- end }} + {{- if .Values.primary.initContainers }} + {{- include "common.tplvalues.render" ( dict "value" .Values.primary.initContainers "context" $ ) | nindent 8 }} + {{- end }} + containers: + - name: postgresql + image: {{ include "postgresql.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy | quote }} + {{- if .Values.primary.containerSecurityContext.enabled }} + securityContext: {{- omit .Values.primary.containerSecurityContext "enabled" | toYaml | nindent 12 }} + {{- end }} + {{- if .Values.diagnosticMode.enabled }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.command "context" $) | nindent 12 }} + {{- else if .Values.primary.command }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.primary.command "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.diagnosticMode.enabled }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.args "context" $) | nindent 12 }} + {{- else if .Values.primary.args }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.primary.args "context" $) | nindent 12 }} + {{- end }} + env: + - name: BITNAMI_DEBUG + value: {{ ternary "true" "false" (or .Values.image.debug .Values.diagnosticMode.enabled) | quote }} + - name: POSTGRESQL_PORT_NUMBER + value: {{ .Values.containerPorts.postgresql | quote }} + - name: POSTGRESQL_VOLUME_DIR + value: {{ .Values.primary.persistence.mountPath | quote }} + {{- if .Values.primary.persistence.mountPath }} + - name: PGDATA + value: {{ .Values.postgresqlDataDir | quote }} + {{- end }} + # Authentication + {{- if and (not (empty $customUser)) (ne $customUser "postgres") }} + - name: POSTGRES_USER + value: {{ $customUser | quote }} + {{- if .Values.auth.enablePostgresUser }} + {{- if .Values.auth.usePasswordFiles }} + - name: POSTGRES_POSTGRES_PASSWORD_FILE + value: "/opt/bitnami/postgresql/secrets/postgres-password" + {{- else }} + - name: POSTGRES_POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "postgresql.secretName" . }} + key: {{ include "postgresql.adminPasswordKey" . }} + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.auth.usePasswordFiles }} + - name: POSTGRES_PASSWORD_FILE + value: {{ printf "/opt/bitnami/postgresql/secrets/%s" (ternary "password" "postgres-password" (and (not (empty $customUser)) (ne $customUser "postgres"))) }} + {{- else }} + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "postgresql.secretName" . }} + key: {{ include "postgresql.userPasswordKey" . }} + {{- end }} + {{- if (include "postgresql.database" .) }} + - name: POSTGRES_DB + value: {{ (include "postgresql.database" .) | quote }} + {{- end }} + # Replication + {{- if or (eq .Values.architecture "replication") .Values.primary.standby.enabled }} + - name: POSTGRES_REPLICATION_MODE + value: {{ ternary "slave" "master" .Values.primary.standby.enabled | quote }} + - name: POSTGRES_REPLICATION_USER + value: {{ .Values.auth.replicationUsername | quote }} + {{- if .Values.auth.usePasswordFiles }} + - name: POSTGRES_REPLICATION_PASSWORD_FILE + value: "/opt/bitnami/postgresql/secrets/replication-password" + {{- else }} + - name: POSTGRES_REPLICATION_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "postgresql.secretName" . }} + key: {{ include "postgresql.replicationPasswordKey" . }} + {{- end }} + {{- if not (eq .Values.replication.synchronousCommit "off") }} + - name: POSTGRES_SYNCHRONOUS_COMMIT_MODE + value: {{ .Values.replication.synchronousCommit | quote }} + - name: POSTGRES_NUM_SYNCHRONOUS_REPLICAS + value: {{ .Values.replication.numSynchronousReplicas | quote }} + {{- end }} + - name: POSTGRES_CLUSTER_APP_NAME + value: {{ .Values.replication.applicationName }} + {{- end }} + # Initdb + {{- if .Values.primary.initdb.args }} + - name: POSTGRES_INITDB_ARGS + value: {{ .Values.primary.initdb.args | quote }} + {{- end }} + {{- if .Values.primary.initdb.postgresqlWalDir }} + - name: POSTGRES_INITDB_WALDIR + value: {{ .Values.primary.initdb.postgresqlWalDir | quote }} + {{- end }} + {{- if .Values.primary.initdb.user }} + - name: POSTGRESQL_INITSCRIPTS_USERNAME + value: {{ .Values.primary.initdb.user }} + {{- end }} + {{- if .Values.primary.initdb.password }} + - name: POSTGRESQL_INITSCRIPTS_PASSWORD + value: {{ .Values.primary.initdb.password | quote }} + {{- end }} + # Standby + {{- if .Values.primary.standby.enabled }} + - name: POSTGRES_MASTER_HOST + value: {{ .Values.primary.standby.primaryHost }} + - name: POSTGRES_MASTER_PORT_NUMBER + value: {{ .Values.primary.standby.primaryPort | quote }} + {{- end }} + # LDAP + - name: POSTGRESQL_ENABLE_LDAP + value: {{ ternary "yes" "no" .Values.ldap.enabled | quote }} + {{- if .Values.ldap.enabled }} + {{- if or .Values.ldap.url .Values.ldap.uri }} + - name: POSTGRESQL_LDAP_URL + value: {{ coalesce .Values.ldap.url .Values.ldap.uri }} + {{- else }} + - name: POSTGRESQL_LDAP_SERVER + value: {{ .Values.ldap.server }} + - name: POSTGRESQL_LDAP_PORT + value: {{ .Values.ldap.port | quote }} + - name: POSTGRESQL_LDAP_SCHEME + value: {{ .Values.ldap.scheme }} + {{- if (include "postgresql.ldap.tls.enabled" .) }} + - name: POSTGRESQL_LDAP_TLS + value: "1" + {{- end }} + - name: POSTGRESQL_LDAP_PREFIX + value: {{ .Values.ldap.prefix | quote }} + - name: POSTGRESQL_LDAP_SUFFIX + value: {{ .Values.ldap.suffix | quote }} + - name: POSTGRESQL_LDAP_BASE_DN + value: {{ coalesce .Values.ldap.baseDN .Values.ldap.basedn }} + - name: POSTGRESQL_LDAP_BIND_DN + value: {{ coalesce .Values.ldap.bindDN .Values.ldap.binddn}} + {{- if or (not (empty .Values.ldap.bind_password)) (not (empty .Values.ldap.bindpw)) }} + - name: POSTGRESQL_LDAP_BIND_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "postgresql.secretName" . }} + key: ldap-password + {{- end }} + - name: POSTGRESQL_LDAP_SEARCH_ATTR + value: {{ coalesce .Values.ldap.search_attr .Values.ldap.searchAttribute }} + - name: POSTGRESQL_LDAP_SEARCH_FILTER + value: {{ coalesce .Values.ldap.search_filter .Values.ldap.searchFilter }} + {{- end }} + {{- end }} + # TLS + - name: POSTGRESQL_ENABLE_TLS + value: {{ ternary "yes" "no" .Values.tls.enabled | quote }} + {{- if .Values.tls.enabled }} + - name: POSTGRESQL_TLS_PREFER_SERVER_CIPHERS + value: {{ ternary "yes" "no" .Values.tls.preferServerCiphers | quote }} + - name: POSTGRESQL_TLS_CERT_FILE + value: {{ include "postgresql.tlsCert" . }} + - name: POSTGRESQL_TLS_KEY_FILE + value: {{ include "postgresql.tlsCertKey" . }} + {{- if .Values.tls.certCAFilename }} + - name: POSTGRESQL_TLS_CA_FILE + value: {{ include "postgresql.tlsCACert" . }} + {{- end }} + {{- if .Values.tls.crlFilename }} + - name: POSTGRESQL_TLS_CRL_FILE + value: {{ include "postgresql.tlsCRL" . }} + {{- end }} + {{- end }} + # Audit + - name: POSTGRESQL_LOG_HOSTNAME + value: {{ .Values.audit.logHostname | quote }} + - name: POSTGRESQL_LOG_CONNECTIONS + value: {{ .Values.audit.logConnections | quote }} + - name: POSTGRESQL_LOG_DISCONNECTIONS + value: {{ .Values.audit.logDisconnections | quote }} + {{- if .Values.audit.logLinePrefix }} + - name: POSTGRESQL_LOG_LINE_PREFIX + value: {{ .Values.audit.logLinePrefix | quote }} + {{- end }} + {{- if .Values.audit.logTimezone }} + - name: POSTGRESQL_LOG_TIMEZONE + value: {{ .Values.audit.logTimezone | quote }} + {{- end }} + {{- if .Values.audit.pgAuditLog }} + - name: POSTGRESQL_PGAUDIT_LOG + value: {{ .Values.audit.pgAuditLog | quote }} + {{- end }} + - name: POSTGRESQL_PGAUDIT_LOG_CATALOG + value: {{ .Values.audit.pgAuditLogCatalog | quote }} + # Others + - name: POSTGRESQL_CLIENT_MIN_MESSAGES + value: {{ .Values.audit.clientMinMessages | quote }} + - name: POSTGRESQL_SHARED_PRELOAD_LIBRARIES + value: {{ .Values.postgresqlSharedPreloadLibraries | quote }} + {{- if .Values.primary.extraEnvVars }} + {{- include "common.tplvalues.render" (dict "value" .Values.primary.extraEnvVars "context" $) | nindent 12 }} + {{- end }} + {{- if or .Values.primary.extraEnvVarsCM .Values.primary.extraEnvVarsSecret }} + envFrom: + {{- if .Values.primary.extraEnvVarsCM }} + - configMapRef: + name: {{ .Values.primary.extraEnvVarsCM }} + {{- end }} + {{- if .Values.primary.extraEnvVarsSecret }} + - secretRef: + name: {{ .Values.primary.extraEnvVarsSecret }} + {{- end }} + {{- end }} + ports: + - name: tcp-postgresql + containerPort: {{ .Values.containerPorts.postgresql }} + {{- if not .Values.diagnosticMode.enabled }} + {{- if .Values.primary.customStartupProbe }} + startupProbe: {{- include "common.tplvalues.render" (dict "value" .Values.primary.customStartupProbe "context" $) | nindent 12 }} + {{- else if .Values.primary.startupProbe.enabled }} + startupProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.primary.startupProbe "enabled") "context" $) | nindent 12 }} + exec: + command: + - /bin/sh + - -c + {{- if (include "postgresql.database" .) }} + - exec pg_isready -U {{ default "postgres" $customUser | quote }} -d "dbname={{ include "postgresql.database" . }} {{- if and .Values.tls.enabled .Values.tls.certCAFilename }} sslcert={{ include "postgresql.tlsCert" . }} sslkey={{ include "postgresql.tlsCertKey" . }}{{- end }}" -h 127.0.0.1 -p {{ .Values.containerPorts.postgresql }} + {{- else }} + - exec pg_isready -U {{ default "postgres" $customUser | quote }} {{- if and .Values.tls.enabled .Values.tls.certCAFilename }} -d "sslcert={{ include "postgresql.tlsCert" . }} sslkey={{ include "postgresql.tlsCertKey" . }}"{{- end }} -h 127.0.0.1 -p {{ .Values.containerPorts.postgresql }} + {{- end }} + {{- end }} + {{- if .Values.primary.customLivenessProbe }} + livenessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.primary.customLivenessProbe "context" $) | nindent 12 }} + {{- else if .Values.primary.livenessProbe.enabled }} + livenessProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.primary.livenessProbe "enabled") "context" $) | nindent 12 }} + exec: + command: + - /bin/sh + - -c + {{- if (include "postgresql.database" .) }} + - exec pg_isready -U {{ default "postgres" $customUser | quote }} -d "dbname={{ include "postgresql.database" . }} {{- if and .Values.tls.enabled .Values.tls.certCAFilename }} sslcert={{ include "postgresql.tlsCert" . }} sslkey={{ include "postgresql.tlsCertKey" . }}{{- end }}" -h 127.0.0.1 -p {{ .Values.containerPorts.postgresql }} + {{- else }} + - exec pg_isready -U {{ default "postgres" $customUser | quote }} {{- if and .Values.tls.enabled .Values.tls.certCAFilename }} -d "sslcert={{ include "postgresql.tlsCert" . }} sslkey={{ include "postgresql.tlsCertKey" . }}"{{- end }} -h 127.0.0.1 -p {{ .Values.containerPorts.postgresql }} + {{- end }} + {{- end }} + {{- if .Values.primary.customReadinessProbe }} + readinessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.primary.customReadinessProbe "context" $) | nindent 12 }} + {{- else if .Values.primary.readinessProbe.enabled }} + readinessProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.primary.readinessProbe "enabled") "context" $) | nindent 12 }} + exec: + command: + - /bin/sh + - -c + - -e + {{- include "postgresql.readinessProbeCommand" . | nindent 16 }} + {{- end }} + {{- end }} + {{- if .Values.primary.resources }} + resources: {{- toYaml .Values.primary.resources | nindent 12 }} + {{- end }} + {{- if .Values.primary.lifecycleHooks }} + lifecycle: {{- include "common.tplvalues.render" (dict "value" .Values.primary.lifecycleHooks "context" $) | nindent 12 }} + {{- end }} + volumeMounts: + {{- if or .Values.primary.initdb.scriptsConfigMap .Values.primary.initdb.scripts }} + - name: custom-init-scripts + mountPath: /docker-entrypoint-initdb.d/ + {{- end }} + {{- if .Values.primary.initdb.scriptsSecret }} + - name: custom-init-scripts-secret + mountPath: /docker-entrypoint-initdb.d/secret + {{- end }} + {{- if or .Values.primary.extendedConfiguration .Values.primary.existingExtendedConfigmap }} + - name: postgresql-extended-config + mountPath: /bitnami/postgresql/conf/conf.d/ + {{- end }} + {{- if .Values.auth.usePasswordFiles }} + - name: postgresql-password + mountPath: /opt/bitnami/postgresql/secrets/ + {{- end }} + {{- if .Values.tls.enabled }} + - name: postgresql-certificates + mountPath: /opt/bitnami/postgresql/certs + readOnly: true + {{- end }} + {{- if .Values.shmVolume.enabled }} + - name: dshm + mountPath: /dev/shm + {{- end }} + {{- if .Values.primary.persistence.enabled }} + - name: data + mountPath: {{ .Values.primary.persistence.mountPath }} + {{- if .Values.primary.persistence.subPath }} + subPath: {{ .Values.primary.persistence.subPath }} + {{- end }} + {{- end }} + {{- if or .Values.primary.configuration .Values.primary.pgHbaConfiguration .Values.primary.existingConfigmap }} + - name: postgresql-config + mountPath: /bitnami/postgresql/conf + {{- end }} + {{- if .Values.primary.extraVolumeMounts }} + {{- include "common.tplvalues.render" (dict "value" .Values.primary.extraVolumeMounts "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.metrics.enabled }} + - name: metrics + image: {{ include "postgresql.metrics.image" . }} + imagePullPolicy: {{ .Values.metrics.image.pullPolicy | quote }} + {{- if .Values.metrics.containerSecurityContext.enabled }} + securityContext: {{- omit .Values.metrics.containerSecurityContext "enabled" | toYaml | nindent 12 }} + {{- end }} + {{- if .Values.diagnosticMode.enabled }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.command "context" $) | nindent 12 }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.args "context" $) | nindent 12 }} + {{- else if .Values.metrics.customMetrics }} + args: ["--extend.query-path", "/conf/custom-metrics.yaml"] + {{- end }} + env: + {{- $database := required "In order to enable metrics you need to specify a database (.Values.auth.database or .Values.global.postgresql.auth.database)" (include "postgresql.database" .) }} + - name: DATA_SOURCE_URI + value: {{ printf "127.0.0.1:%d/%s?sslmode=disable" (int (include "postgresql.service.port" .)) $database }} + {{- if .Values.auth.usePasswordFiles }} + - name: DATA_SOURCE_PASS_FILE + value: {{ printf "/opt/bitnami/postgresql/secrets/%s" (ternary "password" "postgres-password" (and (not (empty $customUser)) (ne $customUser "postgres"))) }} + {{- else }} + - name: DATA_SOURCE_PASS + valueFrom: + secretKeyRef: + name: {{ include "postgresql.secretName" . }} + key: {{ include "postgresql.userPasswordKey" . }} + {{- end }} + - name: DATA_SOURCE_USER + value: {{ default "postgres" $customUser | quote }} + {{- if .Values.metrics.extraEnvVars }} + {{- include "common.tplvalues.render" (dict "value" .Values.metrics.extraEnvVars "context" $) | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: {{ .Values.metrics.containerPorts.metrics }} + {{- if not .Values.diagnosticMode.enabled }} + {{- if .Values.metrics.customStartupProbe }} + startupProbe: {{- include "common.tplvalues.render" (dict "value" .Values.metrics.customStartupProbe "context" $) | nindent 12 }} + {{- else if .Values.metrics.startupProbe.enabled }} + startupProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.metrics.startupProbe "enabled") "context" $) | nindent 12 }} + tcpSocket: + port: http-metrics + {{- end }} + {{- if .Values.metrics.customLivenessProbe }} + livenessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.metrics.customLivenessProbe "context" $) | nindent 12 }} + {{- else if .Values.metrics.livenessProbe.enabled }} + livenessProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.metrics.livenessProbe "enabled") "context" $) | nindent 12 }} + httpGet: + path: / + port: http-metrics + {{- end }} + {{- if .Values.metrics.customReadinessProbe }} + readinessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.metrics.customReadinessProbe "context" $) | nindent 12 }} + {{- else if .Values.metrics.readinessProbe.enabled }} + readinessProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.metrics.readinessProbe "enabled") "context" $) | nindent 12 }} + httpGet: + path: / + port: http-metrics + {{- end }} + {{- end }} + volumeMounts: + {{- if .Values.auth.usePasswordFiles }} + - name: postgresql-password + mountPath: /opt/bitnami/postgresql/secrets/ + {{- end }} + {{- if .Values.metrics.customMetrics }} + - name: custom-metrics + mountPath: /conf + readOnly: true + {{- end }} + {{- if .Values.metrics.resources }} + resources: {{- toYaml .Values.metrics.resources | nindent 12 }} + {{- end }} + {{- end }} + {{- if .Values.primary.sidecars }} + {{- include "common.tplvalues.render" ( dict "value" .Values.primary.sidecars "context" $ ) | nindent 8 }} + {{- end }} + volumes: + {{- if or .Values.primary.configuration .Values.primary.pgHbaConfiguration .Values.primary.existingConfigmap }} + - name: postgresql-config + configMap: + name: {{ include "postgresql.primary.configmapName" . }} + {{- end }} + {{- if or .Values.primary.extendedConfiguration .Values.primary.existingExtendedConfigmap }} + - name: postgresql-extended-config + configMap: + name: {{ include "postgresql.primary.extendedConfigmapName" . }} + {{- end }} + {{- if .Values.auth.usePasswordFiles }} + - name: postgresql-password + secret: + secretName: {{ include "postgresql.secretName" . }} + {{- end }} + {{- if or .Values.primary.initdb.scriptsConfigMap .Values.primary.initdb.scripts }} + - name: custom-init-scripts + configMap: + name: {{ include "postgresql.initdb.scriptsCM" . }} + {{- end }} + {{- if .Values.primary.initdb.scriptsSecret }} + - name: custom-init-scripts-secret + secret: + secretName: {{ tpl .Values.primary.initdb.scriptsSecret $ }} + {{- end }} + {{- if .Values.tls.enabled }} + - name: raw-certificates + secret: + secretName: {{ include "postgresql.tlsSecretName" . }} + - name: postgresql-certificates + emptyDir: {} + {{- end }} + {{- if .Values.primary.extraVolumes }} + {{- include "common.tplvalues.render" ( dict "value" .Values.primary.extraVolumes "context" $ ) | nindent 8 }} + {{- end }} + {{- if and .Values.metrics.enabled .Values.metrics.customMetrics }} + - name: custom-metrics + configMap: + name: {{ printf "%s-metrics" (include "common.names.fullname" .) }} + {{- end }} + {{- if .Values.shmVolume.enabled }} + - name: dshm + emptyDir: + medium: Memory + {{- if .Values.shmVolume.sizeLimit }} + sizeLimit: {{ .Values.shmVolume.sizeLimit }} + {{- end }} + {{- end }} + {{- if and .Values.primary.persistence.enabled .Values.primary.persistence.existingClaim }} + - name: data + persistentVolumeClaim: + claimName: {{ tpl .Values.primary.persistence.existingClaim $ }} + {{- else if not .Values.primary.persistence.enabled }} + - name: data + emptyDir: {} + {{- else }} + volumeClaimTemplates: + - metadata: + name: data + {{- if .Values.primary.persistence.annotations }} + annotations: {{- include "common.tplvalues.render" (dict "value" .Values.primary.persistence.annotations "context" $) | nindent 10 }} + {{- end }} + {{- if .Values.primary.persistence.labels }} + labels: {{- include "common.tplvalues.render" (dict "value" .Values.primary.persistence.labels "context" $) | nindent 10 }} + {{- end }} + spec: + accessModes: + {{- range .Values.primary.persistence.accessModes }} + - {{ . | quote }} + {{- end }} + {{- if .Values.primary.persistence.dataSource }} + dataSource: {{- include "common.tplvalues.render" (dict "value" .Values.primary.persistence.dataSource "context" $) | nindent 10 }} + {{- end }} + resources: + requests: + storage: {{ .Values.primary.persistence.size | quote }} + {{- if .Values.primary.persistence.selector }} + selector: {{- include "common.tplvalues.render" (dict "value" .Values.primary.persistence.selector "context" $) | nindent 10 }} + {{- end }} + {{- include "common.storage.class" (dict "persistence" .Values.primary.persistence "global" .Values.global) | nindent 8 }} + {{- end }} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/templates/primary/svc-headless.yaml b/charts/kong/kong/2.41.0/charts/postgresql/templates/primary/svc-headless.yaml new file mode 100644 index 0000000000..b7826318fc --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/templates/primary/svc-headless.yaml @@ -0,0 +1,31 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "postgresql.primary.svc.headless" . }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + app.kubernetes.io/component: primary + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + # Use this annotation in addition to the actual publishNotReadyAddresses + # 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" +spec: + type: ClusterIP + clusterIP: None + # We want all pods in the StatefulSet to have their addresses published for + # the sake of the other Postgresql 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: + - name: tcp-postgresql + port: {{ template "postgresql.service.port" . }} + targetPort: tcp-postgresql + selector: {{- include "common.labels.matchLabels" . | nindent 4 }} + app.kubernetes.io/component: primary diff --git a/charts/kong/kong/2.41.0/charts/postgresql/templates/primary/svc.yaml b/charts/kong/kong/2.41.0/charts/postgresql/templates/primary/svc.yaml new file mode 100644 index 0000000000..cf184809ae --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/templates/primary/svc.yaml @@ -0,0 +1,51 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "postgresql.primary.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + app.kubernetes.io/component: primary + annotations: + {{- if .Values.commonAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.primary.service.annotations }} + {{- include "common.tplvalues.render" (dict "value" .Values.primary.service.annotations "context" $) | nindent 4 }} + {{- end }} +spec: + type: {{ .Values.primary.service.type }} + {{- if or (eq .Values.primary.service.type "LoadBalancer") (eq .Values.primary.service.type "NodePort") }} + externalTrafficPolicy: {{ .Values.primary.service.externalTrafficPolicy | quote }} + {{- end }} + {{- if and (eq .Values.primary.service.type "LoadBalancer") (not (empty .Values.primary.service.loadBalancerSourceRanges)) }} + loadBalancerSourceRanges: {{ .Values.primary.service.loadBalancerSourceRanges }} + {{- end }} + {{- if and (eq .Values.primary.service.type "LoadBalancer") (not (empty .Values.primary.service.loadBalancerIP)) }} + loadBalancerIP: {{ .Values.primary.service.loadBalancerIP }} + {{- end }} + {{- if and .Values.primary.service.clusterIP (eq .Values.primary.service.type "ClusterIP") }} + clusterIP: {{ .Values.primary.service.clusterIP }} + {{- end }} + {{- if .Values.primary.service.sessionAffinity }} + sessionAffinity: {{ .Values.primary.service.sessionAffinity }} + {{- end }} + {{- if .Values.primary.service.sessionAffinityConfig }} + sessionAffinityConfig: {{- include "common.tplvalues.render" (dict "value" .Values.primary.service.sessionAffinityConfig "context" $) | nindent 4 }} + {{- end }} + ports: + - name: tcp-postgresql + port: {{ template "postgresql.service.port" . }} + targetPort: tcp-postgresql + {{- if and (or (eq .Values.primary.service.type "NodePort") (eq .Values.primary.service.type "LoadBalancer")) (not (empty .Values.primary.service.nodePorts.postgresql)) }} + nodePort: {{ .Values.primary.service.nodePorts.postgresql }} + {{- else if eq .Values.primary.service.type "ClusterIP" }} + nodePort: null + {{- end }} + {{- if .Values.primary.service.extraPorts }} + {{- include "common.tplvalues.render" (dict "value" .Values.primary.service.extraPorts "context" $) | nindent 4 }} + {{- end }} + selector: {{- include "common.labels.matchLabels" . | nindent 4 }} + app.kubernetes.io/component: primary diff --git a/charts/kong/kong/2.41.0/charts/postgresql/templates/prometheusrule.yaml b/charts/kong/kong/2.41.0/charts/postgresql/templates/prometheusrule.yaml new file mode 100644 index 0000000000..24be7100be --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/templates/prometheusrule.yaml @@ -0,0 +1,22 @@ +{{- if and .Values.metrics.enabled .Values.metrics.prometheusRule.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ include "common.names.fullname" . }} + namespace: {{ default .Release.Namespace .Values.metrics.prometheusRule.namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: metrics + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.metrics.prometheusRule.labels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.prometheusRule.labels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + groups: + - name: {{ include "common.names.fullname" . }} + rules: {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.prometheusRule.rules "context" $ ) | nindent 8 }} +{{- end }} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/templates/psp.yaml b/charts/kong/kong/2.41.0/charts/postgresql/templates/psp.yaml new file mode 100644 index 0000000000..48d11754d6 --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/templates/psp.yaml @@ -0,0 +1,41 @@ +{{- $pspAvailable := (semverCompare "<1.25-0" (include "common.capabilities.kubeVersion" .)) -}} +{{- if and $pspAvailable .Values.psp.create }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ include "common.names.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + privileged: false + volumes: + - 'configMap' + - 'secret' + - 'persistentVolumeClaim' + - 'emptyDir' + - 'projected' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'MustRunAs' + ranges: + - min: 1 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + - min: 1 + max: 65535 + readOnlyRootFilesystem: false +{{- end }} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/templates/read/extended-configmap.yaml b/charts/kong/kong/2.41.0/charts/postgresql/templates/read/extended-configmap.yaml new file mode 100644 index 0000000000..e329d13853 --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/templates/read/extended-configmap.yaml @@ -0,0 +1,18 @@ +{{- if (include "postgresql.readReplicas.createExtendedConfigmap" .) }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ printf "%s-extended-configuration" (include "postgresql.readReplica.fullname" .) }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: read + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +data: + override.conf: |- + {{- include "common.tplvalues.render" ( dict "value" .Values.readReplicas.extendedConfiguration "context" $ ) | nindent 4 }} +{{- end }} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/templates/read/metrics-configmap.yaml b/charts/kong/kong/2.41.0/charts/postgresql/templates/read/metrics-configmap.yaml new file mode 100644 index 0000000000..b00a6eccb4 --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/templates/read/metrics-configmap.yaml @@ -0,0 +1,16 @@ +{{- if and .Values.metrics.enabled .Values.metrics.customMetrics (eq .Values.architecture "replication") }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ printf "%s-metrics" (include "postgresql.readReplica.fullname" .) }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +data: + custom-metrics.yaml: {{ toYaml .Values.metrics.customMetrics | quote }} +{{- end }} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/templates/read/metrics-svc.yaml b/charts/kong/kong/2.41.0/charts/postgresql/templates/read/metrics-svc.yaml new file mode 100644 index 0000000000..b3e54974e9 --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/templates/read/metrics-svc.yaml @@ -0,0 +1,31 @@ +{{- if and .Values.metrics.enabled (eq .Values.architecture "replication") }} +apiVersion: v1 +kind: Service +metadata: + name: {{ printf "%s-metrics" (include "postgresql.readReplica.fullname" .) }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: metrics-read + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + annotations: + {{- if .Values.commonAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.metrics.service.annotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.service.annotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + type: ClusterIP + sessionAffinity: {{ .Values.metrics.service.sessionAffinity }} + {{- if .Values.metrics.service.clusterIP }} + clusterIP: {{ .Values.metrics.service.clusterIP }} + {{- end }} + ports: + - name: http-metrics + port: {{ .Values.metrics.service.ports.metrics }} + targetPort: http-metrics + selector: {{- include "common.labels.matchLabels" . | nindent 4 }} + app.kubernetes.io/component: read +{{- end }} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/templates/read/networkpolicy.yaml b/charts/kong/kong/2.41.0/charts/postgresql/templates/read/networkpolicy.yaml new file mode 100644 index 0000000000..c969cd7a7c --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/templates/read/networkpolicy.yaml @@ -0,0 +1,36 @@ +{{- if and .Values.networkPolicy.enabled (eq .Values.architecture "replication") .Values.networkPolicy.ingressRules.readReplicasAccessOnlyFrom.enabled }} +apiVersion: {{ include "common.capabilities.networkPolicy.apiVersion" . }} +kind: NetworkPolicy +metadata: + name: {{ printf "%s-ingress" (include "postgresql.readReplica.fullname" .) }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: read + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + podSelector: + matchLabels: {{- include "common.labels.matchLabels" . | nindent 6 }} + app.kubernetes.io/component: read + ingress: + {{- if and .Values.networkPolicy.ingressRules.readReplicasAccessOnlyFrom.enabled (or .Values.networkPolicy.ingressRules.readReplicasAccessOnlyFrom.namespaceSelector .Values.networkPolicy.ingressRules.readReplicasAccessOnlyFrom.podSelector) }} + - from: + {{- if .Values.networkPolicy.ingressRules.readReplicasAccessOnlyFrom.namespaceSelector }} + - namespaceSelector: + matchLabels: {{- include "common.tplvalues.render" (dict "value" .Values.networkPolicy.ingressRules.readReplicasAccessOnlyFrom.namespaceSelector "context" $) | nindent 14 }} + {{- end }} + {{- if .Values.networkPolicy.ingressRules.readReplicasAccessOnlyFrom.podSelector }} + - podSelector: + matchLabels: {{- include "common.tplvalues.render" (dict "value" .Values.networkPolicy.ingressRules.readReplicasAccessOnlyFrom.podSelector "context" $) | nindent 14 }} + {{- end }} + ports: + - port: {{ .Values.containerPorts.postgresql }} + {{- end }} + {{- if .Values.networkPolicy.ingressRules.readReplicasAccessOnlyFrom.customRules }} + {{- include "common.tplvalues.render" (dict "value" .Values.networkPolicy.ingressRules.readReplicasAccessOnlyFrom.customRules "context" $) | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/templates/read/servicemonitor.yaml b/charts/kong/kong/2.41.0/charts/postgresql/templates/read/servicemonitor.yaml new file mode 100644 index 0000000000..d511d6beb2 --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/templates/read/servicemonitor.yaml @@ -0,0 +1,48 @@ +{{- if and .Values.metrics.enabled .Values.metrics.serviceMonitor.enabled (eq .Values.architecture "replication") }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "postgresql.readReplica.fullname" . }} + namespace: {{ default .Release.Namespace .Values.metrics.serviceMonitor.namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: metrics-read + {{- if .Values.metrics.serviceMonitor.labels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.serviceMonitor.labels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + {{- if .Values.metrics.serviceMonitor.jobLabel }} + jobLabel: {{ .Values.metrics.serviceMonitor.jobLabel }} + {{- end }} + selector: + matchLabels: {{- include "common.labels.matchLabels" . | nindent 6 }} + {{- if .Values.metrics.serviceMonitor.selector }} + {{- include "common.tplvalues.render" (dict "value" .Values.metrics.serviceMonitor.selector "context" $) | nindent 6 }} + {{- end }} + app.kubernetes.io/component: metrics-read + endpoints: + - port: http-metrics + {{- if .Values.metrics.serviceMonitor.interval }} + interval: {{ .Values.metrics.serviceMonitor.interval }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.metrics.serviceMonitor.scrapeTimeout }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.relabelings }} + relabelings: {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.serviceMonitor.relabelings "context" $) | nindent 6 }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.metricRelabelings }} + metricRelabelings: {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.serviceMonitor.metricRelabelings "context" $) | nindent 6 }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.honorLabels }} + honorLabels: {{ .Values.metrics.serviceMonitor.honorLabels }} + {{- end }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace | quote }} +{{- end }} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/templates/read/statefulset.yaml b/charts/kong/kong/2.41.0/charts/postgresql/templates/read/statefulset.yaml new file mode 100644 index 0000000000..b3ff1da693 --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/templates/read/statefulset.yaml @@ -0,0 +1,531 @@ +{{- if eq .Values.architecture "replication" }} +{{- $customUser := include "postgresql.username" . }} +apiVersion: {{ include "common.capabilities.statefulset.apiVersion" . }} +kind: StatefulSet +metadata: + name: {{ include "postgresql.readReplica.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: read + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.readReplicas.labels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.readReplicas.labels "context" $ ) | nindent 4 }} + {{- end }} + annotations: + {{- if .Values.commonAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.readReplicas.annotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.readReplicas.annotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.readReplicas.replicaCount }} + serviceName: {{ include "postgresql.readReplica.svc.headless" . }} + {{- if .Values.readReplicas.updateStrategy }} + updateStrategy: {{- toYaml .Values.readReplicas.updateStrategy | nindent 4 }} + {{- end }} + selector: + matchLabels: {{- include "common.labels.matchLabels" . | nindent 6 }} + app.kubernetes.io/component: read + template: + metadata: + name: {{ include "postgresql.readReplica.fullname" . }} + labels: {{- include "common.labels.standard" . | nindent 8 }} + app.kubernetes.io/component: read + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 8 }} + {{- end }} + {{- if .Values.readReplicas.podLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.readReplicas.podLabels "context" $ ) | nindent 8 }} + {{- end }} + annotations: + {{- if (include "postgresql.readReplicas.createExtendedConfigmap" .) }} + checksum/extended-configuration: {{ include (print $.Template.BasePath "/read/extended-configmap.yaml") . | sha256sum }} + {{- end }} + {{- if .Values.readReplicas.podAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.readReplicas.podAnnotations "context" $ ) | nindent 8 }} + {{- end }} + spec: + {{- if .Values.readReplicas.extraPodSpec }} + {{- include "common.tplvalues.render" (dict "value" .Values.readReplicas.extraPodSpec "context" $) | nindent 6 }} + {{- end }} + serviceAccountName: {{ include "postgresql.serviceAccountName" . }} + {{- include "postgresql.imagePullSecrets" . | nindent 6 }} + {{- if .Values.readReplicas.hostAliases }} + hostAliases: {{- include "common.tplvalues.render" (dict "value" .Values.readReplicas.hostAliases "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.readReplicas.affinity }} + affinity: {{- include "common.tplvalues.render" (dict "value" .Values.readReplicas.affinity "context" $) | nindent 8 }} + {{- else }} + affinity: + podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.readReplicas.podAffinityPreset "component" "read" "context" $) | nindent 10 }} + podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.readReplicas.podAntiAffinityPreset "component" "read" "context" $) | nindent 10 }} + nodeAffinity: {{- include "common.affinities.nodes" (dict "type" .Values.readReplicas.nodeAffinityPreset.type "key" .Values.readReplicas.nodeAffinityPreset.key "values" .Values.readReplicas.nodeAffinityPreset.values) | nindent 10 }} + {{- end }} + {{- if .Values.readReplicas.nodeSelector }} + nodeSelector: {{- include "common.tplvalues.render" (dict "value" .Values.readReplicas.nodeSelector "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.readReplicas.tolerations }} + tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.readReplicas.tolerations "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.readReplicas.topologySpreadConstraints }} + topologySpreadConstraints: {{- include "common.tplvalues.render" (dict "value" .Values.readReplicas.topologySpreadConstraints "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.readReplicas.priorityClassName }} + priorityClassName: {{ .Values.readReplicas.priorityClassName }} + {{- end }} + {{- if .Values.readReplicas.schedulerName }} + schedulerName: {{ .Values.readReplicas.schedulerName | quote }} + {{- end }} + {{- if .Values.readReplicas.terminationGracePeriodSeconds }} + terminationGracePeriodSeconds: {{ .Values.readReplicas.terminationGracePeriodSeconds }} + {{- end }} + {{- if .Values.readReplicas.podSecurityContext.enabled }} + securityContext: {{- omit .Values.readReplicas.podSecurityContext "enabled" | toYaml | nindent 8 }} + {{- end }} + hostNetwork: {{ .Values.readReplicas.hostNetwork }} + hostIPC: {{ .Values.readReplicas.hostIPC }} + initContainers: + {{- if and .Values.tls.enabled (not .Values.volumePermissions.enabled) }} + - name: copy-certs + image: {{ include "postgresql.volumePermissions.image" . }} + imagePullPolicy: {{ .Values.volumePermissions.image.pullPolicy | quote }} + {{- if .Values.readReplicas.resources }} + resources: {{- toYaml .Values.readReplicas.resources | nindent 12 }} + {{- end }} + # We don't require a privileged container in this case + {{- if .Values.readReplicas.containerSecurityContext.enabled }} + securityContext: {{- omit .Values.readReplicas.containerSecurityContext "enabled" | toYaml | nindent 12 }} + {{- end }} + command: + - /bin/sh + - -ec + - | + cp /tmp/certs/* /opt/bitnami/postgresql/certs/ + chmod 600 {{ include "postgresql.tlsCertKey" . }} + volumeMounts: + - name: raw-certificates + mountPath: /tmp/certs + - name: postgresql-certificates + mountPath: /opt/bitnami/postgresql/certs + {{- else if and .Values.volumePermissions.enabled (or .Values.readReplicas.persistence.enabled .Values.shmVolume.enabled) }} + - name: init-chmod-data + image: {{ include "postgresql.volumePermissions.image" . }} + imagePullPolicy: {{ .Values.volumePermissions.image.pullPolicy | quote }} + {{- if .Values.readReplicas.resources }} + resources: {{- toYaml .Values.readReplicas.resources | nindent 12 }} + {{- end }} + command: + - /bin/sh + - -ec + - | + {{- if .Values.readReplicas.persistence.enabled }} + {{- if eq ( toString ( .Values.volumePermissions.containerSecurityContext.runAsUser )) "auto" }} + chown `id -u`:`id -G | cut -d " " -f2` {{ .Values.readReplicas.persistence.mountPath }} + {{- else }} + chown {{ .Values.readReplicas.containerSecurityContext.runAsUser }}:{{ .Values.readReplicas.podSecurityContext.fsGroup }} {{ .Values.readReplicas.persistence.mountPath }} + {{- end }} + mkdir -p {{ .Values.readReplicas.persistence.mountPath }}/data {{- if (include "postgresql.mountConfigurationCM" .) }} {{ .Values.readReplicas.persistence.mountPath }}/conf {{- end }} + chmod 700 {{ .Values.readReplicas.persistence.mountPath }}/data {{- if (include "postgresql.mountConfigurationCM" .) }} {{ .Values.readReplicas.persistence.mountPath }}/conf {{- end }} + find {{ .Values.readReplicas.persistence.mountPath }} -mindepth 1 -maxdepth 1 {{- if not (include "postgresql.mountConfigurationCM" .) }} -not -name "conf" {{- end }} -not -name ".snapshot" -not -name "lost+found" | \ + {{- if eq ( toString ( .Values.volumePermissions.containerSecurityContext.runAsUser )) "auto" }} + xargs -r chown -R `id -u`:`id -G | cut -d " " -f2` + {{- else }} + xargs -r chown -R {{ .Values.readReplicas.containerSecurityContext.runAsUser }}:{{ .Values.readReplicas.podSecurityContext.fsGroup }} + {{- end }} + {{- end }} + {{- if .Values.shmVolume.enabled }} + chmod -R 777 /dev/shm + {{- end }} + {{- if .Values.tls.enabled }} + cp /tmp/certs/* /opt/bitnami/postgresql/certs/ + {{- if eq ( toString ( .Values.volumePermissions.containerSecurityContext.runAsUser )) "auto" }} + chown -R `id -u`:`id -G | cut -d " " -f2` /opt/bitnami/postgresql/certs/ + {{- else }} + chown -R {{ .Values.readReplicas.containerSecurityContext.runAsUser }}:{{ .Values.readReplicas.podSecurityContext.fsGroup }} /opt/bitnami/postgresql/certs/ + {{- end }} + chmod 600 {{ include "postgresql.tlsCertKey" . }} + {{- end }} + {{- if eq ( toString ( .Values.volumePermissions.containerSecurityContext.runAsUser )) "auto" }} + securityContext: {{- omit .Values.volumePermissions.containerSecurityContext "runAsUser" | toYaml | nindent 12 }} + {{- else }} + securityContext: {{- .Values.volumePermissions.containerSecurityContext | toYaml | nindent 12 }} + {{- end }} + volumeMounts: + {{ if .Values.readReplicas.persistence.enabled }} + - name: data + mountPath: {{ .Values.readReplicas.persistence.mountPath }} + {{- if .Values.readReplicas.persistence.subPath }} + subPath: {{ .Values.readReplicas.persistence.subPath }} + {{- end }} + {{- end }} + {{- if .Values.shmVolume.enabled }} + - name: dshm + mountPath: /dev/shm + {{- end }} + {{- if .Values.tls.enabled }} + - name: raw-certificates + mountPath: /tmp/certs + - name: postgresql-certificates + mountPath: /opt/bitnami/postgresql/certs + {{- end }} + {{- end }} + {{- if .Values.readReplicas.initContainers }} + {{- include "common.tplvalues.render" ( dict "value" .Values.readReplicas.initContainers "context" $ ) | nindent 8 }} + {{- end }} + containers: + - name: postgresql + image: {{ include "postgresql.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy | quote }} + {{- if .Values.readReplicas.containerSecurityContext.enabled }} + securityContext: {{- omit .Values.readReplicas.containerSecurityContext "enabled" | toYaml | nindent 12 }} + {{- end }} + {{- if .Values.diagnosticMode.enabled }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.command "context" $) | nindent 12 }} + {{- else if .Values.readReplicas.command }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.readReplicas.command "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.diagnosticMode.enabled }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.args "context" $) | nindent 12 }} + {{- else if .Values.readReplicas.args }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.readReplicas.args "context" $) | nindent 12 }} + {{- end }} + env: + - name: BITNAMI_DEBUG + value: {{ ternary "true" "false" (or .Values.image.debug .Values.diagnosticMode.enabled) | quote }} + - name: POSTGRESQL_PORT_NUMBER + value: {{ .Values.containerPorts.postgresql | quote }} + - name: POSTGRESQL_VOLUME_DIR + value: {{ .Values.readReplicas.persistence.mountPath | quote }} + {{- if .Values.readReplicas.persistence.mountPath }} + - name: PGDATA + value: {{ .Values.postgresqlDataDir | quote }} + {{- end }} + # Authentication + {{- if and (not (empty $customUser)) (ne $customUser "postgres") .Values.auth.enablePostgresUser }} + {{- if .Values.auth.usePasswordFiles }} + - name: POSTGRES_POSTGRES_PASSWORD_FILE + value: "/opt/bitnami/postgresql/secrets/postgres-password" + {{- else }} + - name: POSTGRES_POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "postgresql.secretName" . }} + key: {{ include "postgresql.adminPasswordKey" . }} + {{- end }} + {{- end }} + {{- if .Values.auth.usePasswordFiles }} + - name: POSTGRES_PASSWORD_FILE + value: {{ printf "/opt/bitnami/postgresql/secrets/%s" (ternary "password" "postgres-password" (and (not (empty $customUser)) (ne $customUser "postgres"))) }} + {{- else }} + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "postgresql.secretName" . }} + key: {{ include "postgresql.userPasswordKey" . }} + {{- end }} + # Replication + - name: POSTGRES_REPLICATION_MODE + value: "slave" + - name: POSTGRES_REPLICATION_USER + value: {{ .Values.auth.replicationUsername | quote }} + {{- if .Values.auth.usePasswordFiles }} + - name: POSTGRES_REPLICATION_PASSWORD_FILE + value: "/opt/bitnami/postgresql/secrets/replication-password" + {{- else }} + - name: POSTGRES_REPLICATION_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "postgresql.secretName" . }} + key: {{ include "postgresql.replicationPasswordKey" . }} + {{- end }} + - name: POSTGRES_CLUSTER_APP_NAME + value: {{ .Values.replication.applicationName }} + - name: POSTGRES_MASTER_HOST + value: {{ include "postgresql.primary.fullname" . }} + - name: POSTGRES_MASTER_PORT_NUMBER + value: {{ include "postgresql.service.port" . | quote }} + # TLS + - name: POSTGRESQL_ENABLE_TLS + value: {{ ternary "yes" "no" .Values.tls.enabled | quote }} + {{- if .Values.tls.enabled }} + - name: POSTGRESQL_TLS_PREFER_SERVER_CIPHERS + value: {{ ternary "yes" "no" .Values.tls.preferServerCiphers | quote }} + - name: POSTGRESQL_TLS_CERT_FILE + value: {{ include "postgresql.tlsCert" . }} + - name: POSTGRESQL_TLS_KEY_FILE + value: {{ include "postgresql.tlsCertKey" . }} + {{- if .Values.tls.certCAFilename }} + - name: POSTGRESQL_TLS_CA_FILE + value: {{ include "postgresql.tlsCACert" . }} + {{- end }} + {{- if .Values.tls.crlFilename }} + - name: POSTGRESQL_TLS_CRL_FILE + value: {{ include "postgresql.tlsCRL" . }} + {{- end }} + {{- end }} + # Audit + - name: POSTGRESQL_LOG_HOSTNAME + value: {{ .Values.audit.logHostname | quote }} + - name: POSTGRESQL_LOG_CONNECTIONS + value: {{ .Values.audit.logConnections | quote }} + - name: POSTGRESQL_LOG_DISCONNECTIONS + value: {{ .Values.audit.logDisconnections | quote }} + {{- if .Values.audit.logLinePrefix }} + - name: POSTGRESQL_LOG_LINE_PREFIX + value: {{ .Values.audit.logLinePrefix | quote }} + {{- end }} + {{- if .Values.audit.logTimezone }} + - name: POSTGRESQL_LOG_TIMEZONE + value: {{ .Values.audit.logTimezone | quote }} + {{- end }} + {{- if .Values.audit.pgAuditLog }} + - name: POSTGRESQL_PGAUDIT_LOG + value: {{ .Values.audit.pgAuditLog | quote }} + {{- end }} + - name: POSTGRESQL_PGAUDIT_LOG_CATALOG + value: {{ .Values.audit.pgAuditLogCatalog | quote }} + # Others + - name: POSTGRESQL_CLIENT_MIN_MESSAGES + value: {{ .Values.audit.clientMinMessages | quote }} + - name: POSTGRESQL_SHARED_PRELOAD_LIBRARIES + value: {{ .Values.postgresqlSharedPreloadLibraries | quote }} + {{- if .Values.readReplicas.extraEnvVars }} + {{- include "common.tplvalues.render" (dict "value" .Values.readReplicas.extraEnvVars "context" $) | nindent 12 }} + {{- end }} + {{- if or .Values.readReplicas.extraEnvVarsCM .Values.readReplicas.extraEnvVarsSecret }} + envFrom: + {{- if .Values.readReplicas.extraEnvVarsCM }} + - configMapRef: + name: {{ .Values.readReplicas.extraEnvVarsCM }} + {{- end }} + {{- if .Values.readReplicas.extraEnvVarsSecret }} + - secretRef: + name: {{ .Values.readReplicas.extraEnvVarsSecret }} + {{- end }} + {{- end }} + ports: + - name: tcp-postgresql + containerPort: {{ .Values.containerPorts.postgresql }} + {{- if not .Values.diagnosticMode.enabled }} + {{- if .Values.readReplicas.customStartupProbe }} + startupProbe: {{- include "common.tplvalues.render" (dict "value" .Values.readReplicas.customStartupProbe "context" $) | nindent 12 }} + {{- else if .Values.readReplicas.startupProbe.enabled }} + startupProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.readReplicas.startupProbe "enabled") "context" $) | nindent 12 }} + exec: + command: + - /bin/sh + - -c + {{- if (include "postgresql.database" .) }} + - exec pg_isready -U {{ default "postgres" $customUser| quote }} -d "dbname={{ include "postgresql.database" . }} {{- if and .Values.tls.enabled .Values.tls.certCAFilename }} sslcert={{ include "postgresql.tlsCert" . }} sslkey={{ include "postgresql.tlsCertKey" . }}{{- end }}" -h 127.0.0.1 -p {{ .Values.containerPorts.postgresql }} + {{- else }} + - exec pg_isready -U {{ default "postgres" $customUser | quote }} {{- if and .Values.tls.enabled .Values.tls.certCAFilename }} -d "sslcert={{ include "postgresql.tlsCert" . }} sslkey={{ include "postgresql.tlsCertKey" . }}"{{- end }} -h 127.0.0.1 -p {{ .Values.containerPorts.postgresql }} + {{- end }} + {{- end }} + {{- if .Values.readReplicas.customLivenessProbe }} + livenessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.readReplicas.customLivenessProbe "context" $) | nindent 12 }} + {{- else if .Values.readReplicas.livenessProbe.enabled }} + livenessProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.readReplicas.livenessProbe "enabled") "context" $) | nindent 12 }} + exec: + command: + - /bin/sh + - -c + {{- if (include "postgresql.database" .) }} + - exec pg_isready -U {{ default "postgres" $customUser | quote }} -d "dbname={{ include "postgresql.database" . }} {{- if and .Values.tls.enabled .Values.tls.certCAFilename }} sslcert={{ include "postgresql.tlsCert" . }} sslkey={{ include "postgresql.tlsCertKey" . }}{{- end }}" -h 127.0.0.1 -p {{ .Values.containerPorts.postgresql }} + {{- else }} + - exec pg_isready -U {{default "postgres" $customUser | quote }} {{- if and .Values.tls.enabled .Values.tls.certCAFilename }} -d "sslcert={{ include "postgresql.tlsCert" . }} sslkey={{ include "postgresql.tlsCertKey" . }}"{{- end }} -h 127.0.0.1 -p {{ .Values.containerPorts.postgresql }} + {{- end }} + {{- end }} + {{- if .Values.readReplicas.customReadinessProbe }} + readinessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.readReplicas.customReadinessProbe "context" $) | nindent 12 }} + {{- else if .Values.readReplicas.readinessProbe.enabled }} + readinessProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.readReplicas.readinessProbe "enabled") "context" $) | nindent 12 }} + exec: + command: + - /bin/sh + - -c + - -e + {{- include "postgresql.readinessProbeCommand" . | nindent 16 }} + {{- end }} + {{- end }} + {{- if .Values.readReplicas.resources }} + resources: {{- toYaml .Values.readReplicas.resources | nindent 12 }} + {{- end }} + {{- if .Values.readReplicas.lifecycleHooks }} + lifecycle: {{- include "common.tplvalues.render" (dict "value" .Values.readReplicas.lifecycleHooks "context" $) | nindent 12 }} + {{- end }} + volumeMounts: + {{- if .Values.auth.usePasswordFiles }} + - name: postgresql-password + mountPath: /opt/bitnami/postgresql/secrets/ + {{- end }} + {{- if .Values.readReplicas.extendedConfiguration }} + - name: postgresql-extended-config + mountPath: /bitnami/postgresql/conf/conf.d/ + {{- end }} + {{- if .Values.tls.enabled }} + - name: postgresql-certificates + mountPath: /opt/bitnami/postgresql/certs + readOnly: true + {{- end }} + {{- if .Values.shmVolume.enabled }} + - name: dshm + mountPath: /dev/shm + {{- end }} + {{- if .Values.readReplicas.persistence.enabled }} + - name: data + mountPath: {{ .Values.readReplicas.persistence.mountPath }} + {{- if .Values.readReplicas.persistence.subPath }} + subPath: {{ .Values.readReplicas.persistence.subPath }} + {{- end }} + {{- end }} + {{- if .Values.readReplicas.extraVolumeMounts }} + {{- include "common.tplvalues.render" (dict "value" .Values.readReplicas.extraVolumeMounts "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.metrics.enabled }} + - name: metrics + image: {{ include "postgresql.metrics.image" . }} + imagePullPolicy: {{ .Values.metrics.image.pullPolicy | quote }} + {{- if .Values.metrics.containerSecurityContext.enabled }} + securityContext: {{- omit .Values.metrics.containerSecurityContext "enabled" | toYaml | nindent 12 }} + {{- end }} + {{- if .Values.diagnosticMode.enabled }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.command "context" $) | nindent 12 }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.args "context" $) | nindent 12 }} + {{- else if .Values.metrics.customMetrics }} + args: [ "--extend.query-path", "/conf/custom-metrics.yaml" ] + {{- end }} + env: + {{- $database := required "In order to enable metrics you need to specify a database (.Values.auth.database or .Values.global.postgresql.auth.database)" (include "postgresql.database" .) }} + - name: DATA_SOURCE_URI + value: {{ printf "127.0.0.1:%d/%s?sslmode=disable" (int (include "postgresql.service.port" .)) $database }} + {{- if .Values.auth.usePasswordFiles }} + - name: DATA_SOURCE_PASS_FILE + value: {{ printf "/opt/bitnami/postgresql/secrets/%s" (ternary "password" "postgres-password" (and (not (empty $customUser)) (ne $customUser "postgres"))) }} + {{- else }} + - name: DATA_SOURCE_PASS + valueFrom: + secretKeyRef: + name: {{ include "postgresql.secretName" . }} + key: {{ include "postgresql.userPasswordKey" . }} + {{- end }} + - name: DATA_SOURCE_USER + value: {{ default "postgres" $customUser | quote }} + {{- if .Values.metrics.extraEnvVars }} + {{- include "common.tplvalues.render" (dict "value" .Values.metrics.extraEnvVars "context" $) | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: {{ .Values.metrics.containerPorts.metrics }} + {{- if not .Values.diagnosticMode.enabled }} + {{- if .Values.metrics.customStartupProbe }} + startupProbe: {{- include "common.tplvalues.render" (dict "value" .Values.metrics.customStartupProbe "context" $) | nindent 12 }} + {{- else if .Values.metrics.startupProbe.enabled }} + startupProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.metrics.startupProbe "enabled") "context" $) | nindent 12 }} + tcpSocket: + port: http-metrics + {{- end }} + {{- if .Values.metrics.customLivenessProbe }} + livenessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.metrics.customLivenessProbe "context" $) | nindent 12 }} + {{- else if .Values.metrics.livenessProbe.enabled }} + livenessProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.metrics.livenessProbe "enabled") "context" $) | nindent 12 }} + httpGet: + path: / + port: http-metrics + {{- end }} + {{- if .Values.metrics.customReadinessProbe }} + readinessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.metrics.customReadinessProbe "context" $) | nindent 12 }} + {{- else if .Values.metrics.readinessProbe.enabled }} + readinessProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.metrics.readinessProbe "enabled") "context" $) | nindent 12 }} + httpGet: + path: / + port: http-metrics + {{- end }} + {{- end }} + volumeMounts: + {{- if .Values.auth.usePasswordFiles }} + - name: postgresql-password + mountPath: /opt/bitnami/postgresql/secrets/ + {{- end }} + {{- if .Values.metrics.customMetrics }} + - name: custom-metrics + mountPath: /conf + readOnly: true + {{- end }} + {{- if .Values.metrics.resources }} + resources: {{- toYaml .Values.metrics.resources | nindent 12 }} + {{- end }} + {{- end }} + {{- if .Values.readReplicas.sidecars }} + {{- include "common.tplvalues.render" ( dict "value" .Values.readReplicas.sidecars "context" $ ) | nindent 8 }} + {{- end }} + volumes: + {{- if .Values.readReplicas.extendedConfiguration }} + - name: postgresql-extended-config + configMap: + name: {{ include "postgresql.readReplicas.extendedConfigmapName" . }} + {{- end }} + {{- if .Values.auth.usePasswordFiles }} + - name: postgresql-password + secret: + secretName: {{ include "postgresql.secretName" . }} + {{- end }} + {{- if .Values.tls.enabled }} + - name: raw-certificates + secret: + secretName: {{ include "postgresql.tlsSecretName" . }} + - name: postgresql-certificates + emptyDir: {} + {{- end }} + {{- if and .Values.metrics.enabled .Values.metrics.customMetrics }} + - name: custom-metrics + configMap: + name: {{ printf "%s-metrics" (include "common.names.fullname" .) }} + {{- end }} + {{- if .Values.shmVolume.enabled }} + - name: dshm + emptyDir: + medium: Memory + {{- if .Values.shmVolume.sizeLimit }} + sizeLimit: {{ .Values.shmVolume.sizeLimit }} + {{- end }} + {{- end }} + {{- if .Values.readReplicas.extraVolumes }} + {{- include "common.tplvalues.render" ( dict "value" .Values.readReplicas.extraVolumes "context" $ ) | nindent 8 }} + {{- end }} + {{- if and .Values.readReplicas.persistence.enabled .Values.readReplicas.persistence.existingClaim }} + - name: data + persistentVolumeClaim: + claimName: {{ tpl .Values.readReplicas.persistence.existingClaim $ }} + {{- else if not .Values.readReplicas.persistence.enabled }} + - name: data + emptyDir: {} + {{- else }} + volumeClaimTemplates: + - metadata: + name: data + {{- if .Values.readReplicas.persistence.annotations }} + annotations: {{- include "common.tplvalues.render" (dict "value" .Values.readReplicas.persistence.annotations "context" $) | nindent 10 }} + {{- end }} + {{- if .Values.readReplicas.persistence.labels }} + labels: {{- include "common.tplvalues.render" (dict "value" .Values.readReplicas.persistence.labels "context" $) | nindent 10 }} + {{- end }} + spec: + accessModes: + {{- range .Values.readReplicas.persistence.accessModes }} + - {{ . | quote }} + {{- end }} + {{- if .Values.readReplicas.persistence.dataSource }} + dataSource: {{- include "common.tplvalues.render" (dict "value" .Values.readReplicas.persistence.dataSource "context" $) | nindent 10 }} + {{- end }} + resources: + requests: + storage: {{ .Values.readReplicas.persistence.size | quote }} + {{- if .Values.readReplicas.persistence.selector }} + selector: {{- include "common.tplvalues.render" (dict "value" .Values.readReplicas.persistence.selector "context" $) | nindent 10 }} + {{- end -}} + {{- include "common.storage.class" (dict "persistence" .Values.readReplicas.persistence "global" .Values.global) | nindent 8 }} + {{- end }} +{{- end }} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/templates/read/svc-headless.yaml b/charts/kong/kong/2.41.0/charts/postgresql/templates/read/svc-headless.yaml new file mode 100644 index 0000000000..0371e49d47 --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/templates/read/svc-headless.yaml @@ -0,0 +1,33 @@ +{{- if eq .Values.architecture "replication" }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "postgresql.readReplica.svc.headless" . }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + app.kubernetes.io/component: read + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + # Use this annotation in addition to the actual publishNotReadyAddresses + # 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" +spec: + type: ClusterIP + clusterIP: None + # We want all pods in the StatefulSet to have their addresses published for + # the sake of the other Postgresql 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: + - name: tcp-postgresql + port: {{ include "postgresql.readReplica.service.port" . }} + targetPort: tcp-postgresql + selector: {{- include "common.labels.matchLabels" . | nindent 4 }} + app.kubernetes.io/component: read +{{- end }} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/templates/read/svc.yaml b/charts/kong/kong/2.41.0/charts/postgresql/templates/read/svc.yaml new file mode 100644 index 0000000000..3eece4dbb6 --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/templates/read/svc.yaml @@ -0,0 +1,53 @@ +{{- if eq .Values.architecture "replication" }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "postgresql.readReplica.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + app.kubernetes.io/component: read + annotations: + {{- if .Values.commonAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.readReplicas.service.annotations }} + {{- include "common.tplvalues.render" (dict "value" .Values.readReplicas.service.annotations "context" $) | nindent 4 }} + {{- end }} +spec: + type: {{ .Values.readReplicas.service.type }} + {{- if or (eq .Values.readReplicas.service.type "LoadBalancer") (eq .Values.readReplicas.service.type "NodePort") }} + externalTrafficPolicy: {{ .Values.readReplicas.service.externalTrafficPolicy | quote }} + {{- end }} + {{- if and (eq .Values.readReplicas.service.type "LoadBalancer") (not (empty .Values.readReplicas.service.loadBalancerSourceRanges)) }} + loadBalancerSourceRanges: {{ .Values.readReplicas.service.loadBalancerSourceRanges }} + {{- end }} + {{- if and (eq .Values.readReplicas.service.type "LoadBalancer") (not (empty .Values.readReplicas.service.loadBalancerIP)) }} + loadBalancerIP: {{ .Values.readReplicas.service.loadBalancerIP }} + {{- end }} + {{- if and .Values.readReplicas.service.clusterIP (eq .Values.readReplicas.service.type "ClusterIP") }} + clusterIP: {{ .Values.readReplicas.service.clusterIP }} + {{- end }} + {{- if .Values.readReplicas.service.sessionAffinity }} + sessionAffinity: {{ .Values.readReplicas.service.sessionAffinity }} + {{- end }} + {{- if .Values.readReplicas.service.sessionAffinityConfig }} + sessionAffinityConfig: {{- include "common.tplvalues.render" (dict "value" .Values.readReplicas.service.sessionAffinityConfig "context" $) | nindent 4 }} + {{- end }} + ports: + - name: tcp-postgresql + port: {{ include "postgresql.readReplica.service.port" . }} + targetPort: tcp-postgresql + {{- if and (or (eq .Values.readReplicas.service.type "NodePort") (eq .Values.readReplicas.service.type "LoadBalancer")) (not (empty .Values.readReplicas.service.nodePorts.postgresql)) }} + nodePort: {{ .Values.readReplicas.service.nodePorts.postgresql }} + {{- else if eq .Values.readReplicas.service.type "ClusterIP" }} + nodePort: null + {{- end }} + {{- if .Values.readReplicas.service.extraPorts }} + {{- include "common.tplvalues.render" (dict "value" .Values.readReplicas.service.extraPorts "context" $) | nindent 4 }} + {{- end }} + selector: {{- include "common.labels.matchLabels" . | nindent 4 }} + app.kubernetes.io/component: read +{{- end }} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/templates/role.yaml b/charts/kong/kong/2.41.0/charts/postgresql/templates/role.yaml new file mode 100644 index 0000000000..00f9222324 --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/templates/role.yaml @@ -0,0 +1,31 @@ +{{- if .Values.rbac.create }} +kind: Role +apiVersion: {{ include "common.capabilities.rbac.apiVersion" . }} +metadata: + name: {{ include "common.names.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +# yamllint disable rule:indentation +rules: + {{- $pspAvailable := (semverCompare "<1.25-0" (include "common.capabilities.kubeVersion" .)) -}} + {{- if and $pspAvailable .Values.psp.create }} + - apiGroups: + - 'policy' + resources: + - 'podsecuritypolicies' + verbs: + - 'use' + resourceNames: + - {{ include "common.names.fullname" . }} + {{- end }} + {{- if .Values.rbac.rules }} + {{- include "common.tplvalues.render" ( dict "value" .Values.rbac.rules "context" $ ) | nindent 2 }} + {{- end }} +# yamllint enable rule:indentation +{{- end }} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/templates/rolebinding.yaml b/charts/kong/kong/2.41.0/charts/postgresql/templates/rolebinding.yaml new file mode 100644 index 0000000000..0311c0eccf --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/templates/rolebinding.yaml @@ -0,0 +1,22 @@ +{{- if .Values.rbac.create }} +kind: RoleBinding +apiVersion: {{ include "common.capabilities.rbac.apiVersion" . }} +metadata: + name: {{ include "common.names.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +roleRef: + kind: Role + name: {{ include "common.names.fullname" . }} + apiGroup: rbac.authorization.k8s.io +subjects: + - kind: ServiceAccount + name: {{ include "postgresql.serviceAccountName" . }} + namespace: {{ .Release.Namespace | quote }} +{{- end }} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/templates/secrets.yaml b/charts/kong/kong/2.41.0/charts/postgresql/templates/secrets.yaml new file mode 100644 index 0000000000..5f28fb3749 --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/templates/secrets.yaml @@ -0,0 +1,29 @@ +{{- if (include "postgresql.createSecret" .) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "common.names.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +type: Opaque +data: + {{- if .Values.auth.enablePostgresUser }} + postgres-password: {{ include "common.secrets.passwords.manage" (dict "secret" (include "common.names.fullname" .) "key" "postgres-password" "providedValues" (list "global.postgresql.auth.postgresPassword" "auth.postgresPassword") "context" $) }} + {{- end }} + {{- if not (empty (include "postgresql.username" .)) }} + password: {{ include "common.secrets.passwords.manage" (dict "secret" (include "common.names.fullname" .) "key" "password" "providedValues" (list "global.postgresql.auth.password" "auth.password") "context" $) }} + {{- end }} + {{- if eq .Values.architecture "replication" }} + replication-password: {{ include "common.secrets.passwords.manage" (dict "secret" (include "common.names.fullname" .) "key" "replication-password" "providedValues" (list "auth.replicationPassword") "context" $) }} + {{- end }} + # We don't auto-generate LDAP password when it's not provided as we do for other passwords + {{- if and .Values.ldap.enabled (or .Values.ldap.bind_password .Values.ldap.bindpw) }} + ldap-password: {{ coalesce .Values.ldap.bind_password .Values.ldap.bindpw | b64enc | quote }} + {{- end }} +{{- end -}} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/templates/serviceaccount.yaml b/charts/kong/kong/2.41.0/charts/postgresql/templates/serviceaccount.yaml new file mode 100644 index 0000000000..179f8f2e4a --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/templates/serviceaccount.yaml @@ -0,0 +1,19 @@ +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "postgresql.serviceAccountName" . }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + annotations: + {{- if .Values.commonAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.serviceAccount.annotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.serviceAccount.annotations "context" $ ) | nindent 4 }} + {{- end }} +automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} +{{- end }} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/templates/tls-secrets.yaml b/charts/kong/kong/2.41.0/charts/postgresql/templates/tls-secrets.yaml new file mode 100644 index 0000000000..59c577647a --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/templates/tls-secrets.yaml @@ -0,0 +1,27 @@ +{{- if (include "postgresql.createTlsSecret" . ) }} +{{- $ca := genCA "postgresql-ca" 365 }} +{{- $fullname := include "common.names.fullname" . }} +{{- $releaseNamespace := .Release.Namespace }} +{{- $clusterDomain := .Values.clusterDomain }} +{{- $primaryHeadlessServiceName := include "postgresql.primary.svc.headless" . }} +{{- $readHeadlessServiceName := include "postgresql.readReplica.svc.headless" . }} +{{- $altNames := list (printf "*.%s.%s.svc.%s" $fullname $releaseNamespace $clusterDomain) (printf "%s.%s.svc.%s" $fullname $releaseNamespace $clusterDomain) (printf "*.%s.%s.svc.%s" $primaryHeadlessServiceName $releaseNamespace $clusterDomain) (printf "%s.%s.svc.%s" $primaryHeadlessServiceName $releaseNamespace $clusterDomain) (printf "*.%s.%s.svc.%s" $readHeadlessServiceName $releaseNamespace $clusterDomain) (printf "%s.%s.svc.%s" $readHeadlessServiceName $releaseNamespace $clusterDomain) $fullname }} +{{- $crt := genSignedCert $fullname nil $altNames 365 $ca }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ printf "%s-crt" (include "common.names.fullname" .) }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +type: kubernetes.io/tls +data: + ca.crt: {{ $ca.Cert | b64enc | quote }} + tls.crt: {{ $crt.Cert | b64enc | quote }} + tls.key: {{ $crt.Key | b64enc | quote }} +{{- end }} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/values.schema.json b/charts/kong/kong/2.41.0/charts/postgresql/values.schema.json new file mode 100644 index 0000000000..fc41483cdf --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/values.schema.json @@ -0,0 +1,156 @@ +{ + "$schema": "http://json-schema.org/schema#", + "type": "object", + "properties": { + "architecture": { + "type": "string", + "title": "PostgreSQL architecture", + "form": true, + "description": "Allowed values: `standalone` or `replication`" + }, + "auth": { + "type": "object", + "title": "Authentication configuration", + "form": true, + "properties": { + "enablePostgresUser": { + "type": "boolean", + "title": "Enable \"postgres\" admin user", + "description": "Assign a password to the \"postgres\" admin user. Otherwise, remote access will be blocked for this user", + "form": true + }, + "postgresPassword": { + "type": "string", + "title": "Password for the \"postgres\" admin user", + "description": "Defaults to a random 10-character alphanumeric string if not set", + "form": true + }, + "database": { + "type": "string", + "title": "PostgreSQL custom database", + "description": "Name of the custom database to be created during the 1st initialization of PostgreSQL", + "form": true + }, + "username": { + "type": "string", + "title": "PostgreSQL custom user", + "description": "Name of the custom user to be created during the 1st initialization of PostgreSQL. This user only has permissions on the PostgreSQL custom database", + "form": true + }, + "password": { + "type": "string", + "title": "Password for the custom user to create", + "description": "Defaults to a random 10-character alphanumeric string if not set", + "form": true + }, + "replicationUsername": { + "type": "string", + "title": "PostgreSQL replication user", + "description": "Name of user used to manage replication.", + "form": true, + "hidden": { + "value": "standalone", + "path": "architecture" + } + }, + "replicationPassword": { + "type": "string", + "title": "Password for PostgreSQL replication user", + "description": "Defaults to a random 10-character alphanumeric string if not set", + "form": true, + "hidden": { + "value": "standalone", + "path": "architecture" + } + } + } + }, + "persistence": { + "type": "object", + "properties": { + "size": { + "type": "string", + "title": "Persistent Volume Size", + "form": true, + "render": "slider", + "sliderMin": 1, + "sliderMax": 100, + "sliderUnit": "Gi" + } + } + }, + "resources": { + "type": "object", + "title": "Required Resources", + "description": "Configure resource requests", + "form": true, + "properties": { + "requests": { + "type": "object", + "properties": { + "memory": { + "type": "string", + "form": true, + "render": "slider", + "title": "Memory Request", + "sliderMin": 10, + "sliderMax": 2048, + "sliderUnit": "Mi" + }, + "cpu": { + "type": "string", + "form": true, + "render": "slider", + "title": "CPU Request", + "sliderMin": 10, + "sliderMax": 2000, + "sliderUnit": "m" + } + } + } + } + }, + "replication": { + "type": "object", + "form": true, + "title": "Replication Details", + "properties": { + "enabled": { + "type": "boolean", + "title": "Enable Replication", + "form": true + }, + "readReplicas": { + "type": "integer", + "title": "read Replicas", + "form": true, + "hidden": { + "value": "standalone", + "path": "architecture" + } + } + } + }, + "volumePermissions": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "form": true, + "title": "Enable Init Containers", + "description": "Change the owner of the persist volume mountpoint to RunAsUser:fsGroup" + } + } + }, + "metrics": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "title": "Configure metrics exporter", + "form": true + } + } + } + } +} diff --git a/charts/kong/kong/2.41.0/charts/postgresql/values.yaml b/charts/kong/kong/2.41.0/charts/postgresql/values.yaml new file mode 100644 index 0000000000..8d0e5fe37a --- /dev/null +++ b/charts/kong/kong/2.41.0/charts/postgresql/values.yaml @@ -0,0 +1,1399 @@ +## @section Global parameters +## Please, note that this will override the parameters, including dependencies, configured to use the global value +## +global: + ## @param global.imageRegistry Global Docker image registry + ## + imageRegistry: "" + ## @param global.imagePullSecrets Global Docker registry secret names as an array + ## e.g. + ## imagePullSecrets: + ## - myRegistryKeySecretName + ## + imagePullSecrets: [] + ## @param global.storageClass Global StorageClass for Persistent Volume(s) + ## + storageClass: "" + postgresql: + ## @param global.postgresql.auth.postgresPassword Password for the "postgres" admin user (overrides `auth.postgresPassword`) + ## @param global.postgresql.auth.username Name for a custom user to create (overrides `auth.username`) + ## @param global.postgresql.auth.password Password for the custom user to create (overrides `auth.password`) + ## @param global.postgresql.auth.database Name for a custom database to create (overrides `auth.database`) + ## @param global.postgresql.auth.existingSecret Name of existing secret to use for PostgreSQL credentials (overrides `auth.existingSecret`). + ## @param global.postgresql.auth.secretKeys.adminPasswordKey Name of key in existing secret to use for PostgreSQL credentials (overrides `auth.secretKeys.adminPasswordKey`). Only used when `global.postgresql.auth.existingSecret` is set. + ## @param global.postgresql.auth.secretKeys.userPasswordKey Name of key in existing secret to use for PostgreSQL credentials (overrides `auth.secretKeys.userPasswordKey`). Only used when `global.postgresql.auth.existingSecret` is set. + ## @param global.postgresql.auth.secretKeys.replicationPasswordKey Name of key in existing secret to use for PostgreSQL credentials (overrides `auth.secretKeys.replicationPasswordKey`). Only used when `global.postgresql.auth.existingSecret` is set. + ## + auth: + postgresPassword: "" + username: "" + password: "" + database: "" + existingSecret: "" + secretKeys: + adminPasswordKey: "" + userPasswordKey: "" + replicationPasswordKey: "" + ## @param global.postgresql.service.ports.postgresql PostgreSQL service port (overrides `service.ports.postgresql`) + ## + service: + ports: + postgresql: "" + +## @section Common parameters +## + +## @param kubeVersion Override Kubernetes version +## +kubeVersion: "" +## @param nameOverride String to partially override common.names.fullname template (will maintain the release name) +## +nameOverride: "" +## @param fullnameOverride String to fully override common.names.fullname template +## +fullnameOverride: "" +## @param clusterDomain Kubernetes Cluster Domain +## +clusterDomain: cluster.local +## @param extraDeploy Array of extra objects to deploy with the release (evaluated as a template) +## +extraDeploy: [] +## @param commonLabels Add labels to all the deployed resources +## +commonLabels: {} +## @param commonAnnotations Add annotations to all the deployed resources +## +commonAnnotations: {} +## Enable diagnostic mode in the statefulset +## +diagnosticMode: + ## @param diagnosticMode.enabled Enable diagnostic mode (all probes will be disabled and the command will be overridden) + ## + enabled: false + ## @param diagnosticMode.command Command to override all containers in the statefulset + ## + command: + - sleep + ## @param diagnosticMode.args Args to override all containers in the statefulset + ## + args: + - infinity + +## @section PostgreSQL common parameters +## + +## Bitnami PostgreSQL image version +## ref: https://hub.docker.com/r/bitnami/postgresql/tags/ +## @param image.registry PostgreSQL image registry +## @param image.repository PostgreSQL image repository +## @param image.tag PostgreSQL image tag (immutable tags are recommended) +## @param image.digest PostgreSQL image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag +## @param image.pullPolicy PostgreSQL image pull policy +## @param image.pullSecrets Specify image pull secrets +## @param image.debug Specify if debug values should be set +## +image: + registry: docker.io + repository: bitnami/postgresql + tag: 14.5.0-debian-11-r35 + digest: "" + ## Specify a imagePullPolicy + ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' + ## ref: https://kubernetes.io/docs/user-guide/images/#pre-pulling-images + ## + pullPolicy: IfNotPresent + ## Optionally specify an array of imagePullSecrets. + ## Secrets must be manually created in the namespace. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## Example: + ## pullSecrets: + ## - myRegistryKeySecretName + ## + pullSecrets: [] + ## Set to true if you would like to see extra information on logs + ## + debug: false +## Authentication parameters +## ref: https://github.com/bitnami/containers/tree/main/bitnami/postgresql#setting-the-root-password-on-first-run +## ref: https://github.com/bitnami/containers/tree/main/bitnami/postgresql#creating-a-database-on-first-run +## ref: https://github.com/bitnami/containers/tree/main/bitnami/postgresql#creating-a-database-user-on-first-run +## +auth: + ## @param auth.enablePostgresUser Assign a password to the "postgres" admin user. Otherwise, remote access will be blocked for this user + ## + enablePostgresUser: true + ## @param auth.postgresPassword Password for the "postgres" admin user. Ignored if `auth.existingSecret` with key `postgres-password` is provided + ## + postgresPassword: "" + ## @param auth.username Name for a custom user to create + ## + username: "" + ## @param auth.password Password for the custom user to create. Ignored if `auth.existingSecret` with key `password` is provided + ## + password: "" + ## @param auth.database Name for a custom database to create + ## + database: "" + ## @param auth.replicationUsername Name of the replication user + ## + replicationUsername: repl_user + ## @param auth.replicationPassword Password for the replication user. Ignored if `auth.existingSecret` with key `replication-password` is provided + ## + replicationPassword: "" + ## @param auth.existingSecret Name of existing secret to use for PostgreSQL credentials. `auth.postgresPassword`, `auth.password`, and `auth.replicationPassword` will be ignored and picked up from this secret. The secret might also contains the key `ldap-password` if LDAP is enabled. `ldap.bind_password` will be ignored and picked from this secret in this case. + ## + existingSecret: "" + ## @param auth.secretKeys.adminPasswordKey Name of key in existing secret to use for PostgreSQL credentials. Only used when `auth.existingSecret` is set. + ## @param auth.secretKeys.userPasswordKey Name of key in existing secret to use for PostgreSQL credentials. Only used when `auth.existingSecret` is set. + ## @param auth.secretKeys.replicationPasswordKey Name of key in existing secret to use for PostgreSQL credentials. Only used when `auth.existingSecret` is set. + ## + secretKeys: + adminPasswordKey: postgres-password + userPasswordKey: password + replicationPasswordKey: replication-password + ## @param auth.usePasswordFiles Mount credentials as a files instead of using an environment variable + ## + usePasswordFiles: false +## @param architecture PostgreSQL architecture (`standalone` or `replication`) +## +architecture: standalone +## Replication configuration +## Ignored if `architecture` is `standalone` +## +replication: + ## @param replication.synchronousCommit Set synchronous commit mode. Allowed values: `on`, `remote_apply`, `remote_write`, `local` and `off` + ## @param replication.numSynchronousReplicas Number of replicas that will have synchronous replication. Note: Cannot be greater than `readReplicas.replicaCount`. + ## ref: https://www.postgresql.org/docs/current/runtime-config-wal.html#GUC-SYNCHRONOUS-COMMIT + ## + synchronousCommit: "off" + numSynchronousReplicas: 0 + ## @param replication.applicationName Cluster application name. Useful for advanced replication settings + ## + applicationName: my_application +## @param containerPorts.postgresql PostgreSQL container port +## +containerPorts: + postgresql: 5432 +## Audit settings +## https://github.com/bitnami/containers/tree/main/bitnami/postgresql#auditing +## @param audit.logHostname Log client hostnames +## @param audit.logConnections Add client log-in operations to the log file +## @param audit.logDisconnections Add client log-outs operations to the log file +## @param audit.pgAuditLog Add operations to log using the pgAudit extension +## @param audit.pgAuditLogCatalog Log catalog using pgAudit +## @param audit.clientMinMessages Message log level to share with the user +## @param audit.logLinePrefix Template for log line prefix (default if not set) +## @param audit.logTimezone Timezone for the log timestamps +## +audit: + logHostname: false + logConnections: false + logDisconnections: false + pgAuditLog: "" + pgAuditLogCatalog: "off" + clientMinMessages: error + logLinePrefix: "" + logTimezone: "" +## LDAP configuration +## @param ldap.enabled Enable LDAP support +## DEPRECATED ldap.url It will removed in a future, please use 'ldap.uri' instead +## @param ldap.server IP address or name of the LDAP server. +## @param ldap.port Port number on the LDAP server to connect to +## @param ldap.prefix String to prepend to the user name when forming the DN to bind +## @param ldap.suffix String to append to the user name when forming the DN to bind +## DEPRECATED ldap.baseDN It will removed in a future, please use 'ldap.basedn' instead +## DEPRECATED ldap.bindDN It will removed in a future, please use 'ldap.binddn' instead +## DEPRECATED ldap.bind_password It will removed in a future, please use 'ldap.bindpw' instead +## @param ldap.basedn Root DN to begin the search for the user in +## @param ldap.binddn DN of user to bind to LDAP +## @param ldap.bindpw Password for the user to bind to LDAP +## DEPRECATED ldap.search_attr It will removed in a future, please use 'ldap.searchAttribute' instead +## DEPRECATED ldap.search_filter It will removed in a future, please use 'ldap.searchFilter' instead +## @param ldap.searchAttribute Attribute to match against the user name in the search +## @param ldap.searchFilter The search filter to use when doing search+bind authentication +## @param ldap.scheme Set to `ldaps` to use LDAPS +## DEPRECATED ldap.tls as string is deprecated,please use 'ldap.tls.enabled' instead +## @param ldap.tls.enabled Se to true to enable TLS encryption +## +ldap: + enabled: false + server: "" + port: "" + prefix: "" + suffix: "" + basedn: "" + binddn: "" + bindpw: "" + searchAttribute: "" + searchFilter: "" + scheme: "" + tls: + enabled: false + ## @param ldap.uri LDAP URL beginning in the form `ldap[s]://host[:port]/basedn`. If provided, all the other LDAP parameters will be ignored. + ## Ref: https://www.postgresql.org/docs/current/auth-ldap.html + uri: "" +## @param postgresqlDataDir PostgreSQL data dir folder +## +postgresqlDataDir: /bitnami/postgresql/data +## @param postgresqlSharedPreloadLibraries Shared preload libraries (comma-separated list) +## +postgresqlSharedPreloadLibraries: "pgaudit" +## Start PostgreSQL pod(s) without limitations on shm memory. +## By default docker and containerd (and possibly other container runtimes) limit `/dev/shm` to `64M` +## ref: https://github.com/docker-library/postgres/issues/416 +## ref: https://github.com/containerd/containerd/issues/3654 +## +shmVolume: + ## @param shmVolume.enabled Enable emptyDir volume for /dev/shm for PostgreSQL pod(s) + ## + enabled: true + ## @param shmVolume.sizeLimit Set this to enable a size limit on the shm tmpfs + ## Note: the size of the tmpfs counts against container's memory limit + ## e.g: + ## sizeLimit: 1Gi + ## + sizeLimit: "" +## TLS configuration +## +tls: + ## @param tls.enabled Enable TLS traffic support + ## + enabled: false + ## @param tls.autoGenerated Generate automatically self-signed TLS certificates + ## + autoGenerated: false + ## @param tls.preferServerCiphers Whether to use the server's TLS cipher preferences rather than the client's + ## + preferServerCiphers: true + ## @param tls.certificatesSecret Name of an existing secret that contains the certificates + ## + certificatesSecret: "" + ## @param tls.certFilename Certificate filename + ## + certFilename: "" + ## @param tls.certKeyFilename Certificate key filename + ## + certKeyFilename: "" + ## @param tls.certCAFilename CA Certificate filename + ## If provided, PostgreSQL will authenticate TLS/SSL clients by requesting them a certificate + ## ref: https://www.postgresql.org/docs/9.6/auth-methods.html + ## + certCAFilename: "" + ## @param tls.crlFilename File containing a Certificate Revocation List + ## + crlFilename: "" + +## @section PostgreSQL Primary parameters +## +primary: + ## @param primary.name Name of the primary database (eg primary, master, leader, ...) + ## + name: primary + ## @param primary.configuration PostgreSQL Primary main configuration to be injected as ConfigMap + ## ref: https://www.postgresql.org/docs/current/static/runtime-config.html + ## + configuration: "" + ## @param primary.pgHbaConfiguration PostgreSQL Primary client authentication configuration + ## ref: https://www.postgresql.org/docs/current/static/auth-pg-hba-conf.html + ## e.g:# + ## pgHbaConfiguration: |- + ## local all all trust + ## host all all localhost trust + ## host mydatabase mysuser 192.168.0.0/24 md5 + ## + pgHbaConfiguration: "" + ## @param primary.existingConfigmap Name of an existing ConfigMap with PostgreSQL Primary configuration + ## NOTE: `primary.configuration` and `primary.pgHbaConfiguration` will be ignored + ## + existingConfigmap: "" + ## @param primary.extendedConfiguration Extended PostgreSQL Primary configuration (appended to main or default configuration) + ## ref: https://github.com/bitnami/containers/tree/main/bitnami/postgresql#allow-settings-to-be-loaded-from-files-other-than-the-default-postgresqlconf + ## + extendedConfiguration: "" + ## @param primary.existingExtendedConfigmap Name of an existing ConfigMap with PostgreSQL Primary extended configuration + ## NOTE: `primary.extendedConfiguration` will be ignored + ## + existingExtendedConfigmap: "" + ## Initdb configuration + ## ref: https://github.com/bitnami/containers/tree/main/bitnami/postgresql#specifying-initdb-arguments + ## + initdb: + ## @param primary.initdb.args PostgreSQL initdb extra arguments + ## + args: "" + ## @param primary.initdb.postgresqlWalDir Specify a custom location for the PostgreSQL transaction log + ## + postgresqlWalDir: "" + ## @param primary.initdb.scripts Dictionary of initdb scripts + ## Specify dictionary of scripts to be run at first boot + ## e.g: + ## scripts: + ## my_init_script.sh: | + ## #!/bin/sh + ## echo "Do something." + ## + scripts: {} + ## @param primary.initdb.scriptsConfigMap ConfigMap with scripts to be run at first boot + ## NOTE: This will override `primary.initdb.scripts` + ## + scriptsConfigMap: "" + ## @param primary.initdb.scriptsSecret Secret with scripts to be run at first boot (in case it contains sensitive information) + ## NOTE: This can work along `primary.initdb.scripts` or `primary.initdb.scriptsConfigMap` + ## + scriptsSecret: "" + ## @param primary.initdb.user Specify the PostgreSQL username to execute the initdb scripts + ## + user: "" + ## @param primary.initdb.password Specify the PostgreSQL password to execute the initdb scripts + ## + password: "" + ## Configure current cluster's primary server to be the standby server in other cluster. + ## This will allow cross cluster replication and provide cross cluster high availability. + ## You will need to configure pgHbaConfiguration if you want to enable this feature with local cluster replication enabled. + ## @param primary.standby.enabled Whether to enable current cluster's primary as standby server of another cluster or not + ## @param primary.standby.primaryHost The Host of replication primary in the other cluster + ## @param primary.standby.primaryPort The Port of replication primary in the other cluster + ## + standby: + enabled: false + primaryHost: "" + primaryPort: "" + ## @param primary.extraEnvVars Array with extra environment variables to add to PostgreSQL Primary nodes + ## e.g: + ## extraEnvVars: + ## - name: FOO + ## value: "bar" + ## + extraEnvVars: [] + ## @param primary.extraEnvVarsCM Name of existing ConfigMap containing extra env vars for PostgreSQL Primary nodes + ## + extraEnvVarsCM: "" + ## @param primary.extraEnvVarsSecret Name of existing Secret containing extra env vars for PostgreSQL Primary nodes + ## + extraEnvVarsSecret: "" + ## @param primary.command Override default container command (useful when using custom images) + ## + command: [] + ## @param primary.args Override default container args (useful when using custom images) + ## + args: [] + ## Configure extra options for PostgreSQL Primary containers' liveness, readiness and startup probes + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#configure-probes + ## @param primary.livenessProbe.enabled Enable livenessProbe on PostgreSQL Primary containers + ## @param primary.livenessProbe.initialDelaySeconds Initial delay seconds for livenessProbe + ## @param primary.livenessProbe.periodSeconds Period seconds for livenessProbe + ## @param primary.livenessProbe.timeoutSeconds Timeout seconds for livenessProbe + ## @param primary.livenessProbe.failureThreshold Failure threshold for livenessProbe + ## @param primary.livenessProbe.successThreshold Success threshold for livenessProbe + ## + livenessProbe: + enabled: true + initialDelaySeconds: 30 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 6 + successThreshold: 1 + ## @param primary.readinessProbe.enabled Enable readinessProbe on PostgreSQL Primary containers + ## @param primary.readinessProbe.initialDelaySeconds Initial delay seconds for readinessProbe + ## @param primary.readinessProbe.periodSeconds Period seconds for readinessProbe + ## @param primary.readinessProbe.timeoutSeconds Timeout seconds for readinessProbe + ## @param primary.readinessProbe.failureThreshold Failure threshold for readinessProbe + ## @param primary.readinessProbe.successThreshold Success threshold for readinessProbe + ## + readinessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 6 + successThreshold: 1 + ## @param primary.startupProbe.enabled Enable startupProbe on PostgreSQL Primary containers + ## @param primary.startupProbe.initialDelaySeconds Initial delay seconds for startupProbe + ## @param primary.startupProbe.periodSeconds Period seconds for startupProbe + ## @param primary.startupProbe.timeoutSeconds Timeout seconds for startupProbe + ## @param primary.startupProbe.failureThreshold Failure threshold for startupProbe + ## @param primary.startupProbe.successThreshold Success threshold for startupProbe + ## + startupProbe: + enabled: false + initialDelaySeconds: 30 + periodSeconds: 10 + timeoutSeconds: 1 + failureThreshold: 15 + successThreshold: 1 + ## @param primary.customLivenessProbe Custom livenessProbe that overrides the default one + ## + customLivenessProbe: {} + ## @param primary.customReadinessProbe Custom readinessProbe that overrides the default one + ## + customReadinessProbe: {} + ## @param primary.customStartupProbe Custom startupProbe that overrides the default one + ## + customStartupProbe: {} + ## @param primary.lifecycleHooks for the PostgreSQL Primary container to automate configuration before or after startup + ## + lifecycleHooks: {} + ## PostgreSQL Primary resource requests and limits + ## ref: https://kubernetes.io/docs/user-guide/compute-resources/ + ## @param primary.resources.limits The resources limits for the PostgreSQL Primary containers + ## @param primary.resources.requests.memory The requested memory for the PostgreSQL Primary containers + ## @param primary.resources.requests.cpu The requested cpu for the PostgreSQL Primary containers + ## + resources: + limits: {} + requests: + memory: 256Mi + cpu: 250m + ## Pod Security Context + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + ## @param primary.podSecurityContext.enabled Enable security context + ## @param primary.podSecurityContext.fsGroup Group ID for the pod + ## + podSecurityContext: + enabled: true + fsGroup: 1001 + ## Container Security Context + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + ## @param primary.containerSecurityContext.enabled Enable container security context + ## @param primary.containerSecurityContext.runAsUser User ID for the container + ## + containerSecurityContext: + enabled: true + runAsUser: 1001 + ## @param primary.hostAliases PostgreSQL primary pods host aliases + ## https://kubernetes.io/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases/ + ## + hostAliases: [] + ## @param primary.hostNetwork Specify if host network should be enabled for PostgreSQL pod (postgresql primary) + ## + hostNetwork: false + ## @param primary.hostIPC Specify if host IPC should be enabled for PostgreSQL pod (postgresql primary) + ## + hostIPC: false + ## @param primary.labels Map of labels to add to the statefulset (postgresql primary) + ## + labels: {} + ## @param primary.annotations Annotations for PostgreSQL primary pods + ## + annotations: {} + ## @param primary.podLabels Map of labels to add to the pods (postgresql primary) + ## + podLabels: {} + ## @param primary.podAnnotations Map of annotations to add to the pods (postgresql primary) + ## + podAnnotations: {} + ## @param primary.podAffinityPreset PostgreSQL primary pod affinity preset. Ignored if `primary.affinity` is set. Allowed values: `soft` or `hard` + ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity + ## + podAffinityPreset: "" + ## @param primary.podAntiAffinityPreset PostgreSQL primary pod anti-affinity preset. Ignored if `primary.affinity` is set. Allowed values: `soft` or `hard` + ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity + ## + podAntiAffinityPreset: soft + ## PostgreSQL Primary node affinity preset + ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity + ## + nodeAffinityPreset: + ## @param primary.nodeAffinityPreset.type PostgreSQL primary node affinity preset type. Ignored if `primary.affinity` is set. Allowed values: `soft` or `hard` + ## + type: "" + ## @param primary.nodeAffinityPreset.key PostgreSQL primary node label key to match Ignored if `primary.affinity` is set. + ## E.g. + ## key: "kubernetes.io/e2e-az-name" + ## + key: "" + ## @param primary.nodeAffinityPreset.values PostgreSQL primary node label values to match. Ignored if `primary.affinity` is set. + ## E.g. + ## values: + ## - e2e-az1 + ## - e2e-az2 + ## + values: [] + ## @param primary.affinity Affinity for PostgreSQL primary pods assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + ## Note: primary.podAffinityPreset, primary.podAntiAffinityPreset, and primary.nodeAffinityPreset will be ignored when it's set + ## + affinity: {} + ## @param primary.nodeSelector Node labels for PostgreSQL primary pods assignment + ## ref: https://kubernetes.io/docs/user-guide/node-selection/ + ## + nodeSelector: {} + ## @param primary.tolerations Tolerations for PostgreSQL primary pods assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ + ## + tolerations: [] + ## @param primary.topologySpreadConstraints Topology Spread Constraints for pod assignment spread across your cluster among failure-domains. Evaluated as a template + ## Ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/#spread-constraints-for-pods + ## + topologySpreadConstraints: [] + ## @param primary.priorityClassName Priority Class to use for each pod (postgresql primary) + ## + priorityClassName: "" + ## @param primary.schedulerName Use an alternate scheduler, e.g. "stork". + ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ + ## + schedulerName: "" + ## @param primary.terminationGracePeriodSeconds Seconds PostgreSQL primary pod needs to terminate gracefully + ## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods + ## + terminationGracePeriodSeconds: "" + ## @param primary.updateStrategy.type PostgreSQL Primary statefulset strategy type + ## @param primary.updateStrategy.rollingUpdate PostgreSQL Primary statefulset rolling update configuration parameters + ## ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#update-strategies + ## + updateStrategy: + type: RollingUpdate + rollingUpdate: {} + ## @param primary.extraVolumeMounts Optionally specify extra list of additional volumeMounts for the PostgreSQL Primary container(s) + ## + extraVolumeMounts: [] + ## @param primary.extraVolumes Optionally specify extra list of additional volumes for the PostgreSQL Primary pod(s) + ## + extraVolumes: [] + ## @param primary.sidecars Add additional sidecar containers to the PostgreSQL Primary pod(s) + ## For example: + ## sidecars: + ## - name: your-image-name + ## image: your-image + ## imagePullPolicy: Always + ## ports: + ## - name: portname + ## containerPort: 1234 + ## + sidecars: [] + ## @param primary.initContainers Add additional init containers to the PostgreSQL Primary pod(s) + ## Example + ## + ## initContainers: + ## - name: do-something + ## image: busybox + ## command: ['do', 'something'] + ## + initContainers: [] + ## @param primary.extraPodSpec Optionally specify extra PodSpec for the PostgreSQL Primary pod(s) + ## + extraPodSpec: {} + ## PostgreSQL Primary service configuration + ## + service: + ## @param primary.service.type Kubernetes Service type + ## + type: ClusterIP + ## @param primary.service.ports.postgresql PostgreSQL service port + ## + ports: + postgresql: 5432 + ## Node ports to expose + ## NOTE: choose port between <30000-32767> + ## @param primary.service.nodePorts.postgresql Node port for PostgreSQL + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + ## + nodePorts: + postgresql: "" + ## @param primary.service.clusterIP Static clusterIP or None for headless services + ## e.g: + ## clusterIP: None + ## + clusterIP: "" + ## @param primary.service.annotations Annotations for PostgreSQL primary service + ## + annotations: {} + ## @param primary.service.loadBalancerIP Load balancer IP if service type is `LoadBalancer` + ## Set the LoadBalancer service type to internal only + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer + ## + loadBalancerIP: "" + ## @param primary.service.externalTrafficPolicy Enable client source IP preservation + ## ref https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip + ## + externalTrafficPolicy: Cluster + ## @param primary.service.loadBalancerSourceRanges Addresses that are allowed when service is LoadBalancer + ## https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/#restrict-access-for-loadbalancer-service + ## + ## loadBalancerSourceRanges: + ## - 10.10.10.0/24 + ## + loadBalancerSourceRanges: [] + ## @param primary.service.extraPorts Extra ports to expose in the PostgreSQL primary service + ## + extraPorts: [] + ## @param primary.service.sessionAffinity Session Affinity for Kubernetes service, can be "None" or "ClientIP" + ## If "ClientIP", consecutive client requests will be directed to the same Pod + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + ## + sessionAffinity: None + ## @param primary.service.sessionAffinityConfig Additional settings for the sessionAffinity + ## sessionAffinityConfig: + ## clientIP: + ## timeoutSeconds: 300 + ## + sessionAffinityConfig: {} + ## PostgreSQL Primary persistence configuration + ## + persistence: + ## @param primary.persistence.enabled Enable PostgreSQL Primary data persistence using PVC + ## + enabled: true + ## @param primary.persistence.existingClaim Name of an existing PVC to use + ## + existingClaim: "" + ## @param primary.persistence.mountPath The path the volume will be mounted at + ## Note: useful when using custom PostgreSQL images + ## + mountPath: /bitnami/postgresql + ## @param primary.persistence.subPath The subdirectory of the volume to mount to + ## Useful in dev environments and one PV for multiple services + ## + subPath: "" + ## @param primary.persistence.storageClass PVC Storage Class for PostgreSQL Primary data volume + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + storageClass: "" + ## @param primary.persistence.accessModes PVC Access Mode for PostgreSQL volume + ## + accessModes: + - ReadWriteOnce + ## @param primary.persistence.size PVC Storage Request for PostgreSQL volume + ## + size: 8Gi + ## @param primary.persistence.annotations Annotations for the PVC + ## + annotations: {} + ## @param primary.persistence.labels Labels for the PVC + ## + labels: {} + ## @param primary.persistence.selector Selector to match an existing Persistent Volume (this value is evaluated as a template) + ## selector: + ## matchLabels: + ## app: my-app + ## + selector: {} + ## @param primary.persistence.dataSource Custom PVC data source + ## + dataSource: {} + +## @section PostgreSQL read only replica parameters (only used when `architecture` is set to `replication`) +## +readReplicas: + ## @param readReplicas.name Name of the read replicas database (eg secondary, slave, ...) + ## + name: read + ## @param readReplicas.replicaCount Number of PostgreSQL read only replicas + ## + replicaCount: 1 + ## @param readReplicas.extendedConfiguration Extended PostgreSQL read only replicas configuration (appended to main or default configuration) + ## ref: https://github.com/bitnami/containers/tree/main/bitnami/postgresql#allow-settings-to-be-loaded-from-files-other-than-the-default-postgresqlconf + ## + extendedConfiguration: "" + ## @param readReplicas.extraEnvVars Array with extra environment variables to add to PostgreSQL read only nodes + ## e.g: + ## extraEnvVars: + ## - name: FOO + ## value: "bar" + ## + extraEnvVars: [] + ## @param readReplicas.extraEnvVarsCM Name of existing ConfigMap containing extra env vars for PostgreSQL read only nodes + ## + extraEnvVarsCM: "" + ## @param readReplicas.extraEnvVarsSecret Name of existing Secret containing extra env vars for PostgreSQL read only nodes + ## + extraEnvVarsSecret: "" + ## @param readReplicas.command Override default container command (useful when using custom images) + ## + command: [] + ## @param readReplicas.args Override default container args (useful when using custom images) + ## + args: [] + ## Configure extra options for PostgreSQL read only containers' liveness, readiness and startup probes + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#configure-probes + ## @param readReplicas.livenessProbe.enabled Enable livenessProbe on PostgreSQL read only containers + ## @param readReplicas.livenessProbe.initialDelaySeconds Initial delay seconds for livenessProbe + ## @param readReplicas.livenessProbe.periodSeconds Period seconds for livenessProbe + ## @param readReplicas.livenessProbe.timeoutSeconds Timeout seconds for livenessProbe + ## @param readReplicas.livenessProbe.failureThreshold Failure threshold for livenessProbe + ## @param readReplicas.livenessProbe.successThreshold Success threshold for livenessProbe + ## + livenessProbe: + enabled: true + initialDelaySeconds: 30 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 6 + successThreshold: 1 + ## @param readReplicas.readinessProbe.enabled Enable readinessProbe on PostgreSQL read only containers + ## @param readReplicas.readinessProbe.initialDelaySeconds Initial delay seconds for readinessProbe + ## @param readReplicas.readinessProbe.periodSeconds Period seconds for readinessProbe + ## @param readReplicas.readinessProbe.timeoutSeconds Timeout seconds for readinessProbe + ## @param readReplicas.readinessProbe.failureThreshold Failure threshold for readinessProbe + ## @param readReplicas.readinessProbe.successThreshold Success threshold for readinessProbe + ## + readinessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 6 + successThreshold: 1 + ## @param readReplicas.startupProbe.enabled Enable startupProbe on PostgreSQL read only containers + ## @param readReplicas.startupProbe.initialDelaySeconds Initial delay seconds for startupProbe + ## @param readReplicas.startupProbe.periodSeconds Period seconds for startupProbe + ## @param readReplicas.startupProbe.timeoutSeconds Timeout seconds for startupProbe + ## @param readReplicas.startupProbe.failureThreshold Failure threshold for startupProbe + ## @param readReplicas.startupProbe.successThreshold Success threshold for startupProbe + ## + startupProbe: + enabled: false + initialDelaySeconds: 30 + periodSeconds: 10 + timeoutSeconds: 1 + failureThreshold: 15 + successThreshold: 1 + ## @param readReplicas.customLivenessProbe Custom livenessProbe that overrides the default one + ## + customLivenessProbe: {} + ## @param readReplicas.customReadinessProbe Custom readinessProbe that overrides the default one + ## + customReadinessProbe: {} + ## @param readReplicas.customStartupProbe Custom startupProbe that overrides the default one + ## + customStartupProbe: {} + ## @param readReplicas.lifecycleHooks for the PostgreSQL read only container to automate configuration before or after startup + ## + lifecycleHooks: {} + ## PostgreSQL read only resource requests and limits + ## ref: https://kubernetes.io/docs/user-guide/compute-resources/ + ## @param readReplicas.resources.limits The resources limits for the PostgreSQL read only containers + ## @param readReplicas.resources.requests.memory The requested memory for the PostgreSQL read only containers + ## @param readReplicas.resources.requests.cpu The requested cpu for the PostgreSQL read only containers + ## + resources: + limits: {} + requests: + memory: 256Mi + cpu: 250m + ## Pod Security Context + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + ## @param readReplicas.podSecurityContext.enabled Enable security context + ## @param readReplicas.podSecurityContext.fsGroup Group ID for the pod + ## + podSecurityContext: + enabled: true + fsGroup: 1001 + ## Container Security Context + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + ## @param readReplicas.containerSecurityContext.enabled Enable container security context + ## @param readReplicas.containerSecurityContext.runAsUser User ID for the container + ## + containerSecurityContext: + enabled: true + runAsUser: 1001 + ## @param readReplicas.hostAliases PostgreSQL read only pods host aliases + ## https://kubernetes.io/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases/ + ## + hostAliases: [] + ## @param readReplicas.hostNetwork Specify if host network should be enabled for PostgreSQL pod (PostgreSQL read only) + ## + hostNetwork: false + ## @param readReplicas.hostIPC Specify if host IPC should be enabled for PostgreSQL pod (postgresql primary) + ## + hostIPC: false + ## @param readReplicas.labels Map of labels to add to the statefulset (PostgreSQL read only) + ## + labels: {} + ## @param readReplicas.annotations Annotations for PostgreSQL read only pods + ## + annotations: {} + ## @param readReplicas.podLabels Map of labels to add to the pods (PostgreSQL read only) + ## + podLabels: {} + ## @param readReplicas.podAnnotations Map of annotations to add to the pods (PostgreSQL read only) + ## + podAnnotations: {} + ## @param readReplicas.podAffinityPreset PostgreSQL read only pod affinity preset. Ignored if `primary.affinity` is set. Allowed values: `soft` or `hard` + ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity + ## + podAffinityPreset: "" + ## @param readReplicas.podAntiAffinityPreset PostgreSQL read only pod anti-affinity preset. Ignored if `primary.affinity` is set. Allowed values: `soft` or `hard` + ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity + ## + podAntiAffinityPreset: soft + ## PostgreSQL read only node affinity preset + ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity + ## + nodeAffinityPreset: + ## @param readReplicas.nodeAffinityPreset.type PostgreSQL read only node affinity preset type. Ignored if `primary.affinity` is set. Allowed values: `soft` or `hard` + ## + type: "" + ## @param readReplicas.nodeAffinityPreset.key PostgreSQL read only node label key to match Ignored if `primary.affinity` is set. + ## E.g. + ## key: "kubernetes.io/e2e-az-name" + ## + key: "" + ## @param readReplicas.nodeAffinityPreset.values PostgreSQL read only node label values to match. Ignored if `primary.affinity` is set. + ## E.g. + ## values: + ## - e2e-az1 + ## - e2e-az2 + ## + values: [] + ## @param readReplicas.affinity Affinity for PostgreSQL read only pods assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + ## Note: primary.podAffinityPreset, primary.podAntiAffinityPreset, and primary.nodeAffinityPreset will be ignored when it's set + ## + affinity: {} + ## @param readReplicas.nodeSelector Node labels for PostgreSQL read only pods assignment + ## ref: https://kubernetes.io/docs/user-guide/node-selection/ + ## + nodeSelector: {} + ## @param readReplicas.tolerations Tolerations for PostgreSQL read only pods assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ + ## + tolerations: [] + ## @param readReplicas.topologySpreadConstraints Topology Spread Constraints for pod assignment spread across your cluster among failure-domains. Evaluated as a template + ## Ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/#spread-constraints-for-pods + ## + topologySpreadConstraints: [] + ## @param readReplicas.priorityClassName Priority Class to use for each pod (PostgreSQL read only) + ## + priorityClassName: "" + ## @param readReplicas.schedulerName Use an alternate scheduler, e.g. "stork". + ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ + ## + schedulerName: "" + ## @param readReplicas.terminationGracePeriodSeconds Seconds PostgreSQL read only pod needs to terminate gracefully + ## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods + ## + terminationGracePeriodSeconds: "" + ## @param readReplicas.updateStrategy.type PostgreSQL read only statefulset strategy type + ## @param readReplicas.updateStrategy.rollingUpdate PostgreSQL read only statefulset rolling update configuration parameters + ## ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#update-strategies + ## + updateStrategy: + type: RollingUpdate + rollingUpdate: {} + ## @param readReplicas.extraVolumeMounts Optionally specify extra list of additional volumeMounts for the PostgreSQL read only container(s) + ## + extraVolumeMounts: [] + ## @param readReplicas.extraVolumes Optionally specify extra list of additional volumes for the PostgreSQL read only pod(s) + ## + extraVolumes: [] + ## @param readReplicas.sidecars Add additional sidecar containers to the PostgreSQL read only pod(s) + ## For example: + ## sidecars: + ## - name: your-image-name + ## image: your-image + ## imagePullPolicy: Always + ## ports: + ## - name: portname + ## containerPort: 1234 + ## + sidecars: [] + ## @param readReplicas.initContainers Add additional init containers to the PostgreSQL read only pod(s) + ## Example + ## + ## initContainers: + ## - name: do-something + ## image: busybox + ## command: ['do', 'something'] + ## + initContainers: [] + ## @param readReplicas.extraPodSpec Optionally specify extra PodSpec for the PostgreSQL read only pod(s) + ## + extraPodSpec: {} + ## PostgreSQL read only service configuration + ## + service: + ## @param readReplicas.service.type Kubernetes Service type + ## + type: ClusterIP + ## @param readReplicas.service.ports.postgresql PostgreSQL service port + ## + ports: + postgresql: 5432 + ## Node ports to expose + ## NOTE: choose port between <30000-32767> + ## @param readReplicas.service.nodePorts.postgresql Node port for PostgreSQL + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + ## + nodePorts: + postgresql: "" + ## @param readReplicas.service.clusterIP Static clusterIP or None for headless services + ## e.g: + ## clusterIP: None + ## + clusterIP: "" + ## @param readReplicas.service.annotations Annotations for PostgreSQL read only service + ## + annotations: {} + ## @param readReplicas.service.loadBalancerIP Load balancer IP if service type is `LoadBalancer` + ## Set the LoadBalancer service type to internal only + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer + ## + loadBalancerIP: "" + ## @param readReplicas.service.externalTrafficPolicy Enable client source IP preservation + ## ref https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip + ## + externalTrafficPolicy: Cluster + ## @param readReplicas.service.loadBalancerSourceRanges Addresses that are allowed when service is LoadBalancer + ## https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/#restrict-access-for-loadbalancer-service + ## + ## loadBalancerSourceRanges: + ## - 10.10.10.0/24 + ## + loadBalancerSourceRanges: [] + ## @param readReplicas.service.extraPorts Extra ports to expose in the PostgreSQL read only service + ## + extraPorts: [] + ## @param readReplicas.service.sessionAffinity Session Affinity for Kubernetes service, can be "None" or "ClientIP" + ## If "ClientIP", consecutive client requests will be directed to the same Pod + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + ## + sessionAffinity: None + ## @param readReplicas.service.sessionAffinityConfig Additional settings for the sessionAffinity + ## sessionAffinityConfig: + ## clientIP: + ## timeoutSeconds: 300 + ## + sessionAffinityConfig: {} + ## PostgreSQL read only persistence configuration + ## + persistence: + ## @param readReplicas.persistence.enabled Enable PostgreSQL read only data persistence using PVC + ## + enabled: true + ## @param readReplicas.persistence.existingClaim Name of an existing PVC to use + ## + existingClaim: "" + ## @param readReplicas.persistence.mountPath The path the volume will be mounted at + ## Note: useful when using custom PostgreSQL images + ## + mountPath: /bitnami/postgresql + ## @param readReplicas.persistence.subPath The subdirectory of the volume to mount to + ## Useful in dev environments and one PV for multiple services + ## + subPath: "" + ## @param readReplicas.persistence.storageClass PVC Storage Class for PostgreSQL read only data volume + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + storageClass: "" + ## @param readReplicas.persistence.accessModes PVC Access Mode for PostgreSQL volume + ## + accessModes: + - ReadWriteOnce + ## @param readReplicas.persistence.size PVC Storage Request for PostgreSQL volume + ## + size: 8Gi + ## @param readReplicas.persistence.annotations Annotations for the PVC + ## + annotations: {} + ## @param readReplicas.persistence.labels Labels for the PVC + ## + labels: {} + ## @param readReplicas.persistence.selector Selector to match an existing Persistent Volume (this value is evaluated as a template) + ## selector: + ## matchLabels: + ## app: my-app + ## + selector: {} + ## @param readReplicas.persistence.dataSource Custom PVC data source + ## + dataSource: {} + +## @section NetworkPolicy parameters + +## Add networkpolicies +## +networkPolicy: + ## @param networkPolicy.enabled Enable network policies + ## + enabled: false + ## @param networkPolicy.metrics.enabled Enable network policies for metrics (prometheus) + ## @param networkPolicy.metrics.namespaceSelector [object] Monitoring namespace selector labels. These labels will be used to identify the prometheus' namespace. + ## @param networkPolicy.metrics.podSelector [object] Monitoring pod selector labels. These labels will be used to identify the Prometheus pods. + ## + metrics: + enabled: false + ## e.g: + ## namespaceSelector: + ## label: monitoring + ## + namespaceSelector: {} + ## e.g: + ## podSelector: + ## label: monitoring + ## + podSelector: {} + ## Ingress Rules + ## + ingressRules: + ## @param networkPolicy.ingressRules.primaryAccessOnlyFrom.enabled Enable ingress rule that makes PostgreSQL primary node only accessible from a particular origin. + ## @param networkPolicy.ingressRules.primaryAccessOnlyFrom.namespaceSelector [object] Namespace selector label that is allowed to access the PostgreSQL primary node. This label will be used to identified the allowed namespace(s). + ## @param networkPolicy.ingressRules.primaryAccessOnlyFrom.podSelector [object] Pods selector label that is allowed to access the PostgreSQL primary node. This label will be used to identified the allowed pod(s). + ## @param networkPolicy.ingressRules.primaryAccessOnlyFrom.customRules [object] Custom network policy for the PostgreSQL primary node. + ## + primaryAccessOnlyFrom: + enabled: false + ## e.g: + ## namespaceSelector: + ## label: ingress + ## + namespaceSelector: {} + ## e.g: + ## podSelector: + ## label: access + ## + podSelector: {} + ## custom ingress rules + ## e.g: + ## customRules: + ## - from: + ## - namespaceSelector: + ## matchLabels: + ## label: example + customRules: {} + ## @param networkPolicy.ingressRules.readReplicasAccessOnlyFrom.enabled Enable ingress rule that makes PostgreSQL read-only nodes only accessible from a particular origin. + ## @param networkPolicy.ingressRules.readReplicasAccessOnlyFrom.namespaceSelector [object] Namespace selector label that is allowed to access the PostgreSQL read-only nodes. This label will be used to identified the allowed namespace(s). + ## @param networkPolicy.ingressRules.readReplicasAccessOnlyFrom.podSelector [object] Pods selector label that is allowed to access the PostgreSQL read-only nodes. This label will be used to identified the allowed pod(s). + ## @param networkPolicy.ingressRules.readReplicasAccessOnlyFrom.customRules [object] Custom network policy for the PostgreSQL read-only nodes. + ## + readReplicasAccessOnlyFrom: + enabled: false + ## e.g: + ## namespaceSelector: + ## label: ingress + ## + namespaceSelector: {} + ## e.g: + ## podSelector: + ## label: access + ## + podSelector: {} + ## custom ingress rules + ## e.g: + ## CustomRules: + ## - from: + ## - namespaceSelector: + ## matchLabels: + ## label: example + customRules: {} + ## @param networkPolicy.egressRules.denyConnectionsToExternal Enable egress rule that denies outgoing traffic outside the cluster, except for DNS (port 53). + ## @param networkPolicy.egressRules.customRules [object] Custom network policy rule + ## + egressRules: + # Deny connections to external. This is not compatible with an external database. + denyConnectionsToExternal: false + ## Additional custom egress rules + ## e.g: + ## customRules: + ## - to: + ## - namespaceSelector: + ## matchLabels: + ## label: example + customRules: {} + +## @section Volume Permissions parameters + +## Init containers parameters: +## volumePermissions: Change the owner and group of the persistent volume(s) mountpoint(s) to 'runAsUser:fsGroup' on each node +## +volumePermissions: + ## @param volumePermissions.enabled Enable init container that changes the owner and group of the persistent volume + ## + enabled: false + ## @param volumePermissions.image.registry Init container volume-permissions image registry + ## @param volumePermissions.image.repository Init container volume-permissions image repository + ## @param volumePermissions.image.tag Init container volume-permissions image tag (immutable tags are recommended) + ## @param volumePermissions.image.digest Init container volume-permissions image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag + ## @param volumePermissions.image.pullPolicy Init container volume-permissions image pull policy + ## @param volumePermissions.image.pullSecrets Init container volume-permissions image pull secrets + ## + image: + registry: docker.io + repository: bitnami/bitnami-shell + tag: 11-debian-11-r45 + digest: "" + pullPolicy: IfNotPresent + ## Optionally specify an array of imagePullSecrets. + ## Secrets must be manually created in the namespace. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## Example: + ## pullSecrets: + ## - myRegistryKeySecretName + ## + pullSecrets: [] + ## Init container resource requests and limits + ## ref: https://kubernetes.io/docs/user-guide/compute-resources/ + ## @param volumePermissions.resources.limits Init container volume-permissions resource limits + ## @param volumePermissions.resources.requests Init container volume-permissions resource requests + ## + resources: + limits: {} + requests: {} + ## Init container' Security Context + ## Note: the chown of the data folder is done to containerSecurityContext.runAsUser + ## and not the below volumePermissions.containerSecurityContext.runAsUser + ## @param volumePermissions.containerSecurityContext.runAsUser User ID for the init container + ## + containerSecurityContext: + runAsUser: 0 + +## @section Other Parameters + +## Service account for PostgreSQL to use. +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ +## +serviceAccount: + ## @param serviceAccount.create Enable creation of ServiceAccount for PostgreSQL pod + ## + create: false + ## @param serviceAccount.name The name of the ServiceAccount to use. + ## If not set and create is true, a name is generated using the common.names.fullname template + ## + name: "" + ## @param serviceAccount.automountServiceAccountToken Allows auto mount of ServiceAccountToken on the serviceAccount created + ## Can be set to false if pods using this serviceAccount do not need to use K8s API + ## + automountServiceAccountToken: true + ## @param serviceAccount.annotations Additional custom annotations for the ServiceAccount + ## + annotations: {} +## Creates role for ServiceAccount +## @param rbac.create Create Role and RoleBinding (required for PSP to work) +## +rbac: + create: false + ## @param rbac.rules Custom RBAC rules to set + ## e.g: + ## rules: + ## - apiGroups: + ## - "" + ## resources: + ## - pods + ## verbs: + ## - get + ## - list + ## + rules: [] +## Pod Security Policy +## ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/ +## @param psp.create Whether to create a PodSecurityPolicy. WARNING: PodSecurityPolicy is deprecated in Kubernetes v1.21 or later, unavailable in v1.25 or later +## +psp: + create: false + +## @section Metrics Parameters + +metrics: + ## @param metrics.enabled Start a prometheus exporter + ## + enabled: false + ## @param metrics.image.registry PostgreSQL Prometheus Exporter image registry + ## @param metrics.image.repository PostgreSQL Prometheus Exporter image repository + ## @param metrics.image.tag PostgreSQL Prometheus Exporter image tag (immutable tags are recommended) + ## @param metrics.image.digest PostgreSQL image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag + ## @param metrics.image.pullPolicy PostgreSQL Prometheus Exporter image pull policy + ## @param metrics.image.pullSecrets Specify image pull secrets + ## + image: + registry: docker.io + repository: bitnami/postgres-exporter + tag: 0.11.1-debian-11-r22 + digest: "" + pullPolicy: IfNotPresent + ## Optionally specify an array of imagePullSecrets. + ## Secrets must be manually created in the namespace. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## Example: + ## pullSecrets: + ## - myRegistryKeySecretName + ## + pullSecrets: [] + ## @param metrics.customMetrics Define additional custom metrics + ## ref: https://github.com/wrouesnel/postgres_exporter#adding-new-metrics-via-a-config-file + ## customMetrics: + ## pg_database: + ## query: "SELECT d.datname AS name, CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT') THEN pg_catalog.pg_database_size(d.datname) ELSE 0 END AS size_bytes FROM pg_catalog.pg_database d where datname not in ('template0', 'template1', 'postgres')" + ## metrics: + ## - name: + ## usage: "LABEL" + ## description: "Name of the database" + ## - size_bytes: + ## usage: "GAUGE" + ## description: "Size of the database in bytes" + ## + customMetrics: {} + ## @param metrics.extraEnvVars Extra environment variables to add to PostgreSQL Prometheus exporter + ## see: https://github.com/wrouesnel/postgres_exporter#environment-variables + ## For example: + ## extraEnvVars: + ## - name: PG_EXPORTER_DISABLE_DEFAULT_METRICS + ## value: "true" + ## + extraEnvVars: [] + ## PostgreSQL Prometheus exporter containers' Security Context + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container + ## @param metrics.containerSecurityContext.enabled Enable PostgreSQL Prometheus exporter containers' Security Context + ## @param metrics.containerSecurityContext.runAsUser Set PostgreSQL Prometheus exporter containers' Security Context runAsUser + ## @param metrics.containerSecurityContext.runAsNonRoot Set PostgreSQL Prometheus exporter containers' Security Context runAsNonRoot + ## + containerSecurityContext: + enabled: true + runAsUser: 1001 + runAsNonRoot: true + ## Configure extra options for PostgreSQL Prometheus exporter containers' liveness, readiness and startup probes + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#configure-probes + ## @param metrics.livenessProbe.enabled Enable livenessProbe on PostgreSQL Prometheus exporter containers + ## @param metrics.livenessProbe.initialDelaySeconds Initial delay seconds for livenessProbe + ## @param metrics.livenessProbe.periodSeconds Period seconds for livenessProbe + ## @param metrics.livenessProbe.timeoutSeconds Timeout seconds for livenessProbe + ## @param metrics.livenessProbe.failureThreshold Failure threshold for livenessProbe + ## @param metrics.livenessProbe.successThreshold Success threshold for livenessProbe + ## + livenessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 6 + successThreshold: 1 + ## @param metrics.readinessProbe.enabled Enable readinessProbe on PostgreSQL Prometheus exporter containers + ## @param metrics.readinessProbe.initialDelaySeconds Initial delay seconds for readinessProbe + ## @param metrics.readinessProbe.periodSeconds Period seconds for readinessProbe + ## @param metrics.readinessProbe.timeoutSeconds Timeout seconds for readinessProbe + ## @param metrics.readinessProbe.failureThreshold Failure threshold for readinessProbe + ## @param metrics.readinessProbe.successThreshold Success threshold for readinessProbe + ## + readinessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 6 + successThreshold: 1 + ## @param metrics.startupProbe.enabled Enable startupProbe on PostgreSQL Prometheus exporter containers + ## @param metrics.startupProbe.initialDelaySeconds Initial delay seconds for startupProbe + ## @param metrics.startupProbe.periodSeconds Period seconds for startupProbe + ## @param metrics.startupProbe.timeoutSeconds Timeout seconds for startupProbe + ## @param metrics.startupProbe.failureThreshold Failure threshold for startupProbe + ## @param metrics.startupProbe.successThreshold Success threshold for startupProbe + ## + startupProbe: + enabled: false + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 1 + failureThreshold: 15 + successThreshold: 1 + ## @param metrics.customLivenessProbe Custom livenessProbe that overrides the default one + ## + customLivenessProbe: {} + ## @param metrics.customReadinessProbe Custom readinessProbe that overrides the default one + ## + customReadinessProbe: {} + ## @param metrics.customStartupProbe Custom startupProbe that overrides the default one + ## + customStartupProbe: {} + ## @param metrics.containerPorts.metrics PostgreSQL Prometheus exporter metrics container port + ## + containerPorts: + metrics: 9187 + ## PostgreSQL Prometheus exporter resource requests and limits + ## ref: https://kubernetes.io/docs/user-guide/compute-resources/ + ## @param metrics.resources.limits The resources limits for the PostgreSQL Prometheus exporter container + ## @param metrics.resources.requests The requested resources for the PostgreSQL Prometheus exporter container + ## + resources: + limits: {} + requests: {} + ## Service configuration + ## + service: + ## @param metrics.service.ports.metrics PostgreSQL Prometheus Exporter service port + ## + ports: + metrics: 9187 + ## @param metrics.service.clusterIP Static clusterIP or None for headless services + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#choosing-your-own-ip-address + ## + clusterIP: "" + ## @param metrics.service.sessionAffinity Control where client requests go, to the same pod or round-robin + ## Values: ClientIP or None + ## ref: https://kubernetes.io/docs/user-guide/services/ + ## + sessionAffinity: None + ## @param metrics.service.annotations [object] Annotations for Prometheus to auto-discover the metrics endpoint + ## + annotations: + prometheus.io/scrape: "true" + prometheus.io/port: "{{ .Values.metrics.service.ports.metrics }}" + ## Prometheus Operator ServiceMonitor configuration + ## + serviceMonitor: + ## @param metrics.serviceMonitor.enabled Create ServiceMonitor Resource for scraping metrics using Prometheus Operator + ## + enabled: false + ## @param metrics.serviceMonitor.namespace Namespace for the ServiceMonitor Resource (defaults to the Release Namespace) + ## + namespace: "" + ## @param metrics.serviceMonitor.interval Interval at which metrics should be scraped. + ## ref: https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#endpoint + ## + interval: "" + ## @param metrics.serviceMonitor.scrapeTimeout Timeout after which the scrape is ended + ## ref: https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#endpoint + ## + scrapeTimeout: "" + ## @param metrics.serviceMonitor.labels Additional labels that can be used so ServiceMonitor will be discovered by Prometheus + ## + labels: {} + ## @param metrics.serviceMonitor.selector Prometheus instance selector labels + ## ref: https://github.com/bitnami/charts/tree/main/bitnami/prometheus-operator#prometheus-configuration + ## + selector: {} + ## @param metrics.serviceMonitor.relabelings RelabelConfigs to apply to samples before scraping + ## + relabelings: [] + ## @param metrics.serviceMonitor.metricRelabelings MetricRelabelConfigs to apply to samples before ingestion + ## + metricRelabelings: [] + ## @param metrics.serviceMonitor.honorLabels Specify honorLabels parameter to add the scrape endpoint + ## + honorLabels: false + ## @param metrics.serviceMonitor.jobLabel The name of the label on the target service to use as the job name in prometheus. + ## + jobLabel: "" + ## Custom PrometheusRule to be defined + ## The value is evaluated as a template, so, for example, the value can depend on .Release or .Chart + ## ref: https://github.com/coreos/prometheus-operator#customresourcedefinitions + ## + prometheusRule: + ## @param metrics.prometheusRule.enabled Create a PrometheusRule for Prometheus Operator + ## + enabled: false + ## @param metrics.prometheusRule.namespace Namespace for the PrometheusRule Resource (defaults to the Release Namespace) + ## + namespace: "" + ## @param metrics.prometheusRule.labels Additional labels that can be used so PrometheusRule will be discovered by Prometheus + ## + labels: {} + ## @param metrics.prometheusRule.rules PrometheusRule definitions + ## Make sure to constraint the rules to the current postgresql service. + ## rules: + ## - alert: HugeReplicationLag + ## expr: pg_replication_lag{service="{{ printf "%s-metrics" (include "common.names.fullname" .) }}"} / 3600 > 1 + ## for: 1m + ## labels: + ## severity: critical + ## annotations: + ## description: replication for {{ include "common.names.fullname" . }} PostgreSQL is lagging by {{ "{{ $value }}" }} hour(s). + ## summary: PostgreSQL replication is lagging by {{ "{{ $value }}" }} hour(s). + ## + rules: [] diff --git a/charts/kong/kong/2.41.0/crds/custom-resource-definitions.yaml b/charts/kong/kong/2.41.0/crds/custom-resource-definitions.yaml new file mode 100644 index 0000000000..28bc3f2fc4 --- /dev/null +++ b/charts/kong/kong/2.41.0/crds/custom-resource-definitions.yaml @@ -0,0 +1,2974 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.1 + name: ingressclassparameterses.configuration.konghq.com +spec: + group: configuration.konghq.com + names: + kind: IngressClassParameters + listKind: IngressClassParametersList + plural: ingressclassparameterses + singular: ingressclassparameters + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: IngressClassParameters is the Schema for the IngressClassParameters + 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 is the IngressClassParameters specification. + properties: + enableLegacyRegexDetection: + default: false + description: |- + EnableLegacyRegexDetection automatically detects if ImplementationSpecific Ingress paths are regular expression + paths using the legacy 2.x heuristic. The controller adds the "~" prefix to those paths if the Kong version is + 3.0 or higher. + type: boolean + serviceUpstream: + default: false + description: Offload load-balancing to kube-proxy or sidecar. + type: boolean + type: object + type: object + served: true + storage: true +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.1 + name: kongclusterplugins.configuration.konghq.com +spec: + group: configuration.konghq.com + names: + categories: + - kong-ingress-controller + kind: KongClusterPlugin + listKind: KongClusterPluginList + plural: kongclusterplugins + shortNames: + - kcp + singular: kongclusterplugin + scope: Cluster + versions: + - additionalPrinterColumns: + - description: Name of the plugin + jsonPath: .plugin + name: Plugin-Type + type: string + - description: Age + jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: Indicates if the plugin is disabled + jsonPath: .disabled + name: Disabled + priority: 1 + type: boolean + - description: Configuration of the plugin + jsonPath: .config + name: Config + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Programmed")].status + name: Programmed + type: string + name: v1 + schema: + openAPIV3Schema: + description: KongClusterPlugin is the Schema for the kongclusterplugins 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 + config: + description: |- + Config contains the plugin configuration. It's a list of keys and values + required to configure the plugin. + Please read the documentation of the plugin being configured to set values + in here. For any plugin in Kong, anything that goes in the `config` JSON + key in the Admin API request, goes into this property. + Only one of `config` or `configFrom` may be used in a KongClusterPlugin, not both at once. + type: object + x-kubernetes-preserve-unknown-fields: true + configFrom: + description: |- + ConfigFrom references a secret containing the plugin configuration. + This should be used when the plugin configuration contains sensitive information, + such as AWS credentials in the Lambda plugin or the client secret in the OIDC plugin. + Only one of `config` or `configFrom` may be used in a KongClusterPlugin, not both at once. + properties: + secretKeyRef: + description: Specifies a name, a namespace, and a key of a secret + to refer to. + properties: + key: + description: The key containing the value. + type: string + name: + description: The secret containing the key. + type: string + namespace: + description: The namespace containing the secret. + type: string + required: + - key + - name + - namespace + type: object + required: + - secretKeyRef + type: object + configPatches: + description: |- + ConfigPatches represents JSON patches to the configuration of the plugin. + Each item means a JSON patch to add something in the configuration, + where path is specified in `path` and value is in `valueFrom` referencing + a key in a secret. + When Config is specified, patches will be applied to the configuration in Config. + Otherwise, patches will be applied to an empty object. + items: + description: |- + NamespacedConfigPatch is a JSON patch to add values from secrets to KongClusterPlugin + to the generated configuration of plugin in Kong. + properties: + path: + description: Path is the JSON path to add the patch. + type: string + valueFrom: + description: ValueFrom is the reference to a key of a secret where + the patched value comes from. + properties: + secretKeyRef: + description: Specifies a name, a namespace, and a key of a secret + to refer to. + properties: + key: + description: The key containing the value. + type: string + name: + description: The secret containing the key. + type: string + namespace: + description: The namespace containing the secret. + type: string + required: + - key + - name + - namespace + type: object + required: + - secretKeyRef + type: object + required: + - path + - valueFrom + type: object + type: array + consumerRef: + description: ConsumerRef is a reference to a particular consumer. + type: string + disabled: + description: Disabled set if the plugin is disabled or not. + type: boolean + instance_name: + description: |- + InstanceName is an optional custom name to identify an instance of the plugin. This is useful when running the + same plugin in multiple contexts, for example, on multiple services. + 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 + ordering: + description: |- + Ordering overrides the normal plugin execution order. It's only available on Kong Enterprise. + `` is a request processing phase (for example, `access` or `body_filter`) and + `` is the name of the plugin that will run before or after the KongPlugin. + For example, a KongPlugin with `plugin: rate-limiting` and `before.access: ["key-auth"]` + will create a rate limiting plugin that limits requests _before_ they are authenticated. + properties: + after: + additionalProperties: + items: + type: string + type: array + description: PluginOrderingPhase indicates which plugins in a phase + should affect the target plugin's order + type: object + before: + additionalProperties: + items: + type: string + type: array + description: PluginOrderingPhase indicates which plugins in a phase + should affect the target plugin's order + type: object + type: object + plugin: + description: PluginName is the name of the plugin to which to apply the + config. + type: string + protocols: + description: |- + Protocols configures plugin to run on requests received on specific + protocols. + items: + description: |- + KongProtocol is a valid Kong protocol. + This alias is necessary to deal with https://github.com/kubernetes-sigs/controller-tools/issues/342 + enum: + - http + - https + - grpc + - grpcs + - tcp + - tls + - udp + type: string + type: array + run_on: + description: |- + RunOn configures the plugin to run on the first or the second or both + nodes in case of a service mesh deployment. + enum: + - first + - second + - all + type: string + status: + description: Status represents the current status of the KongClusterPlugin + resource. + properties: + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Programmed + description: |- + Conditions describe the current conditions of the KongClusterPluginStatus. + + Known condition types are: + + * "Programmed" + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + 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. + 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 + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object + required: + - plugin + type: object + x-kubernetes-validations: + - message: Using both config and configFrom fields is not allowed. + rule: '!(has(self.config) && has(self.configFrom))' + - message: Using both configFrom and configPatches fields is not allowed. + rule: '!(has(self.configFrom) && has(self.configPatches))' + - message: The plugin field is immutable + rule: self.plugin == oldSelf.plugin + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.1 + name: kongconsumergroups.configuration.konghq.com +spec: + group: configuration.konghq.com + names: + categories: + - kong-ingress-controller + kind: KongConsumerGroup + listKind: KongConsumerGroupList + plural: kongconsumergroups + shortNames: + - kcg + singular: kongconsumergroup + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Age + jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="Programmed")].status + name: Programmed + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: KongConsumerGroup is the Schema for the kongconsumergroups 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 + status: + description: Status represents the current status of the KongConsumerGroup + resource. + properties: + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Programmed + description: |- + Conditions describe the current conditions of the KongConsumerGroup. + + Known condition types are: + + * "Programmed" + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + 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. + 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 + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.1 + name: kongconsumers.configuration.konghq.com +spec: + group: configuration.konghq.com + names: + categories: + - kong-ingress-controller + kind: KongConsumer + listKind: KongConsumerList + plural: kongconsumers + shortNames: + - kc + singular: kongconsumer + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Username of a Kong Consumer + jsonPath: .username + name: Username + type: string + - description: Age + jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="Programmed")].status + name: Programmed + type: string + name: v1 + schema: + openAPIV3Schema: + description: KongConsumer is the Schema for the kongconsumers 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 + consumerGroups: + description: |- + ConsumerGroups are references to consumer groups (that consumer wants to be part of) + provisioned in Kong. + items: + type: string + type: array + x-kubernetes-list-type: set + credentials: + description: |- + Credentials are references to secrets containing a credential to be + provisioned in Kong. + items: + type: string + type: array + x-kubernetes-list-type: set + custom_id: + description: |- + CustomID is a Kong cluster-unique existing ID for the consumer - useful for mapping + Kong with users in your existing database. + 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 + status: + description: Status represents the current status of the KongConsumer + resource. + properties: + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Programmed + description: |- + Conditions describe the current conditions of the KongConsumer. + + Known condition types are: + + * "Programmed" + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + 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. + 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 + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object + username: + description: Username is a Kong cluster-unique username of the consumer. + type: string + type: object + x-kubernetes-validations: + - message: Need to provide either username or custom_id + rule: has(self.username) || has(self.custom_id) + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.1 + name: kongcustomentities.configuration.konghq.com +spec: + group: configuration.konghq.com + names: + categories: + - kong-ingress-controller + kind: KongCustomEntity + listKind: KongCustomEntityList + plural: kongcustomentities + shortNames: + - kce + singular: kongcustomentity + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: type of the Kong entity + jsonPath: .spec.type + name: Entity Type + type: string + - description: Age + jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="Programmed")].status + name: Programmed + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: KongCustomEntity defines a "custom" Kong entity that KIC cannot + support the entity type directly. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + properties: + controllerName: + description: ControllerName specifies the controller that should reconcile + it, like ingress class. + type: string + fields: + description: Fields defines the fields of the Kong entity itself. + x-kubernetes-preserve-unknown-fields: true + parentRef: + description: |- + ParentRef references the kubernetes resource it attached to when its scope is "attached". + Currently only KongPlugin/KongClusterPlugin allowed. This will make the custom entity to be attached + to the entity(service/route/consumer) where the plugin is attached. + properties: + group: + type: string + kind: + type: string + name: + type: string + namespace: + description: Empty namespace means the same namespace of the owning + object. + type: string + required: + - name + type: object + type: + description: EntityType is the type of the Kong entity. The type is + used in generating declarative configuration. + type: string + required: + - controllerName + - fields + - type + type: object + status: + description: Status stores the reconciling status of the resource. + properties: + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Programmed + description: |- + Conditions describe the current conditions of the KongCustomEntityStatus. + + Known condition types are: + + * "Programmed" + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + 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. + 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 + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + required: + - conditions + type: object + required: + - spec + type: object + x-kubernetes-validations: + - message: The spec.type field is immutable + rule: self.spec.type == oldSelf.spec.type + - message: The spec.type field cannot be known Kong entity types + rule: '!(self.spec.type in [''services'',''routes'',''upstreams'',''targets'',''plugins'',''consumers'',''consumer_groups''])' + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.1 + name: kongingresses.configuration.konghq.com +spec: + group: configuration.konghq.com + names: + categories: + - kong-ingress-controller + kind: KongIngress + listKind: KongIngressList + plural: kongingresses + shortNames: + - ki + singular: kongingress + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: KongIngress is the Schema for the kongingresses 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 + proxy: + description: |- + Proxy defines additional connection options for the routes to be configured in the + Kong Gateway, e.g. `connection_timeout`, `retries`, etc. + properties: + connect_timeout: + description: "The timeout in milliseconds for\testablishing a connection + to the upstream server.\nDeprecated: use Service's \"konghq.com/connect-timeout\" + annotation instead." + minimum: 0 + type: integer + path: + description: |- + (optional) The path to be used in requests to the upstream server. + Deprecated: use Service's "konghq.com/path" annotation instead. + pattern: ^/.*$ + type: string + protocol: + description: |- + The protocol used to communicate with the upstream. + Deprecated: use Service's "konghq.com/protocol" annotation instead. + enum: + - http + - https + - grpc + - grpcs + - tcp + - tls + - udp + type: string + read_timeout: + description: |- + The timeout in milliseconds between two successive read operations + for transmitting a request to the upstream server. + Deprecated: use Service's "konghq.com/read-timeout" annotation instead. + minimum: 0 + type: integer + retries: + description: |- + The number of retries to execute upon failure to proxy. + Deprecated: use Service's "konghq.com/retries" annotation instead. + minimum: 0 + type: integer + write_timeout: + description: |- + The timeout in milliseconds between two successive write operations + for transmitting a request to the upstream server. + Deprecated: use Service's "konghq.com/write-timeout" annotation instead. + minimum: 0 + type: integer + type: object + route: + description: |- + Route define rules to match client requests. + Each Route is associated with a Service, + and a Service may have multiple Routes associated to it. + properties: + headers: + additionalProperties: + items: + type: string + type: array + description: |- + Headers contains one or more lists of values indexed by header name + that will cause this Route to match if present in the request. + The Host header cannot be used with this attribute. + Deprecated: use Ingress' "konghq.com/headers" annotation instead. + type: object + https_redirect_status_code: + description: |- + HTTPSRedirectStatusCode is the status code Kong responds with + when all properties of a Route match except the protocol. + Deprecated: use Ingress' "ingress.kubernetes.io/force-ssl-redirect" or + "konghq.com/https-redirect-status-code" annotations instead. + type: integer + methods: + description: |- + Methods is a list of HTTP methods that match this Route. + Deprecated: use Ingress' "konghq.com/methods" annotation instead. + items: + type: string + type: array + path_handling: + description: |- + PathHandling controls how the Service path, Route path and requested path + are combined when sending a request to the upstream. + Deprecated: use Ingress' "konghq.com/path-handling" annotation instead. + enum: + - v0 + - v1 + type: string + preserve_host: + description: |- + PreserveHost sets When matching a Route via one of the hosts domain names, + use the request Host header in the upstream request headers. + If set to false, the upstream Host header will be that of the Service’s host. + Deprecated: use Ingress' "konghq.com/preserve-host" annotation instead. + type: boolean + protocols: + description: |- + Protocols is an array of the protocols this Route should allow. + Deprecated: use Ingress' "konghq.com/protocols" annotation instead. + items: + description: |- + KongProtocol is a valid Kong protocol. + This alias is necessary to deal with https://github.com/kubernetes-sigs/controller-tools/issues/342 + enum: + - http + - https + - grpc + - grpcs + - tcp + - tls + - udp + type: string + type: array + regex_priority: + description: |- + RegexPriority is a number used to choose which route resolves a given request + when several routes match it using regexes simultaneously. + Deprecated: use Ingress' "konghq.com/regex-priority" annotation instead. + type: integer + request_buffering: + description: |- + RequestBuffering sets whether to enable request body buffering or not. + Deprecated: use Ingress' "konghq.com/request-buffering" annotation instead. + type: boolean + response_buffering: + description: |- + ResponseBuffering sets whether to enable response body buffering or not. + Deprecated: use Ingress' "konghq.com/response-buffering" annotation instead. + type: boolean + snis: + description: |- + SNIs is a list of SNIs that match this Route when using stream routing. + Deprecated: use Ingress' "konghq.com/snis" annotation instead. + items: + type: string + type: array + strip_path: + description: |- + StripPath sets When matching a Route via one of the paths + strip the matching prefix from the upstream request URL. + Deprecated: use Ingress' "konghq.com/strip-path" annotation instead. + type: boolean + type: object + upstream: + description: |- + Upstream represents a virtual hostname and can be used to loadbalance + incoming requests over multiple targets (e.g. Kubernetes `Services` can + be a target, OR `Endpoints` can be targets). + properties: + algorithm: + description: |- + Algorithm is the load balancing algorithm to use. + Accepted values are: "round-robin", "consistent-hashing", "least-connections", "latency". + enum: + - round-robin + - consistent-hashing + - least-connections + - latency + type: string + hash_fallback: + description: |- + HashFallback defines What to use as hashing input + if the primary hash_on does not return a hash. + Accepted values are: "none", "consumer", "ip", "header", "cookie". + type: string + hash_fallback_header: + description: |- + HashFallbackHeader is the header name to take the value from as hash input. + Only required when "hash_fallback" is set to "header". + type: string + hash_fallback_query_arg: + description: HashFallbackQueryArg is the "hash_fallback" version of + HashOnQueryArg. + type: string + hash_fallback_uri_capture: + description: HashFallbackURICapture is the "hash_fallback" version + of HashOnURICapture. + type: string + hash_on: + description: |- + HashOn defines what to use as hashing input. + Accepted values are: "none", "consumer", "ip", "header", "cookie", "path", "query_arg", "uri_capture". + type: string + hash_on_cookie: + description: |- + The cookie name to take the value from as hash input. + Only required when "hash_on" or "hash_fallback" is set to "cookie". + type: string + hash_on_cookie_path: + description: |- + The cookie path to set in the response headers. + Only required when "hash_on" or "hash_fallback" is set to "cookie". + type: string + hash_on_header: + description: |- + HashOnHeader defines the header name to take the value from as hash input. + Only required when "hash_on" is set to "header". + type: string + hash_on_query_arg: + description: HashOnQueryArg is the query string parameter whose value + is the hash input when "hash_on" is set to "query_arg". + type: string + hash_on_uri_capture: + description: |- + HashOnURICapture is the name of the capture group whose value is the hash input when "hash_on" is set to + "uri_capture". + type: string + healthchecks: + description: Healthchecks defines the health check configurations + in Kong. + properties: + active: + description: ActiveHealthcheck configures active health check + probing. + properties: + concurrency: + minimum: 1 + type: integer + headers: + additionalProperties: + items: + type: string + type: array + type: object + healthy: + description: |- + Healthy configures thresholds and HTTP status codes + to mark targets healthy for an upstream. + properties: + http_statuses: + items: + type: integer + type: array + interval: + minimum: 0 + type: integer + successes: + minimum: 0 + type: integer + type: object + http_path: + pattern: ^/.*$ + type: string + https_sni: + type: string + https_verify_certificate: + type: boolean + timeout: + minimum: 0 + type: integer + type: + type: string + unhealthy: + description: |- + Unhealthy configures thresholds and HTTP status codes + to mark targets unhealthy. + properties: + http_failures: + minimum: 0 + type: integer + http_statuses: + items: + type: integer + type: array + interval: + minimum: 0 + type: integer + tcp_failures: + minimum: 0 + type: integer + timeouts: + minimum: 0 + type: integer + type: object + type: object + passive: + description: |- + PassiveHealthcheck configures passive checks around + passive health checks. + properties: + healthy: + description: |- + Healthy configures thresholds and HTTP status codes + to mark targets healthy for an upstream. + properties: + http_statuses: + items: + type: integer + type: array + interval: + minimum: 0 + type: integer + successes: + minimum: 0 + type: integer + type: object + type: + type: string + unhealthy: + description: |- + Unhealthy configures thresholds and HTTP status codes + to mark targets unhealthy. + properties: + http_failures: + minimum: 0 + type: integer + http_statuses: + items: + type: integer + type: array + interval: + minimum: 0 + type: integer + tcp_failures: + minimum: 0 + type: integer + timeouts: + minimum: 0 + type: integer + type: object + type: object + threshold: + type: number + type: object + host_header: + description: |- + HostHeader is The hostname to be used as Host header + when proxying requests through Kong. + type: string + slots: + description: Slots is the number of slots in the load balancer algorithm. + minimum: 10 + type: integer + type: object + type: object + x-kubernetes-validations: + - message: '''proxy'' field is no longer supported, use Service''s annotations + instead' + rule: '!has(self.proxy)' + - message: '''route'' field is no longer supported, use Ingress'' annotations + instead' + rule: '!has(self.route)' + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.1 + name: konglicenses.configuration.konghq.com +spec: + group: configuration.konghq.com + names: + categories: + - kong-ingress-controller + kind: KongLicense + listKind: KongLicenseList + plural: konglicenses + shortNames: + - kl + singular: konglicense + scope: Cluster + versions: + - additionalPrinterColumns: + - description: Age + jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: Enabled to configure on Kong gateway instances + jsonPath: .enabled + name: Enabled + type: boolean + name: v1alpha1 + schema: + openAPIV3Schema: + description: KongLicense stores a Kong enterprise license to apply to managed + Kong gateway instances. + 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 + enabled: + default: true + description: |- + Enabled is set to true to let controllers (like KIC or KGO) to reconcile it. + Default value is true to apply the license by default. + type: boolean + 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 + rawLicenseString: + description: RawLicenseString is a string with the raw content of the + license. + type: string + status: + description: Status is the status of the KongLicense being processed by + controllers. + properties: + controllers: + items: + description: |- + KongLicenseControllerStatus is the status of owning KongLicense being processed + identified by the controllerName field. + properties: + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Programmed + description: Conditions describe the current conditions of the + KongLicense on the controller. + items: + description: Condition contains details for one aspect of + the current state of this API Resource. + 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. + 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 + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + controllerName: + description: |- + ControllerName is an identifier of the controller to reconcile this KongLicense. + Should be unique in the list of controller statuses. + type: string + controllerRef: + description: |- + ControllerRef is the reference of the controller to reconcile this KongLicense. + It is usually the name of (KIC/KGO) pod that reconciles it. + properties: + group: + description: |- + Group is the group of referent. + It should be empty if the referent is in "core" group (like pod). + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: |- + Kind is the kind of the referent. + By default the nil kind means kind Pod. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. + It should be empty if the referent is cluster scoped. + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - name + type: object + required: + - controllerName + type: object + type: array + x-kubernetes-list-map-keys: + - controllerName + x-kubernetes-list-type: map + type: object + required: + - enabled + - rawLicenseString + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.1 + name: kongplugins.configuration.konghq.com +spec: + group: configuration.konghq.com + names: + categories: + - kong-ingress-controller + kind: KongPlugin + listKind: KongPluginList + plural: kongplugins + shortNames: + - kp + singular: kongplugin + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Name of the plugin + jsonPath: .plugin + name: Plugin-Type + type: string + - description: Age + jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: Indicates if the plugin is disabled + jsonPath: .disabled + name: Disabled + priority: 1 + type: boolean + - description: Configuration of the plugin + jsonPath: .config + name: Config + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Programmed")].status + name: Programmed + type: string + name: v1 + schema: + openAPIV3Schema: + description: KongPlugin is the Schema for the kongplugins 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 + config: + description: |- + Config contains the plugin configuration. It's a list of keys and values + required to configure the plugin. + Please read the documentation of the plugin being configured to set values + in here. For any plugin in Kong, anything that goes in the `config` JSON + key in the Admin API request, goes into this property. + Only one of `config` or `configFrom` may be used in a KongPlugin, not both at once. + type: object + x-kubernetes-preserve-unknown-fields: true + configFrom: + description: |- + ConfigFrom references a secret containing the plugin configuration. + This should be used when the plugin configuration contains sensitive information, + such as AWS credentials in the Lambda plugin or the client secret in the OIDC plugin. + Only one of `config` or `configFrom` may be used in a KongPlugin, not both at once. + properties: + secretKeyRef: + description: Specifies a name and a key of a secret to refer to. The + namespace is implicitly set to the one of referring object. + properties: + key: + description: The key containing the value. + type: string + name: + description: The secret containing the key. + type: string + required: + - key + - name + type: object + required: + - secretKeyRef + type: object + configPatches: + description: |- + ConfigPatches represents JSON patches to the configuration of the plugin. + Each item means a JSON patch to add something in the configuration, + where path is specified in `path` and value is in `valueFrom` referencing + a key in a secret. + When Config is specified, patches will be applied to the configuration in Config. + Otherwise, patches will be applied to an empty object. + items: + description: |- + ConfigPatch is a JSON patch (RFC6902) to add values from Secret to the generated configuration. + It is an equivalent of the following patch: + `{"op": "add", "path": {.Path}, "value": {.ComputedValueFrom}}`. + properties: + path: + description: Path is the JSON-Pointer value (RFC6901) that references + a location within the target configuration. + type: string + valueFrom: + description: ValueFrom is the reference to a key of a secret where + the patched value comes from. + properties: + secretKeyRef: + description: Specifies a name and a key of a secret to refer + to. The namespace is implicitly set to the one of referring + object. + properties: + key: + description: The key containing the value. + type: string + name: + description: The secret containing the key. + type: string + required: + - key + - name + type: object + required: + - secretKeyRef + type: object + required: + - path + - valueFrom + type: object + type: array + consumerRef: + description: ConsumerRef is a reference to a particular consumer. + type: string + disabled: + description: Disabled set if the plugin is disabled or not. + type: boolean + instance_name: + description: |- + InstanceName is an optional custom name to identify an instance of the plugin. This is useful when running the + same plugin in multiple contexts, for example, on multiple services. + 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 + ordering: + description: |- + Ordering overrides the normal plugin execution order. It's only available on Kong Enterprise. + `` is a request processing phase (for example, `access` or `body_filter`) and + `` is the name of the plugin that will run before or after the KongPlugin. + For example, a KongPlugin with `plugin: rate-limiting` and `before.access: ["key-auth"]` + will create a rate limiting plugin that limits requests _before_ they are authenticated. + properties: + after: + additionalProperties: + items: + type: string + type: array + description: PluginOrderingPhase indicates which plugins in a phase + should affect the target plugin's order + type: object + before: + additionalProperties: + items: + type: string + type: array + description: PluginOrderingPhase indicates which plugins in a phase + should affect the target plugin's order + type: object + type: object + plugin: + description: PluginName is the name of the plugin to which to apply the + config. + type: string + protocols: + description: |- + Protocols configures plugin to run on requests received on specific + protocols. + items: + description: |- + KongProtocol is a valid Kong protocol. + This alias is necessary to deal with https://github.com/kubernetes-sigs/controller-tools/issues/342 + enum: + - http + - https + - grpc + - grpcs + - tcp + - tls + - udp + type: string + type: array + run_on: + description: |- + RunOn configures the plugin to run on the first or the second or both + nodes in case of a service mesh deployment. + enum: + - first + - second + - all + type: string + status: + description: Status represents the current status of the KongPlugin resource. + properties: + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Programmed + description: |- + Conditions describe the current conditions of the KongPluginStatus. + + Known condition types are: + + * "Programmed" + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + 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. + 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 + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object + required: + - plugin + type: object + x-kubernetes-validations: + - message: Using both config and configFrom fields is not allowed. + rule: '!(has(self.config) && has(self.configFrom))' + - message: Using both configFrom and configPatches fields is not allowed. + rule: '!(has(self.configFrom) && has(self.configPatches))' + - message: The plugin field is immutable + rule: self.plugin == oldSelf.plugin + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.1 + labels: + gateway.networking.k8s.io/policy: direct + name: kongupstreampolicies.configuration.konghq.com +spec: + group: configuration.konghq.com + names: + categories: + - kong-ingress-controller + kind: KongUpstreamPolicy + listKind: KongUpstreamPolicyList + plural: kongupstreampolicies + shortNames: + - kup + singular: kongupstreampolicy + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + description: |- + KongUpstreamPolicy allows configuring algorithm that should be used for load balancing traffic between Kong + Upstream's Targets. It also allows configuring health checks for Kong Upstream's Targets. + + Its configuration is similar to Kong Upstream object (https://docs.konghq.com/gateway/latest/admin-api/#upstream-object), + and it is applied to Kong Upstream objects created by the controller. + + It can be attached to Services. To attach it to a Service, it has to be annotated with + `konghq.com/upstream-policy: `, where `` is the name of the KongUpstreamPolicy + object in the same namespace as the Service. + + When attached to a Service, it will affect all Kong Upstreams created for the Service. + + When attached to a Service used in a Gateway API *Route rule with multiple BackendRefs, all of its Services MUST + be configured with the same KongUpstreamPolicy. Otherwise, the controller will *ignore* the KongUpstreamPolicy. + + Note: KongUpstreamPolicy doesn't implement Gateway API's GEP-713 strictly. + In particular, it doesn't use the TargetRef for attaching to Services and Gateway API *Routes - annotations are + used instead. This is to allow reusing the same KongUpstreamPolicy for multiple Services and Gateway API *Routes. + 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 contains the configuration of the Kong upstream. + properties: + algorithm: + description: |- + Algorithm is the load balancing algorithm to use. + Accepted values are: "round-robin", "consistent-hashing", "least-connections", "latency". + enum: + - round-robin + - consistent-hashing + - least-connections + - latency + type: string + hashOn: + description: |- + HashOn defines how to calculate hash for consistent-hashing load balancing algorithm. + Algorithm must be set to "consistent-hashing" for this field to have effect. + properties: + cookie: + description: Cookie is the name of the cookie to use as hash input. + type: string + cookiePath: + description: CookiePath is cookie path to set in the response + headers. + type: string + header: + description: Header is the name of the header to use as hash input. + type: string + input: + description: |- + Input allows using one of the predefined inputs (ip, consumer, path). + For other parametrized inputs, use one of the fields below. + enum: + - ip + - consumer + - path + type: string + queryArg: + description: QueryArg is the name of the query argument to use + as hash input. + type: string + uriCapture: + description: URICapture is the name of the URI capture group to + use as hash input. + type: string + type: object + hashOnFallback: + description: |- + HashOnFallback defines how to calculate hash for consistent-hashing load balancing algorithm if the primary hash + function fails. + Algorithm must be set to "consistent-hashing" for this field to have effect. + properties: + cookie: + description: Cookie is the name of the cookie to use as hash input. + type: string + cookiePath: + description: CookiePath is cookie path to set in the response + headers. + type: string + header: + description: Header is the name of the header to use as hash input. + type: string + input: + description: |- + Input allows using one of the predefined inputs (ip, consumer, path). + For other parametrized inputs, use one of the fields below. + enum: + - ip + - consumer + - path + type: string + queryArg: + description: QueryArg is the name of the query argument to use + as hash input. + type: string + uriCapture: + description: URICapture is the name of the URI capture group to + use as hash input. + type: string + type: object + healthchecks: + description: Healthchecks defines the health check configurations + in Kong. + properties: + active: + description: Active configures active health check probing. + properties: + concurrency: + description: Concurrency is the number of targets to check + concurrently. + minimum: 1 + type: integer + headers: + additionalProperties: + items: + type: string + type: array + description: Headers is a list of HTTP headers to add to the + probe request. + type: object + healthy: + description: Healthy configures thresholds and HTTP status + codes to mark targets healthy for an upstream. + properties: + httpStatuses: + description: HTTPStatuses is a list of HTTP status codes + that Kong considers a success. + items: + description: HTTPStatus is an HTTP status code. + maximum: 599 + minimum: 100 + type: integer + type: array + interval: + description: Interval is the interval between active health + checks for an upstream in seconds when in a healthy + state. + minimum: 0 + type: integer + successes: + description: Successes is the number of successes to consider + a target healthy. + minimum: 0 + type: integer + type: object + httpPath: + description: HTTPPath is the path to use in GET HTTP request + to run as a probe. + pattern: ^/.*$ + type: string + httpsSni: + description: HTTPSSNI is the SNI to use in GET HTTPS request + to run as a probe. + type: string + httpsVerifyCertificate: + description: HTTPSVerifyCertificate is a boolean value that + indicates if the certificate should be verified. + type: boolean + timeout: + description: Timeout is the probe timeout in seconds. + minimum: 0 + type: integer + type: + description: |- + Type determines whether to perform active health checks using HTTP or HTTPS, or just attempt a TCP connection. + Accepted values are "http", "https", "tcp", "grpc", "grpcs". + enum: + - http + - https + - tcp + - grpc + - grpcs + type: string + unhealthy: + description: Unhealthy configures thresholds and HTTP status + codes to mark targets unhealthy for an upstream. + properties: + httpFailures: + description: HTTPFailures is the number of failures to + consider a target unhealthy. + minimum: 0 + type: integer + httpStatuses: + description: HTTPStatuses is a list of HTTP status codes + that Kong considers a failure. + items: + description: HTTPStatus is an HTTP status code. + maximum: 599 + minimum: 100 + type: integer + type: array + interval: + description: Interval is the interval between active health + checks for an upstream in seconds when in an unhealthy + state. + minimum: 0 + type: integer + tcpFailures: + description: TCPFailures is the number of TCP failures + in a row to consider a target unhealthy. + minimum: 0 + type: integer + timeouts: + description: Timeouts is the number of timeouts in a row + to consider a target unhealthy. + minimum: 0 + type: integer + type: object + type: object + passive: + description: Passive configures passive health check probing. + properties: + healthy: + description: Healthy configures thresholds and HTTP status + codes to mark targets healthy for an upstream. + properties: + httpStatuses: + description: HTTPStatuses is a list of HTTP status codes + that Kong considers a success. + items: + description: HTTPStatus is an HTTP status code. + maximum: 599 + minimum: 100 + type: integer + type: array + interval: + description: Interval is the interval between active health + checks for an upstream in seconds when in a healthy + state. + minimum: 0 + type: integer + successes: + description: Successes is the number of successes to consider + a target healthy. + minimum: 0 + type: integer + type: object + type: + description: |- + Type determines whether to perform passive health checks interpreting HTTP/HTTPS statuses, + or just check for TCP connection success. + Accepted values are "http", "https", "tcp", "grpc", "grpcs". + enum: + - http + - https + - tcp + - grpc + - grpcs + type: string + unhealthy: + description: Unhealthy configures thresholds and HTTP status + codes to mark targets unhealthy. + properties: + httpFailures: + description: HTTPFailures is the number of failures to + consider a target unhealthy. + minimum: 0 + type: integer + httpStatuses: + description: HTTPStatuses is a list of HTTP status codes + that Kong considers a failure. + items: + description: HTTPStatus is an HTTP status code. + maximum: 599 + minimum: 100 + type: integer + type: array + interval: + description: Interval is the interval between active health + checks for an upstream in seconds when in an unhealthy + state. + minimum: 0 + type: integer + tcpFailures: + description: TCPFailures is the number of TCP failures + in a row to consider a target unhealthy. + minimum: 0 + type: integer + timeouts: + description: Timeouts is the number of timeouts in a row + to consider a target unhealthy. + minimum: 0 + type: integer + type: object + type: object + threshold: + description: |- + Threshold is the minimum percentage of the upstream’s targets’ weight that must be available for the whole + upstream to be considered healthy. + type: integer + type: object + slots: + description: |- + Slots is the number of slots in the load balancer algorithm. + If not set, the default value in Kong for the algorithm is used. + maximum: 65536 + minimum: 10 + type: integer + type: object + status: + description: Status defines the current state of KongUpstreamPolicy + properties: + ancestors: + description: |- + Ancestors is a list of ancestor resources (usually Gateways) that are + associated with the policy, and the status of the policy with respect to + each ancestor. When this policy attaches to a parent, the controller that + manages the parent and the ancestors MUST add an entry to this list when + the controller first sees the policy and SHOULD update the entry as + appropriate when the relevant ancestor is modified. + + Note that choosing the relevant ancestor is left to the Policy designers; + an important part of Policy design is designing the right object level at + which to namespace this status. + + Note also that implementations MUST ONLY populate ancestor status for + the Ancestor resources they are responsible for. Implementations MUST + use the ControllerName field to uniquely identify the entries in this list + that they are responsible for. + + Note that to achieve this, the list of PolicyAncestorStatus structs + MUST be treated as a map with a composite key, made up of the AncestorRef + and ControllerName fields combined. + + A maximum of 16 ancestors will be represented in this list. An empty list + means the Policy is not relevant for any ancestors. + + If this slice is full, implementations MUST NOT add further entries. + Instead they MUST consider the policy unimplementable and signal that + on any related resources such as the ancestor that would be referenced + here. For example, if this list was full on BackendTLSPolicy, no + additional Gateways would be able to reference the Service targeted by + the BackendTLSPolicy. + items: + description: |- + PolicyAncestorStatus describes the status of a route with respect to an + associated Ancestor. + + Ancestors refer to objects that are either the Target of a policy or above it + in terms of object hierarchy. For example, if a policy targets a Service, the + Policy's Ancestors are, in order, the Service, the HTTPRoute, the Gateway, and + the GatewayClass. Almost always, in this hierarchy, the Gateway will be the most + useful object to place Policy status on, so we recommend that implementations + SHOULD use Gateway as the PolicyAncestorStatus object unless the designers + have a _very_ good reason otherwise. + + In the context of policy attachment, the Ancestor is used to distinguish which + resource results in a distinct application of this policy. For example, if a policy + targets a Service, it may have a distinct result per attached Gateway. + + Policies targeting the same resource may have different effects depending on the + ancestors of those resources. For example, different Gateways targeting the same + Service may have different capabilities, especially if they have different underlying + implementations. + + For example, in BackendTLSPolicy, the Policy attaches to a Service that is + used as a backend in a HTTPRoute that is itself attached to a Gateway. + In this case, the relevant object for status is the Gateway, and that is the + ancestor object referred to in this status. + + Note that a parent is also an ancestor, so for objects where the parent is the + relevant object for status, this struct SHOULD still be used. + + This struct is intended to be used in a slice that's effectively a map, + with a composite key made up of the AncestorRef and the ControllerName. + properties: + ancestorRef: + description: |- + AncestorRef corresponds with a ParentRef in the spec that this + PolicyAncestorStatus struct describes the status of. + properties: + group: + default: gateway.networking.k8s.io + description: |- + Group is the group of the referent. + When unspecified, "gateway.networking.k8s.io" is inferred. + To set the core API group (such as for a "Service" kind referent), + Group must be explicitly set to "" (empty string). + + Support: Core + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Gateway + description: |- + Kind is kind of the referent. + + There are two kinds of parent resources with "Core" support: + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + Support for other resources is Implementation-Specific. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: |- + Name is the name of the referent. + + Support: Core + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. When unspecified, this refers + to the local namespace of the Route. + + Note that there are specific rules for ParentRefs which cross namespace + boundaries. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example: + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. + + + ParentRefs from a Route to a Service in the same namespace are "producer" + routes, which apply default routing rules to inbound connections from + any namespace to the Service. + + ParentRefs from a Route to a Service in a different namespace are + "consumer" routes, and these routing rules are only applied to outbound + connections originating from the same namespace as the Route, for which + the intended destination of the connections are a Service targeted as a + ParentRef of the Route. + + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: |- + Port is the network port this Route targets. It can be interpreted + differently based on the type of parent resource. + + When the parent resource is a Gateway, this targets all listeners + listening on the specified port that also support this kind of Route(and + select this Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to a specific port + as opposed to a listener(s) whose port(s) may be changed. When both Port + and SectionName are specified, the name and port of the selected listener + must match both specified values. + + + When the parent resource is a Service, this targets a specific port in the + Service spec. When both Port (experimental) and SectionName are specified, + the name and port of the selected port must match both specified values. + + + Implementations MAY choose to support other parent resources. + Implementations supporting other types of parent resources MUST clearly + document how/if Port is interpreted. + + For the purpose of status, an attachment is considered successful as + long as the parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: |- + SectionName is the name of a section within the target resource. In the + following resources, SectionName is interpreted as the following: + + * Gateway: Listener name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + * Service: Port name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + + Implementations MAY choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName is + interpreted. + + When unspecified (empty string), this will reference the entire resource. + For the purpose of status, an attachment is considered successful if at + least one section in the parent resource accepts it. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from + the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, the + Route MUST be considered detached from the Gateway. + + Support: Core + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - name + type: object + conditions: + description: Conditions describes the status of the Policy with + respect to the given Ancestor. + items: + description: Condition contains details for one aspect of + the current state of this API Resource. + 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. + 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 + maxItems: 8 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + controllerName: + description: |- + ControllerName is a domain/path string that indicates the name of the + controller that wrote this status. This corresponds with the + controllerName field on GatewayClass. + + Example: "example.net/gateway-controller". + + The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are + valid Kubernetes names + (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). + + Controllers MUST populate this field when writing status. Controllers should ensure that + entries to status populated with their ControllerName are cleaned up when they are no + longer necessary. + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + required: + - ancestorRef + - controllerName + type: object + maxItems: 16 + type: array + required: + - ancestors + type: object + type: object + x-kubernetes-validations: + - message: Only one of spec.hashOn.(input|cookie|header|uriCapture|queryArg) + can be set. + rule: 'has(self.spec.hashOn) ? [has(self.spec.hashOn.input), has(self.spec.hashOn.cookie), + has(self.spec.hashOn.header), has(self.spec.hashOn.uriCapture), has(self.spec.hashOn.queryArg)].filter(fieldSet, + fieldSet == true).size() <= 1 : true' + - message: When spec.hashOn.cookie is set, spec.hashOn.cookiePath is required. + rule: 'has(self.spec.hashOn) && has(self.spec.hashOn.cookie) ? has(self.spec.hashOn.cookiePath) + : true' + - message: When spec.hashOn.cookiePath is set, spec.hashOn.cookie is required. + rule: 'has(self.spec.hashOn) && has(self.spec.hashOn.cookiePath) ? has(self.spec.hashOn.cookie) + : true' + - message: spec.algorithm must be set to "consistent-hashing" when spec.hashOn + is set. + rule: 'has(self.spec.hashOn) ? has(self.spec.algorithm) && self.spec.algorithm + == "consistent-hashing" : true' + - message: Only one of spec.hashOnFallback.(input|header|uriCapture|queryArg) + can be set. + rule: 'has(self.spec.hashOnFallback) ? [has(self.spec.hashOnFallback.input), + has(self.spec.hashOnFallback.header), has(self.spec.hashOnFallback.uriCapture), + has(self.spec.hashOnFallback.queryArg)].filter(fieldSet, fieldSet == true).size() + <= 1 : true' + - message: spec.algorithm must be set to "consistent-hashing" when spec.hashOnFallback + is set. + rule: 'has(self.spec.hashOnFallback) ? has(self.spec.algorithm) && self.spec.algorithm + == "consistent-hashing" : true' + - message: spec.hashOnFallback.cookie must not be set. + rule: 'has(self.spec.hashOnFallback) ? !has(self.spec.hashOnFallback.cookie) + : true' + - message: spec.hashOnFallback.cookiePath must not be set. + rule: 'has(self.spec.hashOnFallback) ? !has(self.spec.hashOnFallback.cookiePath) + : true' + - message: spec.healthchecks.passive.healthy.interval must not be set. + rule: 'has(self.spec.healthchecks) && has(self.spec.healthchecks.passive) + && has(self.spec.healthchecks.passive.healthy) ? !has(self.spec.healthchecks.passive.healthy.interval) + : true' + - message: spec.healthchecks.passive.unhealthy.interval must not be set. + rule: 'has(self.spec.healthchecks) && has(self.spec.healthchecks.passive) + && has(self.spec.healthchecks.passive.unhealthy) ? !has(self.spec.healthchecks.passive.unhealthy.interval) + : true' + - message: spec.hashOnFallback must not be set when spec.hashOn.cookie is + set. + rule: 'has(self.spec.hashOn) && has(self.spec.hashOn.cookie) ? !has(self.spec.hashOnFallback) + : true' + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.1 + name: kongvaults.configuration.konghq.com +spec: + group: configuration.konghq.com + names: + categories: + - kong-ingress-controller + kind: KongVault + listKind: KongVaultList + plural: kongvaults + shortNames: + - kv + singular: kongvault + scope: Cluster + versions: + - additionalPrinterColumns: + - description: Name of the backend of the vault + jsonPath: .spec.backend + name: Backend Type + type: string + - description: Prefix of vault URI to reference the values in the vault + jsonPath: .spec.prefix + name: Prefix + type: string + - description: Age + jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: Description + jsonPath: .spec.description + name: Description + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Programmed")].status + name: Programmed + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + KongVault is the schema for kongvaults API which defines a custom Kong vault. + A Kong vault is a storage to store sensitive data, where the values can be referenced in configuration of plugins. + See: https://docs.konghq.com/gateway/latest/kong-enterprise/secrets-management/ + 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: KongVaultSpec defines specification of a custom Kong vault. + properties: + backend: + description: |- + Backend is the type of the backend storing the secrets in the vault. + The supported backends of Kong is listed here: + https://docs.konghq.com/gateway/latest/kong-enterprise/secrets-management/backends/ + minLength: 1 + type: string + config: + description: Config is the configuration of the vault. Varies for + different backends. + x-kubernetes-preserve-unknown-fields: true + description: + description: Description is the additional information about the vault. + type: string + prefix: + description: |- + Prefix is the prefix of vault URI for referencing values in the vault. + It is immutable after created. + minLength: 1 + type: string + required: + - backend + - prefix + type: object + status: + description: KongVaultStatus represents the current status of the KongVault + resource. + properties: + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Programmed + description: |- + Conditions describe the current conditions of the KongVaultStatus. + + Known condition types are: + + * "Programmed" + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + 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. + 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 + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + required: + - conditions + type: object + required: + - spec + type: object + x-kubernetes-validations: + - message: The spec.prefix field is immutable + rule: self.spec.prefix == oldSelf.spec.prefix + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.1 + name: tcpingresses.configuration.konghq.com +spec: + group: configuration.konghq.com + names: + categories: + - kong-ingress-controller + kind: TCPIngress + listKind: TCPIngressList + plural: tcpingresses + singular: tcpingress + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Address of the load balancer + jsonPath: .status.loadBalancer.ingress[*].ip + name: Address + type: string + - description: Age + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: TCPIngress is the Schema for the tcpingresses 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 is the TCPIngress specification. + properties: + rules: + description: A list of rules used to configure the Ingress. + items: + description: |- + IngressRule represents a rule to apply against incoming requests. + Matching is performed based on an (optional) SNI and port. + properties: + backend: + description: |- + Backend defines the referenced service endpoint to which the traffic + will be forwarded to. + properties: + serviceName: + description: Specifies the name of the referenced service. + minLength: 1 + type: string + servicePort: + description: Specifies the port of the referenced service. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - serviceName + - servicePort + type: object + host: + description: |- + Host is the fully qualified domain name of a network host, as defined + by RFC 3986. + If a Host is not specified, then port-based TCP routing is performed. Kong + doesn't care about the content of the TCP stream in this case. + If a Host is specified, the protocol must be TLS over TCP. + A plain-text TCP request cannot be routed based on Host. It can only + be routed based on Port. + type: string + port: + description: |- + Port is the port on which to accept TCP or TLS over TCP sessions and + route. It is a required field. If a Host is not specified, the requested + are routed based only on Port. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - backend + - port + type: object + type: array + tls: + description: |- + TLS configuration. This is similar to the `tls` section in the + Ingress resource in networking.v1beta1 group. + The mapping of SNIs to TLS cert-key pair defined here will be + used for HTTP Ingress rules as well. Once can define the mapping in + this resource or the original Ingress resource, both have the same + effect. + items: + description: IngressTLS describes the transport layer security. + properties: + hosts: + description: |- + Hosts are a list of hosts included in the TLS certificate. The values in + this list must match the name/s used in the tlsSecret. Defaults to the + wildcard host setting for the loadbalancer controller fulfilling this + Ingress, if left unspecified. + items: + type: string + type: array + secretName: + description: SecretName is the name of the secret used to terminate + SSL traffic. + type: string + type: object + type: array + type: object + status: + description: TCPIngressStatus defines the observed state of TCPIngress. + properties: + loadBalancer: + description: LoadBalancer contains the current status of the load-balancer. + properties: + ingress: + description: |- + Ingress is a list containing ingress points for the load-balancer. + Traffic intended for the service should be sent to these ingress points. + items: + description: |- + LoadBalancerIngress represents the status of a load-balancer ingress point: + traffic intended for the service should be sent to an ingress point. + properties: + hostname: + description: |- + Hostname is set for load-balancer ingress points that are DNS based + (typically AWS load-balancers) + type: string + ip: + description: |- + IP is set for load-balancer ingress points that are IP based + (typically GCE or OpenStack load-balancers) + type: string + ipMode: + description: |- + IPMode specifies how the load-balancer IP behaves, and may only be specified when the ip field is specified. + Setting this to "VIP" indicates that traffic is delivered to the node with + the destination set to the load-balancer's IP and port. + Setting this to "Proxy" indicates that traffic is delivered to the node or pod with + the destination set to the node's IP and node port or the pod's IP and port. + Service implementations may use this information to adjust traffic routing. + type: string + ports: + description: |- + Ports is a list of records of service ports + If used, every port defined in the service should have an entry in it + items: + properties: + error: + description: |- + Error is to record the problem with the service port + The format of the error shall comply with the following rules: + - built-in error values shall be specified in this file and those shall use + CamelCase names + - cloud provider specific error values must have names that comply with the + format foo.example.com/CamelCase. + 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 + port: + description: Port is the port number of the service + port of which status is recorded here + format: int32 + type: integer + protocol: + description: |- + Protocol is the protocol of the service port of which status is recorded here + The supported values are: "TCP", "UDP", "SCTP" + type: string + required: + - error + - port + - protocol + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.1 + name: udpingresses.configuration.konghq.com +spec: + group: configuration.konghq.com + names: + categories: + - kong-ingress-controller + kind: UDPIngress + listKind: UDPIngressList + plural: udpingresses + singular: udpingress + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Address of the load balancer + jsonPath: .status.loadBalancer.ingress[*].ip + name: Address + type: string + - description: Age + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: UDPIngress is the Schema for the udpingresses 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 is the UDPIngress specification. + properties: + rules: + description: A list of rules used to configure the Ingress. + items: + description: |- + UDPIngressRule represents a rule to apply against incoming requests + wherein no Host matching is available for request routing, only the port + is used to match requests. + properties: + backend: + description: |- + Backend defines the Kubernetes service which accepts traffic from the + listening Port defined above. + properties: + serviceName: + description: Specifies the name of the referenced service. + minLength: 1 + type: string + servicePort: + description: Specifies the port of the referenced service. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - serviceName + - servicePort + type: object + port: + description: |- + Port indicates the port for the Kong proxy to accept incoming traffic + on, which will then be routed to the service Backend. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - backend + - port + type: object + type: array + type: object + status: + description: UDPIngressStatus defines the observed state of UDPIngress. + properties: + loadBalancer: + description: LoadBalancer contains the current status of the load-balancer. + properties: + ingress: + description: |- + Ingress is a list containing ingress points for the load-balancer. + Traffic intended for the service should be sent to these ingress points. + items: + description: |- + LoadBalancerIngress represents the status of a load-balancer ingress point: + traffic intended for the service should be sent to an ingress point. + properties: + hostname: + description: |- + Hostname is set for load-balancer ingress points that are DNS based + (typically AWS load-balancers) + type: string + ip: + description: |- + IP is set for load-balancer ingress points that are IP based + (typically GCE or OpenStack load-balancers) + type: string + ipMode: + description: |- + IPMode specifies how the load-balancer IP behaves, and may only be specified when the ip field is specified. + Setting this to "VIP" indicates that traffic is delivered to the node with + the destination set to the load-balancer's IP and port. + Setting this to "Proxy" indicates that traffic is delivered to the node or pod with + the destination set to the node's IP and node port or the pod's IP and port. + Service implementations may use this information to adjust traffic routing. + type: string + ports: + description: |- + Ports is a list of records of service ports + If used, every port defined in the service should have an entry in it + items: + properties: + error: + description: |- + Error is to record the problem with the service port + The format of the error shall comply with the following rules: + - built-in error values shall be specified in this file and those shall use + CamelCase names + - cloud provider specific error values must have names that comply with the + format foo.example.com/CamelCase. + 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 + port: + description: Port is the port number of the service + port of which status is recorded here + format: int32 + type: integer + protocol: + description: |- + Protocol is the protocol of the service port of which status is recorded here + The supported values are: "TCP", "UDP", "SCTP" + type: string + required: + - error + - port + - protocol + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/kong/kong/2.41.0/questions.yml b/charts/kong/kong/2.41.0/questions.yml new file mode 100644 index 0000000000..27b774b9b7 --- /dev/null +++ b/charts/kong/kong/2.41.0/questions.yml @@ -0,0 +1,33 @@ +labels: + io.rancher.certified: partner + io.cattle.role: project # options are cluster/project +categories: +- API Gateway +questions: +- variable: admin.enabled + default: "false" + description: "Enable REST Admin API" + label: REST Admin API + type: boolean + show_subquestion_if: true + group: "Admin API" + subquestions: + - variable: admin.type + default: "LoadBalancer" + description: "Kubernetes Service Type" + label: Service Type + type: enum + options: + - ClusterIP + - NodePort + - LoadBalancer + - variable: admin.http.enabled + default: "false" + description: "Enable HTTP for REST Admin API" + label: REST Admin API - HTTP + type: boolean +- variable: proxy.http.enabled + default: "true" + description: "Enable HTTP for Proxy" + label: Proxy - HTTP + type: boolean diff --git a/charts/kong/kong/2.41.0/templates/NOTES.txt b/charts/kong/kong/2.41.0/templates/NOTES.txt new file mode 100644 index 0000000000..bb370e95fd --- /dev/null +++ b/charts/kong/kong/2.41.0/templates/NOTES.txt @@ -0,0 +1,48 @@ +To connect to Kong, please execute the following commands: +{{ if contains "LoadBalancer" .Values.proxy.type }} +HOST=$(kubectl get svc --namespace {{ template "kong.namespace" . }} {{ template "kong.fullname" . }}-proxy -o jsonpath='{.status.loadBalancer.ingress[0].ip}') +PORT=$(kubectl get svc --namespace {{ template "kong.namespace" . }} {{ template "kong.fullname" . }}-proxy -o jsonpath='{.spec.ports[0].port}') +{{ else if contains "NodePort" .Values.proxy.type }}HOST=$(kubectl get nodes --namespace {{ template "kong.namespace" . }} -o jsonpath='{.items[0].status.addresses[0].address}') +PORT=$(kubectl get svc --namespace {{ template "kong.namespace" . }} {{ template "kong.fullname" . }}-proxy -o jsonpath='{.spec.ports[0].nodePort}') +{{ end -}} +export PROXY_IP=${HOST}:${PORT} +curl $PROXY_IP + +Once installed, please follow along the getting started guide to start using +Kong: https://docs.konghq.com/kubernetes-ingress-controller/latest/guides/getting-started/ + +{{ $warnings := list -}} + +{{- if (hasKey .Values.ingressController "serviceAccount") -}} +{{- if (or (hasKey .Values.ingressController.serviceAccount "name") (hasKey .Values.ingressController.serviceAccount "annotations")) -}} +{{- $warnings = append $warnings "you have set either .ingressController.serviceAccount.name or .ingressController.serviceAccount.annotations. These settings have moved to .deployment.serviceAccount.name and .deployment.serviceAccount.annotations. You must move your configuration to the new location in values.yaml" -}} +{{- end -}} +{{- end -}} + +{{- if and .Values.manager.enabled (or .Values.manager.http.enabled .Values.manager.tls.enabled) -}} +{{- if not (and .Values.admin.enabled (or .Values.admin.http.enabled .Values.admin.tls.enabled)) -}} +{{- $warnings = append $warnings "Kong Manager will not be functional because the Admin API is not enabled. Setting both .admin.enabled and .admin.http.enabled and/or .admin.tls.enabled to true to enable the Admin API over HTTP/TLS." -}} +{{- end -}} +{{- end -}} + +{{- if and .Values.ingressController.konnect.enabled .Values.ingressController.konnect.runtimeGroupID -}} +{{- if not .Values.ingressController.konnect.controlPlaneID -}} +{{- $warnings = append $warnings "Please use `.ingressController.konnect.controlPlaneID` instead. `.ingressController.konnect.runtimeGroupID` will be removed in a future release." -}} +{{- end -}} +{{- end -}} + +{{- include "kong.deprecation-warnings" $warnings -}} + +{{- if .Values.demo -}} + +############################################################################################# +##### WARNING: DEMO VALUES USED +############################################################################################# + +The values file used has been marked as a demo configuration. +It should NOT be used in production without comprehensive review of all settings provided. + +############################################################################################# +##### WARNING: DEMO VALUES USED +############################################################################################# +{{- end -}} diff --git a/charts/kong/kong/2.41.0/templates/_helpers.tpl b/charts/kong/kong/2.41.0/templates/_helpers.tpl new file mode 100644 index 0000000000..fe20eb4f33 --- /dev/null +++ b/charts/kong/kong/2.41.0/templates/_helpers.tpl @@ -0,0 +1,1844 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +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 "kong.namespace" -}} +{{- default .Release.Namespace .Values.namespace -}} +{{- end -}} + +{{- define "kong.release" -}} +{{- default .Release.Name -}} +{{- end -}} + +{{- define "kong.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- define "kong.fullname" -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- default (printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-") .Values.fullnameOverride -}} +{{- end -}} + +{{- define "kong.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- define "kong.metaLabels" -}} +app.kubernetes.io/name: {{ template "kong.name" . }} +helm.sh/chart: {{ template "kong.chart" . }} +app.kubernetes.io/instance: "{{ .Release.Name }}" +app.kubernetes.io/managed-by: "{{ .Release.Service }}" +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- range $key, $value := .Values.extraLabels }} +{{ $key }}: {{ include "kong.renderTpl" (dict "value" $value "context" $) | quote }} +{{- end }} +{{- end -}} + +{{- define "kong.selectorLabels" -}} +app.kubernetes.io/name: {{ template "kong.name" . }} +app.kubernetes.io/component: app +app.kubernetes.io/instance: "{{ .Release.Name }}" +{{- end -}} + +{{- define "kong.postgresql.fullname" -}} +{{- $name := default "postgresql" .Values.postgresql.nameOverride -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- define "kong.dblessConfig.fullname" -}} +{{- $name := default "kong-custom-dbless-config" .Values.dblessConfig.nameOverride -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "kong.serviceAccountName" -}} +{{- if .Values.deployment.serviceAccount.create -}} + {{ default (include "kong.fullname" .) .Values.deployment.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.deployment.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the secret for service account token to use +*/}} +{{- define "kong.serviceAccountTokenName" -}} +{{ include "kong.serviceAccountName" . }}-token +{{- end -}} + +{{/* +Create Ingress resource for a Kong service +*/}} +{{- define "kong.ingress" -}} +{{- $servicePort := include "kong.ingress.servicePort" . }} +{{- $path := .ingress.path -}} +{{- $hostname := .ingress.hostname -}} +{{- $pathType := .ingress.pathType -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ .fullName }}-{{ .serviceName }} + namespace: {{ .namespace }} + labels: + {{- .metaLabels | nindent 4 }} + {{- range $key, $value := .ingress.labels }} + {{- $key | nindent 4 }}: {{ $value | quote }} + {{- end }} + {{- if .ingress.annotations }} + annotations: + {{- range $key, $value := .ingress.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} +spec: +{{- if .ingress.ingressClassName }} + ingressClassName: {{ .ingress.ingressClassName }} +{{- end }} + rules: + {{- if ( not (or $hostname .ingress.hosts)) }} + - http: + paths: + - backend: + service: + name: {{ .fullName }}-{{ .serviceName }} + port: + number: {{ $servicePort }} + path: {{ $path }} + pathType: {{ $pathType }} + {{- else if $hostname }} + - host: {{ $hostname | quote }} + http: + paths: + - backend: + service: + name: {{ .fullName }}-{{ .serviceName }} + port: + number: {{ $servicePort }} + path: {{ $path }} + pathType: {{ $pathType }} + {{- end }} + {{- range .ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - backend: + {{- if .backend -}} + {{ .backend | toYaml | nindent 12 }} + {{- else }} + service: + name: {{ $.fullName }}-{{ $.serviceName }} + port: + number: {{ $servicePort }} + {{- end }} + {{- if (and $hostname (and (eq $path .path))) }} + {{- fail "duplication of specified ingress path" }} + {{- end }} + path: {{ .path }} + pathType: {{ .pathType }} + {{- end }} + {{- end }} + {{- if (hasKey .ingress "tls") }} + tls: + {{- if (kindIs "string" .ingress.tls) }} + - hosts: + {{- range .ingress.hosts }} + - {{ .host | quote }} + {{- end }} + {{- if $hostname }} + - {{ $hostname | quote }} + {{- end }} + secretName: {{ .ingress.tls }} + {{- else if (kindIs "slice" .ingress.tls) }} + {{- range .ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Create Service resource for a Kong service +*/}} +{{- define "kong.service" -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ .fullName }}-{{ .serviceName }} + namespace: {{ .namespace }} + {{- if .annotations }} + annotations: + {{- range $key, $value := .annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} + labels: + {{- .metaLabels | nindent 4 }} + {{- range $key, $value := .labels }} + {{ $key }}: {{ $value | quote }} + {{- end }} +spec: + type: {{ .type }} + {{- if eq .type "LoadBalancer" }} + {{- if .loadBalancerIP }} + loadBalancerIP: {{ .loadBalancerIP }} + {{- end }} + {{- if .loadBalancerSourceRanges }} + loadBalancerSourceRanges: + {{- range $cidr := .loadBalancerSourceRanges }} + - {{ $cidr }} + {{- end }} + {{- end }} + {{- if .loadBalancerClass }} + loadBalancerClass: {{ .loadBalancerClass }} + {{- end }} + {{- end }} + {{- if .externalIPs }} + externalIPs: + {{- range $ip := .externalIPs }} + - {{ $ip }} + {{- end -}} + {{- end }} + ports: + {{- if .http }} + {{- if .http.enabled }} + {{- if ne ( .http.servicePort | toString ) "0" }} + - name: kong-{{ .serviceName }} + port: {{ .http.servicePort }} + targetPort: {{ .http.containerPort }} + {{- if .http.appProtocol }} + appProtocol: {{ .http.appProtocol }} + {{- end }} + {{- if (and (or (eq .type "LoadBalancer") (eq .type "NodePort")) (not (empty .http.nodePort))) }} + nodePort: {{ .http.nodePort }} + {{- end }} + protocol: TCP + {{- end }} + {{- end }} + {{- end }} + {{- if .tls.enabled }} + - name: kong-{{ .serviceName }}-tls + port: {{ .tls.servicePort }} + targetPort: {{ .tls.overrideServiceTargetPort | default .tls.containerPort }} + {{- if .tls.appProtocol }} + appProtocol: {{ .tls.appProtocol }} + {{- end }} + {{- if (and (or (eq .type "LoadBalancer") (eq .type "NodePort")) (not (empty .tls.nodePort))) }} + nodePort: {{ .tls.nodePort }} + {{- end }} + protocol: TCP + {{- end }} + {{- if (hasKey . "stream") }} + {{- $defaultProtocol := "TCP" }} + {{- if (hasSuffix "udp-proxy" .serviceName) }} + {{- $defaultProtocol = "UDP" }} + {{- end }} + {{- range $index, $streamEntry := .stream }} + {{- if (not (hasKey $streamEntry "protocol")) }} + {{- $_ := set $streamEntry "protocol" $defaultProtocol }} + {{- end }} + {{- end }} + {{- range .stream }} + - name: stream{{ if (eq (default "TCP" .protocol) "UDP") }}udp{{ end }}-{{ .containerPort }} + port: {{ .servicePort }} + targetPort: {{ .containerPort }} + {{- if (and (or (eq $.type "LoadBalancer") (eq $.type "NodePort")) (not (empty .nodePort))) }} + nodePort: {{ .nodePort }} + {{- end }} + protocol: {{ .protocol | default "TCP" }} + {{- end }} + {{- end }} + {{- if .externalTrafficPolicy }} + externalTrafficPolicy: {{ .externalTrafficPolicy }} + {{- end }} + {{- if .clusterIP }} + {{- if (or (not (eq .clusterIP "None")) (and (eq .type "ClusterIP") (eq .clusterIP "None"))) }} + clusterIP: {{ .clusterIP }} + {{- end }} + {{- end }} + selector: + {{- .selectorLabels | nindent 4 }} +{{- end -}} + + +{{/* +Create KONG_SERVICE_LISTEN strings +Generic tool for creating KONG_PROXY_LISTEN, KONG_ADMIN_LISTEN, etc. +*/}} +{{- define "kong.listen" -}} + {{- $unifiedListen := list -}} + {{- $defaultAddrs := (list "0.0.0.0" "[::]") -}} + + {{/* Some services do not support these blocks at all, so these checks are a + two-stage "is it safe to evaluate this?" and then "should we evaluate + this?" + */}} + {{- if .http -}} + {{- if .http.enabled -}} + {{- $listenConfig := dict -}} + {{- $listenConfig := merge $listenConfig .http -}} + {{- $addresses := (default $defaultAddrs .addresses) -}} + {{- range $addresses -}} + {{- $_ := set $listenConfig "address" . -}} + {{- $httpListen := (include "kong.singleListen" $listenConfig) -}} + {{- $unifiedListen = append $unifiedListen $httpListen -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- if .tls -}} + {{- if .tls.enabled -}} + {{/* + This is a bit of a hack to support always including "ssl" in the parameter + list for TLS listens. It's not possible to set a variable to an object from + .Values and then modify one of the objects values locally, although + https://github.com/helm/helm/issues/4987 indicates it should be. Instead, + this creates a new object and new parameters list built from the original. + */}} + {{- $listenConfig := dict -}} + {{- $listenConfig := merge $listenConfig .tls -}} + {{- $parameters := append .tls.parameters "ssl" -}} + {{- $_ := set $listenConfig "parameters" $parameters -}} + {{- $addresses := (default $defaultAddrs .addresses) -}} + {{- range $addresses -}} + {{- $_ := set $listenConfig "address" . -}} + {{- $tlsListen := (include "kong.singleListen" $listenConfig) -}} + {{- $unifiedListen = append $unifiedListen $tlsListen -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- $listenString := ($unifiedListen | join ", ") -}} + {{- if eq (len $listenString) 0 -}} + {{- $listenString = "off" -}} + {{- end -}} + {{- $listenString -}} +{{- end -}} + +{{/* +Create KONG_PORT_MAPS string +Parameters: takes a service (e.g. .Values.proxy) as its argument and returns KONG_PORT_MAPS for that service. +*/}} +{{- define "kong.port_maps" -}} + {{- $portMaps := list -}} + + {{- if .http.enabled -}} + {{- if ne (.http.servicePort | toString ) "0" -}} + {{- $portMaps = append $portMaps (printf "%d:%d" (int64 .http.servicePort) (int64 .http.containerPort)) -}} + {{- end -}} + {{- end -}} + + {{- if .tls.enabled -}} + {{- $portMaps = append $portMaps (printf "%d:%d" (int64 .tls.servicePort) (int64 .tls.containerPort)) -}} + {{- end -}} + + {{- $portMapsString := ($portMaps | join ", ") -}} + {{- $portMapsString -}} +{{- end -}} + +{{/* +Create KONG_STREAM_LISTEN string +*/}} +{{- define "kong.streamListen" -}} + {{- $unifiedListen := list -}} + {{- $defaultAddrs := (list "0.0.0.0" "[::]") -}} + {{- range .stream -}} + {{- $listenConfig := dict -}} + {{- $listenConfig := merge $listenConfig . -}} + {{- $addresses := (default $defaultAddrs .addresses) -}} + {{- range $addresses -}} + {{- $_ := set $listenConfig "address" . -}} + {{/* You set NGINX stream listens to UDP using a parameter due to historical reasons. + Our configuration is dual-purpose, for both the Service and listen string, so we + forcibly inject this parameter if that's the Service protocol. The default handles + configs that predate the addition of the protocol field, where we only supported TCP. */}} + {{- if (eq (default "TCP" $listenConfig.protocol) "UDP") -}} + {{- $_ := set $listenConfig "parameters" (append (default (list) $listenConfig.parameters) "udp") -}} + {{- end -}} + {{- $unifiedListen = append $unifiedListen (include "kong.singleListen" $listenConfig ) -}} + {{- end -}} + {{- end -}} + + {{- $listenString := ($unifiedListen | join ", ") -}} + {{- if eq (len $listenString) 0 -}} + {{- $listenString = "" -}} + {{- end -}} + {{- $listenString -}} +{{- end -}} + +{{/* +Create a single listen (IP+port+parameter combo) +*/}} +{{- define "kong.singleListen" -}} + {{- $listen := list -}} + {{- $listen = append $listen (printf "%s:%d" .address (int64 .containerPort)) -}} + {{- range $param := .parameters | default (list) | uniq }} + {{- $listen = append $listen $param -}} + {{- end -}} + {{- $listen | join " " -}} +{{- end -}} + +{{/* +Return the admin API service name for service discovery +*/}} +{{- define "kong.adminSvc" -}} +{{- $gatewayDiscovery := .Values.ingressController.gatewayDiscovery -}} +{{- if $gatewayDiscovery.enabled -}} + {{- $adminApiService := $gatewayDiscovery.adminApiService -}} + {{- $adminApiServiceName := $gatewayDiscovery.adminApiService.name -}} + {{- $generateAdminApiService := $gatewayDiscovery.generateAdminApiService -}} + + {{- if and $generateAdminApiService $adminApiService.name -}} + {{- fail (printf ".Values.ingressController.gatewayDiscovery.adminApiService and .Values.ingressController.gatewayDiscovery.generateAdminApiService must not be provided at the same time") -}} + {{- end -}} + + {{- if $generateAdminApiService -}} + {{- $adminApiServiceName = (printf "%s-%s" .Release.Name "gateway-admin") -}} + {{- else }} + {{- $_ := required ".ingressController.gatewayDiscovery.adminApiService.name has to be provided when .Values.ingressController.gatewayDiscovery.enabled is set to true" $adminApiServiceName -}} + {{- end }} + + {{- if (semverCompare "< 2.9.0" (include "kong.effectiveVersion" .Values.ingressController.image)) }} + {{- fail (printf "Gateway discovery is available in controller versions 2.9 and up. Detected %s" (include "kong.effectiveVersion" .Values.ingressController.image)) }} + {{- end }} + + {{- if .Values.deployment.kong.enabled }} + {{- fail "deployment.kong.enabled and ingressController.gatewayDiscovery.enabled are mutually exclusive and cannot be enabled at once. Gateway discovery requires a split release installation of Gateways and Ingress Controller." }} + {{- end }} + + {{- $namespace := $adminApiService.namespace | default ( include "kong.namespace" . ) -}} + {{- printf "%s/%s" $namespace $adminApiServiceName -}} +{{- else -}} + {{- fail "Can't use gateway discovery when .Values.ingressController.gatewayDiscovery.enabled is set to false." -}} +{{- end -}} +{{- end -}} + +{{/* +Return the local admin API URL, preferring HTTPS if available +*/}} +{{- define "kong.adminLocalURL" -}} + {{- if .Values.admin.tls.enabled -}} +https://localhost:{{ .Values.admin.tls.containerPort }} + {{- else if .Values.admin.http.enabled -}} +http://localhost:{{ .Values.admin.http.containerPort }} + {{- else -}} +http://localhost:9999 # You have no admin listens! The controller will not work unless you set .Values.admin.http.enabled=true or .Values.admin.tls.enabled=true! + {{- end -}} +{{- end -}} + +{{/* +Create the ingress servicePort value string +*/}} + +{{- define "kong.ingress.servicePort" -}} +{{- if .tls.enabled -}} + {{ .tls.servicePort }} +{{- else -}} + {{ .http.servicePort }} +{{- end -}} +{{- end -}} + +{{/* +Generate an appropriate external URL from a Kong service's ingress configuration +Strips trailing slashes from the path. Manager at least does not handle these +intelligently and will append its own slash regardless, and the admin API cannot handle +the extra slash. +*/}} + +{{- define "kong.ingress.serviceUrl" -}} +{{- if .tls -}} + https://{{ .hostname }}{{ .path | trimSuffix "/" }} +{{- else -}} + http://{{ .hostname }}{{ .path | trimSuffix "/" }} +{{- end -}} +{{- end -}} + +{{/* +The name of the service used for the ingress controller's validation webhook +*/}} + +{{- define "kong.service.validationWebhook" -}} +{{ include "kong.fullname" . }}-validation-webhook +{{- end -}} + + +{{/* +The name of the Service which will be used by the controller to update the Ingress status field. +*/}} + +{{- define "kong.controller-publish-service" -}} +{{- $proxyOverride := "" -}} + {{- if .Values.proxy.nameOverride -}} + {{- $proxyOverride = ( tpl .Values.proxy.nameOverride . ) -}} + {{- end -}} +{{- (printf "%s/%s" ( include "kong.namespace" . ) ( default ( printf "%s-proxy" (include "kong.fullname" . )) $proxyOverride )) -}} +{{- end -}} + +{{- define "kong.ingressController.env" -}} +{{/* + ====== AUTO-GENERATED ENVIRONMENT VARIABLES ====== +*/}} + + +{{- $autoEnv := dict -}} + {{- $_ := set $autoEnv "CONTROLLER_KONG_ADMIN_TLS_SKIP_VERIFY" true -}} + {{- $_ := set $autoEnv "CONTROLLER_PUBLISH_SERVICE" ( include "kong.controller-publish-service" . ) -}} + {{- $_ := set $autoEnv "CONTROLLER_INGRESS_CLASS" .Values.ingressController.ingressClass -}} + {{- $_ := set $autoEnv "CONTROLLER_ELECTION_ID" (printf "kong-ingress-controller-leader-%s" .Values.ingressController.ingressClass) -}} + + {{- if .Values.ingressController.admissionWebhook.enabled }} + {{- $address := (default "0.0.0.0" .Values.ingressController.admissionWebhook.address) -}} + {{- $_ := set $autoEnv "CONTROLLER_ADMISSION_WEBHOOK_LISTEN" (printf "%s:%d" $address (int64 .Values.ingressController.admissionWebhook.port)) -}} + {{- end }} + {{- if (not (eq (len .Values.ingressController.watchNamespaces) 0)) }} + {{- $_ := set $autoEnv "CONTROLLER_WATCH_NAMESPACE" (.Values.ingressController.watchNamespaces | join ",") -}} + {{- end }} + +{{/* + ====== ADMIN API CONFIGURATION ====== +*/}} + + {{- if .Values.ingressController.gatewayDiscovery.enabled -}} + {{- $_ := set $autoEnv "CONTROLLER_KONG_ADMIN_SVC" (include "kong.adminSvc" . ) -}} + {{- else -}} + {{- $_ := set $autoEnv "CONTROLLER_KONG_ADMIN_URL" (include "kong.adminLocalURL" .) -}} + {{- end -}} + + {{- if .Values.ingressController.adminApi.tls.client.enabled }} + {{- $_ := set $autoEnv "CONTROLLER_KONG_ADMIN_TLS_CLIENT_CERT_FILE" "/etc/secrets/admin-api-cert/tls.crt" -}} + {{- $_ := set $autoEnv "CONTROLLER_KONG_ADMIN_TLS_CLIENT_KEY_FILE" "/etc/secrets/admin-api-cert/tls.key" -}} + {{- end }} + +{{/* + ====== KONNECT ENVIRONMENT VARIABLES ====== +*/}} + +{{- if .Values.ingressController.konnect.enabled }} + {{- if (semverCompare "< 2.9.0" (include "kong.effectiveVersion" .Values.ingressController.image)) }} + {{- fail (printf "Konnect sync is available in controller versions 2.9 and up. Detected %s" (include "kong.effectiveVersion" .Values.ingressController.image)) }} + {{- end }} + + {{- if not .Values.ingressController.gatewayDiscovery.enabled }} + {{- fail "ingressController.gatewayDiscovery.enabled has to be true when ingressController.konnect.enabled"}} + {{- end }} + + {{- $konnect := .Values.ingressController.konnect -}} + {{- $_ := required "ingressController.konnect.controlPlaneID is required when ingressController.konnect.enabled" $konnect.controlPlaneID -}} + + {{- if $konnect.controlPlaneID }} + {{- $_ = set $autoEnv "CONTROLLER_KONNECT_CONTROL_PLANE_ID" $konnect.controlPlaneID -}} + {{- else if $konnect.runtimeGroupID }} + {{- $_ = set $autoEnv "CONTROLLER_KONNECT_CONTROL_PLANE_ID" $konnect.runtimeGroupID -}} + {{- else }} + {{- fail "At least one of konnect.controlPlaneID or konnect.runtimeGroupID must be set." -}} + {{- end }} + + {{- $_ = set $autoEnv "CONTROLLER_KONNECT_SYNC_ENABLED" true -}} + {{- $_ = set $autoEnv "CONTROLLER_KONNECT_ADDRESS" (printf "https://%s" .Values.ingressController.konnect.apiHostname) -}} + + {{- $tlsCert := include "secretkeyref" (dict "name" $konnect.tlsClientCertSecretName "key" "tls.crt") -}} + {{- $tlsKey := include "secretkeyref" (dict "name" $konnect.tlsClientCertSecretName "key" "tls.key") -}} + {{- $_ = set $autoEnv "CONTROLLER_KONNECT_TLS_CLIENT_CERT" $tlsCert -}} + {{- $_ = set $autoEnv "CONTROLLER_KONNECT_TLS_CLIENT_KEY" $tlsKey -}} + + {{- if $konnect.license.enabled }} + {{- $_ = set $autoEnv "CONTROLLER_KONNECT_LICENSING_ENABLED" true -}} + {{- end }} +{{- end }} + +{{/* + ====== USER-SET ENVIRONMENT VARIABLES ====== +*/}} + +{{- $userEnv := dict -}} +{{- range $key, $val := .Values.ingressController.env }} + {{- $upper := upper $key -}} + {{- $var := printf "CONTROLLER_%s" $upper -}} + {{- $_ := set $userEnv $var $val -}} +{{- end -}} + +{{/* + ====== CUSTOM-SET INGRESS CONTROLLER ENVIRONMENT VARIABLES ====== +*/}} + +{{- $customIngressEnv := dict -}} +{{- range $key, $val := .Values.ingressController.customEnv }} + {{- $upper := upper $key -}} + {{- $_ := set $customIngressEnv $upper $val -}} +{{- end -}} + +{{/* + ====== MERGE AND RENDER ENV BLOCK ====== +*/}} + +{{- $completeEnv := mergeOverwrite $autoEnv $userEnv $customIngressEnv -}} +{{- template "kong.renderEnv" $completeEnv -}} + +{{- end -}} + +{{- define "kong.userDefinedVolumes" -}} +{{- if .Values.deployment.userDefinedVolumes }} +{{- toYaml .Values.deployment.userDefinedVolumes }} +{{- end }} +{{- end -}} + +{{- define "kong.volumes" -}} +- name: {{ template "kong.fullname" . }}-prefix-dir + emptyDir: + sizeLimit: {{ .Values.deployment.prefixDir.sizeLimit }} +- name: {{ template "kong.fullname" . }}-tmp + emptyDir: + sizeLimit: {{ .Values.deployment.tmpDir.sizeLimit }} +{{- if (and (not .Values.deployment.serviceAccount.automountServiceAccountToken) (or .Values.deployment.serviceAccount.create .Values.deployment.serviceAccount.name)) }} +- name: {{ template "kong.serviceAccountTokenName" . }} + {{- /* Due to GKE versions (e.g. v1.23.15-gke.1900) we need to handle pre-release part of the version as well. + See the related documentation of semver module that Helm depends on for semverCompare: + https://github.com/Masterminds/semver#working-with-prerelease-versions + Related Helm issue: https://github.com/helm/helm/issues/3810 */}} + {{- if semverCompare ">=1.20.0-0" .Capabilities.KubeVersion.Version }} + projected: + sources: + - serviceAccountToken: + expirationSeconds: 3607 + path: token + - configMap: + items: + - key: ca.crt + path: ca.crt + name: kube-root-ca.crt + - downwardAPI: + items: + - fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + path: namespace + {{- else }} + secret: + secretName: {{ template "kong.serviceAccountTokenName" . }} + items: + - key: token + path: token + - key: ca.crt + path: ca.crt + - key: namespace + path: namespace + {{- end }} +{{- end }} +{{- if and ( .Capabilities.APIVersions.Has "cert-manager.io/v1" ) .Values.certificates.enabled -}} +{{- if .Values.certificates.cluster.enabled }} +- name: {{ include "kong.fullname" . }}-cluster-cert + secret: + secretName: {{ include "kong.fullname" . }}-cluster-cert +{{- end }} +{{- if .Values.certificates.proxy.enabled }} +- name: {{ include "kong.fullname" . }}-proxy-cert + secret: + secretName: {{ include "kong.fullname" . }}-proxy-cert +{{- end }} +{{- if .Values.certificates.admin.enabled }} +- name: {{ include "kong.fullname" . }}-admin-cert + secret: + secretName: {{ include "kong.fullname" . }}-admin-cert +{{- end }} +{{- if .Values.enterprise.enabled }} +{{- if .Values.certificates.portal.enabled }} +- name: {{ include "kong.fullname" . }}-portal-cert + secret: + secretName: {{ include "kong.fullname" . }}-portal-cert +{{- end }} +{{- end }} +{{- end }} +{{- if (and (.Values.postgresql.enabled) .Values.waitImage.enabled) }} +- name: {{ template "kong.fullname" . }}-bash-wait-for-postgres + configMap: + name: {{ template "kong.fullname" . }}-bash-wait-for-postgres + defaultMode: 0755 +{{- end }} +{{- range .Values.plugins.configMaps }} +- name: kong-plugin-{{ .pluginName }} + configMap: + name: {{ .name }} +{{- range .subdirectories }} +- name: {{ .name }} + configMap: + name: {{ .name }} +{{- end }} +{{- end }} +{{- range .Values.plugins.secrets }} +- name: kong-plugin-{{ .pluginName }} + secret: + secretName: {{ .name }} +{{- range .subdirectories }} +- name: {{ .name }} + secret: + secretName: {{ .name }} +{{- end }} +{{- end }} + +{{- if (and (not .Values.ingressController.enabled) (eq .Values.env.database "off")) }} + {{- $dblessSourceCount := (add (.Values.dblessConfig.configMap | len | min 1) (.Values.dblessConfig.secret | len | min 1) (.Values.dblessConfig.config | len | min 1)) -}} + {{- if gt $dblessSourceCount 1 -}} + {{- fail "Ambiguous configuration: only one of of .Values.dblessConfig.configMap, .Values.dblessConfig.secret, and .Values.dblessConfig.config can be set." -}} + {{- else if eq $dblessSourceCount 1 }} +- name: kong-custom-dbless-config-volume + {{- if .Values.dblessConfig.configMap }} + configMap: + name: {{ .Values.dblessConfig.configMap }} + {{- else if .Values.dblessConfig.secret }} + secret: + secretName: {{ .Values.dblessConfig.secret }} + {{- else }} + configMap: + name: {{ template "kong.dblessConfig.fullname" . }} + {{- end }} + {{- end }} +{{- end }} + +{{- if and .Values.ingressController.enabled .Values.ingressController.admissionWebhook.enabled }} +- name: webhook-cert + secret: + {{- if .Values.ingressController.admissionWebhook.certificate.provided }} + secretName: {{ .Values.ingressController.admissionWebhook.certificate.secretName }} + {{- else }} + secretName: {{ template "kong.fullname" . }}-validation-webhook-keypair + {{- end }} +{{- end }} +{{- if or $.Values.admin.tls.client.secretName $.Values.admin.tls.client.caBundle }} +- name: admin-client-ca + configMap: + name: {{ template "kong.fullname" . }}-admin-client-ca +{{- end -}} +{{- range $secretVolume := .Values.secretVolumes }} +- name: {{ . }} + secret: + secretName: {{ . }} +{{- end }} +{{- range .Values.extraConfigMaps }} +- name: {{ .name }} + configMap: + name: {{ .name }} +{{- end }} +{{- range .Values.extraSecrets }} +- name: {{ .name }} + secret: + secretName: {{ .name }} +{{- end }} +{{- if and .Values.ingressController.adminApi.tls.client.enabled .Values.ingressController.enabled }} +- name: admin-api-cert + secret: + secretName: {{ template "adminApiService.certSecretName" . }} +{{- end }} +{{- end -}} + +{{- define "controller.adminApiCertVolumeMount" -}} +{{- if and .Values.ingressController.adminApi.tls.client.enabled .Values.ingressController.enabled }} +- name: admin-api-cert + mountPath: /etc/secrets/admin-api-cert + readOnly: true +{{- end -}} +{{- end -}} + +{{- define "kong.userDefinedVolumeMounts" -}} +{{- if .userDefinedVolumeMounts }} +{{- toYaml .userDefinedVolumeMounts }} +{{- end }} +{{- end -}} + +{{- define "kong.volumeMounts" -}} +- name: {{ template "kong.fullname" . }}-prefix-dir + mountPath: /kong_prefix/ +- name: {{ template "kong.fullname" . }}-tmp + mountPath: /tmp +{{- if and ( .Capabilities.APIVersions.Has "cert-manager.io/v1" ) .Values.certificates.enabled -}} +{{- if .Values.certificates.cluster.enabled }} +- name: {{ include "kong.fullname" . }}-cluster-cert + mountPath: /etc/cert-manager/cluster/ +{{- end }} +{{- if .Values.certificates.proxy.enabled }} +- name: {{ include "kong.fullname" . }}-proxy-cert + mountPath: /etc/cert-manager/proxy/ +{{- end }} +{{- if .Values.certificates.admin.enabled }} +- name: {{ include "kong.fullname" . }}-admin-cert + mountPath: /etc/cert-manager/admin/ +{{- end }} +{{- if .Values.enterprise.enabled }} +{{- if .Values.certificates.portal.enabled }} +- name: {{ include "kong.fullname" . }}-portal-cert + mountPath: /etc/cert-manager/portal/ +{{- end }} +{{- end }} +{{- end }} +{{- $dblessSourceCount := (add (.Values.dblessConfig.configMap | len | min 1) (.Values.dblessConfig.secret | len | min 1) (.Values.dblessConfig.config | len | min 1)) -}} + {{- if eq $dblessSourceCount 1 -}} + {{- if (and (not .Values.ingressController.enabled) (eq .Values.env.database "off")) }} +- name: kong-custom-dbless-config-volume + mountPath: /kong_dbless/ + {{- end }} + {{- end }} +{{- if or $.Values.admin.tls.client.caBundle $.Values.admin.tls.client.secretName }} +- name: admin-client-ca + mountPath: /etc/admin-client-ca/ + readOnly: true +{{- end -}} +{{- range .Values.secretVolumes }} +- name: {{ . }} + mountPath: /etc/secrets/{{ . }} +{{- end }} +{{- range .Values.plugins.configMaps }} +{{- $mountPath := printf "/opt/kong/plugins/%s" .pluginName }} +- name: kong-plugin-{{ .pluginName }} + mountPath: {{ $mountPath }} + readOnly: true +{{- range .subdirectories }} +- name: {{ .name }} + mountPath: {{ printf "%s/%s" $mountPath ( .path | default .name ) }} + readOnly: true +{{- end }} +{{- end }} +{{- range .Values.plugins.secrets }} +{{- $mountPath := printf "/opt/kong/plugins/%s" .pluginName }} +- name: kong-plugin-{{ .pluginName }} + mountPath: {{ $mountPath }} + readOnly: true +{{- range .subdirectories }} +- name: {{ .name }} + mountPath: {{ printf "%s/%s" $mountPath .path }} + readOnly: true +{{- end }} +{{- end }} + +{{- range .Values.extraConfigMaps }} +- name: {{ .name }} + mountPath: {{ .mountPath }} + + {{- if .subPath }} + subPath: {{ .subPath }} + {{- end }} +{{- end }} +{{- range .Values.extraSecrets }} +- name: {{ .name }} + mountPath: {{ .mountPath }} + + {{- if .subPath }} + subPath: {{ .subPath }} + {{- end }} +{{- end }} + +{{- end -}} + +{{- define "kong.plugins" -}} +{{ $myList := list "bundled" }} +{{- range .Values.plugins.configMaps -}} +{{- $myList = append $myList .pluginName -}} +{{- end -}} +{{- range .Values.plugins.secrets -}} + {{ $myList = append $myList .pluginName -}} +{{- end }} +{{- $myList | uniq | join "," -}} +{{- end -}} + +{{- define "kong.wait-for-db" -}} +- name: wait-for-db + image: {{ include "kong.getRepoTag" .Values.image }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + securityContext: + {{ toYaml .Values.containerSecurityContext | nindent 4 }} + env: + {{- include "kong.env" . | nindent 2 }} + {{- include "kong.envFrom" .Values.envFrom | nindent 2 }} +{{/* TODO the prefix override is to work around https://github.com/Kong/charts/issues/295 + Note that we use args instead of command here to /not/ override the standard image entrypoint. */}} + args: [ "/bin/bash", "-c", "export KONG_NGINX_DAEMON=on KONG_PREFIX=`mktemp -d` KONG_KEYRING_ENABLED=off; until kong start; do echo 'waiting for db'; sleep 1; done; kong stop"] + volumeMounts: + {{- include "kong.volumeMounts" . | nindent 4 }} + {{- include "kong.userDefinedVolumeMounts" .Values.deployment | nindent 4 }} + resources: + {{- toYaml .Values.resources | nindent 4 }} +{{- end -}} + +{{/* effectiveVersion takes an image dict from values.yaml. if .effectiveSemver is set, it returns that, else it returns .tag */}} +{{- define "kong.effectiveVersion" -}} +{{- /* Because Kong Gateway enterprise uses versions with 4 segments and not 3 */ -}} +{{- /* as semver does, we need to account for that here by extracting */ -}} +{{- /* first 3 segments for comparison */ -}} +{{- if .effectiveSemver -}} + {{- if regexMatch "^[0-9]+.[0-9]+.[0-9]+" .effectiveSemver -}} + {{- regexFind "^[0-9]+.[0-9]+.[0-9]+" .effectiveSemver -}} + {{- else -}} + {{- .effectiveSemver -}} + {{- end -}} +{{- else -}} + {{- $tag := (trimSuffix "-redhat" .tag) -}} + {{- if regexMatch "^[0-9]+.[0-9]+.[0-9]+" .tag -}} + {{- regexFind "^[0-9]+.[0-9]+.[0-9]+" .tag -}} + {{- else -}} + {{- .tag -}} + {{- end -}} +{{- end -}} +{{- end -}} + +{{- define "kong.controller-container" -}} +- name: ingress-controller + securityContext: +{{ toYaml .Values.containerSecurityContext | nindent 4 }} + args: + {{ if .Values.ingressController.args}} + {{- range $val := .Values.ingressController.args }} + - {{ $val }} + {{- end }} + {{- end }} + ports: + {{- if .Values.ingressController.admissionWebhook.enabled }} + - name: webhook + containerPort: {{ .Values.ingressController.admissionWebhook.port }} + protocol: TCP + {{- end }} + {{ if (semverCompare ">= 2.0.0" (include "kong.effectiveVersion" .Values.ingressController.image)) -}} + - name: cmetrics + containerPort: 10255 + protocol: TCP + {{- end }} + - name: cstatus + containerPort: 10254 + protocol: TCP + env: + - name: POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace +{{- include "kong.ingressController.env" . | indent 2 }} +{{ include "kong.envFrom" .Values.ingressController.envFrom | indent 2 }} + image: {{ include "kong.getRepoTag" .Values.ingressController.image }} + imagePullPolicy: {{ .Values.image.pullPolicy }} +{{/* disableReadiness is a hidden setting to drop this block entirely for use with a debugger + Helm value interpretation doesn't let you replace the default HTTP checks with any other + check type, and all HTTP checks freeze when a debugger pauses operation. + Setting disableReadiness to ANY value disables the probes. +*/}} +{{- if (not (hasKey .Values.ingressController "disableProbes")) }} + readinessProbe: +{{ toYaml .Values.ingressController.readinessProbe | indent 4 }} + livenessProbe: +{{ toYaml .Values.ingressController.livenessProbe | indent 4 }} +{{- end }} + resources: +{{ toYaml .Values.ingressController.resources | indent 4 }} + volumeMounts: +{{- if .Values.ingressController.admissionWebhook.enabled }} + - name: webhook-cert + mountPath: /admission-webhook + readOnly: true +{{- end }} +{{- if (and (not .Values.deployment.serviceAccount.automountServiceAccountToken) (or .Values.deployment.serviceAccount.create .Values.deployment.serviceAccount.name)) }} + - name: {{ template "kong.serviceAccountTokenName" . }} + mountPath: /var/run/secrets/kubernetes.io/serviceaccount + readOnly: true +{{- end }} + {{- include "kong.userDefinedVolumeMounts" .Values.ingressController | nindent 2 }} + {{- include "controller.adminApiCertVolumeMount" . | nindent 2 }} +{{- end -}} + +{{- define "secretkeyref" -}} +valueFrom: + secretKeyRef: + name: {{ .name }} + key: {{ .key }} +{{- end -}} + +{{/* +Use the Pod security context defined in Values or set the UID by default +*/}} +{{- define "kong.podsecuritycontext" -}} +{{ .Values.securityContext | toYaml }} +{{- end -}} + +{{- define "kong.no_daemon_env" -}} +{{- template "kong.env" . }} +- name: KONG_NGINX_DAEMON + value: "off" +{{- end -}} + +{{/* +The environment values passed to Kong; this should come after all +the template that it itself is using form the above sections. +*/}} +{{- define "kong.env" -}} +{{/* + ====== AUTO-GENERATED ENVIRONMENT VARIABLES ====== +*/}} +{{- $autoEnv := dict -}} + +{{- $_ := set $autoEnv "KONG_LUA_PACKAGE_PATH" "/opt/?.lua;/opt/?/init.lua;;" -}} + +{{- $_ := set $autoEnv "KONG_PROXY_ACCESS_LOG" "/dev/stdout" -}} +{{- $_ := set $autoEnv "KONG_PROXY_STREAM_ACCESS_LOG" "/dev/stdout basic" -}} +{{- $_ := set $autoEnv "KONG_ADMIN_ACCESS_LOG" "/dev/stdout" -}} +{{- $_ := set $autoEnv "KONG_STATUS_ACCESS_LOG" "off" -}} +{{- $_ := set $autoEnv "KONG_PROXY_ERROR_LOG" "/dev/stderr" -}} +{{- $_ := set $autoEnv "KONG_PROXY_STREAM_ERROR_LOG" "/dev/stderr" -}} +{{- $_ := set $autoEnv "KONG_ADMIN_ERROR_LOG" "/dev/stderr" -}} +{{- $_ := set $autoEnv "KONG_STATUS_ERROR_LOG" "/dev/stderr" -}} + +{{- if .Values.ingressController.enabled -}} + {{- $_ := set $autoEnv "KONG_KIC" "on" -}} +{{- end -}} + +{{- with .Values.admin -}} + {{- $listenConfig := dict -}} + {{- $listenConfig := merge $listenConfig . -}} + {{- if (and (not (hasKey . "addresses")) (not .enabled)) -}} + {{- $_ := set $listenConfig "addresses" (list "127.0.0.1" "[::1]") -}} + {{- end -}} + {{- $_ := set $autoEnv "KONG_ADMIN_LISTEN" (include "kong.listen" $listenConfig) -}} + + {{- if or .tls.client.secretName .tls.client.caBundle -}} + {{- $_ := set $autoEnv "KONG_NGINX_ADMIN_SSL_VERIFY_CLIENT" "on" -}} + {{- $_ := set $autoEnv "KONG_NGINX_ADMIN_SSL_CLIENT_CERTIFICATE" "/etc/admin-client-ca/tls.crt" -}} + {{- end -}} + +{{- end -}} + +{{- if and ( .Capabilities.APIVersions.Has "cert-manager.io/v1" ) .Values.certificates.enabled -}} + {{- if (and .Values.certificates.cluster.enabled .Values.cluster.enabled) -}} + {{- $_ := set $autoEnv "KONG_CLUSTER_MTLS" "pki" -}} + {{- $_ := set $autoEnv "KONG_CLUSTER_SERVER_NAME" .Values.certificates.cluster.commonName -}} + {{- $_ := set $autoEnv "KONG_CLUSTER_CA_CERT" "/etc/cert-manager/cluster/ca.crt" -}} + {{- $_ := set $autoEnv "KONG_CLUSTER_CERT" "/etc/cert-manager/cluster/tls.crt" -}} + {{- $_ := set $autoEnv "KONG_CLUSTER_CERT_KEY" "/etc/cert-manager/cluster/tls.key" -}} + {{- end -}} + + {{- if .Values.certificates.proxy.enabled -}} + {{- $_ := set $autoEnv "KONG_SSL_CERT" "/etc/cert-manager/proxy/tls.crt" -}} + {{- $_ := set $autoEnv "KONG_SSL_CERT_KEY" "/etc/cert-manager/proxy/tls.key" -}} + {{- end -}} + + {{- if .Values.certificates.admin.enabled -}} + {{- $_ := set $autoEnv "KONG_ADMIN_SSL_CERT" "/etc/cert-manager/admin/tls.crt" -}} + {{- $_ := set $autoEnv "KONG_ADMIN_SSL_CERT_KEY" "/etc/cert-manager/admin/tls.key" -}} + {{- if .Values.enterprise.enabled }} + {{- $_ := set $autoEnv "KONG_ADMIN_GUI_SSL_CERT" "/etc/cert-manager/admin/tls.crt" -}} + {{- $_ := set $autoEnv "KONG_ADMIN_GUI_SSL_CERT_KEY" "/etc/cert-manager/admin/tls.key" -}} + {{- end -}} + {{- end -}} + + {{- if .Values.enterprise.enabled }} + {{- if .Values.certificates.portal.enabled -}} + {{- $_ := set $autoEnv "KONG_PORTAL_API_SSL_CERT" "/etc/cert-manager/portal/tls.crt" -}} + {{- $_ := set $autoEnv "KONG_PORTAL_API_SSL_CERT_KEY" "/etc/cert-manager/portal/tls.key" -}} + {{- $_ := set $autoEnv "KONG_PORTAL_GUI_SSL_CERT" "/etc/cert-manager/portal/tls.crt" -}} + {{- $_ := set $autoEnv "KONG_PORTAL_GUI_SSL_CERT_KEY" "/etc/cert-manager/portal/tls.key" -}} + {{- end -}} + {{- end -}} +{{- end -}} + +{{- if .Values.admin.ingress.enabled }} + {{- $_ := set $autoEnv "KONG_ADMIN_GUI_API_URL" (include "kong.ingress.serviceUrl" .Values.admin.ingress) -}} + {{- $_ := set $autoEnv "KONG_ADMIN_API_URI" (include "kong.ingress.serviceUrl" .Values.admin.ingress) -}} +{{- end -}} + +{{- $_ := set $autoEnv "KONG_PROXY_LISTEN" (include "kong.listen" .Values.proxy) -}} + +{{- $streamStrings := list -}} +{{- if .Values.proxy.enabled -}} + {{- $tcpStreamString := (include "kong.streamListen" .Values.proxy) -}} + {{- if (not (eq $tcpStreamString "")) -}} + {{- $streamStrings = (append $streamStrings $tcpStreamString) -}} + {{- end -}} +{{- end -}} +{{- if .Values.udpProxy.enabled -}} + {{- $udpStreamString := (include "kong.streamListen" .Values.udpProxy) -}} + {{- if (not (eq $udpStreamString "")) -}} + {{- $streamStrings = (append $streamStrings $udpStreamString) -}} + {{- end -}} +{{- end -}} +{{- $streamString := $streamStrings | join ", " -}} +{{- if (eq (len $streamString) 0) -}} + {{- $streamString = "off" -}} +{{- end -}} +{{- $_ := set $autoEnv "KONG_STREAM_LISTEN" $streamString -}} + +{{- $_ := set $autoEnv "KONG_STATUS_LISTEN" (include "kong.listen" .Values.status) -}} + +{{- if .Values.proxy.enabled -}} + {{- $_ := set $autoEnv "KONG_PORT_MAPS" (include "kong.port_maps" .Values.proxy) -}} +{{- end -}} + +{{- $_ := set $autoEnv "KONG_CLUSTER_LISTEN" (include "kong.listen" .Values.cluster) -}} + +{{- if .Values.enterprise.enabled }} + {{- $_ := set $autoEnv "KONG_PORTAL_API_ACCESS_LOG" "/dev/stdout" -}} + {{- $_ := set $autoEnv "KONG_PORTAL_GUI_ACCESS_LOG" "/dev/stdout" -}} + {{- $_ := set $autoEnv "KONG_ADMIN_GUI_ACCESS_LOG" "/dev/stdout" -}} + {{- $_ := set $autoEnv "KONG_PORTAL_API_ERROR_LOG" "/dev/stderr" -}} + {{- $_ := set $autoEnv "KONG_PORTAL_GUI_ERROR_LOG" "/dev/stderr" -}} + {{- $_ := set $autoEnv "KONG_ADMIN_GUI_ERROR_LOG" "/dev/stderr" -}} + + {{- $_ := set $autoEnv "KONG_ADMIN_GUI_LISTEN" (include "kong.listen" .Values.manager) -}} + {{- if .Values.manager.ingress.enabled }} + {{- $_ := set $autoEnv "KONG_ADMIN_GUI_URL" (include "kong.ingress.serviceUrl" .Values.manager.ingress) -}} + {{- end -}} + + {{- if not .Values.enterprise.vitals.enabled }} + {{- $_ := set $autoEnv "KONG_VITALS" "off" -}} + {{- end }} + {{- $_ := set $autoEnv "KONG_CLUSTER_TELEMETRY_LISTEN" (include "kong.listen" .Values.clustertelemetry) -}} + + {{- if .Values.enterprise.portal.enabled }} + {{- $_ := set $autoEnv "KONG_PORTAL" "on" -}} + {{- $_ := set $autoEnv "KONG_PORTAL_GUI_LISTEN" (include "kong.listen" .Values.portal) -}} + {{- $_ := set $autoEnv "KONG_PORTAL_API_LISTEN" (include "kong.listen" .Values.portalapi) -}} + + {{- if .Values.portal.ingress.enabled }} + {{- $_ := set $autoEnv "KONG_PORTAL_GUI_HOST" .Values.portal.ingress.hostname -}} + {{- if .Values.portal.ingress.tls }} + {{- $_ := set $autoEnv "KONG_PORTAL_GUI_PROTOCOL" "https" -}} + {{- else }} + {{- $_ := set $autoEnv "KONG_PORTAL_GUI_PROTOCOL" "http" -}} + {{- end }} + {{- end }} + + {{- if .Values.portalapi.ingress.enabled }} + {{- $_ := set $autoEnv "KONG_PORTAL_API_URL" (include "kong.ingress.serviceUrl" .Values.portalapi.ingress) -}} + {{- end }} + {{- end }} + + {{- if .Values.enterprise.rbac.enabled }} + {{- $_ := set $autoEnv "KONG_ENFORCE_RBAC" "on" -}} + {{- $_ := set $autoEnv "KONG_ADMIN_GUI_AUTH" .Values.enterprise.rbac.admin_gui_auth | default "basic-auth" -}} + + {{- if not (eq .Values.enterprise.rbac.admin_gui_auth "basic-auth") }} + {{- $guiAuthConf := include "secretkeyref" (dict "name" .Values.enterprise.rbac.admin_gui_auth_conf_secret "key" "admin_gui_auth_conf") -}} + {{- $_ := set $autoEnv "KONG_ADMIN_GUI_AUTH_CONF" $guiAuthConf -}} + {{- end }} + + {{/* + KONG_ADMIN_GUI_SESSION_CONF is required for Kong versions <3.6.0. + For >=3.6.0, when openid-connect is used as the admin_gui_auth, the session_conf_secret is not required. + https://docs.konghq.com/gateway/3.6.x/kong-manager/auth/oidc/migrate/ + */}} + {{- if or (not (eq .Values.enterprise.rbac.admin_gui_auth "openid-connect")) + (semverCompare "< 3.6.0" (include "kong.effectiveVersion" .Values.image)) + -}} + {{- $guiSessionConf := include "secretkeyref" (dict "name" .Values.enterprise.rbac.session_conf_secret "key" "admin_gui_session_conf") -}} + {{- $_ := set $autoEnv "KONG_ADMIN_GUI_SESSION_CONF" $guiSessionConf -}} + {{- end }} + {{- end }} + + {{- if .Values.enterprise.smtp.enabled }} + {{- $_ := set $autoEnv "KONG_SMTP_MOCK" "off" -}} + {{- $_ := set $autoEnv "KONG_PORTAL_EMAILS_FROM" .Values.enterprise.smtp.portal_emails_from -}} + {{- $_ := set $autoEnv "KONG_PORTAL_EMAILS_REPLY_TO" .Values.enterprise.smtp.portal_emails_reply_to -}} + {{- $_ := set $autoEnv "KONG_ADMIN_EMAILS_FROM" .Values.enterprise.smtp.admin_emails_from -}} + {{- $_ := set $autoEnv "KONG_ADMIN_EMAILS_REPLY_TO" .Values.enterprise.smtp.admin_emails_reply_to -}} + {{- $_ := set $autoEnv "KONG_SMTP_ADMIN_EMAILS" .Values.enterprise.smtp.smtp_admin_emails -}} + {{- $_ := set $autoEnv "KONG_SMTP_HOST" .Values.enterprise.smtp.smtp_host -}} + {{- $_ := set $autoEnv "KONG_SMTP_AUTH_TYPE" .Values.enterprise.smtp.smtp_auth_type -}} + {{- $_ := set $autoEnv "KONG_SMTP_SSL" .Values.enterprise.smtp.smtp_ssl -}} + {{- $_ := set $autoEnv "KONG_SMTP_PORT" .Values.enterprise.smtp.smtp_port -}} + {{- $_ := set $autoEnv "KONG_SMTP_STARTTLS" (quote .Values.enterprise.smtp.smtp_starttls) -}} + {{- if .Values.enterprise.smtp.auth.smtp_username }} + {{- $_ := set $autoEnv "KONG_SMTP_USERNAME" .Values.enterprise.smtp.auth.smtp_username -}} + {{- $smtpPassword := include "secretkeyref" (dict "name" .Values.enterprise.smtp.auth.smtp_password_secret "key" "smtp_password") -}} + {{- $_ := set $autoEnv "KONG_SMTP_PASSWORD" $smtpPassword -}} + {{- end }} + {{- else }} + {{- $_ := set $autoEnv "KONG_SMTP_MOCK" "on" -}} + {{- end }} + + {{- if .Values.enterprise.license_secret -}} + {{- $lic := include "secretkeyref" (dict "name" .Values.enterprise.license_secret "key" "license") -}} + {{- $_ := set $autoEnv "KONG_LICENSE_DATA" $lic -}} + {{- end }} + +{{- end }} {{/* End of the Enterprise settings block */}} + +{{- if .Values.postgresql.enabled }} + {{- $_ := set $autoEnv "KONG_PG_HOST" (include "kong.postgresql.fullname" .) -}} + {{- $_ := set $autoEnv "KONG_PG_PORT" .Values.postgresql.service.ports.postgresql -}} + {{- $pgPassword := include "secretkeyref" (dict "name" (include "kong.postgresql.fullname" .) "key" "password") -}} + + {{- $_ := set $autoEnv "KONG_PG_PASSWORD" $pgPassword -}} +{{- else if eq .Values.env.database "postgres" }} + {{- $_ := set $autoEnv "KONG_PG_PORT" "5432" }} +{{- end }} + +{{- if (and (not .Values.ingressController.enabled) (eq .Values.env.database "off")) }} +{{- $dblessSourceCount := (add (.Values.dblessConfig.configMap | len | min 1) (.Values.dblessConfig.secret | len | min 1) (.Values.dblessConfig.config | len | min 1)) -}} +{{- if eq $dblessSourceCount 1 -}} + {{- $_ := set $autoEnv "KONG_DECLARATIVE_CONFIG" "/kong_dbless/kong.yml" -}} +{{- end }} +{{- end }} + +{{- if (.Values.plugins) }} +{{- $_ := set $autoEnv "KONG_PLUGINS" (include "kong.plugins" .) -}} +{{- end }} + +{{/* + ====== USER-SET ENVIRONMENT VARIABLES ====== +*/}} + +{{- $userEnv := dict -}} +{{- range $key, $val := .Values.env }} + {{- if (contains "_log" $key) -}} + {{- if (eq (typeOf $val) "bool") -}} + {{- fail (printf "env.%s must use string 'off' to disable. Without quotes, YAML will coerce the value to a boolean and Kong will reject it" $key) -}} + {{- end -}} + {{- end -}} + {{- $upper := upper $key -}} + {{- $var := printf "KONG_%s" $upper -}} + {{- $_ := set $userEnv $var $val -}} +{{- end -}} + +{{/* + ====== CUSTOM-SET ENVIRONMENT VARIABLES ====== +*/}} + +{{- $customEnv := dict -}} +{{- range $key, $val := .Values.customEnv }} + {{- $upper := upper $key -}} + {{- $_ := set $customEnv $upper $val -}} +{{- end -}} + +{{/* + ====== MERGE AND RENDER ENV BLOCK ====== +*/}} + +{{- $completeEnv := mergeOverwrite $autoEnv $userEnv $customEnv -}} +{{- template "kong.renderEnv" $completeEnv -}} + +{{- end -}} + +{{/* +Given a dictionary of variable=value pairs, render a container env block. +Environment variables are sorted alphabetically +*/}} +{{- define "kong.renderEnv" -}} + +{{- $dict := . -}} + +{{- range keys . | sortAlpha }} +{{- $val := pluck . $dict | first -}} +{{- $valueType := printf "%T" $val -}} +{{ if eq $valueType "map[string]interface {}" }} +- name: {{ . }} +{{ toYaml $val | indent 2 -}} +{{- else if eq $valueType "string" }} +{{- if regexMatch "valueFrom" $val }} +- name: {{ . }} +{{ $val | indent 2 }} +{{- else }} +- name: {{ . }} + value: {{ $val | quote }} +{{- end }} +{{- else }} +- name: {{ . }} + value: {{ $val | quote }} +{{- end }} +{{- end -}} + +{{- end -}} + +{{- define "kong.wait-for-postgres" -}} +- name: wait-for-postgres +{{- if (or .Values.waitImage.unifiedRepoTag .Values.waitImage.repository) }} + image: {{ include "kong.getRepoTag" .Values.waitImage }} +{{- else }} {{/* default to the Kong image */}} + image: {{ include "kong.getRepoTag" .Values.image }} +{{- end }} + imagePullPolicy: {{ .Values.waitImage.pullPolicy }} + env: + {{- include "kong.no_daemon_env" . | nindent 2 }} + {{- include "kong.envFrom" .Values.envFrom | nindent 2 }} + command: [ "bash", "/wait_postgres/wait.sh" ] + volumeMounts: + - name: {{ template "kong.fullname" . }}-bash-wait-for-postgres + mountPath: /wait_postgres + resources: + {{- toYaml .Values.migrations.resources | nindent 4 }} +{{- end -}} + +{{- define "kong.deprecation-warnings" -}} + {{- $warnings := list -}} + {{- range $warning := . }} + {{- $warnings = append $warnings (wrap 80 (printf "WARNING: %s" $warning)) -}} + {{- $warnings = append $warnings "\n\n" -}} + {{- end -}} + {{- $warningString := ($warnings | join "") -}} + {{- $warningString -}} +{{- end -}} + +{{- define "kong.getRepoTag" -}} +{{- if .unifiedRepoTag }} +{{- .unifiedRepoTag }} +{{- else if .repository }} +{{- .repository }}:{{ .tag }} +{{- end -}} +{{- end -}} + +{{/* +kong.kubernetesRBACRoles outputs a static list of RBAC rules (the "rules" block +of a Role or ClusterRole) that provide the ingress controller access to the +Kubernetes namespace-scoped resources it uses to build Kong configuration. + +Collectively, these are built from: +kubectl kustomize github.com/kong/kubernetes-ingress-controller/config/rbac?ref=main +kubectl kustomize github.com/kong/kubernetes-ingress-controller/config/rbac/gateway?ref=main + +However, there is no way to generate the split between cluster and namespaced +role sets used in the charts. Updating these requires separating out cluster +resource roles into their separate templates. +*/}} +{{- define "kong.kubernetesRBACRules" -}} +{{- if (semverCompare ">= 3.2.0" (include "kong.effectiveVersion" .Values.ingressController.image)) }} +- apiGroups: + - configuration.konghq.com + resources: + - kongcustomentities + verbs: + - get + - list + - watch +- apiGroups: + - configuration.konghq.com + resources: + - kongcustomentities/status + verbs: + - get + - patch + - update +{{- end }} +{{- if and (semverCompare ">= 3.1.0" (include "kong.effectiveVersion" .Values.ingressController.image)) + (contains (print .Values.ingressController.env.feature_gates) "KongServiceFacade=true") }} +- apiGroups: + - incubator.ingress-controller.konghq.com + resources: + - kongservicefacades + verbs: + - get + - list + - watch +- apiGroups: + - incubator.ingress-controller.konghq.com + resources: + - kongservicefacades/status + verbs: + - get + - patch + - update +{{- end }} +{{- if (semverCompare ">= 3.0.0" (include "kong.effectiveVersion" .Values.ingressController.image)) }} +- apiGroups: + - configuration.konghq.com + resources: + - kongupstreampolicies + verbs: + - get + - list + - watch +- apiGroups: + - configuration.konghq.com + resources: + - kongupstreampolicies/status + verbs: + - get + - patch + - update +{{- end }} +{{- if (semverCompare ">= 2.11.0" (include "kong.effectiveVersion" .Values.ingressController.image)) }} +- apiGroups: + - configuration.konghq.com + resources: + - kongconsumergroups + verbs: + - get + - list + - watch +- apiGroups: + - configuration.konghq.com + resources: + - kongconsumergroups/status + verbs: + - get + - patch + - update +{{- end }} +{{- if (semverCompare "< 2.10.0" (include "kong.effectiveVersion" .Values.ingressController.image)) }} +- apiGroups: + - "" + resources: + - endpoints + verbs: + - list + - watch +{{- end }} +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +- apiGroups: + - "" + resources: + - nodes + verbs: + - list + - watch +- apiGroups: + - "" + resources: + - pods + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - secrets + verbs: + - list + - watch +- apiGroups: + - "" + resources: + - services + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - services/status + verbs: + - get + - patch + - update +- apiGroups: + - configuration.konghq.com + resources: + - ingressclassparameterses + verbs: + - get + - list + - watch +- apiGroups: + - configuration.konghq.com + resources: + - kongconsumers + verbs: + - get + - list + - watch +- apiGroups: + - configuration.konghq.com + resources: + - kongconsumers/status + verbs: + - get + - patch + - update +- apiGroups: + - configuration.konghq.com + resources: + - kongingresses + verbs: + - get + - list + - watch +- apiGroups: + - configuration.konghq.com + resources: + - kongingresses/status + verbs: + - get + - patch + - update +- apiGroups: + - configuration.konghq.com + resources: + - kongplugins + verbs: + - get + - list + - watch +- apiGroups: + - configuration.konghq.com + resources: + - kongplugins/status + verbs: + - get + - patch + - update +- apiGroups: + - configuration.konghq.com + resources: + - tcpingresses + verbs: + - get + - list + - watch +- apiGroups: + - configuration.konghq.com + resources: + - tcpingresses/status + verbs: + - get + - patch + - update +- apiGroups: + - configuration.konghq.com + resources: + - udpingresses + verbs: + - get + - list + - watch +- apiGroups: + - configuration.konghq.com + resources: + - udpingresses/status + verbs: + - get + - patch + - update +- apiGroups: + - extensions + resources: + - ingresses + verbs: + - get + - list + - watch +- apiGroups: + - extensions + resources: + - ingresses/status + verbs: + - get + - patch + - update +{{- if or (.Capabilities.APIVersions.Has "gateway.networking.k8s.io/v1alpha2") (.Capabilities.APIVersions.Has "gateway.networking.k8s.io/v1beta1") (.Capabilities.APIVersions.Has "gateway.networking.k8s.io/v1")}} +- apiGroups: + - gateway.networking.k8s.io + resources: + - gateways + verbs: + - get + - list + - update + - watch +- apiGroups: + - gateway.networking.k8s.io + resources: + - gateways/status + verbs: + - get + - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + verbs: + - get + - list + - watch +- apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes/status + verbs: + - get + - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - referencegrants + verbs: + - get + - list + - watch +- apiGroups: + - gateway.networking.k8s.io + resources: + - referencegrants/status + verbs: + - get +- apiGroups: + - gateway.networking.k8s.io + resources: + - tcproutes + verbs: + - get + - list + - watch +- apiGroups: + - gateway.networking.k8s.io + resources: + - tcproutes/status + verbs: + - get + - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - tlsroutes + verbs: + - get + - list + - watch +- apiGroups: + - gateway.networking.k8s.io + resources: + - tlsroutes/status + verbs: + - get + - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - udproutes + verbs: + - get + - list + - watch +- apiGroups: + - gateway.networking.k8s.io + resources: + - udproutes/status + verbs: + - get + - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - grpcroutes + verbs: + - get + - list + - watch +- apiGroups: + - gateway.networking.k8s.io + resources: + - grpcroutes/status + verbs: + - get + - patch + - update +{{- end }} +{{- if (.Capabilities.APIVersions.Has "networking.internal.knative.dev/v1alpha1") }} +- apiGroups: + - networking.internal.knative.dev + resources: + - ingresses + verbs: + - get + - list + - watch +- apiGroups: + - networking.internal.knative.dev + resources: + - ingresses/status + verbs: + - get + - patch + - update +{{- end }} +- apiGroups: + - networking.k8s.io + resources: + - ingresses + verbs: + - get + - list + - watch +- apiGroups: + - networking.k8s.io + resources: + - ingresses/status + verbs: + - get + - patch + - update +- apiGroups: + - discovery.k8s.io + resources: + - endpointslices + verbs: + - get + - list + - watch +{{- end -}} + +{{/* +kong.kubernetesRBACClusterRoles outputs a static list of RBAC rules (the "rules" block +of a Role or ClusterRole) that provide the ingress controller access to the +Kubernetes Cluster-scoped resources it uses to build Kong configuration. +*/}} +{{- define "kong.kubernetesRBACClusterRules" -}} +{{- if (semverCompare ">= 3.1.0" (include "kong.effectiveVersion" .Values.ingressController.image)) }} +- apiGroups: + - configuration.konghq.com + resources: + - konglicenses + verbs: + - get + - list + - watch +- apiGroups: + - configuration.konghq.com + resources: + - konglicenses/status + verbs: + - get + - patch + - update +{{- end -}} +{{- if (semverCompare ">= 3.1.0" (include "kong.effectiveVersion" .Values.ingressController.image)) }} +- apiGroups: + - configuration.konghq.com + resources: + - kongvaults + verbs: + - get + - list + - watch +- apiGroups: + - configuration.konghq.com + resources: + - kongvaults/status + verbs: + - get + - patch + - update +{{- end }} +- apiGroups: + - configuration.konghq.com + resources: + - kongclusterplugins + verbs: + - get + - list + - watch +- apiGroups: + - configuration.konghq.com + resources: + - kongclusterplugins/status + verbs: + - get + - patch + - update +{{- if (semverCompare ">= 2.10.0" (include "kong.effectiveVersion" .Values.ingressController.image)) }} +- apiGroups: + - apiextensions.k8s.io + resources: + - customresourcedefinitions + verbs: + - list + - watch +{{- end }} +{{- if or (.Capabilities.APIVersions.Has "gateway.networking.k8s.io/v1alpha2") (.Capabilities.APIVersions.Has "gateway.networking.k8s.io/v1beta1") (.Capabilities.APIVersions.Has "gateway.networking.k8s.io/v1")}} +- apiGroups: + - gateway.networking.k8s.io + resources: + - gatewayclasses + verbs: + - get + - list + - watch +- apiGroups: + - gateway.networking.k8s.io + resources: + - gatewayclasses/status + verbs: + - get + - update +- apiGroups: + - "" + resources: + - namespaces + verbs: + - get + - list + - watch +{{- end }} +- apiGroups: + - networking.k8s.io + resources: + - ingressclasses + verbs: + - get + - list + - watch +{{- end -}} + +{{- define "kong.autoscalingVersion" -}} +{{- if (.Capabilities.APIVersions.Has "autoscaling/v2") -}} +autoscaling/v2 +{{- else if (.Capabilities.APIVersions.Has "autoscaling/v2beta2") -}} +autoscaling/v2beta2 +{{- else -}} +autoscaling/v1 +{{- end -}} +{{- end -}} + +{{- define "kong.policyVersion" -}} +{{- if (.Capabilities.APIVersions.Has "policy/v1beta1" ) -}} +policy/v1beta1 +{{- else -}} +{{- fail (printf "Cluster doesn't have policy/v1beta1 API." ) }} +{{- end -}} +{{- end -}} + +{{- define "kong.renderTpl" -}} + {{- if typeIs "string" .value }} +{{- tpl .value .context }} + {{- else }} +{{- tpl (.value | toYaml) .context }} + {{- end }} +{{- end -}} + +{{- define "kong.ingressVersion" -}} +{{- if (.Capabilities.APIVersions.Has "networking.k8s.io/v1") -}} +networking.k8s.io/v1 +{{- else if (.Capabilities.APIVersions.Has "networking.k8s.io/v1beta1") -}} +networking.k8s.io/v1beta1 +{{- else -}} +extensions/v1beta1 +{{- end -}} +{{- end -}} + +{{- define "kong.proxy.compatibleReadiness" -}} +{{- $proxyReadiness := .Values.readinessProbe -}} +{{- if (or (semverCompare "< 3.3.0" (include "kong.effectiveVersion" .Values.image)) (and .Values.ingressController.enabled (semverCompare "< 2.11.0" (include "kong.effectiveVersion" .Values.ingressController.image)))) -}} + {{- if (eq $proxyReadiness.httpGet.path "/status/ready") -}} + {{- $_ := set $proxyReadiness.httpGet "path" "/status" -}} + {{- end -}} +{{- end -}} +{{- (toYaml $proxyReadiness) -}} +{{- end -}} + +{{- define "kong.envFrom" -}} + {{- if (gt (len .) 0) -}} +envFrom: +{{- toYaml . | nindent 2 -}} + {{- else -}} + {{- end -}} +{{- end -}} diff --git a/charts/kong/kong/2.41.0/templates/admission-webhook.yaml b/charts/kong/kong/2.41.0/templates/admission-webhook.yaml new file mode 100644 index 0000000000..1f121eff0e --- /dev/null +++ b/charts/kong/kong/2.41.0/templates/admission-webhook.yaml @@ -0,0 +1,256 @@ +{{- if (and .Values.ingressController.admissionWebhook.enabled .Values.ingressController.enabled) }} +{{- $certCert := "" -}} +{{- $certKey := "" -}} +{{- $caCert := "" -}} +{{- $caKey := "" -}} +{{- if not .Values.ingressController.admissionWebhook.certificate.provided }} +{{- $cn := printf "%s.%s.svc" ( include "kong.service.validationWebhook" . ) ( include "kong.namespace" . ) -}} +{{- $ca := genCA "kong-admission-ca" 3650 -}} +{{- $cert := genSignedCert $cn nil (list $cn) 3650 $ca -}} +{{- $certCert = $cert.Cert -}} +{{- $certKey = $cert.Key -}} +{{- $caCert = $ca.Cert -}} +{{- $caKey = $ca.Key -}} + +{{- $caSecret := (lookup "v1" "Secret" (include "kong.namespace" .) (printf "%s-validation-webhook-ca-keypair" (include "kong.fullname" .))) -}} +{{- $certSecret := (lookup "v1" "Secret" (include "kong.namespace" .) (printf "%s-validation-webhook-keypair" (include "kong.fullname" .))) -}} +{{- if $certSecret }} +{{- $certCert = (b64dec (get $certSecret.data "tls.crt")) -}} +{{- $certKey = (b64dec (get $certSecret.data "tls.key")) -}} +{{- end }} +{{- if $caSecret }} +{{- $caCert = (b64dec (get $caSecret.data "tls.crt")) -}} +{{- $caKey = (b64dec (get $caSecret.data "tls.key")) -}} +{{- end }} +{{- end }} +kind: ValidatingWebhookConfiguration +{{- if .Capabilities.APIVersions.Has "admissionregistration.k8s.io/v1" }} +apiVersion: admissionregistration.k8s.io/v1 +{{- else }} +apiVersion: admissionregistration.k8s.io/v1beta1 +{{- end }} +metadata: + name: {{ template "kong.fullname" . }}-validations + namespace: {{ template "kong.namespace" . }} + labels: + {{- include "kong.metaLabels" . | nindent 4 }} + {{- if .Values.ingressController.admissionWebhook.annotations }} + annotations: + {{- range $key, $value := .Values.ingressController.admissionWebhook.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} +webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + {{- if not .Values.ingressController.admissionWebhook.certificate.provided }} + caBundle: {{ b64enc $caCert }} + {{- else }} + {{- if .Values.ingressController.admissionWebhook.certificate.caBundle }} + caBundle: {{ b64enc .Values.ingressController.admissionWebhook.certificate.caBundle }} + {{- end }} + {{- end }} + service: + name: {{ template "kong.service.validationWebhook" . }} + namespace: {{ template "kong.namespace" . }} + failurePolicy: {{ .Values.ingressController.admissionWebhook.failurePolicy }} + matchPolicy: Equivalent + name: secrets.credentials.validation.ingress-controller.konghq.com + {{- with .Values.ingressController.admissionWebhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.ingressController.admissionWebhook.timeoutSeconds }} + timeoutSeconds: {{ . }} + {{- end }} + objectSelector: + matchExpressions: + - key: "konghq.com/credential" + operator: "Exists" + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - secrets + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + {{- if not .Values.ingressController.admissionWebhook.certificate.provided }} + caBundle: {{ b64enc $caCert }} + {{- else }} + {{- if .Values.ingressController.admissionWebhook.certificate.caBundle }} + caBundle: {{ b64enc .Values.ingressController.admissionWebhook.certificate.caBundle }} + {{- end }} + {{- end }} + service: + name: {{ template "kong.service.validationWebhook" . }} + namespace: {{ template "kong.namespace" . }} + failurePolicy: {{ .Values.ingressController.admissionWebhook.failurePolicy }} + matchPolicy: Equivalent + name: secrets.plugins.validation.ingress-controller.konghq.com + {{- with .Values.ingressController.admissionWebhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.ingressController.admissionWebhook.timeoutSeconds }} + timeoutSeconds: {{ . }} + {{- end }} + {{- if .Values.ingressController.admissionWebhook.filterSecrets }} + objectSelector: + matchExpressions: + - key: "konghq.com/validate" + operator: "Exists" + {{- else }} + objectSelector: + matchExpressions: + - key: owner + operator: NotIn + values: + - helm + {{- end }} + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - secrets + sideEffects: None +- name: validations.kong.konghq.com + {{- with .Values.ingressController.admissionWebhook.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.ingressController.admissionWebhook.timeoutSeconds }} + timeoutSeconds: {{ . }} + {{- end }} + objectSelector: + matchExpressions: + - key: owner + operator: NotIn + values: + - helm + failurePolicy: {{ .Values.ingressController.admissionWebhook.failurePolicy }} + sideEffects: None + admissionReviewVersions: ["v1beta1"] + rules: + - apiGroups: + - configuration.konghq.com + apiVersions: + - '*' + operations: + - CREATE + - UPDATE + resources: + - kongconsumers + - kongplugins +{{- if (semverCompare ">= 2.0.4" (include "kong.effectiveVersion" .Values.ingressController.image)) }} + - kongclusterplugins +{{- end }} +{{- if (semverCompare ">= 2.8.0" (include "kong.effectiveVersion" .Values.ingressController.image)) }} + - kongingresses +{{- end }} +{{- if (semverCompare ">= 3.0.0" (include "kong.effectiveVersion" .Values.ingressController.image)) }} + - apiGroups: + - '' + apiVersions: + - 'v1' + operations: + - CREATE + - UPDATE + resources: + - services +{{- end }} +{{- if (semverCompare ">= 2.12.0" (include "kong.effectiveVersion" .Values.ingressController.image)) }} + - apiGroups: + - networking.k8s.io + apiVersions: + - 'v1' + operations: + - CREATE + - UPDATE + resources: + - ingresses + - apiGroups: + - gateway.networking.k8s.io + apiVersions: + - 'v1alpha2' + - 'v1beta1' +{{- if (semverCompare ">= 3.0.0" (include "kong.effectiveVersion" .Values.ingressController.image)) }} + - 'v1' +{{- end }} + operations: + - CREATE + - UPDATE + resources: + - gateways + - httproutes +{{- end }} + clientConfig: + {{- if not .Values.ingressController.admissionWebhook.certificate.provided }} + caBundle: {{ b64enc $caCert }} + {{- else }} + {{- if .Values.ingressController.admissionWebhook.certificate.caBundle }} + caBundle: {{ b64enc .Values.ingressController.admissionWebhook.certificate.caBundle }} + {{- end }} + {{- end }} + service: + name: {{ template "kong.service.validationWebhook" . }} + namespace: {{ template "kong.namespace" . }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ template "kong.service.validationWebhook" . }} + namespace: {{ template "kong.namespace" . }} + labels: + {{- include "kong.metaLabels" . | nindent 4 }} + {{- if .Values.ingressController.admissionWebhook.service.labels }} + {{- toYaml .Values.ingressController.admissionWebhook.service.labels | nindent 4 }} + {{- end }} +spec: + ports: + - name: webhook + port: 443 + protocol: TCP + targetPort: webhook + selector: + {{- include "kong.metaLabels" . | nindent 4 }} + app.kubernetes.io/component: app +{{- if not .Values.ingressController.admissionWebhook.certificate.provided }} +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "kong.fullname" . }}-validation-webhook-ca-keypair + namespace: {{ template "kong.namespace" . }} + labels: + {{- include "kong.metaLabels" . | nindent 4 }} +type: kubernetes.io/tls +data: + tls.crt: {{ b64enc $caCert }} + tls.key: {{ b64enc $caKey }} +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "kong.fullname" . }}-validation-webhook-keypair + namespace: {{ template "kong.namespace" . }} + labels: + {{- include "kong.metaLabels" . | nindent 4 }} +type: kubernetes.io/tls +data: + tls.crt: {{ b64enc $certCert }} + tls.key: {{ b64enc $certKey }} +{{- end }} +{{- end }} diff --git a/charts/kong/kong/2.41.0/templates/certificate.yaml b/charts/kong/kong/2.41.0/templates/certificate.yaml new file mode 100644 index 0000000000..a7079cd9ff --- /dev/null +++ b/charts/kong/kong/2.41.0/templates/certificate.yaml @@ -0,0 +1,89 @@ +{{- if and ( .Capabilities.APIVersions.Has "cert-manager.io/v1" ) .Values.certificates.enabled -}} + +{{- $genericCertificateConfig := dict -}} +{{- $_ := set $genericCertificateConfig "fullName" (include "kong.fullname" .) -}} +{{- $_ := set $genericCertificateConfig "namespace" (include "kong.namespace" .) -}} +{{- $_ := set $genericCertificateConfig "metaLabels" (include "kong.metaLabels" .) -}} +{{- $_ := set $genericCertificateConfig "globalIssuer" .Values.certificates.issuer -}} +{{- $_ := set $genericCertificateConfig "globalClusterIssuer" .Values.certificates.clusterIssuer -}} +{{- $_ := set $genericCertificateConfig "globalSubject" .Values.certificates.subject -}} +{{- $_ := set $genericCertificateConfig "globalPrivateKey" .Values.certificates.privateKey -}} +{{- $_ := set $genericCertificateConfig "defaultIssuer" (printf "%s-%s-%s" .Release.Name .Chart.Name "selfsigned-issuer") -}} + +{{- if .Values.certificates.admin.enabled }} +{{- $certificateConfig := mustMerge (mustDeepCopy $genericCertificateConfig) .Values.certificates.admin -}} +{{- $_ := set $certificateConfig "serviceName" "admin" -}} +{{- include "kong.certificate" $certificateConfig -}} +{{- end }} + +{{- if (and .Values.certificates.portal.enabled .Values.enterprise.enabled) }} +{{- $certificateConfig := mustMerge (mustDeepCopy $genericCertificateConfig) .Values.certificates.portal -}} +{{- $_ := set $certificateConfig "serviceName" "portal" -}} +{{- include "kong.certificate" $certificateConfig -}} +{{- end }} + +{{- if .Values.certificates.proxy.enabled }} +{{- $certificateConfig := mustMerge (mustDeepCopy $genericCertificateConfig) .Values.certificates.proxy -}} +{{- $_ := set $certificateConfig "serviceName" "proxy" -}} +{{- include "kong.certificate" $certificateConfig -}} +{{- end }} + +{{- if .Values.certificates.cluster.enabled }} +{{- $certificateConfig := dict -}} +{{- $certificateConfig = mustMerge (mustDeepCopy $genericCertificateConfig) .Values.certificates.cluster -}} +{{- $_ := set $certificateConfig "serviceName" "cluster" -}} +{{- include "kong.certificate" $certificateConfig -}} +{{- end }} + +{{- end }} + +{{- define "kong.certificate" }} +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: {{ .fullName }}-{{ .serviceName }} + namespace: {{ .namespace }} + labels: + {{- .metaLabels | nindent 4 }} +spec: + secretName: {{ .fullName }}-{{ .serviceName }}-cert + commonName: {{ .commonName }} + dnsNames: + {{- range (append .dnsNames .commonName) }} + - {{ . | quote }} + {{- end }} + renewBefore: 360h0m0s + duration: 2160h0m0s + {{ if .subject -}} + subject: + {{- toYaml .subject | nindent 4 }} + {{ else if .globalSubject -}} + subject: + {{- toYaml .globalSubject | nindent 4 }} + {{- end }} + {{ if .privateKey -}} + privateKey: + {{- toYaml .privateKey | nindent 4 }} + {{ else if .globalPrivateKey -}} + privateKey: + {{- toYaml .globalPrivateKey | nindent 4 }} + {{- end }} + {{ if .clusterIssuer -}} + issuerRef: + name: {{ .clusterIssuer }} + kind: ClusterIssuer + {{ else if .issuer -}} + issuerRef: + name: {{ .issuer }} + kind: Issuer + {{ else if .globalClusterIssuer -}} + issuerRef: + name: {{ .globalClusterIssuer}} + kind: ClusterIssuer + {{ else if .globalIssuer -}} + issuerRef: + name: {{ .globalIssuer }} + kind: Issuer + {{- end -}} +{{- end }} diff --git a/charts/kong/kong/2.41.0/templates/config-dbless.yaml b/charts/kong/kong/2.41.0/templates/config-dbless.yaml new file mode 100644 index 0000000000..5619b59a53 --- /dev/null +++ b/charts/kong/kong/2.41.0/templates/config-dbless.yaml @@ -0,0 +1,17 @@ +{{- if .Values.deployment.kong.enabled }} +{{- if (and (not .Values.ingressController.enabled) (eq .Values.env.database "off")) }} +{{- if not (or .Values.dblessConfig.configMap .Values.dblessConfig.secret) }} +{{- if .Values.dblessConfig.config }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "kong.dblessConfig.fullname" . }} + namespace: {{ template "kong.namespace" . }} + labels: + {{- include "kong.metaLabels" . | nindent 4 }} +data: + kong.yml: | {{- .Values.dblessConfig.config | nindent 4 }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/kong/kong/2.41.0/templates/controller-rbac-resources.yaml b/charts/kong/kong/2.41.0/templates/controller-rbac-resources.yaml new file mode 100644 index 0000000000..f5873f052c --- /dev/null +++ b/charts/kong/kong/2.41.0/templates/controller-rbac-resources.yaml @@ -0,0 +1,170 @@ +{{- if and .Values.ingressController.rbac.create .Values.ingressController.enabled -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "kong.fullname" . }} + namespace: {{ template "kong.namespace" . }} + labels: + {{- include "kong.metaLabels" . | nindent 4 }} +rules: + - apiGroups: + - "" + resources: + - configmaps + - pods + - secrets + - namespaces + verbs: + - get + - apiGroups: + - "" + resources: + - configmaps + resourceNames: + # Defaults to "-" + # Here: "-" + # This has to be adapted if you change either parameter + # when launching the nginx-ingress-controller. + - "kong-ingress-controller-leader-{{ .Values.ingressController.ingressClass }}-{{ .Values.ingressController.ingressClass }}" + verbs: + - get + - update + - apiGroups: + - "" + resources: + - configmaps + verbs: + - create +{{- if (semverCompare "< 2.10.0" (include "kong.effectiveVersion" .Values.ingressController.image)) }} + - apiGroups: + - "" + resources: + - endpoints + verbs: + - get +{{- end }} + # Begin KIC 2.x leader permissions + - apiGroups: + - "" + - coordination.k8s.io + resources: + - configmaps + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch + - apiGroups: + - "" + resources: + - services + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "kong.fullname" . }} + namespace: {{ template "kong.namespace" . }} + labels: + {{- include "kong.metaLabels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "kong.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ template "kong.serviceAccountName" . }} + namespace: {{ template "kong.namespace" . }} +{{- if eq (len .Values.ingressController.watchNamespaces) 0 }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "kong.metaLabels" . | nindent 4 }} + name: {{ template "kong.fullname" . }} +rules: +{{ include "kong.kubernetesRBACRules" . }} +{{ include "kong.kubernetesRBACClusterRules" . }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "kong.fullname" . }} + labels: + {{- include "kong.metaLabels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "kong.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ template "kong.serviceAccountName" . }} + namespace: {{ template "kong.namespace" . }} +{{- else }} +{{- range .Values.ingressController.watchNamespaces }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + {{- include "kong.metaLabels" $ | nindent 4 }} + name: {{ template "kong.fullname" $ }}-{{ . }} + namespace: {{ . }} +rules: +{{ include "kong.kubernetesRBACRules" $ }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "kong.fullname" $ }}-{{ . }} + labels: + {{- include "kong.metaLabels" $ | nindent 4 }} + namespace: {{ . }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "kong.fullname" $ }}-{{ . }} +subjects: + - kind: ServiceAccount + name: {{ template "kong.serviceAccountName" $ }} + namespace: {{ template "kong.namespace" $ }} +{{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "kong.metaLabels" . | nindent 4 }} + name: {{ template "kong.fullname" . }} +rules: +{{ include "kong.kubernetesRBACClusterRules" . }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "kong.fullname" . }} + labels: + {{- include "kong.metaLabels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "kong.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ template "kong.serviceAccountName" . }} + namespace: {{ template "kong.namespace" . }} +{{- end -}} +{{- end -}} diff --git a/charts/kong/kong/2.41.0/templates/custom-resource-definitions.yaml b/charts/kong/kong/2.41.0/templates/custom-resource-definitions.yaml new file mode 100644 index 0000000000..5a6dda1a63 --- /dev/null +++ b/charts/kong/kong/2.41.0/templates/custom-resource-definitions.yaml @@ -0,0 +1,34 @@ +{{- $installCRDs := false -}} +{{- if (hasKey .Values.ingressController "installCRDs") -}} + {{/* Explicitly set, honor whatever's set */}} + {{- $installCRDs = .Values.ingressController.installCRDs -}} +{{- else -}} + {{/* Legacy default handling. CRD installation is _not_ enabled, but CRDs are already present + and are managed by this release. This release previously relied on the <2.0 default + .Values.ingressController.installCRDs=true. The default change would delete CRDs on upgrade, + which would cascade delete all associated CRs. This unexpected loss of configuration is bad, + so this clause pretends the default didn't change if you have an existing release that relied + on it + */}} + {{- $kongPluginCRD := false -}} + {{- if .Capabilities.APIVersions.Has "apiextensions.k8s.io/v1/CustomResourceDefinition" -}} + {{- $kongPluginCRD = (lookup "apiextensions.k8s.io/v1" "CustomResourceDefinition" "" "kongplugins.configuration.konghq.com") -}} + {{- else -}} + {{/* TODO: remove the v1beta1 path when we no longer support k8s <1.16 */}} + {{- $kongPluginCRD = (lookup "apiextensions.k8s.io/v1beta1" "CustomResourceDefinition" "" "kongplugins.configuration.konghq.com") -}} + {{- end -}} + {{- if $kongPluginCRD -}} + {{- if (hasKey $kongPluginCRD.metadata "annotations") -}} + {{- if (eq .Release.Name (get $kongPluginCRD.metadata.annotations "meta.helm.sh/release-name")) -}} + {{- $installCRDs = true -}} + {{- end -}} + {{- end -}} + {{- end -}} +{{- end -}} + +{{- if $installCRDs -}} +{{- range $path, $bytes := .Files.Glob "crds/*.yaml" }} +{{ $.Files.Get $path }} +--- +{{- end }} +{{- end }} diff --git a/charts/kong/kong/2.41.0/templates/deployment.yaml b/charts/kong/kong/2.41.0/templates/deployment.yaml new file mode 100644 index 0000000000..4f4fe902d7 --- /dev/null +++ b/charts/kong/kong/2.41.0/templates/deployment.yaml @@ -0,0 +1,313 @@ +{{- if or .Values.deployment.kong.enabled .Values.ingressController.enabled }} +apiVersion: apps/v1 +{{- if .Values.deployment.daemonset }} +kind: DaemonSet +{{- else }} +kind: Deployment +{{- end }} +metadata: + name: {{ template "kong.fullname" . }} + namespace: {{ template "kong.namespace" . }} + labels: + {{- include "kong.metaLabels" . | nindent 4 }} + app.kubernetes.io/component: app + {{- if .Values.deploymentAnnotations }} + annotations: + {{- range $key, $value := .Values.deploymentAnnotations }} + {{ $key }}: {{ include "kong.renderTpl" (dict "value" $value "context" $) | quote }} + {{- end }} + {{- end }} +spec: + {{- if not .Values.autoscaling.enabled }} + {{- if not .Values.deployment.daemonset }} + replicas: {{ .Values.replicaCount }} + {{- end }} + {{- end }} + {{- if .Values.deployment.revisionHistoryLimit }} + revisionHistoryLimit: {{ .Values.deployment.revisionHistoryLimit }} + {{- end }} + selector: + matchLabels: + {{- include "kong.selectorLabels" . | nindent 6 }} + {{- if .Values.updateStrategy }} + {{- if .Values.deployment.daemonset }} + updateStrategy: + {{- else }} + strategy: + {{- end }} +{{ toYaml .Values.updateStrategy | indent 4 }} + {{- end }} + {{- if .Values.deployment.minReadySeconds }} + minReadySeconds: {{ .Values.deployment.minReadySeconds }} + {{- end }} + + template: + metadata: + annotations: + {{- if (and (not .Values.deployment.serviceAccount.automountServiceAccountToken) (or .Values.deployment.serviceAccount.create .Values.deployment.serviceAccount.name)) }} + kuma.io/service-account-token-volume: {{ template "kong.serviceAccountTokenName" . }} + {{- end }} + {{- if (and (not .Values.ingressController.enabled) (eq .Values.env.database "off" )) }} + {{- if .Values.dblessConfig.config }} + checksum/dbless.config: {{ toYaml .Values.dblessConfig.config | sha256sum }} + {{- end }} + {{- end }} + {{- if .Values.podAnnotations }} + {{- range $key, $value := .Values.podAnnotations }} + {{ $key }}: {{ include "kong.renderTpl" (dict "value" $value "context" $) | quote }} + {{- end }} + {{- end }} + labels: + {{- include "kong.metaLabels" . | nindent 8 }} + app.kubernetes.io/component: app + app: {{ template "kong.fullname" . }} + version: {{ .Chart.AppVersion | quote }} + {{- if .Values.podLabels }} + {{ include "kong.renderTpl" (dict "value" .Values.podLabels "context" $) | nindent 8 }} + {{- end }} + spec: + {{- if .Values.deployment.hostname }} + hostname: {{ .Values.deployment.hostname }} + {{- end }} + {{- if .Values.deployment.hostNetwork }} + hostNetwork: true + {{- end }} + {{- if .Values.priorityClassName }} + priorityClassName: "{{ .Values.priorityClassName }}" + {{- end }} + {{- if or .Values.deployment.serviceAccount.create .Values.deployment.serviceAccount.name }} + serviceAccountName: {{ template "kong.serviceAccountName" . }} + {{- end }} + {{- if (and (or .Values.deployment.serviceAccount.create .Values.deployment.serviceAccount.name) .Values.deployment.serviceAccount.automountServiceAccountToken) }} + automountServiceAccountToken: true + {{- else }} + automountServiceAccountToken: false + {{ end }} + {{- if .Values.image.pullSecrets }} + imagePullSecrets: + {{- range .Values.image.pullSecrets }} + - name: {{ . }} + {{- end }} + {{- end }} + {{- if .Values.deployment.kong.enabled }} + initContainers: + - name: clear-stale-pid + image: {{ include "kong.getRepoTag" .Values.image }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + securityContext: + {{ toYaml .Values.containerSecurityContext | nindent 10 }} + resources: +{{ toYaml .Values.resources | indent 10 }} + command: + - "rm" + - "-vrf" + - "$KONG_PREFIX/pids" + env: + {{- include "kong.env" . | nindent 8 }} + {{- include "kong.envFrom" .Values.envFrom | nindent 8 }} + volumeMounts: + {{- include "kong.volumeMounts" . | nindent 8 }} + {{- if .Values.deployment.initContainers }} + {{- toYaml .Values.deployment.initContainers | nindent 6 }} + {{- end }} + {{- if (and (not (eq .Values.env.database "off")) .Values.waitImage.enabled) }} + {{- include "kong.wait-for-db" . | nindent 6 }} + {{- end }} + {{- end }} + {{- if .Values.deployment.hostAliases }} + hostAliases: + {{- toYaml .Values.deployment.hostAliases | nindent 6 }} + {{- end}} + {{- if .Values.dnsPolicy }} + dnsPolicy: {{ .Values.dnsPolicy | quote }} + {{- end }} + {{- if .Values.dnsConfig }} + dnsConfig: +{{ toYaml .Values.dnsConfig | indent 8 }} + {{- end }} + containers: + {{- if .Values.ingressController.enabled }} + {{- include "kong.controller-container" . | nindent 6 }} + {{ end }} + {{- if .Values.deployment.sidecarContainers }} + {{- toYaml .Values.deployment.sidecarContainers | nindent 6 }} + {{- end }} + {{- if .Values.deployment.kong.enabled }} + - name: "proxy" + image: {{ include "kong.getRepoTag" .Values.image }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + securityContext: + {{ toYaml .Values.containerSecurityContext | nindent 10 }} + env: + {{- include "kong.no_daemon_env" . | nindent 8 }} + {{- include "kong.envFrom" .Values.envFrom | nindent 8 }} + lifecycle: + {{- toYaml .Values.lifecycle | nindent 10 }} + ports: + {{- if (and .Values.admin.http.enabled .Values.admin.enabled) }} + - name: admin + containerPort: {{ .Values.admin.http.containerPort }} + {{- if .Values.admin.http.hostPort }} + hostPort: {{ .Values.admin.http.hostPort }} + {{- end}} + protocol: TCP + {{- end }} + {{- if (and .Values.admin.tls.enabled .Values.admin.enabled) }} + - name: admin-tls + containerPort: {{ .Values.admin.tls.containerPort }} + {{- if .Values.admin.tls.hostPort }} + hostPort: {{ .Values.admin.tls.hostPort }} + {{- end}} + protocol: TCP + {{- end }} + {{- if (and .Values.proxy.http.enabled .Values.proxy.enabled) }} + - name: proxy + containerPort: {{ .Values.proxy.http.containerPort }} + {{- if .Values.proxy.http.hostPort }} + hostPort: {{ .Values.proxy.http.hostPort }} + {{- end}} + protocol: TCP + {{- end }} + {{- if (and .Values.proxy.tls.enabled .Values.proxy.enabled)}} + - name: proxy-tls + containerPort: {{ .Values.proxy.tls.containerPort }} + {{- if .Values.proxy.tls.hostPort }} + hostPort: {{ .Values.proxy.tls.hostPort }} + {{- end}} + protocol: TCP + {{- end }} + {{- range .Values.proxy.stream }} + - name: stream{{ if (eq (default "TCP" .protocol) "UDP") }}udp{{ end }}-{{ .containerPort }} + containerPort: {{ .containerPort }} + {{- if .hostPort }} + hostPort: {{ .hostPort }} + {{- end}} + protocol: {{ .protocol }} + {{- end }} + {{- range .Values.udpProxy.stream }} + - name: streamudp-{{ .containerPort }} + containerPort: {{ .containerPort }} + {{- if .hostPort }} + hostPort: {{ .hostPort }} + {{- end}} + protocol: {{ .protocol }} + {{- end }} + {{- if (and .Values.status.http.enabled .Values.status.enabled)}} + - name: status + containerPort: {{ .Values.status.http.containerPort }} + {{- if .Values.status.http.hostPort }} + hostPort: {{ .Values.status.http.hostPort }} + {{- end}} + protocol: TCP + {{- end }} + {{- if (and .Values.status.tls.enabled .Values.status.enabled) }} + - name: status-tls + containerPort: {{ .Values.status.tls.containerPort }} + {{- if .Values.status.tls.hostPort }} + hostPort: {{ .Values.status.tls.hostPort }} + {{- end}} + protocol: TCP + {{- end }} + {{- if (and .Values.cluster.tls.enabled .Values.cluster.enabled) }} + - name: cluster-tls + containerPort: {{ .Values.cluster.tls.containerPort }} + {{- if .Values.cluster.tls.hostPort }} + hostPort: {{ .Values.cluster.tls.hostPort }} + {{- end}} + protocol: TCP + {{- end }} + {{- if .Values.enterprise.enabled }} + {{- if (and .Values.manager.http.enabled .Values.manager.enabled) }} + - name: manager + containerPort: {{ .Values.manager.http.containerPort }} + {{- if .Values.manager.http.hostPort }} + hostPort: {{ .Values.manager.http.hostPort }} + {{- end}} + protocol: TCP + {{- end }} + {{- if (and .Values.manager.tls.enabled .Values.manager.enabled) }} + - name: manager-tls + containerPort: {{ .Values.manager.tls.containerPort }} + {{- if .Values.manager.tls.hostPort }} + hostPort: {{ .Values.manager.tls.hostPort }} + {{- end}} + protocol: TCP + {{- end }} + {{- if (and .Values.portal.http.enabled .Values.portal.enabled) }} + - name: portal + containerPort: {{ .Values.portal.http.containerPort }} + {{- if .Values.portal.http.hostPort }} + hostPort: {{ .Values.portal.http.hostPort }} + {{- end}} + protocol: TCP + {{- end }} + {{- if (and .Values.portal.tls.enabled .Values.portal.enabled) }} + - name: portal-tls + containerPort: {{ .Values.portal.tls.containerPort }} + {{- if .Values.portal.tls.hostPort }} + hostPort: {{ .Values.portal.tls.hostPort }} + {{- end}} + protocol: TCP + {{- end }} + {{- if (and .Values.portalapi.http.enabled .Values.portalapi.enabled) }} + - name: portalapi + containerPort: {{ .Values.portalapi.http.containerPort }} + {{- if .Values.portalapi.http.hostPort }} + hostPort: {{ .Values.portalapi.http.hostPort }} + {{- end}} + protocol: TCP + {{- end }} + {{- if (and .Values.portalapi.tls.enabled .Values.portalapi.enabled) }} + - name: portalapi-tls + containerPort: {{ .Values.portalapi.tls.containerPort }} + {{- if .Values.portalapi.tls.hostPort }} + hostPort: {{ .Values.portalapi.tls.hostPort }} + {{- end}} + protocol: TCP + {{- end }} + {{- if (and .Values.clustertelemetry.tls.enabled .Values.clustertelemetry.enabled) }} + - name: clustert-tls + containerPort: {{ .Values.clustertelemetry.tls.containerPort }} + {{- if .Values.clustertelemetry.tls.hostPort }} + hostPort: {{ .Values.clustertelemetry.tls.hostPort }} + {{- end}} + protocol: TCP + {{- end }} + {{- end }} + volumeMounts: + {{- include "kong.volumeMounts" . | nindent 10 }} + {{- include "kong.userDefinedVolumeMounts" .Values.deployment | nindent 10 }} + readinessProbe: +{{ include "kong.proxy.compatibleReadiness" . | indent 10 }} + livenessProbe: +{{ toYaml .Values.livenessProbe | indent 10 }} + {{- if .Values.startupProbe }} + startupProbe: +{{ toYaml .Values.startupProbe | indent 10 }} + {{- end }} + resources: +{{ toYaml .Values.resources | indent 10 }} + {{- end }} {{/* End of Kong container spec */}} + {{- if .Values.affinity }} + affinity: +{{ toYaml .Values.affinity | indent 8 }} + {{- end }} + {{- if .Values.topologySpreadConstraints }} + topologySpreadConstraints: +{{ toYaml .Values.topologySpreadConstraints | indent 8 }} + {{- end }} + securityContext: + {{- include "kong.podsecuritycontext" . | nindent 8 }} + {{- if .Values.nodeSelector }} + nodeSelector: +{{ toYaml .Values.nodeSelector | indent 8 }} + {{- end }} + terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }} + {{- if .Values.tolerations }} + tolerations: +{{ toYaml .Values.tolerations | indent 8 }} + {{- end }} + volumes: + {{- include "kong.volumes" . | nindent 8 -}} + {{- include "kong.userDefinedVolumes" . | nindent 8 -}} +{{- end }} diff --git a/charts/kong/kong/2.41.0/templates/extraManifests.yaml b/charts/kong/kong/2.41.0/templates/extraManifests.yaml new file mode 100644 index 0000000000..a9bb3b6ba8 --- /dev/null +++ b/charts/kong/kong/2.41.0/templates/extraManifests.yaml @@ -0,0 +1,4 @@ +{{ range .Values.extraObjects }} +--- +{{ tpl (toYaml .) $ }} +{{ end }} diff --git a/charts/kong/kong/2.41.0/templates/hpa.yaml b/charts/kong/kong/2.41.0/templates/hpa.yaml new file mode 100644 index 0000000000..922ade82df --- /dev/null +++ b/charts/kong/kong/2.41.0/templates/hpa.yaml @@ -0,0 +1,26 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: {{ include "kong.autoscalingVersion" . }} +kind: HorizontalPodAutoscaler +metadata: + name: "{{ template "kong.fullname" . }}" + namespace: {{ template "kong.namespace" . }} + labels: + {{- include "kong.metaLabels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: "{{ template "kong.fullname" . }}" + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + {{- if .Values.autoscaling.behavior }} + behavior: + {{- toYaml .Values.autoscaling.behavior | nindent 4 }} + {{- end }} + {{- if contains "autoscaling/v2" (include "kong.autoscalingVersion" . ) }} + metrics: + {{- toYaml .Values.autoscaling.metrics | nindent 4 }} + {{- else }} + targetCPUUtilizationPercentage: {{ .Values.autoscaling.targetCPUUtilizationPercentage | default 80 }} + {{- end }} +{{- end }} diff --git a/charts/kong/kong/2.41.0/templates/ingress-class.yaml b/charts/kong/kong/2.41.0/templates/ingress-class.yaml new file mode 100644 index 0000000000..d2ac47d69a --- /dev/null +++ b/charts/kong/kong/2.41.0/templates/ingress-class.yaml @@ -0,0 +1,33 @@ +{{/* Default to not managing if unsupported or created outside this chart */}} +{{- $includeIngressClass := false -}} +{{- if .Values.ingressController.enabled -}} + {{- if (.Capabilities.APIVersions.Has "networking.k8s.io/v1/IngressClass") -}} + {{- with (lookup "networking.k8s.io/v1" "IngressClass" "" .Values.ingressController.ingressClass) -}} + {{- if (hasKey .metadata "annotations") -}} + {{- if (eq $.Release.Name (get .metadata.annotations "meta.helm.sh/release-name")) -}} + {{/* IngressClass exists and is managed by this chart */}} + {{- $includeIngressClass = true -}} + {{- end -}} + {{- end -}} + {{- else -}} + {{/* IngressClass doesn't exist */}} + {{- $includeIngressClass = true -}} + {{- end -}} + {{- end -}} +{{- end -}} +{{- if $includeIngressClass -}} +apiVersion: networking.k8s.io/v1 +kind: IngressClass +metadata: + name: {{ .Values.ingressController.ingressClass }} + {{- if .Values.ingressController.ingressClassAnnotations }} + annotations: + {{- range $key, $value := .Values.ingressController.ingressClassAnnotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} + labels: + {{- include "kong.metaLabels" . | nindent 4 }} +spec: + controller: ingress-controllers.konghq.com/kong +{{- end -}} diff --git a/charts/kong/kong/2.41.0/templates/migrations-post-upgrade.yaml b/charts/kong/kong/2.41.0/templates/migrations-post-upgrade.yaml new file mode 100644 index 0000000000..73225392ce --- /dev/null +++ b/charts/kong/kong/2.41.0/templates/migrations-post-upgrade.yaml @@ -0,0 +1,97 @@ +{{- if .Values.deployment.kong.enabled }} +{{- if (and .Values.migrations.postUpgrade (not (eq .Values.env.database "off"))) }} +# Why is this Job duplicated and not using only helm hooks? +# See: https://github.com/helm/charts/pull/7362 +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ template "kong.fullname" . }}-post-upgrade-migrations + namespace: {{ template "kong.namespace" . }} + labels: + {{- include "kong.metaLabels" . | nindent 4 }} + app.kubernetes.io/component: post-upgrade-migrations + annotations: + helm.sh/hook: "post-upgrade" + helm.sh/hook-delete-policy: "before-hook-creation" + {{- range $key, $value := .Values.migrations.jobAnnotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} +spec: + backoffLimit: {{ .Values.migrations.backoffLimit }} + template: + metadata: + name: {{ template "kong.name" . }}-post-upgrade-migrations + labels: + {{- include "kong.metaLabels" . | nindent 8 }} + app.kubernetes.io/component: post-upgrade-migrations + {{- if .Values.migrations.annotations }} + annotations: + {{- range $key, $value := .Values.migrations.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- if (and (not .Values.deployment.serviceAccount.automountServiceAccountToken) (or .Values.deployment.serviceAccount.create .Values.deployment.serviceAccount.name)) }} + kuma.io/service-account-token-volume: {{ template "kong.serviceAccountTokenName" . }} + {{- end }} + {{- end }} + spec: + {{- if or .Values.deployment.serviceAccount.create .Values.deployment.serviceAccount.name }} + serviceAccountName: {{ template "kong.serviceAccountName" . }} + {{- end }} + {{- if (and (or .Values.deployment.serviceAccount.create .Values.deployment.serviceAccount.name) .Values.deployment.serviceAccount.automountServiceAccountToken) }} + automountServiceAccountToken: true + {{- else }} + automountServiceAccountToken: false + {{ end }} + {{- if .Values.image.pullSecrets }} + imagePullSecrets: + {{- range .Values.image.pullSecrets }} + - name: {{ . }} + {{- end }} + {{- end }} + {{- if (or (and (.Values.postgresql.enabled) .Values.waitImage.enabled) .Values.deployment.initContainers) }} + initContainers: + {{- if .Values.deployment.initContainers }} + {{- toYaml .Values.deployment.initContainers | nindent 6 }} + {{- end }} + {{- if (and (.Values.postgresql.enabled) .Values.waitImage.enabled) }} + {{- include "kong.wait-for-postgres" . | nindent 6 }} + {{- end }} + {{- end }} + containers: + {{- if .Values.migrations.sidecarContainers }} + {{- toYaml .Values.migrations.sidecarContainers | nindent 6 }} + {{- end }} + - name: {{ template "kong.name" . }}-post-upgrade-migrations + image: {{ include "kong.getRepoTag" .Values.image }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + securityContext: + {{ toYaml .Values.containerSecurityContext | nindent 10 }} + env: + {{- include "kong.no_daemon_env" . | nindent 8 }} + {{- include "kong.envFrom" .Values.envFrom | nindent 8 }} + args: [ "kong", "migrations", "finish" ] + volumeMounts: + {{- include "kong.volumeMounts" . | nindent 8 }} + {{- include "kong.userDefinedVolumeMounts" .Values.deployment | nindent 8 }} + resources: + {{- toYaml .Values.migrations.resources | nindent 10 }} + securityContext: + {{- include "kong.podsecuritycontext" . | nindent 8 }} + {{- if .Values.affinity }} + affinity: + {{- toYaml .Values.affinity | nindent 8 }} + {{- end }} + {{- if .Values.nodeSelector }} + nodeSelector: + {{- toYaml .Values.nodeSelector | nindent 8 }} + {{- end }} + {{- if .Values.tolerations }} + tolerations: + {{- toYaml .Values.tolerations | nindent 8 }} + {{- end }} + restartPolicy: OnFailure + volumes: + {{- include "kong.volumes" . | nindent 6 -}} + {{- include "kong.userDefinedVolumes" . | nindent 6 -}} +{{- end }} +{{- end }} diff --git a/charts/kong/kong/2.41.0/templates/migrations-pre-upgrade.yaml b/charts/kong/kong/2.41.0/templates/migrations-pre-upgrade.yaml new file mode 100644 index 0000000000..9efb8baea9 --- /dev/null +++ b/charts/kong/kong/2.41.0/templates/migrations-pre-upgrade.yaml @@ -0,0 +1,99 @@ +{{- if .Values.deployment.kong.enabled }} +{{- if (and .Values.migrations.preUpgrade (not (eq .Values.env.database "off"))) }} +# Why is this Job duplicated and not using only helm hooks? +# See: https://github.com/helm/charts/pull/7362 +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ template "kong.fullname" . }}-pre-upgrade-migrations + namespace: {{ template "kong.namespace" . }} + labels: + {{- include "kong.metaLabels" . | nindent 4 }} + app.kubernetes.io/component: pre-upgrade-migrations + annotations: + helm.sh/hook: "pre-upgrade" + helm.sh/hook-delete-policy: "before-hook-creation" + argocd.argoproj.io/hook: Sync + argocd.argoproj.io/hook-delete-policy: BeforeHookCreation + {{- range $key, $value := .Values.migrations.jobAnnotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} +spec: + backoffLimit: {{ .Values.migrations.backoffLimit }} + template: + metadata: + name: {{ template "kong.name" . }}-pre-upgrade-migrations + labels: + {{- include "kong.metaLabels" . | nindent 8 }} + app.kubernetes.io/component: pre-upgrade-migrations + {{- if .Values.migrations.annotations }} + annotations: + {{- range $key, $value := .Values.migrations.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- if (and (not .Values.deployment.serviceAccount.automountServiceAccountToken) (or .Values.deployment.serviceAccount.create .Values.deployment.serviceAccount.name)) }} + kuma.io/service-account-token-volume: {{ template "kong.serviceAccountTokenName" . }} + {{- end }} + {{- end }} + spec: + {{- if or .Values.deployment.serviceAccount.create .Values.deployment.serviceAccount.name }} + serviceAccountName: {{ template "kong.serviceAccountName" . }} + {{- end }} + {{- if (and (or .Values.deployment.serviceAccount.create .Values.deployment.serviceAccount.name) .Values.deployment.serviceAccount.automountServiceAccountToken) }} + automountServiceAccountToken: true + {{- else }} + automountServiceAccountToken: false + {{ end }} + {{- if .Values.image.pullSecrets }} + imagePullSecrets: + {{- range .Values.image.pullSecrets }} + - name: {{ . }} + {{- end }} + {{- end }} + {{- if (or (and (.Values.postgresql.enabled) .Values.waitImage.enabled) .Values.deployment.initContainers) }} + initContainers: + {{- if .Values.deployment.initContainers }} + {{- toYaml .Values.deployment.initContainers | nindent 6 }} + {{- end }} + {{- if (and (.Values.postgresql.enabled) .Values.waitImage.enabled) }} + {{- include "kong.wait-for-postgres" . | nindent 6 }} + {{- end }} + {{- end }} + containers: + {{- if .Values.migrations.sidecarContainers }} + {{- toYaml .Values.migrations.sidecarContainers | nindent 6 }} + {{- end }} + - name: {{ template "kong.name" . }}-upgrade-migrations + image: {{ include "kong.getRepoTag" .Values.image }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + securityContext: + {{ toYaml .Values.containerSecurityContext | nindent 10 }} + env: + {{- include "kong.no_daemon_env" . | nindent 8 }} + {{- include "kong.envFrom" .Values.envFrom | nindent 8 }} + args: [ "kong", "migrations", "up" ] + volumeMounts: + {{- include "kong.volumeMounts" . | nindent 8 }} + {{- include "kong.userDefinedVolumeMounts" .Values.deployment | nindent 8 }} + resources: + {{- toYaml .Values.migrations.resources| nindent 10 }} + securityContext: + {{- include "kong.podsecuritycontext" . | nindent 8 }} + {{- if .Values.affinity }} + affinity: + {{- toYaml .Values.affinity | nindent 8 }} + {{- end }} + {{- if .Values.nodeSelector }} + nodeSelector: + {{- toYaml .Values.nodeSelector | nindent 8 }} + {{- end }} + {{- if .Values.tolerations }} + tolerations: + {{- toYaml .Values.tolerations | nindent 8 }} + {{- end }} + restartPolicy: OnFailure + volumes: + {{- include "kong.volumes" . | nindent 6 -}} + {{- include "kong.userDefinedVolumes" . | nindent 6 -}} +{{- end }} +{{- end }} diff --git a/charts/kong/kong/2.41.0/templates/migrations.yaml b/charts/kong/kong/2.41.0/templates/migrations.yaml new file mode 100644 index 0000000000..e1a85fb90c --- /dev/null +++ b/charts/kong/kong/2.41.0/templates/migrations.yaml @@ -0,0 +1,108 @@ +{{- if .Values.deployment.kong.enabled }} +{{- if .Release.IsInstall -}} +{{/* .migrations.init isn't normally exposed in values.yaml, since it should + generally always run on install--there should never be any reason to + disable it, and at worst it's a no-op. However, https://github.com/helm/helm/issues/3308 + means we cannot use the default function to create a hidden value, hence + the workaround with this $runInit variable. + */}} +{{- $runInit := true -}} +{{- if (hasKey .Values.migrations "init") -}} + {{- $runInit = .Values.migrations.init -}} +{{- end -}} + +{{- if (and ($runInit) (not (eq .Values.env.database "off"))) }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ template "kong.fullname" . }}-init-migrations + namespace: {{ template "kong.namespace" . }} + labels: + {{- include "kong.metaLabels" . | nindent 4 }} + app.kubernetes.io/component: init-migrations + annotations: + argocd.argoproj.io/hook: Sync + argocd.argoproj.io/hook-delete-policy: BeforeHookCreation + {{- range $key, $value := .Values.migrations.jobAnnotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} +spec: + backoffLimit: {{ .Values.migrations.backoffLimit }} + template: + metadata: + name: {{ template "kong.name" . }}-init-migrations + labels: + {{- include "kong.metaLabels" . | nindent 8 }} + app.kubernetes.io/component: init-migrations + {{- if .Values.migrations.annotations }} + annotations: + {{- range $key, $value := .Values.migrations.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- if (and (not .Values.deployment.serviceAccount.automountServiceAccountToken) (or .Values.deployment.serviceAccount.create .Values.deployment.serviceAccount.name)) }} + kuma.io/service-account-token-volume: {{ template "kong.serviceAccountTokenName" . }} + {{- end }} + {{- end }} + spec: + {{- if or .Values.deployment.serviceAccount.create .Values.deployment.serviceAccount.name }} + serviceAccountName: {{ template "kong.serviceAccountName" . }} + {{- end }} + {{- if (and (or .Values.deployment.serviceAccount.create .Values.deployment.serviceAccount.name) .Values.deployment.serviceAccount.automountServiceAccountToken) }} + automountServiceAccountToken: true + {{- else }} + automountServiceAccountToken: false + {{ end }} + {{- if .Values.image.pullSecrets }} + imagePullSecrets: + {{- range .Values.image.pullSecrets }} + - name: {{ . }} + {{- end }} + {{- end }} + {{- if (or (and (.Values.postgresql.enabled) .Values.waitImage.enabled) .Values.deployment.initContainers) }} + initContainers: + {{- if .Values.deployment.initContainers }} + {{- toYaml .Values.deployment.initContainers | nindent 6 }} + {{- end }} + {{- if (and (.Values.postgresql.enabled) .Values.waitImage.enabled) }} + {{- include "kong.wait-for-postgres" . | nindent 6 }} + {{- end }} + {{- end }} + containers: + {{- if .Values.migrations.sidecarContainers }} + {{- toYaml .Values.migrations.sidecarContainers | nindent 6 }} + {{- end }} + - name: {{ template "kong.name" . }}-migrations + image: {{ include "kong.getRepoTag" .Values.image }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + securityContext: + {{ toYaml .Values.containerSecurityContext | nindent 10 }} + env: + {{- include "kong.no_daemon_env" . | nindent 8 }} + {{- include "kong.envFrom" .Values.envFrom | nindent 8 }} + args: [ "kong", "migrations", "bootstrap" ] + volumeMounts: + {{- include "kong.volumeMounts" . | nindent 8 }} + {{- include "kong.userDefinedVolumeMounts" .Values.deployment | nindent 8 }} + resources: + {{- toYaml .Values.migrations.resources | nindent 10 }} + securityContext: + {{- include "kong.podsecuritycontext" . | nindent 8 }} + {{- if .Values.affinity }} + affinity: + {{- toYaml .Values.affinity | nindent 8 }} + {{- end }} + {{- if .Values.nodeSelector }} + nodeSelector: + {{- toYaml .Values.nodeSelector | nindent 8 }} + {{- end }} + {{- if .Values.tolerations }} + tolerations: + {{- toYaml .Values.tolerations | nindent 8 }} + {{- end }} + restartPolicy: OnFailure + volumes: + {{- include "kong.volumes" . | nindent 6 -}} + {{- include "kong.userDefinedVolumes" . | nindent 6 -}} +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/kong/kong/2.41.0/templates/pdb.yaml b/charts/kong/kong/2.41.0/templates/pdb.yaml new file mode 100644 index 0000000000..8d918c5a5b --- /dev/null +++ b/charts/kong/kong/2.41.0/templates/pdb.yaml @@ -0,0 +1,26 @@ +{{- if .Values.podDisruptionBudget.enabled }} +{{- if and (not .Values.autoscaling.enabled) (le (int .Values.replicaCount) 1) }} +{{- fail "Enabling PodDisruptionBudget with replicaCount: 1 and no autoscaling prevents pod restarts during upgrades" }} +{{- end }} +{{- if and .Values.autoscaling.enabled (le (int .Values.autoscaling.minReplicas) 1) }} +{{- fail "Enabling PodDisruptionBudget with autoscaling.minReplicas: 1 prevents pod restarts during upgrades" }} +{{- end }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ template "kong.fullname" . }} + namespace: {{ template "kong.namespace" . }} + labels: + {{- include "kong.metaLabels" . | nindent 4 }} +spec: + {{- if .Values.podDisruptionBudget.minAvailable }} + minAvailable: {{ .Values.podDisruptionBudget.minAvailable }} + {{- end }} + {{- if .Values.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ .Values.podDisruptionBudget.maxUnavailable }} + {{- end }} + selector: + matchLabels: + {{- include "kong.metaLabels" . | nindent 6 }} + app.kubernetes.io/component: app +{{- end }} diff --git a/charts/kong/kong/2.41.0/templates/psp.yaml b/charts/kong/kong/2.41.0/templates/psp.yaml new file mode 100644 index 0000000000..bc9844798b --- /dev/null +++ b/charts/kong/kong/2.41.0/templates/psp.yaml @@ -0,0 +1,53 @@ +{{- if and (.Values.podSecurityPolicy.enabled) }} +apiVersion: {{ include "kong.policyVersion" . }} +kind: PodSecurityPolicy +metadata: + name: {{ template "kong.serviceAccountName" . }}-psp + labels: + {{- include "kong.metaLabels" . | nindent 4 }} + {{- with .Values.podSecurityPolicy.labels }} + {{- range $key, $value := . }} + {{ $key }}: {{ $value }} + {{- end }} + {{- end }} + {{- with .Values.podSecurityPolicy.annotations }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} +spec: +{{ .Values.podSecurityPolicy.spec | toYaml | indent 2 }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "kong.serviceAccountName" . }}-psp + labels: + {{- include "kong.metaLabels" . | nindent 4 }} +rules: + - apiGroups: + - policy + resources: + - podsecuritypolicies + verbs: + - use + resourceNames: + - {{ template "kong.serviceAccountName" . }}-psp +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "kong.serviceAccountName" . }}-psp + namespace: {{ template "kong.namespace" . }} + labels: + {{- include "kong.metaLabels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ template "kong.serviceAccountName" . }} + namespace: {{ template "kong.namespace" . }} +roleRef: + kind: ClusterRole + name: {{ template "kong.serviceAccountName" . }}-psp + apiGroup: rbac.authorization.k8s.io +{{- end }} diff --git a/charts/kong/kong/2.41.0/templates/secret-sa-token.yaml b/charts/kong/kong/2.41.0/templates/secret-sa-token.yaml new file mode 100644 index 0000000000..fe8a67d239 --- /dev/null +++ b/charts/kong/kong/2.41.0/templates/secret-sa-token.yaml @@ -0,0 +1,14 @@ +{{- /* Due to GKE versions (e.g. v1.23.15-gke.1900) we need to handle pre-release part of the version as well. +See the related documentation of semver module that Helm depends on for semverCompare: +https://github.com/Masterminds/semver#working-with-prerelease-versions +Related Helm issue: https://github.com/helm/helm/issues/3810 */}} +{{- if and (or .Values.deployment.serviceAccount.create .Values.deployment.serviceAccount.name) (semverCompare "<1.20.0-0" .Capabilities.KubeVersion.Version) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "kong.serviceAccountTokenName" . }} + namespace: {{ template "kong.namespace" . }} + annotations: + kubernetes.io/service-account.name: {{ template "kong.serviceAccountName" . }} +type: kubernetes.io/service-account-token +{{- end }} diff --git a/charts/kong/kong/2.41.0/templates/service-account.yaml b/charts/kong/kong/2.41.0/templates/service-account.yaml new file mode 100644 index 0000000000..41ef6ace63 --- /dev/null +++ b/charts/kong/kong/2.41.0/templates/service-account.yaml @@ -0,0 +1,15 @@ +{{- if and (or .Values.deployment.kong.enabled .Values.ingressController.enabled) .Values.deployment.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "kong.serviceAccountName" . }} + namespace: {{ template "kong.namespace" . }} + {{- if .Values.deployment.serviceAccount.annotations }} + annotations: + {{- range $key, $value := .Values.deployment.serviceAccount.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} + labels: + {{- include "kong.metaLabels" . | nindent 4 }} +{{- end -}} diff --git a/charts/kong/kong/2.41.0/templates/service-kong-admin.yaml b/charts/kong/kong/2.41.0/templates/service-kong-admin.yaml new file mode 100644 index 0000000000..d005016530 --- /dev/null +++ b/charts/kong/kong/2.41.0/templates/service-kong-admin.yaml @@ -0,0 +1,113 @@ +{{- if .Values.deployment.kong.enabled }} +{{- if and .Values.admin.enabled (or .Values.admin.http.enabled .Values.admin.tls.enabled) -}} +{{- $serviceConfig := dict -}} +{{- $serviceConfig := merge $serviceConfig .Values.admin -}} +{{- $_ := set $serviceConfig "ingressVersion" (include "kong.ingressVersion" .) -}} +{{- $_ := set $serviceConfig "fullName" (include "kong.fullname" .) -}} +{{- $_ := set $serviceConfig "namespace" (include "kong.namespace" .) -}} +{{- $_ := set $serviceConfig "metaLabels" (include "kong.metaLabels" .) -}} +{{- $_ := set $serviceConfig "selectorLabels" (include "kong.selectorLabels" .) -}} +{{- $_ := set $serviceConfig "serviceName" "admin" -}} +{{- include "kong.service" $serviceConfig }} +{{ if .Values.admin.ingress.enabled }} +--- +{{ include "kong.ingress" $serviceConfig }} +{{- end -}} +{{- end -}} +{{- end -}} + +{{- define "adminApiService.certSecretName" -}} + {{- default (printf "%s-admin-api-keypair" (include "kong.fullname" .)) .Values.ingressController.adminApi.tls.client.secretName -}} +{{- end -}} + +{{- define "adminApiService.caSecretName" -}} + {{- default (printf "%s-admin-api-ca-keypair" (include "kong.fullname" .)) .Values.ingressController.adminApi.tls.client.caSecretName -}} +{{- end -}} + +{{- $clientVerifyEnabled := .Values.ingressController.adminApi.tls.client.enabled -}} +{{- $clientCertProvided := .Values.ingressController.adminApi.tls.client.certProvided -}} + +{{/* If the client verification is enabled but no secret was provided by the user, let's generate certificates. */ -}} +{{- if and $clientVerifyEnabled (not $clientCertProvided) }} +{{- $certCert := "" -}} +{{- $certKey := "" -}} + +{{- $cn := printf "admin.%s.svc" ( include "kong.namespace" . ) -}} +{{- $ca := genCA "admin-api-ca" 3650 -}} +{{- $cert := genSignedCert $cn nil (list $cn) 3650 $ca -}} + +{{- $certCert = $cert.Cert -}} +{{- $certKey = $cert.Key -}} +{{/* Verify whether a secret with a given name already exists. If it does, let's use its cert and key data. */}} +{{- $certSecret := (lookup "v1" "Secret" (include "kong.namespace" .) (include "adminApiService.certSecretName" .)) -}} +{{- if $certSecret }} +{{- $certCert = (b64dec (get $certSecret.data "tls.crt")) -}} +{{- $certKey = (b64dec (get $certSecret.data "tls.key")) -}} +{{- end }} + +{{- $caCert := $ca.Cert -}} +{{- $caKey := $ca.Key -}} +{{/* Verify whether a secret with a given name already exists. If it does, let's use its cert and key data. */ -}} +{{- $caSecret := (lookup "v1" "Secret" (include "kong.namespace" .) (include "adminApiService.caSecretName" .))}} +{{- if $caSecret }} +{{- $caCert = (b64dec (get $caSecret.data "tls.crt")) -}} +{{- $caKey = (b64dec (get $caSecret.data "tls.key")) -}} +{{- end }} + +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "adminApiService.certSecretName" . }} + namespace: {{ template "kong.namespace" . }} + labels: + {{- include "kong.metaLabels" . | nindent 4 }} +type: kubernetes.io/tls +data: + tls.crt: {{ b64enc $certCert }} + tls.key: {{ b64enc $certKey }} +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "adminApiService.caSecretName" . }} + namespace: {{ template "kong.namespace" . }} + labels: + {{- include "kong.metaLabels" . | nindent 4 }} +type: kubernetes.io/tls +data: + tls.crt: {{ b64enc $caCert }} + tls.key: {{ b64enc $caKey }} +{{- end }} + +{{- /* Create a CA ConfigMap for Kong. */ -}} +{{- $secretProvided := $.Values.admin.tls.client.secretName -}} +{{- $bundleProvided := $.Values.admin.tls.client.caBundle -}} + +{{- if or $secretProvided $bundleProvided -}} +{{- $cert := "" -}} + +{{- if $secretProvided -}} +{{- $certSecret := (lookup "v1" "Secret" (include "kong.namespace" .) $.Values.admin.tls.client.secretName) -}} +{{- if $certSecret }} +{{- $cert = (b64dec (get $certSecret.data "tls.crt")) -}} +{{- else -}} +{{- fail (printf "%s/%s secret not found" (include "kong.namespace" .) $.Values.admin.tls.client.secretName) -}} +{{- end }} +{{- end }} + +{{- if $bundleProvided -}} +{{- $cert = $.Values.admin.tls.client.caBundle -}} +{{- end }} + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "kong.fullname" . }}-admin-client-ca + namespace: {{ template "kong.namespace" . }} + labels: + {{- include "kong.metaLabels" . | nindent 4 }} +data: + tls.crt: {{ $cert | quote }} +{{- end -}} diff --git a/charts/kong/kong/2.41.0/templates/service-kong-cluster-telemetry.yaml b/charts/kong/kong/2.41.0/templates/service-kong-cluster-telemetry.yaml new file mode 100644 index 0000000000..b245bca946 --- /dev/null +++ b/charts/kong/kong/2.41.0/templates/service-kong-cluster-telemetry.yaml @@ -0,0 +1,17 @@ +{{- if .Values.deployment.kong.enabled }} +{{- if and .Values.clustertelemetry.enabled .Values.clustertelemetry.tls.enabled -}} +{{- $serviceConfig := dict -}} +{{- $serviceConfig := merge $serviceConfig .Values.clustertelemetry -}} +{{- $_ := set $serviceConfig "ingressVersion" (include "kong.ingressVersion" .) -}} +{{- $_ := set $serviceConfig "fullName" (include "kong.fullname" .) -}} +{{- $_ := set $serviceConfig "namespace" (include "kong.namespace" .) -}} +{{- $_ := set $serviceConfig "metaLabels" (include "kong.metaLabels" .) -}} +{{- $_ := set $serviceConfig "selectorLabels" (include "kong.selectorLabels" .) -}} +{{- $_ := set $serviceConfig "serviceName" "clustertelemetry" -}} +{{- include "kong.service" $serviceConfig }} +{{ if .Values.clustertelemetry.ingress.enabled }} +--- +{{ include "kong.ingress" $serviceConfig }} +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/charts/kong/kong/2.41.0/templates/service-kong-cluster.yaml b/charts/kong/kong/2.41.0/templates/service-kong-cluster.yaml new file mode 100644 index 0000000000..f4ef662965 --- /dev/null +++ b/charts/kong/kong/2.41.0/templates/service-kong-cluster.yaml @@ -0,0 +1,17 @@ +{{- if .Values.deployment.kong.enabled }} +{{- if and .Values.cluster.enabled .Values.cluster.tls.enabled -}} +{{- $serviceConfig := dict -}} +{{- $serviceConfig := merge $serviceConfig .Values.cluster -}} +{{- $_ := set $serviceConfig "ingressVersion" (include "kong.ingressVersion" .) -}} +{{- $_ := set $serviceConfig "fullName" (include "kong.fullname" .) -}} +{{- $_ := set $serviceConfig "namespace" (include "kong.namespace" .) -}} +{{- $_ := set $serviceConfig "metaLabels" (include "kong.metaLabels" .) -}} +{{- $_ := set $serviceConfig "selectorLabels" (include "kong.selectorLabels" .) -}} +{{- $_ := set $serviceConfig "serviceName" "cluster" -}} +{{- include "kong.service" $serviceConfig }} +{{ if .Values.cluster.ingress.enabled }} +--- +{{ include "kong.ingress" $serviceConfig }} +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/charts/kong/kong/2.41.0/templates/service-kong-manager.yaml b/charts/kong/kong/2.41.0/templates/service-kong-manager.yaml new file mode 100644 index 0000000000..e6732871b7 --- /dev/null +++ b/charts/kong/kong/2.41.0/templates/service-kong-manager.yaml @@ -0,0 +1,17 @@ +{{- if .Values.deployment.kong.enabled }} +{{- if and .Values.manager.enabled (or .Values.manager.http.enabled .Values.manager.tls.enabled) -}} +{{- $serviceConfig := dict -}} +{{- $serviceConfig := merge $serviceConfig .Values.manager -}} +{{- $_ := set $serviceConfig "ingressVersion" (include "kong.ingressVersion" .) -}} +{{- $_ := set $serviceConfig "fullName" (include "kong.fullname" .) -}} +{{- $_ := set $serviceConfig "namespace" (include "kong.namespace" .) -}} +{{- $_ := set $serviceConfig "metaLabels" (include "kong.metaLabels" .) -}} +{{- $_ := set $serviceConfig "selectorLabels" (include "kong.selectorLabels" .) -}} +{{- $_ := set $serviceConfig "serviceName" "manager" -}} +{{- include "kong.service" $serviceConfig }} +{{ if .Values.manager.ingress.enabled }} +--- +{{ include "kong.ingress" $serviceConfig }} +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/charts/kong/kong/2.41.0/templates/service-kong-portal-api.yaml b/charts/kong/kong/2.41.0/templates/service-kong-portal-api.yaml new file mode 100644 index 0000000000..710f201881 --- /dev/null +++ b/charts/kong/kong/2.41.0/templates/service-kong-portal-api.yaml @@ -0,0 +1,19 @@ +{{- if .Values.deployment.kong.enabled }} +{{- if .Values.enterprise.enabled }} +{{- if and .Values.portalapi.enabled (or .Values.portalapi.http.enabled .Values.portalapi.tls.enabled) -}} +{{- $serviceConfig := dict -}} +{{- $serviceConfig := merge $serviceConfig .Values.portalapi -}} +{{- $_ := set $serviceConfig "ingressVersion" (include "kong.ingressVersion" .) -}} +{{- $_ := set $serviceConfig "fullName" (include "kong.fullname" .) -}} +{{- $_ := set $serviceConfig "namespace" (include "kong.namespace" .) -}} +{{- $_ := set $serviceConfig "metaLabels" (include "kong.metaLabels" .) -}} +{{- $_ := set $serviceConfig "selectorLabels" (include "kong.selectorLabels" .) -}} +{{- $_ := set $serviceConfig "serviceName" "portalapi" -}} +{{- include "kong.service" $serviceConfig }} +{{ if .Values.portalapi.ingress.enabled }} +--- +{{ include "kong.ingress" $serviceConfig }} +{{- end -}} +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/charts/kong/kong/2.41.0/templates/service-kong-portal.yaml b/charts/kong/kong/2.41.0/templates/service-kong-portal.yaml new file mode 100644 index 0000000000..0be4b09b8e --- /dev/null +++ b/charts/kong/kong/2.41.0/templates/service-kong-portal.yaml @@ -0,0 +1,19 @@ +{{- if .Values.deployment.kong.enabled }} +{{- if .Values.enterprise.enabled }} +{{- if and .Values.portal.enabled (or .Values.portal.http.enabled .Values.portal.tls.enabled) -}} +{{- $serviceConfig := dict -}} +{{- $serviceConfig := merge $serviceConfig .Values.portal -}} +{{- $_ := set $serviceConfig "ingressVersion" (include "kong.ingressVersion" .) -}} +{{- $_ := set $serviceConfig "fullName" (include "kong.fullname" .) -}} +{{- $_ := set $serviceConfig "namespace" (include "kong.namespace" .) -}} +{{- $_ := set $serviceConfig "metaLabels" (include "kong.metaLabels" .) -}} +{{- $_ := set $serviceConfig "selectorLabels" (include "kong.selectorLabels" .) -}} +{{- $_ := set $serviceConfig "serviceName" "portal" -}} +{{- include "kong.service" $serviceConfig }} +{{ if .Values.portal.ingress.enabled }} +--- +{{ include "kong.ingress" $serviceConfig }} +{{- end -}} +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/charts/kong/kong/2.41.0/templates/service-kong-proxy.yaml b/charts/kong/kong/2.41.0/templates/service-kong-proxy.yaml new file mode 100644 index 0000000000..58a255ea22 --- /dev/null +++ b/charts/kong/kong/2.41.0/templates/service-kong-proxy.yaml @@ -0,0 +1,16 @@ +{{- if .Values.deployment.kong.enabled }} +{{- if and .Values.proxy.enabled (or .Values.proxy.http.enabled .Values.proxy.tls.enabled) -}} +{{- $serviceConfig := dict -}} +{{- $serviceConfig := merge $serviceConfig .Values.proxy -}} +{{- $_ := set $serviceConfig "fullName" (include "kong.fullname" .) -}} +{{- $_ := set $serviceConfig "namespace" (include "kong.namespace" .) -}} +{{- $_ := set $serviceConfig "metaLabels" (include "kong.metaLabels" .) -}} +{{- $_ := set $serviceConfig "selectorLabels" (include "kong.selectorLabels" .) -}} +{{- $_ := set $serviceConfig "serviceName" "proxy" -}} +{{- include "kong.service" $serviceConfig }} +{{ if .Values.proxy.ingress.enabled }} +--- +{{ include "kong.ingress" $serviceConfig }} +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/charts/kong/kong/2.41.0/templates/service-kong-udp-proxy.yaml b/charts/kong/kong/2.41.0/templates/service-kong-udp-proxy.yaml new file mode 100644 index 0000000000..bb25c5d74e --- /dev/null +++ b/charts/kong/kong/2.41.0/templates/service-kong-udp-proxy.yaml @@ -0,0 +1,15 @@ +{{- if .Values.deployment.kong.enabled }} +{{- if and .Values.udpProxy.enabled -}} +{{- $serviceConfig := dict -}} +{{- $serviceConfig := merge $serviceConfig .Values.udpProxy -}} +{{- $_ := set $serviceConfig "ingressVersion" (include "kong.ingressVersion" .) -}} +{{- $_ := set $serviceConfig "fullName" (include "kong.fullname" .) -}} +{{- $_ := set $serviceConfig "namespace" (include "kong.namespace" .) -}} +{{- $_ := set $serviceConfig "metaLabels" (include "kong.metaLabels" .) -}} +{{- $_ := set $serviceConfig "selectorLabels" (include "kong.selectorLabels" .) -}} +{{- $_ := set $serviceConfig "serviceName" "udp-proxy" -}} +{{- $_ := set $serviceConfig "tls" (dict "enabled" false) -}} +{{- $_ := set $serviceConfig "http" (dict "enabled" false) -}} +{{- include "kong.service" $serviceConfig }} +{{- end -}} +{{- end -}} diff --git a/charts/kong/kong/2.41.0/templates/servicemonitor.yaml b/charts/kong/kong/2.41.0/templates/servicemonitor.yaml new file mode 100644 index 0000000000..6e1f3abb06 --- /dev/null +++ b/charts/kong/kong/2.41.0/templates/servicemonitor.yaml @@ -0,0 +1,57 @@ +{{- if and ( .Capabilities.APIVersions.Has "monitoring.coreos.com/v1" ) .Values.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "kong.fullname" . }} + {{- if .Values.serviceMonitor.namespace }} + namespace: {{ .Values.serviceMonitor.namespace }} + {{- end }} + labels: + {{- include "kong.metaLabels" . | nindent 4 }} + {{- if .Values.serviceMonitor.labels }} + {{ toYaml .Values.serviceMonitor.labels | nindent 4 }} + {{- end }} +spec: + endpoints: + - targetPort: status + scheme: http + {{- if .Values.serviceMonitor.interval }} + interval: {{ .Values.serviceMonitor.interval }} + {{- end }} + {{- if .Values.serviceMonitor.honorLabels }} + honorLabels: true + {{- end }} + {{- if .Values.serviceMonitor.metricRelabelings }} + metricRelabelings: {{ toYaml .Values.serviceMonitor.metricRelabelings | nindent 6 }} + {{- end }} + {{- if .Values.serviceMonitor.relabelings }} + relabelings: {{ toYaml .Values.serviceMonitor.relabelings | nindent 6 }} + {{- end }} + {{- if and .Values.ingressController.enabled (semverCompare ">= 2.0.0" (include "kong.effectiveVersion" .Values.ingressController.image)) }} + - targetPort: cmetrics + scheme: http + {{- if .Values.serviceMonitor.interval }} + interval: {{ .Values.serviceMonitor.interval }} + {{- end }} + {{- if .Values.serviceMonitor.honorLabels }} + honorLabels: true + {{- end }} + {{- if .Values.serviceMonitor.metricRelabelings }} + metricRelabelings: {{ toYaml .Values.serviceMonitor.metricRelabelings | nindent 6 }} + {{- end }} + {{- if .Values.serviceMonitor.relabelings }} + relabelings: {{ toYaml .Values.serviceMonitor.relabelings | nindent 6 }} + {{- end }} + {{- end }} + jobLabel: {{ .Release.Name }} + namespaceSelector: + matchNames: + - {{ template "kong.namespace" . }} + selector: + matchLabels: + enable-metrics: "true" + {{- include "kong.metaLabels" . | nindent 6 }} + {{- if .Values.serviceMonitor.targetLabels }} + targetLabels: {{ toYaml .Values.serviceMonitor.targetLabels | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/kong/kong/2.41.0/templates/wait-for-postgres-script.yaml b/charts/kong/kong/2.41.0/templates/wait-for-postgres-script.yaml new file mode 100644 index 0000000000..67d2e8fc6a --- /dev/null +++ b/charts/kong/kong/2.41.0/templates/wait-for-postgres-script.yaml @@ -0,0 +1,15 @@ +{{ if (and (.Values.postgresql.enabled) .Values.waitImage.enabled) }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "kong.fullname" . }}-bash-wait-for-postgres + namespace: {{ template "kong.namespace" . }} + labels: + {{- include "kong.metaLabels" . | nindent 4 }} +data: + wait.sh: | + until timeout 2 bash -c "9<>/dev/tcp/${KONG_PG_HOST}/${KONG_PG_PORT}" + do echo "waiting for db - trying ${KONG_PG_HOST}:${KONG_PG_PORT}" + sleep 2 + done +{{ end }} diff --git a/charts/kong/kong/2.41.0/values.yaml b/charts/kong/kong/2.41.0/values.yaml new file mode 100644 index 0000000000..2f18a52511 --- /dev/null +++ b/charts/kong/kong/2.41.0/values.yaml @@ -0,0 +1,1264 @@ +# Default values for Kong's Helm Chart. +# Declare variables to be passed into your templates. +# +# Sections: +# - Deployment parameters +# - Kong parameters +# - Ingress Controller parameters +# - Postgres sub-chart parameters +# - Miscellaneous parameters +# - Kong Enterprise parameters + +# ----------------------------------------------------------------------------- +# Deployment parameters +# ----------------------------------------------------------------------------- + +deployment: + kong: + # Enable or disable Kong itself + # Setting this to false with ingressController.enabled=true will create a + # controller-only release. + enabled: true + # The number of old `ReplicaSet`s to retain. + revisionHistoryLimit: 10 + + ## Minimum number of seconds for which a newly created pod should be ready without any of its container crashing, + ## for it to be considered available. + # minReadySeconds: 60 + ## Specify the service account to create and to be assigned to the deployment / daemonset and for the migrations + serviceAccount: + create: true + # Automount the service account token. By default, this is disabled, and the token is only mounted on the controller + # container. Some sidecars require enabling this. Note that enabling this exposes Kubernetes credentials to Kong + # Lua code, increasing potential attack surface. + automountServiceAccountToken: false + ## Optionally specify the name of the service account to create and the annotations to add. + # name: + # annotations: {} + + ## Optionally specify any extra sidecar containers to be included in the deployment + ## See https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#container-v1-core + # sidecarContainers: + # - name: sidecar + # image: sidecar:latest + # initContainers: + # - name: initcon + # image: initcon:latest + # hostAliases: + # - ip: "127.0.0.1" + # hostnames: + # - "foo.local" + # - "bar.local" + + ## Define any volumes and mounts you want present in the Kong proxy container + # userDefinedVolumes: + # - name: "volumeName" + # emptyDir: {} + # userDefinedVolumeMounts: + # - name: "volumeName" + # mountPath: "/opt/user/dir/mount" + test: + # Enable creation of test resources for use with "helm test" + enabled: false + # Use a DaemonSet controller instead of a Deployment controller + daemonset: false + hostNetwork: false + # Set the Deployment's spec.template.hostname field. + # This propagates to Kong API endpoints that report + # the hostname, such as the admin API root and hybrid mode + # /clustering/data-planes endpoint + hostname: "" + # kong_prefix empty dir size + prefixDir: + sizeLimit: 256Mi + # tmp empty dir size + tmpDir: + sizeLimit: 1Gi +# Override namepsace for Kong chart resources. By default, the chart creates resources in the release namespace. +# This may not be desirable when using this chart as a dependency. +# namespace: "example" + +# ----------------------------------------------------------------------------- +# Kong parameters +# ----------------------------------------------------------------------------- + +# Specify Kong configuration +# This chart takes all entries defined under `.env` and transforms them into into `KONG_*` +# environment variables for Kong containers. +# Their names here should match the names used in https://github.com/Kong/kong/blob/master/kong.conf.default +# See https://docs.konghq.com/latest/configuration also for additional details +# Values here take precedence over values from other sections of values.yaml, +# e.g. setting pg_user here will override the value normally set when postgresql.enabled +# is set below. In general, you should not set values here if they are set elsewhere. +env: + database: "off" + # the chart uses the traditional router (for Kong 3.x+) because the ingress + # controller generates traditional routes. if you do not use the controller, + # you may set this to "traditional_compatible" or "expressions" to use the new + # DSL-based router + router_flavor: "traditional" + nginx_worker_processes: "2" + proxy_access_log: /dev/stdout + admin_access_log: /dev/stdout + admin_gui_access_log: /dev/stdout + portal_api_access_log: /dev/stdout + proxy_error_log: /dev/stderr + admin_error_log: /dev/stderr + admin_gui_error_log: /dev/stderr + portal_api_error_log: /dev/stderr + prefix: /kong_prefix/ + +# This section is any customer specific environments variables that doesn't require KONG_ prefix. +# These custom environment variables are typicall used in custom plugins or serverless plugins to +# access environment specific credentials or tokens. +# Example as below, uncomment if required and add additional attributes as required. +# Note that these environment variables will only apply to the proxy and init container. The ingress-controller +# container has its own customEnv section. + +# customEnv: +# api_token: +# valueFrom: +# secretKeyRef: +# key: token +# name: api_key +# client_name: testClient + +# Load all ConfigMap or Secret keys as environment variables: +# https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#configure-all-key-value-pairs-in-a-configmap-as-container-environment-variables +envFrom: [] + +# This section can be used to configure some extra labels that will be added to each Kubernetes object generated. +extraLabels: {} + +# Specify Kong's Docker image and repository details here +image: + repository: kong + tag: "3.6" + # Kong Enterprise + # repository: kong/kong-gateway + # tag: "3.5" + + # Specify a semver version if your image tag is not one (e.g. "nightly") + effectiveSemver: + pullPolicy: IfNotPresent + ## Optionally specify an array of imagePullSecrets. + ## Secrets must be manually created in the namespace. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## + # pullSecrets: + # - myRegistrKeySecretName + +# Specify Kong admin API service and listener configuration +admin: + # Enable creating a Kubernetes service for the admin API + # Disabling this is recommended for most ingress controller configurations + # Enterprise users that wish to use Kong Manager with the controller should enable this + enabled: false + type: NodePort + loadBalancerClass: + # To specify annotations or labels for the admin service, add them to the respective + # "annotations" or "labels" dictionaries below. + annotations: {} + # service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: "*" + labels: {} + + http: + # Enable plaintext HTTP listen for the admin API + # Disabling this and using a TLS listen only is recommended for most configuration + enabled: false + servicePort: 8001 + containerPort: 8001 + # Set a nodePort which is available if service type is NodePort + # nodePort: 32080 + # Additional listen parameters, e.g. "reuseport", "backlog=16384" + parameters: [] + + tls: + # Enable HTTPS listen for the admin API + enabled: true + servicePort: 8444 + containerPort: 8444 + # Set a target port for the TLS port in the admin API service, useful when using TLS + # termination on an ELB. + # overrideServiceTargetPort: 8000 + # Set a nodePort which is available if service type is NodePort + # nodePort: 32443 + # Additional listen parameters, e.g. "reuseport", "backlog=16384" + parameters: + - http2 + + # Specify the CA certificate to use for TLS verification of the Admin API client by: + # - secretName - the secret must contain a key named "tls.crt" with the PEM-encoded certificate. + # - caBundle (PEM-encoded certificate string). + # If both are set, caBundle takes precedence. + client: + caBundle: "" + secretName: "" + + # Kong admin ingress settings. Useful if you want to expose the Admin + # API of Kong outside the k8s cluster. + ingress: + # Enable/disable exposure using ingress. + enabled: false + ingressClassName: + # TLS secret name. + # tls: kong-admin.example.com-tls + # Ingress hostname + hostname: + # Map of ingress annotations. + annotations: {} + # Ingress path. + path: / + # Each path in an Ingress is required to have a corresponding path type. (ImplementationSpecific/Exact/Prefix) + pathType: ImplementationSpecific + +# Specify Kong status listener configuration +# This listen is internal-only. It cannot be exposed through a service or ingress. +status: + enabled: true + http: + # Enable plaintext HTTP listen for the status listen + enabled: true + containerPort: 8100 + parameters: [] + + tls: + # Enable HTTPS listen for the status listen + # Kong versions prior to 2.1 do not support TLS status listens. + # This setting must remain false on those versions + enabled: false + containerPort: 8543 + parameters: [] + +# Name the kong hybrid cluster CA certificate secret +clusterCaSecretName: "" + +# Specify Kong cluster service and listener configuration +# +# The cluster service *must* use TLS. It does not support the "http" block +# available on other services. +# +# The cluster service cannot be exposed through an Ingress, as it must perform +# TLS client validation directly and is not compatible with TLS-terminating +# proxies. If you need to expose it externally, you must use "type: +# LoadBalancer" and use a TCP-only load balancer (check your Kubernetes +# provider's documentation, as the configuration required for this varies). +cluster: + enabled: false + # To specify annotations or labels for the cluster service, add them to the respective + # "annotations" or "labels" dictionaries below. + annotations: {} + # service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: "*" + labels: {} + + tls: + enabled: false + servicePort: 8005 + containerPort: 8005 + parameters: [] + + type: ClusterIP + loadBalancerClass: + + # Kong cluster ingress settings. Useful if you want to split CP and DP + # in different clusters. + ingress: + # Enable/disable exposure using ingress. + enabled: false + ingressClassName: + # TLS secret name. + # tls: kong-cluster.example.com-tls + # Ingress hostname + hostname: + # Map of ingress annotations. + annotations: {} + # Ingress path. + path: / + # Each path in an Ingress is required to have a corresponding path type. (ImplementationSpecific/Exact/Prefix) + pathType: ImplementationSpecific + +# Specify Kong proxy service configuration +proxy: + # Enable creating a Kubernetes service for the proxy + enabled: true + type: LoadBalancer + loadBalancerClass: + # Override proxy Service name + nameOverride: "" + # To specify annotations or labels for the proxy service, add them to the respective + # "annotations" or "labels" dictionaries below. + annotations: {} + # If terminating TLS at the ELB, the following annotations can be used + # "service.beta.kubernetes.io/aws-load-balancer-backend-protocol": "*", + # "service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled": "true", + # "service.beta.kubernetes.io/aws-load-balancer-ssl-cert": "arn:aws:acm:REGION:ACCOUNT:certificate/XXXXXX-XXXXXXX-XXXXXXX-XXXXXXXX", + # "service.beta.kubernetes.io/aws-load-balancer-ssl-ports": "kong-proxy-tls", + # "service.beta.kubernetes.io/aws-load-balancer-type": "elb" + labels: + enable-metrics: "true" + + http: + # Enable plaintext HTTP listen for the proxy + enabled: true + # Set the servicePort: 0 to skip exposing in the service but still + # let the port open in container to allow https to http mapping for + # tls terminated at LB. + servicePort: 80 + containerPort: 8000 + # Set a nodePort which is available if service type is NodePort + # nodePort: 32080 + # Additional listen parameters, e.g. "reuseport", "backlog=16384" + parameters: [] + + tls: + # Enable HTTPS listen for the proxy + enabled: true + servicePort: 443 + containerPort: 8443 + # Set a target port for the TLS port in proxy service + # overrideServiceTargetPort: 8000 + # Set a nodePort which is available if service type is NodePort + # nodePort: 32443 + # Additional listen parameters, e.g. "reuseport", "backlog=16384" + parameters: + - http2 + + # Specify the Service's TLS port's appProtocol. This can be useful when integrating with + # external load balancers that require the `appProtocol` field to be set (e.g. GCP). + appProtocol: "" + + # Define stream (TCP) listen + # To enable, remove "[]", uncomment the section below, and select your desired + # ports and parameters. Listens are dynamically named after their containerPort, + # e.g. "stream-9000" for the below. + # Note: although you can select the protocol here, you cannot set UDP if you + # use a LoadBalancer Service due to limitations in current Kubernetes versions. + # To proxy both TCP and UDP with LoadBalancers, you must enable the udpProxy Service + # in the next section and place all UDP stream listen configuration under it. + stream: [] + # # Set the container (internal) and service (external) ports for this listen. + # # These values should normally be the same. If your environment requires they + # # differ, note that Kong will match routes based on the containerPort only. + # - containerPort: 9000 + # servicePort: 9000 + # protocol: TCP + # # Optionally set a static nodePort if the service type is NodePort + # # nodePort: 32080 + # # Additional listen parameters, e.g. "ssl", "reuseport", "backlog=16384" + # # "ssl" is required for SNI-based routes. It is not supported on versions <2.0 + # parameters: [] + + # Kong proxy ingress settings. + # Note: You need this only if you are using another Ingress Controller + # to expose Kong outside the k8s cluster. + ingress: + # Enable/disable exposure using ingress. + enabled: false + ingressClassName: + # To specify annotations or labels for the ingress, add them to the respective + # "annotations" or "labels" dictionaries below. + annotations: {} + labels: {} + # Ingress hostname + hostname: + # Ingress path (when used with hostname above). + path: / + # Each path in an Ingress is required to have a corresponding path type (when used with hostname above). (ImplementationSpecific/Exact/Prefix) + pathType: ImplementationSpecific + # Ingress hosts. Use this instead of or in combination with hostname to specify multiple ingress host configurations + hosts: [] + # - host: kong-proxy.example.com + # paths: + # # Ingress path. + # - path: /* + # # Each path in an Ingress is required to have a corresponding path type. (ImplementationSpecific/Exact/Prefix) + # pathType: ImplementationSpecific + # - host: kong-proxy-other.example.com + # paths: + # # Ingress path. + # - path: /other + # # Each path in an Ingress is required to have a corresponding path type. (ImplementationSpecific/Exact/Prefix) + # pathType: ImplementationSpecific + # backend: + # service: + # name: kong-other-proxy + # port: + # number: 80 + # + # TLS secret(s) + # tls: kong-proxy.example.com-tls + # Or if multiple hosts/secrets needs to be configured: + # tls: + # - secretName: kong-proxy.example.com-tls + # hosts: + # - kong-proxy.example.com + # - secretName: kong-proxy-other.example.com-tls + # hosts: + # - kong-proxy-other.example.com + + # Optionally specify a static load balancer IP. + # loadBalancerIP: + +# Specify Kong UDP proxy service configuration +# Currently, LoadBalancer type Services are generally limited to a single transport protocol +# Multi-protocol Services are an alpha feature as of Kubernetes 1.20: +# https://kubernetes.io/docs/concepts/services-networking/service/#load-balancers-with-mixed-protocol-types +# You should enable this Service if you proxy UDP traffic, and configure UDP stream listens under it +udpProxy: + # Enable creating a Kubernetes service for UDP proxying + enabled: false + type: LoadBalancer + loadBalancerClass: + # To specify annotations or labels for the proxy service, add them to the respective + # "annotations" or "labels" dictionaries below. + annotations: {} + # service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: "*" + labels: {} + # Optionally specify a static load balancer IP. + # loadBalancerIP: + + # Define stream (UDP) listen + # To enable, remove "[]", uncomment the section below, and select your desired + # ports and parameters. Listens are dynamically named after their servicePort, + # e.g. "stream-9000" for the below. + stream: [] + # # Set the container (internal) and service (external) ports for this listen. + # # These values should normally be the same. If your environment requires they + # # differ, note that Kong will match routes based on the containerPort only. + # - containerPort: 9000 + # servicePort: 9000 + # protocol: UDP + # # Optionally set a static nodePort if the service type is NodePort + # # nodePort: 32080 + # # Additional listen parameters, e.g. "ssl", "reuseport", "backlog=16384" + # # "ssl" is required for SNI-based routes. It is not supported on versions <2.0 + # parameters: [] + +# Custom Kong plugins can be loaded into Kong by mounting the plugin code +# into the file-system of Kong container. +# The plugin code should be present in ConfigMap or Secret inside the same +# namespace as Kong is being installed. +# The `name` property refers to the name of the ConfigMap or Secret +# itself, while the pluginName refers to the name of the plugin as it appears +# in Kong. +# Subdirectories (which are optional) require separate ConfigMaps/Secrets. +# "path" indicates their directory under the main plugin directory: the example +# below will mount the contents of kong-plugin-rewriter-migrations at "/opt/kong/rewriter/migrations". +plugins: {} + # configMaps: + # - pluginName: rewriter + # name: kong-plugin-rewriter + # subdirectories: + # - name: kong-plugin-rewriter-migrations + # path: migrations + # secrets: + # - pluginName: rewriter + # name: kong-plugin-rewriter +# Inject specified secrets as a volume in Kong Container at path /etc/secrets/{secret-name}/ +# This can be used to override default SSL certificates. +# Be aware that the secret name will be used verbatim, and that certain types +# of punctuation (e.g. `.`) can cause issues. +# Example configuration +# secretVolumes: +# - kong-proxy-tls +# - kong-admin-tls +secretVolumes: [] + +# Enable/disable migration jobs, and set annotations for them +migrations: + # Enable pre-upgrade migrations (run "kong migrations up") + preUpgrade: true + # Enable post-upgrade migrations (run "kong migrations finish") + postUpgrade: true + # Annotations to apply to migrations job pods + # By default, these disable service mesh sidecar injection for Istio and Kuma, + # as the sidecar containers do not terminate and prevent the jobs from completing + annotations: + sidecar.istio.io/inject: false + # Additional annotations to apply to migration jobs + # This is helpful in certain non-Helm installation situations such as GitOps + # where additional control is required around this job creation. + jobAnnotations: {} + # Optionally set a backoffLimit. If none is set, Jobs will use the cluster default + backoffLimit: + resources: {} + # Example reasonable setting for "resources": + # resources: + # limits: + # cpu: 100m + # memory: 256Mi + # requests: + # cpu: 50m + # memory: 128Mi + ## Optionally specify any extra sidecar containers to be included in the deployment + ## See https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#container-v1-core + ## Keep in mind these containers should be terminated along with the main + ## migration containers + # sidecarContainers: + # - name: sidecar + # image: sidecar:latest + +# Kong's configuration for DB-less mode +# Note: Use this section only if you are deploying Kong in DB-less mode +# and not as an Ingress Controller. +dblessConfig: + # Either Kong's configuration is managed from an existing ConfigMap (with Key: kong.yml) + configMap: "" + # Or Kong's configuration is managed from an existing Secret (with Key: kong.yml) + secret: "" + # Or the configuration is passed in full-text below + config: | + # # _format_version: "1.1" + # # services: + # # # Example configuration + # # # - name: example.com + # # # url: http://example.com + # # # routes: + # # # - name: example + # # # paths: + # # # - "/example" + ## Optionally specify any extra sidecar containers to be included in the + ## migration jobs + ## See https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#container-v1-core + # sidecarContainers: + # - name: sidecar + # image: sidecar:latest + +# ----------------------------------------------------------------------------- +# Ingress Controller parameters +# ----------------------------------------------------------------------------- + +# Kong Ingress Controller's primary purpose is to satisfy Ingress resources +# created in k8s. It uses CRDs for more fine grained control over routing and +# for Kong specific configuration. +ingressController: + enabled: true + image: + repository: kong/kubernetes-ingress-controller + tag: "3.3" + # Optionally set a semantic version for version-gated features. This can normally + # be left unset. You only need to set this if your tag is not a semver string, + # such as when you are using a "next" tag. Set this to the effective semantic + # version of your tag: for example if using a "next" image for an unreleased 3.1.0 + # version, set this to "3.1.0". + effectiveSemver: + args: [] + + gatewayDiscovery: + enabled: false + generateAdminApiService: false + adminApiService: + namespace: "" + name: "" + + # Specify individual namespaces to watch for ingress configuration. By default, + # when no namespaces are set, the controller watches all namespaces and uses a + # ClusterRole to grant access to Kubernetes resources. When you list specific + # namespaces, the controller will watch those namespaces only and will create + # namespaced-scoped Roles for each of them. The controller will still use a + # ClusterRole for cluster-scoped resources. + # Requires controller 2.0.0 or newer. + watchNamespaces: [] + + # Specify Kong Ingress Controller configuration via environment variables + env: + # The controller disables TLS verification by default because Kong + # generates self-signed certificates by default. Set this to false once you + # have installed CA-signed certificates. + kong_admin_tls_skip_verify: true + # If using Kong Enterprise with RBAC enabled, uncomment the section below + # and specify the secret/key containing your admin token. + # kong_admin_token: + # valueFrom: + # secretKeyRef: + # name: CHANGEME-admin-token-secret + # key: CHANGEME-admin-token-key + + # This section is any customer specific environments variables that doesn't require CONTROLLER_ prefix. + # Example as below, uncomment if required and add additional attributes as required. + # customEnv: + # TZ: "Europe/Berlin" + + # Load all ConfigMap or Secret keys as environment variables: + # https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#configure-all-key-value-pairs-in-a-configmap-as-container-environment-variables + envFrom: [] + + admissionWebhook: + enabled: true + filterSecrets: false + failurePolicy: Ignore + port: 8080 + certificate: + provided: false + namespaceSelector: {} + # Specifiy the secretName when the certificate is provided via a TLS secret + # secretName: "" + # Specifiy the CA bundle of the provided certificate. + # This is a PEM encoded CA bundle which will be used to validate the webhook certificate. If unspecified, system trust roots on the apiserver are used. + # caBundle: + # | Add the CA bundle content here. + service: + # Specify custom labels for the validation webhook service. + labels: {} + # Tune the default Kubernetes timeoutSeconds of 10 seconds + # timeoutSeconds: 10 + + ingressClass: kong + # annotations for IngressClass resource (Kubernetes 1.18+) + ingressClassAnnotations: {} + + ## Define any volumes and mounts you want present in the ingress controller container + ## Volumes are defined above in deployment.userDefinedVolumes + # userDefinedVolumeMounts: + # - name: "volumeName" + # mountPath: "/opt/user/dir/mount" + + rbac: + # Specifies whether RBAC resources should be created + create: true + + # general properties + livenessProbe: + httpGet: + path: "/healthz" + port: 10254 + scheme: HTTP + initialDelaySeconds: 5 + timeoutSeconds: 5 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 3 + readinessProbe: + httpGet: + path: "/readyz" + port: 10254 + scheme: HTTP + initialDelaySeconds: 5 + timeoutSeconds: 5 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 3 + resources: {} + # Example reasonable setting for "resources": + # resources: + # limits: + # cpu: 100m + # memory: 256Mi + # requests: + # cpu: 50m + # memory: 128Mi + + konnect: + enabled: false + # Deprecated: Specifies a Konnect Runtime Group's ID that the controller will push its data-plane config to. + runtimeGroupID: "" + # Specifies a Konnect Control Plane's ID that the controller will push its data-plane config to. + controlPlaneID: "" + + # Specifies a Konnect API hostname that the controller will use to push its data-plane config to. + # By default, this is set to US region's production API hostname. + # If you are using a different region, you can set this to the appropriate hostname (e.g. "eu.kic.api.konghq.com"). + apiHostname: "us.kic.api.konghq.com" + + # Specifies a secret that contains a client TLS certificate that the controller + # will use to authenticate against Konnect APIs. + tlsClientCertSecretName: "konnect-client-tls" + + license: + # Specifies whether the controller should fetch a license from Konnect and apply it to managed Gateways. + enabled: false + + adminApi: + tls: + client: + # Enable TLS client authentication for the Admin API. + enabled: false + + # If set to false, Helm will generate certificates for you. + # If set to true, you are expected to provide your own secret (see secretName, caSecretName). + certProvided: false + + # Client TLS certificate/key pair secret name that Ingress Controller will use to authenticate with Kong Admin API. + # If certProvided is set to false, it is optional (can be specified though if you want to force Helm to use + # a specific secret name). + secretName: "" + + # CA TLS certificate/key pair secret name that the client TLS certificate is signed by. + # If certProvided is set to false, it is optional (can be specified though if you want to force Helm to use + # a specific secret name). + caSecretName: "" + + +# ----------------------------------------------------------------------------- +# Postgres sub-chart parameters +# ----------------------------------------------------------------------------- + +# Kong can run without a database or use either Postgres or Cassandra +# as a backend datatstore for it's configuration. +# By default, this chart installs Kong without a database. + +# If you would like to use a database, there are two options: +# - (recommended) Deploy and maintain a database and pass the connection +# details to Kong via the `env` section. +# - You can use the below `postgresql` sub-chart to deploy a database +# along-with Kong as part of a single Helm release. Running a database +# independently is recommended for production, but the built-in Postgres is +# useful for quickly creating test instances. + +# PostgreSQL chart documentation: +# https://github.com/bitnami/charts/blob/master/bitnami/postgresql/README.md +# +# WARNING: by default, the Postgres chart generates a random password each +# time it upgrades, which breaks access to existing volumes. You should set a +# password explicitly: +# https://github.com/Kong/charts/blob/main/charts/kong/FAQs.md#kong-fails-to-start-after-helm-upgrade-when-postgres-is-used-what-do-i-do + +postgresql: + enabled: false + auth: + username: kong + database: kong + image: + # use postgres < 14 until is https://github.com/Kong/kong/issues/8533 resolved and released + # enterprise (kong-gateway) supports postgres 14 + tag: 13.11.0-debian-11-r20 + service: + ports: + postgresql: "5432" + +# ----------------------------------------------------------------------------- +# Configure cert-manager integration +# ----------------------------------------------------------------------------- + +certificates: + enabled: false + + # Set either `issuer` or `clusterIssuer` to the name of the desired cert manager issuer + # If left blank a built in self-signed issuer will be created and utilized + issuer: "" + clusterIssuer: "" + + # Set proxy.enabled to true to issue default kong-proxy certificate with cert-manager + proxy: + enabled: true + # Set `issuer` or `clusterIssuer` to name of alternate cert-manager clusterIssuer to override default + # self-signed issuer. + issuer: "" + clusterIssuer: "" + # Use commonName and dnsNames to set the common name and dns alt names which this + # certificate is valid for. Wildcard records are supported by the included self-signed issuer. + commonName: "app.example" + # Remove the "[]" and uncomment/change the examples to add SANs + dnsNames: [] + # - "app.example" + # - "*.apps.example" + # - "*.kong.example" + + # Set admin.enabled true to issue kong admin api and manager certificate with cert-manager + admin: + enabled: true + # Set `issuer` or `clusterIssuer` to name of alternate cert-manager clusterIssuer to override default + # self-signed issuer. + issuer: "" + clusterIssuer: "" + # Use commonName and dnsNames to set the common name and dns alt names which this + # certificate is valid for. Wildcard records are supported by the included self-signed issuer. + commonName: "kong.example" + # Remove the "[]" and uncomment/change the examples to add SANs + dnsNames: [] + # - "manager.kong.example" + + # Set portal.enabled to true to issue a developer portal certificate with cert-manager + portal: + enabled: true + # Set `issuer` or `clusterIssuer` to name of alternate cert-manager clusterIssuer to override default + # self-signed issuer. + issuer: "" + clusterIssuer: "" + # Use commonName and dnsNames to set the common name and dns alt names which this + # certificate is valid for. Wildcard records are supported by the included self-signed issuer. + commonName: "developer.example" + # Remove the "{}" and uncomment/change the examples to add SANs + dnsNames: [] + # - "manager.kong.example" + + # Set cluster.enabled true to issue kong hybrid mtls certificate with cert-manager + cluster: + enabled: true + # Issuers used by the control and data plane releases must match for this certificate. + issuer: "" + clusterIssuer: "" + commonName: "kong_clustering" + dnsNames: [] + +# ----------------------------------------------------------------------------- +# Miscellaneous parameters +# ----------------------------------------------------------------------------- + +waitImage: + # Wait for the database to come online before starting Kong or running migrations + # If Kong is to access the database through a service mesh that injects a sidecar to + # Kong's container, this must be disabled. Otherwise there'll be a deadlock: + # InitContainer waiting for DB access that requires the sidecar, and the sidecar + # waiting for InitContainers to finish. + enabled: true + # Optionally specify an image that provides bash for pre-migration database + # checks. If none is specified, the chart uses the Kong image. The official + # Kong images provide bash + # repository: bash + # tag: 5 + pullPolicy: IfNotPresent + +# update strategy +updateStrategy: {} + # type: RollingUpdate + # rollingUpdate: + # maxSurge: "100%" + # maxUnavailable: "0%" + +# If you want to specify resources, uncomment the following +# lines, adjust them as necessary, and remove the curly braces after 'resources:'. +resources: {} + # limits: + # cpu: 1 + # memory: 2G + # requests: + # cpu: 1 + # memory: 2G + +# readinessProbe for Kong pods +readinessProbe: + httpGet: + path: "/status/ready" + port: status + scheme: HTTP + initialDelaySeconds: 5 + timeoutSeconds: 5 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 3 + +# livenessProbe for Kong pods +livenessProbe: + httpGet: + path: "/status" + port: status + scheme: HTTP + initialDelaySeconds: 5 + timeoutSeconds: 5 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 3 + +# startupProbe for Kong pods +# startupProbe: +# httpGet: +# path: "/status" +# port: status +# scheme: HTTP +# initialDelaySeconds: 5 +# timeoutSeconds: 5 +# periodSeconds: 2 +# successThreshold: 1 +# failureThreshold: 40 + +# Proxy container lifecycle hooks +# Ref: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/ +lifecycle: + preStop: + exec: + # kong quit has a default timeout of 10 seconds, and a default wait of 0 seconds. + # Note: together they should be less than the terminationGracePeriodSeconds setting below. + command: + - kong + - quit + - '--wait=15' + +# Sets the termination grace period for pods spawned by the Kubernetes Deployment. +# Ref: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#hook-handler-execution +terminationGracePeriodSeconds: 30 + +# Affinity for pod assignment +# Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity +# affinity: {} + +# Topology spread constraints for pod assignment (requires Kubernetes >= 1.19) +# Ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ +# topologySpreadConstraints: [] + +# Tolerations for pod assignment +# Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +tolerations: [] + +# Node labels for pod assignment +# Ref: https://kubernetes.io/docs/user-guide/node-selection/ +nodeSelector: {} + +# Annotation to be added to Kong pods +podAnnotations: + kuma.io/gateway: enabled + traffic.sidecar.istio.io/includeInboundPorts: "" + +# Labels to be added to Kong pods +podLabels: {} + +# Kong pod count. +# It has no effect when autoscaling.enabled is set to true +replicaCount: 1 + +# Annotations to be added to Kong deployment +deploymentAnnotations: {} + +# Enable autoscaling using HorizontalPodAutoscaler +# When configuring an HPA, you must set resource requests on all containers via +# "resources" and, if using the controller, "ingressController.resources" in values.yaml +autoscaling: + enabled: false + minReplicas: 2 + maxReplicas: 5 + behavior: {} + ## targetCPUUtilizationPercentage only used if the cluster doesn't support autoscaling/v2 or autoscaling/v2beta + targetCPUUtilizationPercentage: + ## Otherwise for clusters that do support autoscaling/v2 or autoscaling/v2beta, use metrics + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 80 + +# Kong Pod Disruption Budget +podDisruptionBudget: + enabled: false + # Uncomment only one of the following when enabled is set to true + # maxUnavailable: "50%" + # minAvailable: "50%" + +podSecurityPolicy: + enabled: false + labels: {} + annotations: {} + spec: + privileged: false + fsGroup: + rule: RunAsAny + runAsUser: + rule: RunAsAny + runAsGroup: + rule: RunAsAny + seLinux: + rule: RunAsAny + supplementalGroups: + rule: RunAsAny + volumes: + - 'configMap' + - 'secret' + - 'emptyDir' + - 'projected' + allowPrivilegeEscalation: false + hostNetwork: false + hostIPC: false + hostPID: false + # Make the root filesystem read-only. This is not compatible with Kong Enterprise <1.5. + # If you use Kong Enterprise <1.5, this must be set to false. + readOnlyRootFilesystem: true + + +priorityClassName: "" + +# securityContext for Kong pods. +securityContext: {} + +# securityContext for containers. +containerSecurityContext: + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + runAsUser: 1000 + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + capabilities: + drop: + - ALL + +## Optional DNS configuration for Kong pods +# dnsPolicy: ClusterFirst +# dnsConfig: +# nameservers: +# - "10.100.0.10" +# options: +# - name: ndots +# value: "5" +# searches: +# - default.svc.cluster.local +# - svc.cluster.local +# - cluster.local +# - us-east-1.compute.internal + +serviceMonitor: + # Specifies whether ServiceMonitor for Prometheus operator should be created + # If you wish to gather metrics from a Kong instance with the proxy disabled (such as a hybrid control plane), see: + # https://github.com/Kong/charts/blob/main/charts/kong/README.md#prometheus-operator-integration + enabled: false + # interval: 30s + # Specifies namespace, where ServiceMonitor should be installed + # namespace: monitoring + # labels: + # foo: bar + # targetLabels: + # - foo + + # honorLabels: false + # metricRelabelings: [] + # relabelings: [] + +# ----------------------------------------------------------------------------- +# Kong Enterprise parameters +# ----------------------------------------------------------------------------- + +# Toggle Kong Enterprise features on or off +# RBAC and SMTP configuration have additional options that must all be set together +# Other settings should be added to the "env" settings below +enterprise: + enabled: false + # Kong Enterprise license secret name + # This secret must contain a single 'license' key, containing your base64-encoded license data + # The license secret is required to unlock all Enterprise features. If you omit it, + # Kong will run in free mode, with some Enterprise features disabled. + # license_secret: kong-enterprise-license + vitals: + enabled: true + portal: + enabled: false + rbac: + enabled: false + admin_gui_auth: basic-auth + # If RBAC is enabled, this Secret must contain an admin_gui_session_conf key + # The key value must be a secret configuration, following the example at + # https://docs.konghq.com/enterprise/latest/kong-manager/authentication/sessions + # If using 3.6+ and OIDC, session configuration is instead handled in the auth configuration, + # and this field can be left empty. + session_conf_secret: "kong-session-config" # CHANGEME + # If admin_gui_auth is not set to basic-auth, provide a secret name which + # has an admin_gui_auth_conf key containing the plugin config JSON + admin_gui_auth_conf_secret: CHANGEME-admin-gui-auth-conf-secret + # For configuring emails and SMTP, please read through: + # https://docs.konghq.com/enterprise/latest/developer-portal/configuration/smtp + # https://docs.konghq.com/enterprise/latest/kong-manager/networking/email + smtp: + enabled: false + portal_emails_from: none@example.com + portal_emails_reply_to: none@example.com + admin_emails_from: none@example.com + admin_emails_reply_to: none@example.com + smtp_admin_emails: none@example.com + smtp_host: smtp.example.com + smtp_port: 587 + smtp_auth_type: '' + smtp_ssl: nil + smtp_starttls: true + auth: + # If your SMTP server does not require authentication, this section can + # be left as-is. If smtp_username is set to anything other than an empty + # string, you must create a Secret with an smtp_password key containing + # your SMTP password and specify its name here. + smtp_username: '' # e.g. postmaster@example.com + smtp_password_secret: CHANGEME-smtp-password + +manager: + # Enable creating a Kubernetes service for Kong Manager + enabled: true + type: NodePort + loadBalancerClass: + # To specify annotations or labels for the Manager service, add them to the respective + # "annotations" or "labels" dictionaries below. + annotations: {} + # service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: "*" + labels: {} + + http: + # Enable plaintext HTTP listen for Kong Manager + enabled: true + servicePort: 8002 + containerPort: 8002 + # Set a nodePort which is available if service type is NodePort + # nodePort: 32080 + # Additional listen parameters, e.g. "reuseport", "backlog=16384" + parameters: [] + + tls: + # Enable HTTPS listen for Kong Manager + enabled: true + servicePort: 8445 + containerPort: 8445 + # Set a nodePort which is available if service type is NodePort + # nodePort: 32443 + # Additional listen parameters, e.g. "reuseport", "backlog=16384" + parameters: + - http2 + + ingress: + # Enable/disable exposure using ingress. + enabled: false + ingressClassName: + # TLS secret name. + # tls: kong-manager.example.com-tls + # Ingress hostname + hostname: + # Map of ingress annotations. + annotations: {} + # Ingress path. + path: / + # Each path in an Ingress is required to have a corresponding path type. (ImplementationSpecific/Exact/Prefix) + pathType: ImplementationSpecific + +portal: + # Enable creating a Kubernetes service for the Developer Portal + enabled: true + type: NodePort + loadBalancerClass: + # To specify annotations or labels for the Portal service, add them to the respective + # "annotations" or "labels" dictionaries below. + annotations: {} + # service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: "*" + labels: {} + + http: + # Enable plaintext HTTP listen for the Developer Portal + enabled: true + servicePort: 8003 + containerPort: 8003 + # Set a nodePort which is available if service type is NodePort + # nodePort: 32080 + # Additional listen parameters, e.g. "reuseport", "backlog=16384" + parameters: [] + + tls: + # Enable HTTPS listen for the Developer Portal + enabled: true + servicePort: 8446 + containerPort: 8446 + # Set a nodePort which is available if service type is NodePort + # nodePort: 32443 + # Additional listen parameters, e.g. "reuseport", "backlog=16384" + parameters: + - http2 + + ingress: + # Enable/disable exposure using ingress. + enabled: false + ingressClassName: + # TLS secret name. + # tls: kong-portal.example.com-tls + # Ingress hostname + hostname: + # Map of ingress annotations. + annotations: {} + # Ingress path. + path: / + # Each path in an Ingress is required to have a corresponding path type. (ImplementationSpecific/Exact/Prefix) + pathType: ImplementationSpecific + +portalapi: + # Enable creating a Kubernetes service for the Developer Portal API + enabled: true + type: NodePort + loadBalancerClass: + # To specify annotations or labels for the Portal API service, add them to the respective + # "annotations" or "labels" dictionaries below. + annotations: {} + # service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: "*" + labels: {} + + http: + # Enable plaintext HTTP listen for the Developer Portal API + enabled: true + servicePort: 8004 + containerPort: 8004 + # Set a nodePort which is available if service type is NodePort + # nodePort: 32080 + # Additional listen parameters, e.g. "reuseport", "backlog=16384" + parameters: [] + + tls: + # Enable HTTPS listen for the Developer Portal API + enabled: true + servicePort: 8447 + containerPort: 8447 + # Set a nodePort which is available if service type is NodePort + # nodePort: 32443 + # Additional listen parameters, e.g. "reuseport", "backlog=16384" + parameters: + - http2 + + ingress: + # Enable/disable exposure using ingress. + enabled: false + ingressClassName: + # TLS secret name. + # tls: kong-portalapi.example.com-tls + # Ingress hostname + hostname: + # Map of ingress annotations. + annotations: {} + # Ingress path. + path: / + # Each path in an Ingress is required to have a corresponding path type. (ImplementationSpecific/Exact/Prefix) + pathType: ImplementationSpecific + +clustertelemetry: + enabled: false + # To specify annotations or labels for the cluster telemetry service, add them to the respective + # "annotations" or "labels" dictionaries below. + annotations: {} + # service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: "*" + labels: {} + + tls: + enabled: false + servicePort: 8006 + containerPort: 8006 + parameters: [] + + type: ClusterIP + loadBalancerClass: + + # Kong clustertelemetry ingress settings. Useful if you want to split + # CP and DP in different clusters. + ingress: + # Enable/disable exposure using ingress. + enabled: false + ingressClassName: + # TLS secret name. + # tls: kong-clustertelemetry.example.com-tls + # Ingress hostname + hostname: + # Map of ingress annotations. + annotations: {} + # Ingress path. + path: / + # Each path in an Ingress is required to have a corresponding path type. (ImplementationSpecific/Exact/Prefix) + pathType: ImplementationSpecific + +extraConfigMaps: [] +# extraConfigMaps: +# - name: my-config-map +# mountPath: /mount/to/my/location +# subPath: my-subpath # Optional, if you wish to mount a single key and not the entire ConfigMap + +extraSecrets: [] +# extraSecrets: +# - name: my-secret +# mountPath: /mount/to/my/location +# subPath: my-subpath # Optional, if you wish to mount a single key and not the entire ConfigMap + +extraObjects: [] +# extraObjects: +# - apiVersion: configuration.konghq.com/v1 +# kind: KongClusterPlugin +# metadata: +# name: prometheus +# config: +# per_consumer: false +# plugin: prometheus diff --git a/charts/linkerd/linkerd-control-plane/2024.8.2/Chart.yaml b/charts/linkerd/linkerd-control-plane/2024.8.2/Chart.yaml index f342e868df..e04e3c15a6 100644 --- a/charts/linkerd/linkerd-control-plane/2024.8.2/Chart.yaml +++ b/charts/linkerd/linkerd-control-plane/2024.8.2/Chart.yaml @@ -2,7 +2,6 @@ annotations: catalog.cattle.io/auto-install: linkerd-crds catalog.cattle.io/certified: partner catalog.cattle.io/display-name: Linkerd Control Plane - catalog.cattle.io/featured: "5" catalog.cattle.io/kube-version: '>=1.22.0-0' catalog.cattle.io/release-name: linkerd-control-plane apiVersion: v2 diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/.helmignore b/charts/linkerd/linkerd-control-plane/2024.8.3/.helmignore new file mode 100644 index 0000000000..79c90a8063 --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/.helmignore @@ -0,0 +1,22 @@ +# 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 +OWNERS +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/Chart.lock b/charts/linkerd/linkerd-control-plane/2024.8.3/Chart.lock new file mode 100644 index 0000000000..a0cb7ec8c5 --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: partials + repository: file://../partials + version: 0.1.0 +digest: sha256:8e42f9c9d4a2dc883f17f94d6044c97518ced19ad0922f47b8760e47135369ba +generated: "2021-12-06T11:42:50.784240359-05:00" diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/Chart.yaml b/charts/linkerd/linkerd-control-plane/2024.8.3/Chart.yaml new file mode 100644 index 0000000000..f3088b0a5d --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/Chart.yaml @@ -0,0 +1,29 @@ +annotations: + catalog.cattle.io/auto-install: linkerd-crds + catalog.cattle.io/certified: partner + catalog.cattle.io/display-name: Linkerd Control Plane + catalog.cattle.io/featured: "5" + catalog.cattle.io/kube-version: '>=1.22.0-0' + catalog.cattle.io/release-name: linkerd-control-plane +apiVersion: v2 +appVersion: edge-24.8.3 +dependencies: +- name: partials + repository: file://./charts/partials + version: 0.1.0 +description: 'Linkerd gives you observability, reliability, and security for your + microservices — with no code change required. ' +home: https://linkerd.io +icon: file://assets/icons/linkerd-control-plane.png +keywords: +- service-mesh +kubeVersion: '>=1.22.0-0' +maintainers: +- email: cncf-linkerd-dev@lists.cncf.io + name: Linkerd authors + url: https://linkerd.io/ +name: linkerd-control-plane +sources: +- https://github.com/linkerd/linkerd2/ +type: application +version: 2024.8.3 diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/README.md b/charts/linkerd/linkerd-control-plane/2024.8.3/README.md new file mode 100644 index 0000000000..3d871f7a74 --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/README.md @@ -0,0 +1,312 @@ +# linkerd-control-plane + +Linkerd gives you observability, reliability, and security +for your microservices — with no code change required. + +![Version: 2024.8.3](https://img.shields.io/badge/Version-2024.8.3-informational?style=flat-square) +![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) +![AppVersion: edge-XX.X.X](https://img.shields.io/badge/AppVersion-edge--XX.X.X-informational?style=flat-square) + +**Homepage:** + +## Quickstart and documentation + +You can run Linkerd on any Kubernetes cluster in a matter of seconds. See the +[Linkerd Getting Started Guide][getting-started] for how. + +For more comprehensive documentation, start with the [Linkerd +docs][linkerd-docs]. + +## Prerequisite: linkerd-crds chart + +Before installing this chart, please install the `linkerd-crds` chart, which +creates all the CRDs that the components from the current chart require. + +## Prerequisite: identity certificates + +The identity component of Linkerd requires setting up a trust anchor +certificate, and an issuer certificate with its key. These need to be provided +to Helm by the user (unlike when using the `linkerd install` CLI which can +generate these automatically). You can provide your own, or follow [these +instructions](https://linkerd.io/2/tasks/generate-certificates/) to generate new +ones. + +Alternatively, both trust anchor and identity issuer certificates may be +derived from in-cluster resources. Existing CA (trust anchor) certificates +**must** live in a `ConfigMap` resource named `linkerd-identity-trust-roots`. +Issuer certificates **must** live in a `Secret` named +`linkerd-identity-issuer`. Both resources should exist in the control-plane's +install namespace. In order to use an existing CA, Linkerd needs to be +installed with `identity.externalCA=true`. To use an existing issuer +certificate, Linkerd should be installed with +`identity.issuer.scheme=kubernetes.io/tls`. + +A more comprehensive description is in the [automatic certificate rotation +guide](https://linkerd.io/2.12/tasks/automatically-rotating-control-plane-tls-credentials/#a-note-on-third-party-cert-management-solutions). + +Note that the provided certificates must be ECDSA certificates. + +## Adding Linkerd's Helm repository + +Included here for completeness-sake, but should have already been added when +`linkerd-base` was installed. + +```bash +# To add the repo for Linkerd edge releases: +helm repo add linkerd https://helm.linkerd.io/edge +``` + +## Installing the chart + +You must provide the certificates and keys described in the preceding section, +and the same expiration date you used to generate the Issuer certificate. + +```bash +helm install linkerd-control-plane -n linkerd \ + --set-file identityTrustAnchorsPEM=ca.crt \ + --set-file identity.issuer.tls.crtPEM=issuer.crt \ + --set-file identity.issuer.tls.keyPEM=issuer.key \ + linkerd/linkerd-control-plane +``` + +Note that you require to install this chart in the same namespace you installed +the `linkerd-base` chart. + +## Setting High-Availability + +Besides the default `values.yaml` file, the chart provides a `values-ha.yaml` +file that overrides some default values as to set things up under a +high-availability scenario, analogous to the `--ha` option in `linkerd install`. +Values such as higher number of replicas, higher memory/cpu limits and +affinities are specified in that file. + +You can get ahold of `values-ha.yaml` by fetching the chart files: + +```bash +helm fetch --untar linkerd/linkerd-control-plane +``` + +Then use the `-f` flag to provide the override file, for example: + +```bash +helm install linkerd-control-plane -n linkerd \ + --set-file identityTrustAnchorsPEM=ca.crt \ + --set-file identity.issuer.tls.crtPEM=issuer.crt \ + --set-file identity.issuer.tls.keyPEM=issuer.key \ + -f linkerd2/values-ha.yaml + linkerd/linkerd-control-plane +``` + +## Get involved + +* Check out Linkerd's source code at [GitHub][linkerd2]. +* Join Linkerd's [user mailing list][linkerd-users], [developer mailing + list][linkerd-dev], and [announcements mailing list][linkerd-announce]. +* Follow [@linkerd][twitter] on Twitter. +* Join the [Linkerd Slack][slack]. + +[getting-started]: https://linkerd.io/2/getting-started/ +[linkerd2]: https://github.com/linkerd/linkerd2 +[linkerd-announce]: https://lists.cncf.io/g/cncf-linkerd-announce +[linkerd-dev]: https://lists.cncf.io/g/cncf-linkerd-dev +[linkerd-docs]: https://linkerd.io/2/overview/ +[linkerd-users]: https://lists.cncf.io/g/cncf-linkerd-users +[slack]: http://slack.linkerd.io +[twitter]: https://twitter.com/linkerd + +## Extensions for Linkerd + +The current chart installs the core Linkerd components, which grant you +reliability and security features. Other functionality is available through +extensions. Check the corresponding docs for each one of the following +extensions: + +* Observability: + [Linkerd-viz](https://github.com/linkerd/linkerd2/blob/main/viz/charts/linkerd-viz/README.md) +* Multicluster: + [Linkerd-multicluster](https://github.com/linkerd/linkerd2/blob/main/multicluster/charts/linkerd-multicluster/README.md) +* Tracing: + [Linkerd-jaeger](https://github.com/linkerd/linkerd2/blob/main/jaeger/charts/linkerd-jaeger/README.md) + +## Requirements + +Kubernetes: `>=1.22.0-0` + +| Repository | Name | Version | +|------------|------|---------| +| file://../partials | partials | 0.1.0 | + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| clusterDomain | string | `"cluster.local"` | Kubernetes DNS Domain name to use | +| clusterNetworks | string | `"10.0.0.0/8,100.64.0.0/10,172.16.0.0/12,192.168.0.0/16,fd00::/8"` | The cluster networks for which service discovery is performed. This should include the pod and service networks, but need not include the node network. By default, all IPv4 private networks and all accepted IPv6 ULAs are specified so that resolution works in typical Kubernetes environments. | +| cniEnabled | bool | `false` | enabling this omits the NET_ADMIN capability in the PSP and the proxy-init container when injecting the proxy; requires the linkerd-cni plugin to already be installed | +| commonLabels | object | `{}` | Labels to apply to all resources | +| controlPlaneTracing | bool | `false` | enables control plane tracing | +| controlPlaneTracingNamespace | string | `"linkerd-jaeger"` | namespace to send control plane traces to | +| controller.podDisruptionBudget | object | `{"maxUnavailable":1}` | sets pod disruption budget parameter for all deployments | +| controller.podDisruptionBudget.maxUnavailable | int | `1` | Maximum number of pods that can be unavailable during disruption | +| controllerGID | int | `-1` | Optional customisation of the group ID for the control plane components (the group ID will be omitted if lower than 0) | +| controllerImage | string | `"cr.l5d.io/linkerd/controller"` | Docker image for the destination and identity components | +| controllerImageVersion | string | `""` | Optionally allow a specific container image Tag (or SHA) to be specified for the controllerImage. | +| controllerLogFormat | string | `"plain"` | Log format for the control plane components | +| controllerLogLevel | string | `"info"` | Log level for the control plane components | +| controllerReplicas | int | `1` | Number of replicas for each control plane pod | +| controllerUID | int | `2103` | User ID for the control plane components | +| debugContainer.image.name | string | `"cr.l5d.io/linkerd/debug"` | Docker image for the debug container | +| debugContainer.image.pullPolicy | string | imagePullPolicy | Pull policy for the debug container image | +| debugContainer.image.version | string | linkerdVersion | Tag for the debug container image | +| deploymentStrategy | object | `{"rollingUpdate":{"maxSurge":"25%","maxUnavailable":"25%"}}` | default kubernetes deployment strategy | +| destinationController.meshedHttp2ClientProtobuf.keep_alive.interval.seconds | int | `10` | | +| destinationController.meshedHttp2ClientProtobuf.keep_alive.timeout.seconds | int | `3` | | +| destinationController.meshedHttp2ClientProtobuf.keep_alive.while_idle | bool | `true` | | +| disableHeartBeat | bool | `false` | Set to true to not start the heartbeat cronjob | +| disableIPv6 | bool | `true` | disables routing IPv6 traffic in addition to IPv4 traffic through the proxy (IPv6 routing only available as of proxy-init v2.3.0 and linkerd-cni v1.4.0) | +| enableEndpointSlices | bool | `true` | enables the use of EndpointSlice informers for the destination service; enableEndpointSlices should be set to true only if EndpointSlice K8s feature gate is on | +| enableH2Upgrade | bool | `true` | Allow proxies to perform transparent HTTP/2 upgrading | +| enablePSP | bool | `false` | Add a PSP resource and bind it to the control plane ServiceAccounts. Note PSP has been deprecated since k8s v1.21 | +| enablePodAntiAffinity | bool | `false` | enables pod anti affinity creation on deployments for high availability | +| enablePodDisruptionBudget | bool | `false` | enables the creation of pod disruption budgets for control plane components | +| enablePprof | bool | `false` | enables the use of pprof endpoints on control plane component's admin servers | +| identity.externalCA | bool | `false` | If the linkerd-identity-trust-roots ConfigMap has already been created | +| identity.issuer.clockSkewAllowance | string | `"20s"` | Amount of time to allow for clock skew within a Linkerd cluster | +| identity.issuer.issuanceLifetime | string | `"24h0m0s"` | Amount of time for which the Identity issuer should certify identity | +| identity.issuer.scheme | string | `"linkerd.io/tls"` | | +| identity.issuer.tls | object | `{"crtPEM":"","keyPEM":""}` | Which scheme is used for the identity issuer secret format | +| identity.issuer.tls.crtPEM | string | `""` | Issuer certificate (ECDSA). It must be provided during install. | +| identity.issuer.tls.keyPEM | string | `""` | Key for the issuer certificate (ECDSA). It must be provided during install | +| identity.kubeAPI.clientBurst | int | `200` | Burst value over clientQPS | +| identity.kubeAPI.clientQPS | int | `100` | Maximum QPS sent to the kube-apiserver before throttling. See [token bucket rate limiter implementation](https://github.com/kubernetes/client-go/blob/v12.0.0/util/flowcontrol/throttle.go) | +| identity.serviceAccountTokenProjection | bool | `true` | Use [Service Account token Volume projection](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#service-account-token-volume-projection) for pod validation instead of the default token | +| identityTrustAnchorsPEM | string | `""` | Trust root certificate (ECDSA). It must be provided during install. | +| identityTrustDomain | string | clusterDomain | Trust domain used for identity | +| imagePullPolicy | string | `"IfNotPresent"` | Docker image pull policy | +| imagePullSecrets | list | `[]` | For Private docker registries, authentication is needed. Registry secrets are applied to the respective service accounts | +| kubeAPI.clientBurst | int | `200` | Burst value over clientQPS | +| kubeAPI.clientQPS | int | `100` | Maximum QPS sent to the kube-apiserver before throttling. See [token bucket rate limiter implementation](https://github.com/kubernetes/client-go/blob/v12.0.0/util/flowcontrol/throttle.go) | +| linkerdVersion | string | `"linkerdVersionValue"` | control plane version. See Proxy section for proxy version | +| networkValidator.connectAddr | string | `""` | Address to which the network-validator will attempt to connect. This should be an IP that the cluster is expected to be able to reach but a port it should not, e.g., a public IP for public clusters and a private IP for air-gapped clusters with a port like 20001. If empty, defaults to 1.1.1.1:20001 and [fd00::1]:20001 for IPv4 and IPv6 respectively. | +| networkValidator.enableSecurityContext | bool | `true` | Include a securityContext in the network-validator pod spec | +| networkValidator.listenAddr | string | `""` | Address to which network-validator listens to requests from itself. If empty, defaults to 0.0.0.0:4140 and [::]:4140 for IPv4 and IPv6 respectively. | +| networkValidator.logFormat | string | plain | Log format (`plain` or `json`) for network-validator | +| networkValidator.logLevel | string | debug | Log level for the network-validator | +| networkValidator.timeout | string | `"10s"` | Timeout before network-validator fails to validate the pod's network connectivity | +| nodeSelector | object | `{"kubernetes.io/os":"linux"}` | NodeSelector section, See the [K8S documentation](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector) for more information | +| podAnnotations | object | `{}` | Additional annotations to add to all pods | +| podLabels | object | `{}` | Additional labels to add to all pods | +| podMonitor.controller.enabled | bool | `true` | Enables the creation of PodMonitor for the control-plane | +| podMonitor.controller.namespaceSelector | string | `"matchNames:\n - {{ .Release.Namespace }}\n - linkerd-viz\n - linkerd-jaeger\n"` | Selector to select which namespaces the Endpoints objects are discovered from | +| podMonitor.enabled | bool | `false` | Enables the creation of Prometheus Operator [PodMonitor](https://prometheus-operator.dev/docs/operator/api/#monitoring.coreos.com/v1.PodMonitor) | +| podMonitor.labels | object | `{}` | Labels to apply to all pod Monitors | +| podMonitor.proxy.enabled | bool | `true` | Enables the creation of PodMonitor for the data-plane | +| podMonitor.scrapeInterval | string | `"10s"` | Interval at which metrics should be scraped | +| podMonitor.scrapeTimeout | string | `"10s"` | Iimeout after which the scrape is ended | +| podMonitor.serviceMirror.enabled | bool | `true` | Enables the creation of PodMonitor for the Service Mirror component | +| policyController.image.name | string | `"cr.l5d.io/linkerd/policy-controller"` | Docker image for the policy controller | +| policyController.image.pullPolicy | string | imagePullPolicy | Pull policy for the policy controller container image | +| policyController.image.version | string | linkerdVersion | Tag for the policy controller container image | +| policyController.logLevel | string | `"info"` | Log level for the policy controller | +| policyController.probeNetworks | list | `["0.0.0.0/0","::/0"]` | The networks from which probes are performed. By default, all networks are allowed so that all probes are authorized. | +| policyController.resources | object | `{"cpu":{"limit":"","request":""},"ephemeral-storage":{"limit":"","request":""},"memory":{"limit":"","request":""}}` | policy controller resource requests & limits | +| policyController.resources.cpu.limit | string | `""` | Maximum amount of CPU units that the policy controller can use | +| policyController.resources.cpu.request | string | `""` | Amount of CPU units that the policy controller requests | +| policyController.resources.ephemeral-storage.limit | string | `""` | Maximum amount of ephemeral storage that the policy controller can use | +| policyController.resources.ephemeral-storage.request | string | `""` | Amount of ephemeral storage that the policy controller requests | +| policyController.resources.memory.limit | string | `""` | Maximum amount of memory that the policy controller can use | +| policyController.resources.memory.request | string | `""` | Maximum amount of memory that the policy controller requests | +| policyValidator.caBundle | string | `""` | Bundle of CA certificates for proxy injector. If not provided nor injected with cert-manager, then Helm will use the certificate generated for `policyValidator.crtPEM`. If `policyValidator.externalSecret` is set to true, this value, injectCaFrom, or injectCaFromSecret must be set, as no certificate will be generated. See the cert-manager [CA Injector Docs](https://cert-manager.io/docs/concepts/ca-injector) for more information. | +| policyValidator.crtPEM | string | `""` | Certificate for the policy validator. If not provided and not using an external secret then Helm will generate one. | +| policyValidator.externalSecret | bool | `false` | Do not create a secret resource for the policyValidator webhook. If this is set to `true`, the value `policyValidator.caBundle` must be set or the ca bundle must injected with cert-manager ca injector using `policyValidator.injectCaFrom` or `policyValidator.injectCaFromSecret` (see below). | +| policyValidator.injectCaFrom | string | `""` | Inject the CA bundle from a cert-manager Certificate. See the cert-manager [CA Injector Docs](https://cert-manager.io/docs/concepts/ca-injector/#injecting-ca-data-from-a-certificate-resource) for more information. | +| policyValidator.injectCaFromSecret | string | `""` | Inject the CA bundle from a Secret. If set, the `cert-manager.io/inject-ca-from-secret` annotation will be added to the webhook. The Secret must have the CA Bundle stored in the `ca.crt` key and have the `cert-manager.io/allow-direct-injection` annotation set to `true`. See the cert-manager [CA Injector Docs](https://cert-manager.io/docs/concepts/ca-injector/#injecting-ca-data-from-a-secret-resource) for more information. | +| policyValidator.keyPEM | string | `""` | Certificate key for the policy validator. If not provided and not using an external secret then Helm will generate one. | +| policyValidator.namespaceSelector | object | `{"matchExpressions":[{"key":"config.linkerd.io/admission-webhooks","operator":"NotIn","values":["disabled"]}]}` | Namespace selector used by admission webhook | +| priorityClassName | string | `""` | Kubernetes priorityClassName for the Linkerd Pods | +| profileValidator.caBundle | string | `""` | Bundle of CA certificates for proxy injector. If not provided nor injected with cert-manager, then Helm will use the certificate generated for `profileValidator.crtPEM`. If `profileValidator.externalSecret` is set to true, this value, injectCaFrom, or injectCaFromSecret must be set, as no certificate will be generated. See the cert-manager [CA Injector Docs](https://cert-manager.io/docs/concepts/ca-injector) for more information. | +| profileValidator.crtPEM | string | `""` | Certificate for the service profile validator. If not provided and not using an external secret then Helm will generate one. | +| profileValidator.externalSecret | bool | `false` | Do not create a secret resource for the profileValidator webhook. If this is set to `true`, the value `proxyInjector.caBundle` must be set or the ca bundle must injected with cert-manager ca injector using `proxyInjector.injectCaFrom` or `proxyInjector.injectCaFromSecret` (see below). | +| profileValidator.injectCaFrom | string | `""` | Inject the CA bundle from a cert-manager Certificate. See the cert-manager [CA Injector Docs](https://cert-manager.io/docs/concepts/ca-injector/#injecting-ca-data-from-a-certificate-resource) for more information. | +| profileValidator.injectCaFromSecret | string | `""` | Inject the CA bundle from a Secret. If set, the `cert-manager.io/inject-ca-from-secret` annotation will be added to the webhook. The Secret must have the CA Bundle stored in the `ca.crt` key and have the `cert-manager.io/allow-direct-injection` annotation set to `true`. See the cert-manager [CA Injector Docs](https://cert-manager.io/docs/concepts/ca-injector/#injecting-ca-data-from-a-secret-resource) for more information. | +| profileValidator.keyPEM | string | `""` | Certificate key for the service profile validator. If not provided and not using an external secret then Helm will generate one. | +| profileValidator.namespaceSelector | object | `{"matchExpressions":[{"key":"config.linkerd.io/admission-webhooks","operator":"NotIn","values":["disabled"]}]}` | Namespace selector used by admission webhook | +| prometheusUrl | string | `""` | url of external prometheus instance (used for the heartbeat) | +| proxy.await | bool | `true` | If set, the application container will not start until the proxy is ready | +| proxy.control.streams.idleTimeout | string | `"5m"` | The timeout between consecutive updates from the control plane. | +| proxy.control.streams.initialTimeout | string | `"3s"` | The timeout for the first update from the control plane. | +| proxy.control.streams.lifetime | string | `"1h"` | The maximum duration for a response stream (i.e. before it will be reinitialized). | +| proxy.cores | int | `0` | The `cpu.limit` and `cores` should be kept in sync. The value of `cores` must be an integer and should typically be set by rounding up from the limit. E.g. if cpu.limit is '1500m', cores should be 2. | +| proxy.defaultInboundPolicy | string | "all-unauthenticated" | The default allow policy to use when no `Server` selects a pod. One of: "all-authenticated", "all-unauthenticated", "cluster-authenticated", "cluster-unauthenticated", "deny", "audit" | +| proxy.disableInboundProtocolDetectTimeout | bool | `false` | When set to true, disables the protocol detection timeout on the inbound side of the proxy by setting it to a very high value | +| proxy.disableOutboundProtocolDetectTimeout | bool | `false` | When set to true, disables the protocol detection timeout on the outbound side of the proxy by setting it to a very high value | +| proxy.enableExternalProfiles | bool | `false` | Enable service profiles for non-Kubernetes services | +| proxy.enableShutdownEndpoint | bool | `false` | Enables the proxy's /shutdown admin endpoint | +| proxy.gid | int | `-1` | Optional customisation of the group id under which the proxy runs (the group ID will be omitted if lower than 0) | +| proxy.image.name | string | `"cr.l5d.io/linkerd/proxy"` | Docker image for the proxy | +| proxy.image.pullPolicy | string | imagePullPolicy | Pull policy for the proxy container image | +| proxy.image.version | string | linkerdVersion | Tag for the proxy container image | +| proxy.inbound.server.http2.keepAliveInterval | string | `"10s"` | The interval at which PINGs are issued to remote HTTP/2 clients. | +| proxy.inbound.server.http2.keepAliveTimeout | string | `"3s"` | The timeout within which keep-alive PINGs must be acknowledged on inbound HTTP/2 connections. | +| proxy.inboundConnectTimeout | string | `"100ms"` | Maximum time allowed for the proxy to establish an inbound TCP connection | +| proxy.inboundDiscoveryCacheUnusedTimeout | string | `"90s"` | Maximum time allowed before an unused inbound discovery result is evicted from the cache | +| proxy.livenessProbe | object | `{"initialDelaySeconds":10,"timeoutSeconds":1}` | LivenessProbe timeout and delay configuration | +| proxy.logFormat | string | `"plain"` | Log format (`plain` or `json`) for the proxy | +| proxy.logHTTPHeaders | `off` or `insecure` | `"off"` | If set to `off`, will prevent the proxy from logging HTTP headers. If set to `insecure`, HTTP headers may be logged verbatim. Note that setting this to `insecure` is not alone sufficient to log HTTP headers; the proxy logLevel must also be set to debug. | +| proxy.logLevel | string | `"warn,linkerd=info,hickory=error"` | Log level for the proxy | +| proxy.nativeSidecar | bool | `false` | Enable KEP-753 native sidecars This is an experimental feature. It requires Kubernetes >= 1.29. If enabled, .proxy.waitBeforeExitSeconds should not be used. | +| proxy.opaquePorts | string | `"25,587,3306,4444,5432,6379,9300,11211"` | Default set of opaque ports - SMTP (25,587) server-first - MYSQL (3306) server-first - Galera (4444) server-first - PostgreSQL (5432) server-first - Redis (6379) server-first - ElasticSearch (9300) server-first - Memcached (11211) clients do not issue any preamble, which breaks detection | +| proxy.outbound.server.http2.keepAliveInterval | string | `"10s"` | The interval at which PINGs are issued to local application HTTP/2 clients. | +| proxy.outbound.server.http2.keepAliveTimeout | string | `"3s"` | The timeout within which keep-alive PINGs must be acknowledged on outbound HTTP/2 connections. | +| proxy.outboundConnectTimeout | string | `"1000ms"` | Maximum time allowed for the proxy to establish an outbound TCP connection | +| proxy.outboundDiscoveryCacheUnusedTimeout | string | `"5s"` | Maximum time allowed before an unused outbound discovery result is evicted from the cache | +| proxy.ports.admin | int | `4191` | Admin port for the proxy container | +| proxy.ports.control | int | `4190` | Control port for the proxy container | +| proxy.ports.inbound | int | `4143` | Inbound port for the proxy container | +| proxy.ports.outbound | int | `4140` | Outbound port for the proxy container | +| proxy.readinessProbe | object | `{"initialDelaySeconds":2,"timeoutSeconds":1}` | ReadinessProbe timeout and delay configuration | +| proxy.requireIdentityOnInboundPorts | string | `""` | | +| proxy.resources.cpu.limit | string | `""` | Maximum amount of CPU units that the proxy can use | +| proxy.resources.cpu.request | string | `""` | Amount of CPU units that the proxy requests | +| proxy.resources.ephemeral-storage.limit | string | `""` | Maximum amount of ephemeral storage that the proxy can use | +| proxy.resources.ephemeral-storage.request | string | `""` | Amount of ephemeral storage that the proxy requests | +| proxy.resources.memory.limit | string | `""` | Maximum amount of memory that the proxy can use | +| proxy.resources.memory.request | string | `""` | Maximum amount of memory that the proxy requests | +| proxy.shutdownGracePeriod | string | `""` | Grace period for graceful proxy shutdowns. If this timeout elapses before all open connections have completed, the proxy will terminate forcefully, closing any remaining connections. | +| proxy.startupProbe.failureThreshold | int | `120` | | +| proxy.startupProbe.initialDelaySeconds | int | `0` | | +| proxy.startupProbe.periodSeconds | int | `1` | | +| proxy.uid | int | `2102` | User id under which the proxy runs | +| proxy.waitBeforeExitSeconds | int | `0` | If set the injected proxy sidecars in the data plane will stay alive for at least the given period before receiving the SIGTERM signal from Kubernetes but no longer than the pod's `terminationGracePeriodSeconds`. See [Lifecycle hooks](https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks) for more info on container lifecycle hooks. | +| proxyInit.closeWaitTimeoutSecs | int | `0` | | +| proxyInit.ignoreInboundPorts | string | `"4567,4568"` | Default set of inbound ports to skip via iptables - Galera (4567,4568) | +| proxyInit.ignoreOutboundPorts | string | `"4567,4568"` | Default set of outbound ports to skip via iptables - Galera (4567,4568) | +| proxyInit.image.name | string | `"cr.l5d.io/linkerd/proxy-init"` | Docker image for the proxy-init container | +| proxyInit.image.pullPolicy | string | imagePullPolicy | Pull policy for the proxy-init container image | +| proxyInit.image.version | string | `"v2.4.1"` | Tag for the proxy-init container image | +| proxyInit.iptablesMode | string | `"legacy"` | Variant of iptables that will be used to configure routing. Currently, proxy-init can be run either in 'nft' or in 'legacy' mode. The mode will control which utility binary will be called. The host must support whichever mode will be used | +| proxyInit.kubeAPIServerPorts | string | `"443,6443"` | Default set of ports to skip via iptables for control plane components so they can communicate with the Kubernetes API Server | +| proxyInit.logFormat | string | plain | Log format (`plain` or `json`) for the proxy-init | +| proxyInit.logLevel | string | info | Log level for the proxy-init | +| proxyInit.privileged | bool | false | Privileged mode allows the container processes to inherit all security capabilities and bypass any security limitations enforced by the kubelet. When used with 'runAsRoot: true', the container will behave exactly as if it was running as root on the host. May escape cgroup limits and see other processes and devices on the host. | +| proxyInit.runAsGroup | int | `65534` | This value is used only if runAsRoot is false; otherwise runAsGroup will be 0 | +| proxyInit.runAsRoot | bool | `false` | Allow overriding the runAsNonRoot behaviour () | +| proxyInit.runAsUser | int | `65534` | This value is used only if runAsRoot is false; otherwise runAsUser will be 0 | +| proxyInit.skipSubnets | string | `""` | Comma-separated list of subnets in valid CIDR format that should be skipped by the proxy | +| proxyInit.xtMountPath.mountPath | string | `"/run"` | | +| proxyInit.xtMountPath.name | string | `"linkerd-proxy-init-xtables-lock"` | | +| proxyInjector.caBundle | string | `""` | Bundle of CA certificates for proxy injector. If not provided nor injected with cert-manager, then Helm will use the certificate generated for `proxyInjector.crtPEM`. If `proxyInjector.externalSecret` is set to true, this value, injectCaFrom, or injectCaFromSecret must be set, as no certificate will be generated. See the cert-manager [CA Injector Docs](https://cert-manager.io/docs/concepts/ca-injector) for more information. | +| proxyInjector.crtPEM | string | `""` | Certificate for the proxy injector. If not provided and not using an external secret then Helm will generate one. | +| proxyInjector.externalSecret | bool | `false` | Do not create a secret resource for the proxyInjector webhook. If this is set to `true`, the value `proxyInjector.caBundle` must be set or the ca bundle must injected with cert-manager ca injector using `proxyInjector.injectCaFrom` or `proxyInjector.injectCaFromSecret` (see below). | +| proxyInjector.injectCaFrom | string | `""` | Inject the CA bundle from a cert-manager Certificate. See the cert-manager [CA Injector Docs](https://cert-manager.io/docs/concepts/ca-injector/#injecting-ca-data-from-a-certificate-resource) for more information. | +| proxyInjector.injectCaFromSecret | string | `""` | Inject the CA bundle from a Secret. If set, the `cert-manager.io/inject-ca-from-secret` annotation will be added to the webhook. The Secret must have the CA Bundle stored in the `ca.crt` key and have the `cert-manager.io/allow-direct-injection` annotation set to `true`. See the cert-manager [CA Injector Docs](https://cert-manager.io/docs/concepts/ca-injector/#injecting-ca-data-from-a-secret-resource) for more information. | +| proxyInjector.keyPEM | string | `""` | Certificate key for the proxy injector. If not provided and not using an external secret then Helm will generate one. | +| proxyInjector.namespaceSelector | object | `{"matchExpressions":[{"key":"config.linkerd.io/admission-webhooks","operator":"NotIn","values":["disabled"]},{"key":"kubernetes.io/metadata.name","operator":"NotIn","values":["kube-system","cert-manager"]}]}` | Namespace selector used by admission webhook. | +| proxyInjector.objectSelector | object | `{"matchExpressions":[{"key":"linkerd.io/control-plane-component","operator":"DoesNotExist"},{"key":"linkerd.io/cni-resource","operator":"DoesNotExist"}]}` | Object selector used by admission webhook. | +| proxyInjector.timeoutSeconds | int | `10` | Timeout in seconds before the API Server cancels a request to the proxy injector. If timeout is exceeded, the webhookfailurePolicy is used. | +| revisionHistoryLimit | int | `10` | Specifies the number of old ReplicaSets to retain to allow rollback. | +| runtimeClassName | string | `""` | Runtime Class Name for all the pods | +| webhookFailurePolicy | string | `"Ignore"` | Failure policy for the proxy injector | + +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.12.0](https://github.com/norwoodj/helm-docs/releases/v1.12.0) diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/README.md.gotmpl b/charts/linkerd/linkerd-control-plane/2024.8.3/README.md.gotmpl new file mode 100644 index 0000000000..19da2a82d6 --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/README.md.gotmpl @@ -0,0 +1,133 @@ +{{ template "chart.header" . }} +{{ template "chart.description" . }} + +{{ template "chart.versionBadge" . }} +{{ template "chart.typeBadge" . }} +{{ template "chart.appVersionBadge" . }} + +{{ template "chart.homepageLine" . }} + +## Quickstart and documentation + +You can run Linkerd on any Kubernetes cluster in a matter of seconds. See the +[Linkerd Getting Started Guide][getting-started] for how. + +For more comprehensive documentation, start with the [Linkerd +docs][linkerd-docs]. + +## Prerequisite: linkerd-crds chart + +Before installing this chart, please install the `linkerd-crds` chart, which +creates all the CRDs that the components from the current chart require. + +## Prerequisite: identity certificates + +The identity component of Linkerd requires setting up a trust anchor +certificate, and an issuer certificate with its key. These need to be provided +to Helm by the user (unlike when using the `linkerd install` CLI which can +generate these automatically). You can provide your own, or follow [these +instructions](https://linkerd.io/2/tasks/generate-certificates/) to generate new +ones. + +Alternatively, both trust anchor and identity issuer certificates may be +derived from in-cluster resources. Existing CA (trust anchor) certificates +**must** live in a `ConfigMap` resource named `linkerd-identity-trust-roots`. +Issuer certificates **must** live in a `Secret` named +`linkerd-identity-issuer`. Both resources should exist in the control-plane's +install namespace. In order to use an existing CA, Linkerd needs to be +installed with `identity.externalCA=true`. To use an existing issuer +certificate, Linkerd should be installed with +`identity.issuer.scheme=kubernetes.io/tls`. + +A more comprehensive description is in the [automatic certificate rotation +guide](https://linkerd.io/2.12/tasks/automatically-rotating-control-plane-tls-credentials/#a-note-on-third-party-cert-management-solutions). + +Note that the provided certificates must be ECDSA certificates. + +## Adding Linkerd's Helm repository + +Included here for completeness-sake, but should have already been added when +`linkerd-base` was installed. + +```bash +# To add the repo for Linkerd edge releases: +helm repo add linkerd https://helm.linkerd.io/edge +``` + +## Installing the chart + +You must provide the certificates and keys described in the preceding section, +and the same expiration date you used to generate the Issuer certificate. + +```bash +helm install linkerd-control-plane -n linkerd \ + --set-file identityTrustAnchorsPEM=ca.crt \ + --set-file identity.issuer.tls.crtPEM=issuer.crt \ + --set-file identity.issuer.tls.keyPEM=issuer.key \ + linkerd/linkerd-control-plane +``` + +Note that you require to install this chart in the same namespace you installed +the `linkerd-base` chart. + +## Setting High-Availability + +Besides the default `values.yaml` file, the chart provides a `values-ha.yaml` +file that overrides some default values as to set things up under a +high-availability scenario, analogous to the `--ha` option in `linkerd install`. +Values such as higher number of replicas, higher memory/cpu limits and +affinities are specified in that file. + +You can get ahold of `values-ha.yaml` by fetching the chart files: + +```bash +helm fetch --untar linkerd/linkerd-control-plane +``` + +Then use the `-f` flag to provide the override file, for example: + +```bash +helm install linkerd-control-plane -n linkerd \ + --set-file identityTrustAnchorsPEM=ca.crt \ + --set-file identity.issuer.tls.crtPEM=issuer.crt \ + --set-file identity.issuer.tls.keyPEM=issuer.key \ + -f linkerd2/values-ha.yaml + linkerd/linkerd-control-plane +``` + +## Get involved + +* Check out Linkerd's source code at [GitHub][linkerd2]. +* Join Linkerd's [user mailing list][linkerd-users], [developer mailing + list][linkerd-dev], and [announcements mailing list][linkerd-announce]. +* Follow [@linkerd][twitter] on Twitter. +* Join the [Linkerd Slack][slack]. + +[getting-started]: https://linkerd.io/2/getting-started/ +[linkerd2]: https://github.com/linkerd/linkerd2 +[linkerd-announce]: https://lists.cncf.io/g/cncf-linkerd-announce +[linkerd-dev]: https://lists.cncf.io/g/cncf-linkerd-dev +[linkerd-docs]: https://linkerd.io/2/overview/ +[linkerd-users]: https://lists.cncf.io/g/cncf-linkerd-users +[slack]: http://slack.linkerd.io +[twitter]: https://twitter.com/linkerd + +## Extensions for Linkerd + +The current chart installs the core Linkerd components, which grant you +reliability and security features. Other functionality is available through +extensions. Check the corresponding docs for each one of the following +extensions: + +* Observability: + [Linkerd-viz](https://github.com/linkerd/linkerd2/blob/main/viz/charts/linkerd-viz/README.md) +* Multicluster: + [Linkerd-multicluster](https://github.com/linkerd/linkerd2/blob/main/multicluster/charts/linkerd-multicluster/README.md) +* Tracing: + [Linkerd-jaeger](https://github.com/linkerd/linkerd2/blob/main/jaeger/charts/linkerd-jaeger/README.md) + +{{ template "chart.requirementsSection" . }} + +{{ template "chart.valuesSection" . }} + +{{ template "helm-docs.versionFooter" . }} diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/app-readme.md b/charts/linkerd/linkerd-control-plane/2024.8.3/app-readme.md new file mode 100644 index 0000000000..351eac5f0d --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/app-readme.md @@ -0,0 +1,14 @@ +# Linkerd 2 Chart + +Linkerd is an ultra light, ultra simple, ultra powerful service mesh. Linkerd +adds security, observability, and reliability to Kubernetes, without the +complexity. + +This particular Helm chart only installs the control plane core. You will also need to install the +linkerd-crds chart. This chart should be automatically installed along with any other dependencies. +If it is not installed as a dependency, install it first. + +To gain access to the observability features, please install the linkerd-viz chart. +Other extensions are available (multicluster, jaeger) under the linkerd Helm repo. + +Full documentation available at: https://linkerd.io/2/overview/ diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/.helmignore b/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/.helmignore new file mode 100644 index 0000000000..f0c1319444 --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/.helmignore @@ -0,0 +1,21 @@ +# 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 diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/Chart.yaml b/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/Chart.yaml new file mode 100644 index 0000000000..23cfc167e3 --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/Chart.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +description: 'A Helm chart containing Linkerd partial templates, depended by the ''linkerd'' + and ''patch'' charts. ' +name: partials +version: 0.1.0 diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/README.md b/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/README.md new file mode 100644 index 0000000000..10805c9b94 --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/README.md @@ -0,0 +1,9 @@ +# partials + +A Helm chart containing Linkerd partial templates, +depended by the 'linkerd' and 'patch' charts. + +![Version: 0.1.0](https://img.shields.io/badge/Version-0.1.0-informational?style=flat-square) + +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.12.0](https://github.com/norwoodj/helm-docs/releases/v1.12.0) diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/README.md.gotmpl b/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/README.md.gotmpl new file mode 100644 index 0000000000..37f5101061 --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/README.md.gotmpl @@ -0,0 +1,14 @@ +{{ template "chart.header" . }} +{{ template "chart.description" . }} + +{{ template "chart.versionBadge" . }} +{{ template "chart.typeBadge" . }} +{{ template "chart.appVersionBadge" . }} + +{{ template "chart.homepageLine" . }} + +{{ template "chart.requirementsSection" . }} + +{{ template "chart.valuesSection" . }} + +{{ template "helm-docs.versionFooter" . }} diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/NOTES.txt b/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/NOTES.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_affinity.tpl b/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_affinity.tpl new file mode 100644 index 0000000000..5dde1da473 --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_affinity.tpl @@ -0,0 +1,38 @@ +{{ define "linkerd.pod-affinity" -}} +podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: {{ default "linkerd.io/control-plane-component" .label }} + operator: In + values: + - {{ .component }} + topologyKey: topology.kubernetes.io/zone + weight: 100 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: {{ default "linkerd.io/control-plane-component" .label }} + operator: In + values: + - {{ .component }} + topologyKey: kubernetes.io/hostname +{{- end }} + +{{ define "linkerd.node-affinity" -}} +nodeAffinity: +{{- toYaml .Values.nodeAffinity | trim | nindent 2 }} +{{- end }} + +{{ define "linkerd.affinity" -}} +{{- if or .Values.enablePodAntiAffinity .Values.nodeAffinity -}} +affinity: +{{- end }} +{{- if .Values.enablePodAntiAffinity -}} +{{- include "linkerd.pod-affinity" . | nindent 2 }} +{{- end }} +{{- if .Values.nodeAffinity -}} +{{- include "linkerd.node-affinity" . | nindent 2 }} +{{- end }} +{{- end }} diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_capabilities.tpl b/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_capabilities.tpl new file mode 100644 index 0000000000..a595d74c1f --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_capabilities.tpl @@ -0,0 +1,16 @@ +{{- define "partials.proxy.capabilities" -}} +capabilities: + {{- if .Values.proxy.capabilities.add }} + add: + {{- toYaml .Values.proxy.capabilities.add | trim | nindent 4 }} + {{- end }} + {{- if .Values.proxy.capabilities.drop }} + drop: + {{- toYaml .Values.proxy.capabilities.drop | trim | nindent 4 }} + {{- end }} +{{- end -}} + +{{- define "partials.proxy-init.capabilities.drop" -}} +drop: +{{ toYaml .Values.proxyInit.capabilities.drop | trim }} +{{- end -}} diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_debug.tpl b/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_debug.tpl new file mode 100644 index 0000000000..4df8cc77bc --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_debug.tpl @@ -0,0 +1,15 @@ +{{- define "partials.debug" -}} +image: {{.Values.debugContainer.image.name}}:{{.Values.debugContainer.image.version | default .Values.linkerdVersion}} +imagePullPolicy: {{.Values.debugContainer.image.pullPolicy | default .Values.imagePullPolicy}} +name: linkerd-debug +terminationMessagePolicy: FallbackToLogsOnError +# some environments require probes, so we provide some infallible ones +livenessProbe: + exec: + command: + - "true" +readinessProbe: + exec: + command: + - "true" +{{- end -}} diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_helpers.tpl b/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_helpers.tpl new file mode 100644 index 0000000000..b6cdc34d08 --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_helpers.tpl @@ -0,0 +1,14 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Splits a coma separated list into a list of string values. +For example "11,22,55,44" will become "11","22","55","44" +*/}} +{{- define "partials.splitStringList" -}} +{{- if gt (len (toString .)) 0 -}} +{{- $ports := toString . | splitList "," -}} +{{- $last := sub (len $ports) 1 -}} +{{- range $i,$port := $ports -}} +"{{$port}}"{{ternary "," "" (ne $i $last)}} +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_metadata.tpl b/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_metadata.tpl new file mode 100644 index 0000000000..04d2f1beab --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_metadata.tpl @@ -0,0 +1,17 @@ +{{- define "partials.annotations.created-by" -}} +linkerd.io/created-by: {{ .Values.cliVersion | default (printf "linkerd/helm %s" ( (.Values.image).version | default .Values.linkerdVersion)) }} +{{- end -}} + +{{- define "partials.proxy.annotations" -}} +linkerd.io/proxy-version: {{.Values.proxy.image.version | default .Values.linkerdVersion}} +cluster-autoscaler.kubernetes.io/safe-to-evict: "true" +linkerd.io/trust-root-sha256: {{ .Values.identityTrustAnchorsPEM | sha256sum }} +{{- end -}} + +{{/* +To add labels to the control-plane components, instead update at individual component manifests as +adding here would also update `spec.selector.matchLabels` which are immutable and would fail upgrades. +*/}} +{{- define "partials.proxy.labels" -}} +linkerd.io/proxy-{{.workloadKind}}: {{.component}} +{{- end -}} diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_network-validator.tpl b/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_network-validator.tpl new file mode 100644 index 0000000000..276056395f --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_network-validator.tpl @@ -0,0 +1,45 @@ +{{- define "partials.network-validator" -}} +name: linkerd-network-validator +image: {{.Values.proxy.image.name}}:{{.Values.proxy.image.version | default .Values.linkerdVersion }} +imagePullPolicy: {{.Values.proxy.image.pullPolicy | default .Values.imagePullPolicy}} +{{ include "partials.resources" .Values.proxy.resources }} +{{- if or .Values.networkValidator.enableSecurityContext }} +securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsGroup: 65534 + runAsNonRoot: true + runAsUser: 65534 + seccompProfile: + type: RuntimeDefault +{{- end }} +command: + - /usr/lib/linkerd/linkerd2-network-validator +args: + - --log-format + - {{ .Values.networkValidator.logFormat }} + - --log-level + - {{ .Values.networkValidator.logLevel }} + - --connect-addr + {{- if .Values.networkValidator.connectAddr }} + - {{ .Values.networkValidator.connectAddr | quote }} + {{- else if .Values.disableIPv6}} + - "1.1.1.1:20001" + {{- else }} + - "[fd00::1]:20001" + {{- end }} + - --listen-addr + {{- if .Values.networkValidator.listenAddr }} + - {{ .Values.networkValidator.listenAddr | quote }} + {{- else if .Values.disableIPv6}} + - "0.0.0.0:4140" + {{- else }} + - "[::]:4140" + {{- end }} + - --timeout + - {{ .Values.networkValidator.timeout }} + +{{- end -}} diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_nodeselector.tpl b/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_nodeselector.tpl new file mode 100644 index 0000000000..4cde0ab16e --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_nodeselector.tpl @@ -0,0 +1,4 @@ +{{- define "linkerd.node-selector" -}} +nodeSelector: +{{- toYaml .Values.nodeSelector | trim | nindent 2 }} +{{- end -}} diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_proxy-config-ann.tpl b/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_proxy-config-ann.tpl new file mode 100644 index 0000000000..9651b3bd1a --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_proxy-config-ann.tpl @@ -0,0 +1,18 @@ +{{- define "partials.proxy.config.annotations" -}} +{{- with .cpu }} +{{- with .request -}} +config.linkerd.io/proxy-cpu-request: {{. | quote}} +{{end}} +{{- with .limit -}} +config.linkerd.io/proxy-cpu-limit: {{. | quote}} +{{- end}} +{{- end}} +{{- with .memory }} +{{- with .request }} +config.linkerd.io/proxy-memory-request: {{. | quote}} +{{end}} +{{- with .limit -}} +config.linkerd.io/proxy-memory-limit: {{. | quote}} +{{- end}} +{{- end }} +{{- end }} diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_proxy-init.tpl b/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_proxy-init.tpl new file mode 100644 index 0000000000..a307b14073 --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_proxy-init.tpl @@ -0,0 +1,98 @@ +{{- define "partials.proxy-init" -}} +args: +{{- if (.Values.proxyInit.iptablesMode | default "legacy" | eq "nft") }} +- --firewall-bin-path +- "iptables-nft" +- --firewall-save-bin-path +- "iptables-nft-save" +{{- else if not (eq .Values.proxyInit.iptablesMode "legacy") }} +{{ fail (printf "Unsupported value \"%s\" for proxyInit.iptablesMode\nValid values: [\"nft\", \"legacy\"]" .Values.proxyInit.iptablesMode) }} +{{end -}} +{{- if .Values.disableIPv6 }} +- --ipv6=false +{{- end }} +- --incoming-proxy-port +- {{.Values.proxy.ports.inbound | quote}} +- --outgoing-proxy-port +- {{.Values.proxy.ports.outbound | quote}} +- --proxy-uid +- {{.Values.proxy.uid | quote}} +{{- if ge (int .Values.proxy.gid) 0 }} +- --proxy-gid +- {{.Values.proxy.gid | quote}} +{{- end }} +- --inbound-ports-to-ignore +- "{{.Values.proxy.ports.control}},{{.Values.proxy.ports.admin}}{{ternary (printf ",%s" (.Values.proxyInit.ignoreInboundPorts | toString)) "" (not (empty .Values.proxyInit.ignoreInboundPorts)) }}" +{{- if .Values.proxyInit.ignoreOutboundPorts }} +- --outbound-ports-to-ignore +- {{.Values.proxyInit.ignoreOutboundPorts | quote}} +{{- end }} +{{- if .Values.proxyInit.closeWaitTimeoutSecs }} +- --timeout-close-wait-secs +- {{ .Values.proxyInit.closeWaitTimeoutSecs | quote}} +{{- end }} +{{- if .Values.proxyInit.logFormat }} +- --log-format +- {{ .Values.proxyInit.logFormat }} +{{- end }} +{{- if .Values.proxyInit.logLevel }} +- --log-level +- {{ .Values.proxyInit.logLevel }} +{{- end }} +{{- if .Values.proxyInit.skipSubnets }} +- --subnets-to-ignore +- {{ .Values.proxyInit.skipSubnets | quote }} +{{- end }} +image: {{.Values.proxyInit.image.name}}:{{.Values.proxyInit.image.version}} +imagePullPolicy: {{.Values.proxyInit.image.pullPolicy | default .Values.imagePullPolicy}} +name: linkerd-init +{{ include "partials.resources" .Values.proxy.resources }} +securityContext: + {{- if or .Values.proxyInit.closeWaitTimeoutSecs .Values.proxyInit.privileged }} + allowPrivilegeEscalation: true + {{- else }} + allowPrivilegeEscalation: false + {{- end }} + capabilities: + add: + - NET_ADMIN + - NET_RAW + {{- if .Values.proxyInit.capabilities -}} + {{- if .Values.proxyInit.capabilities.add }} + {{- toYaml .Values.proxyInit.capabilities.add | trim | nindent 4 }} + {{- end }} + {{- if .Values.proxyInit.capabilities.drop -}} + {{- include "partials.proxy-init.capabilities.drop" . | nindent 4 -}} + {{- end }} + {{- end }} + {{- if or .Values.proxyInit.closeWaitTimeoutSecs .Values.proxyInit.privileged }} + privileged: true + {{- else }} + privileged: false + {{- end }} + {{- if .Values.proxyInit.runAsRoot }} + runAsGroup: 0 + runAsNonRoot: false + runAsUser: 0 + {{- else }} + runAsNonRoot: true + runAsUser: {{ .Values.proxyInit.runAsUser | int | eq 0 | ternary 65534 .Values.proxyInit.runAsUser }} + runAsGroup: {{ .Values.proxyInit.runAsGroup | int | eq 0 | ternary 65534 .Values.proxyInit.runAsGroup }} + {{- end }} + readOnlyRootFilesystem: true + seccompProfile: + type: RuntimeDefault +terminationMessagePolicy: FallbackToLogsOnError +{{- if or (not .Values.cniEnabled) .Values.proxyInit.saMountPath }} +volumeMounts: +{{- end -}} +{{- if not .Values.cniEnabled }} +- mountPath: {{.Values.proxyInit.xtMountPath.mountPath}} + name: {{.Values.proxyInit.xtMountPath.name}} +{{- end -}} +{{- if .Values.proxyInit.saMountPath }} +- mountPath: {{.Values.proxyInit.saMountPath.mountPath}} + name: {{.Values.proxyInit.saMountPath.name}} + readOnly: {{.Values.proxyInit.saMountPath.readOnly}} +{{- end -}} +{{- end -}} diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_proxy.tpl b/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_proxy.tpl new file mode 100644 index 0000000000..7880b394c4 --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_proxy.tpl @@ -0,0 +1,267 @@ +{{ define "partials.proxy" -}} +{{ if and .Values.proxy.nativeSidecar .Values.proxy.waitBeforeExitSeconds }} +{{ fail "proxy.nativeSidecar and waitBeforeExitSeconds cannot be used simultaneously" }} +{{- end }} +{{- if not (has .Values.proxy.logHTTPHeaders (list "insecure" "off" "")) }} +{{- fail "logHTTPHeaders must be one of: insecure | off" }} +{{- end }} +{{- $trustDomain := (.Values.identityTrustDomain | default .Values.clusterDomain) -}} +env: +- name: _pod_name + valueFrom: + fieldRef: + fieldPath: metadata.name +- name: _pod_ns + valueFrom: + fieldRef: + fieldPath: metadata.namespace +- name: _pod_nodeName + valueFrom: + fieldRef: + fieldPath: spec.nodeName +{{- if .Values.proxy.cores }} +- name: LINKERD2_PROXY_CORES + value: {{.Values.proxy.cores | quote}} +{{- end }} +{{ if .Values.proxy.requireIdentityOnInboundPorts -}} +- name: LINKERD2_PROXY_INBOUND_PORTS_REQUIRE_IDENTITY + value: {{.Values.proxy.requireIdentityOnInboundPorts | quote}} +{{ end -}} +{{ if .Values.proxy.requireTLSOnInboundPorts -}} +- name: LINKERD2_PROXY_INBOUND_PORTS_REQUIRE_TLS + value: {{.Values.proxy.requireTLSOnInboundPorts | quote}} +{{ end -}} +- name: LINKERD2_PROXY_SHUTDOWN_ENDPOINT_ENABLED + value: {{.Values.proxy.enableShutdownEndpoint | quote}} +- name: LINKERD2_PROXY_LOG + value: "{{.Values.proxy.logLevel}}{{ if not (eq .Values.proxy.logHTTPHeaders "insecure") }},[{headers}]=off,[{request}]=off{{ end }}" +- name: LINKERD2_PROXY_LOG_FORMAT + value: {{.Values.proxy.logFormat | quote}} +- name: LINKERD2_PROXY_DESTINATION_SVC_ADDR + value: {{ternary "localhost.:8086" (printf "linkerd-dst-headless.%s.svc.%s.:8086" .Release.Namespace .Values.clusterDomain) (eq (toString .Values.proxy.component) "linkerd-destination")}} +- name: LINKERD2_PROXY_DESTINATION_PROFILE_NETWORKS + value: {{.Values.clusterNetworks | quote}} +- name: LINKERD2_PROXY_POLICY_SVC_ADDR + value: {{ternary "localhost.:8090" (printf "linkerd-policy.%s.svc.%s.:8090" .Release.Namespace .Values.clusterDomain) (eq (toString .Values.proxy.component) "linkerd-destination")}} +- name: LINKERD2_PROXY_POLICY_WORKLOAD + value: | + {"ns":"$(_pod_ns)", "pod":"$(_pod_name)"} +- name: LINKERD2_PROXY_INBOUND_DEFAULT_POLICY + value: {{.Values.proxy.defaultInboundPolicy}} +- name: LINKERD2_PROXY_POLICY_CLUSTER_NETWORKS + value: {{.Values.clusterNetworks | quote}} +- name: LINKERD2_PROXY_CONTROL_STREAM_INITIAL_TIMEOUT + value: {{((.Values.proxy.control).streams).initialTimeout | default "" | quote}} +- name: LINKERD2_PROXY_CONTROL_STREAM_IDLE_TIMEOUT + value: {{((.Values.proxy.control).streams).idleTimeout | default "" | quote}} +- name: LINKERD2_PROXY_CONTROL_STREAM_LIFETIME + value: {{((.Values.proxy.control).streams).lifetime | default "" | quote}} +{{ if .Values.proxy.inboundConnectTimeout -}} +- name: LINKERD2_PROXY_INBOUND_CONNECT_TIMEOUT + value: {{.Values.proxy.inboundConnectTimeout | quote}} +{{ end -}} +{{ if .Values.proxy.outboundConnectTimeout -}} +- name: LINKERD2_PROXY_OUTBOUND_CONNECT_TIMEOUT + value: {{.Values.proxy.outboundConnectTimeout | quote}} +{{ end -}} +{{ if .Values.proxy.outboundDiscoveryCacheUnusedTimeout -}} +- name: LINKERD2_PROXY_OUTBOUND_DISCOVERY_IDLE_TIMEOUT + value: {{.Values.proxy.outboundDiscoveryCacheUnusedTimeout | quote}} +{{ end -}} +{{ if .Values.proxy.inboundDiscoveryCacheUnusedTimeout -}} +- name: LINKERD2_PROXY_INBOUND_DISCOVERY_IDLE_TIMEOUT + value: {{.Values.proxy.inboundDiscoveryCacheUnusedTimeout | quote}} +{{ end -}} +{{ if .Values.proxy.disableOutboundProtocolDetectTimeout -}} +- name: LINKERD2_PROXY_OUTBOUND_DETECT_TIMEOUT + value: "365d" +{{ end -}} +{{ if .Values.proxy.disableInboundProtocolDetectTimeout -}} +- name: LINKERD2_PROXY_INBOUND_DETECT_TIMEOUT + value: "365d" +{{ end -}} +- name: LINKERD2_PROXY_CONTROL_LISTEN_ADDR + value: "{{ if .Values.disableIPv6 }}0.0.0.0{{ else }}[::]{{ end }}:{{.Values.proxy.ports.control}}" +- name: LINKERD2_PROXY_ADMIN_LISTEN_ADDR + value: "{{ if .Values.disableIPv6 }}0.0.0.0{{ else }}[::]{{ end }}:{{.Values.proxy.ports.admin}}" +{{- /* Deprecated, superseded by LINKERD2_PROXY_OUTBOUND_LISTEN_ADDRS since proxy's v2.228.0 (deployed since edge-24.4.5) */}} +- name: LINKERD2_PROXY_OUTBOUND_LISTEN_ADDR + value: "127.0.0.1:{{.Values.proxy.ports.outbound}}" +- name: LINKERD2_PROXY_OUTBOUND_LISTEN_ADDRS + value: "127.0.0.1:{{.Values.proxy.ports.outbound}}{{ if not .Values.disableIPv6}},[::1]:{{.Values.proxy.ports.outbound}}{{ end }}" +- name: LINKERD2_PROXY_INBOUND_LISTEN_ADDR + value: "{{ if .Values.disableIPv6 }}0.0.0.0{{ else }}[::]{{ end }}:{{.Values.proxy.ports.inbound}}" +- name: LINKERD2_PROXY_INBOUND_IPS + valueFrom: + fieldRef: + fieldPath: status.podIPs +- name: LINKERD2_PROXY_INBOUND_PORTS + value: {{ .Values.proxy.podInboundPorts | quote }} +{{ if .Values.proxy.isGateway -}} +- name: LINKERD2_PROXY_INBOUND_GATEWAY_SUFFIXES + value: {{printf "svc.%s." .Values.clusterDomain}} +{{ end -}} +{{ if .Values.proxy.isIngress -}} +- name: LINKERD2_PROXY_INGRESS_MODE + value: "true" +{{ end -}} +- name: LINKERD2_PROXY_DESTINATION_PROFILE_SUFFIXES + {{- $internalDomain := printf "svc.%s." .Values.clusterDomain }} + value: {{ternary "." $internalDomain .Values.proxy.enableExternalProfiles}} +- name: LINKERD2_PROXY_INBOUND_ACCEPT_KEEPALIVE + value: 10000ms +- name: LINKERD2_PROXY_OUTBOUND_CONNECT_KEEPALIVE + value: 10000ms +{{- /* Configure inbound and outbound parameters, e.g. for HTTP/2 servers. */}} +{{ range $proxyK, $proxyV := (dict "inbound" .Values.proxy.inbound "outbound" .Values.proxy.outbound) -}} +{{ range $scopeK, $scopeV := $proxyV -}} +{{ range $protoK, $protoV := $scopeV -}} +{{ range $paramK, $paramV := $protoV -}} +- name: LINKERD2_PROXY_{{snakecase $proxyK | upper}}_{{snakecase $scopeK | upper}}_{{snakecase $protoK | upper}}_{{snakecase $paramK | upper}} + value: {{ quote $paramV }} +{{ end -}} +{{ end -}} +{{ end -}} +{{ end -}} +{{ if .Values.proxy.opaquePorts -}} +- name: LINKERD2_PROXY_INBOUND_PORTS_DISABLE_PROTOCOL_DETECTION + value: {{.Values.proxy.opaquePorts | quote}} +{{ end -}} +- name: LINKERD2_PROXY_DESTINATION_CONTEXT + value: | + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} +- name: _pod_sa + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName +- name: _l5d_ns + value: {{.Release.Namespace}} +- name: _l5d_trustdomain + value: {{$trustDomain}} +- name: LINKERD2_PROXY_IDENTITY_DIR + value: /var/run/linkerd/identity/end-entity +- name: LINKERD2_PROXY_IDENTITY_TRUST_ANCHORS +{{- /* +Pods in the `linkerd` namespace are not injected by the proxy injector and instead obtain +the trust anchor bundle from the `linkerd-identity-trust-roots` configmap. This should not +be used in other contexts. +*/}} +{{- if .Values.proxy.loadTrustBundleFromConfigMap }} + valueFrom: + configMapKeyRef: + name: linkerd-identity-trust-roots + key: ca-bundle.crt +{{ else }} + value: | + {{- required "Please provide the identity trust anchors" .Values.identityTrustAnchorsPEM | trim | nindent 4 }} +{{ end -}} +- name: LINKERD2_PROXY_IDENTITY_TOKEN_FILE +{{- if .Values.identity.serviceAccountTokenProjection }} + value: /var/run/secrets/tokens/linkerd-identity-token +{{ else }} + value: /var/run/secrets/kubernetes.io/serviceaccount/token +{{ end -}} +- name: LINKERD2_PROXY_IDENTITY_SVC_ADDR + value: {{ternary "localhost.:8080" (printf "linkerd-identity-headless.%s.svc.%s.:8080" .Release.Namespace .Values.clusterDomain) (eq (toString .Values.proxy.component) "linkerd-identity")}} +- name: LINKERD2_PROXY_IDENTITY_LOCAL_NAME + value: $(_pod_sa).$(_pod_ns).serviceaccount.identity.{{.Release.Namespace}}.{{$trustDomain}} +- name: LINKERD2_PROXY_IDENTITY_SVC_NAME + value: linkerd-identity.{{.Release.Namespace}}.serviceaccount.identity.{{.Release.Namespace}}.{{$trustDomain}} +- name: LINKERD2_PROXY_DESTINATION_SVC_NAME + value: linkerd-destination.{{.Release.Namespace}}.serviceaccount.identity.{{.Release.Namespace}}.{{$trustDomain}} +- name: LINKERD2_PROXY_POLICY_SVC_NAME + value: linkerd-destination.{{.Release.Namespace}}.serviceaccount.identity.{{.Release.Namespace}}.{{$trustDomain}} +{{ if .Values.proxy.accessLog -}} +- name: LINKERD2_PROXY_ACCESS_LOG + value: {{.Values.proxy.accessLog | quote}} +{{ end -}} +{{ if .Values.proxy.shutdownGracePeriod -}} +- name: LINKERD2_PROXY_SHUTDOWN_GRACE_PERIOD + value: {{.Values.proxy.shutdownGracePeriod | quote}} +{{ end -}} +{{ if .Values.proxy.additionalEnv -}} +{{ toYaml .Values.proxy.additionalEnv }} +{{ end -}} +{{ if .Values.proxy.experimentalEnv -}} +{{ toYaml .Values.proxy.experimentalEnv }} +{{ end -}} +image: {{.Values.proxy.image.name}}:{{.Values.proxy.image.version | default .Values.linkerdVersion}} +imagePullPolicy: {{.Values.proxy.image.pullPolicy | default .Values.imagePullPolicy}} +livenessProbe: + httpGet: + path: /live + port: {{.Values.proxy.ports.admin}} + initialDelaySeconds: {{.Values.proxy.livenessProbe.initialDelaySeconds }} + timeoutSeconds: {{.Values.proxy.livenessProbe.timeoutSeconds }} +name: linkerd-proxy +ports: +- containerPort: {{.Values.proxy.ports.inbound}} + name: linkerd-proxy +- containerPort: {{.Values.proxy.ports.admin}} + name: linkerd-admin +readinessProbe: + httpGet: + path: /ready + port: {{.Values.proxy.ports.admin}} + initialDelaySeconds: {{.Values.proxy.readinessProbe.initialDelaySeconds }} + timeoutSeconds: {{.Values.proxy.readinessProbe.timeoutSeconds }} +{{- if and .Values.proxy.nativeSidecar .Values.proxy.await }} +startupProbe: + httpGet: + path: /ready + port: {{.Values.proxy.ports.admin}} + initialDelaySeconds: {{.Values.proxy.startupProbe.initialDelaySeconds}} + periodSeconds: {{.Values.proxy.startupProbe.periodSeconds}} + failureThreshold: {{.Values.proxy.startupProbe.failureThreshold}} +{{- end }} +{{- if .Values.proxy.resources }} +{{ include "partials.resources" .Values.proxy.resources }} +{{- end }} +securityContext: + allowPrivilegeEscalation: false + {{- if .Values.proxy.capabilities -}} + {{- include "partials.proxy.capabilities" . | nindent 2 -}} + {{- end }} + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: {{.Values.proxy.uid}} +{{- if ge (int .Values.proxy.gid) 0 }} + runAsGroup: {{.Values.proxy.gid}} +{{- end }} + seccompProfile: + type: RuntimeDefault +terminationMessagePolicy: FallbackToLogsOnError +{{- if and (not .Values.proxy.nativeSidecar) (or .Values.proxy.await .Values.proxy.waitBeforeExitSeconds) }} +lifecycle: +{{- if .Values.proxy.await }} + postStart: + exec: + command: + - /usr/lib/linkerd/linkerd-await + - --timeout=2m + - --port={{.Values.proxy.ports.admin}} +{{- end }} +{{- if .Values.proxy.waitBeforeExitSeconds }} + preStop: + exec: + command: + - /bin/sleep + - {{.Values.proxy.waitBeforeExitSeconds | quote}} +{{- end }} +{{- end }} +volumeMounts: +- mountPath: /var/run/linkerd/identity/end-entity + name: linkerd-identity-end-entity +{{- if .Values.identity.serviceAccountTokenProjection }} +- mountPath: /var/run/secrets/tokens + name: linkerd-identity-token +{{- end }} +{{- if .Values.proxy.saMountPath }} +- mountPath: {{.Values.proxy.saMountPath.mountPath}} + name: {{.Values.proxy.saMountPath.name}} + readOnly: {{.Values.proxy.saMountPath.readOnly}} +{{- end -}} +{{- if .Values.proxy.nativeSidecar }} +restartPolicy: Always +{{- end -}} +{{- end }} diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_pull-secrets.tpl b/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_pull-secrets.tpl new file mode 100644 index 0000000000..0c9aa4f01c --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_pull-secrets.tpl @@ -0,0 +1,6 @@ +{{- define "partials.image-pull-secrets"}} +{{- if . }} +imagePullSecrets: +{{ toYaml . | indent 2 }} +{{- end }} +{{- end -}} diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_resources.tpl b/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_resources.tpl new file mode 100644 index 0000000000..1fd6789fd7 --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_resources.tpl @@ -0,0 +1,28 @@ +{{- define "partials.resources" -}} +{{- $ephemeralStorage := index . "ephemeral-storage" -}} +resources: + {{- if or (.cpu).limit (.memory).limit ($ephemeralStorage).limit }} + limits: + {{- with (.cpu).limit }} + cpu: {{. | quote}} + {{- end }} + {{- with (.memory).limit }} + memory: {{. | quote}} + {{- end }} + {{- with ($ephemeralStorage).limit }} + ephemeral-storage: {{. | quote}} + {{- end }} + {{- end }} + {{- if or (.cpu).request (.memory).request ($ephemeralStorage).request }} + requests: + {{- with (.cpu).request }} + cpu: {{. | quote}} + {{- end }} + {{- with (.memory).request }} + memory: {{. | quote}} + {{- end }} + {{- with ($ephemeralStorage).request }} + ephemeral-storage: {{. | quote}} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_tolerations.tpl b/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_tolerations.tpl new file mode 100644 index 0000000000..c2292b1464 --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_tolerations.tpl @@ -0,0 +1,4 @@ +{{- define "linkerd.tolerations" -}} +tolerations: +{{ toYaml .Values.tolerations | trim | indent 2 }} +{{- end -}} diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_trace.tpl b/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_trace.tpl new file mode 100644 index 0000000000..dee059541f --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_trace.tpl @@ -0,0 +1,5 @@ +{{ define "partials.linkerd.trace" -}} +{{ if .Values.controlPlaneTracing -}} +- -trace-collector=collector.{{.Values.controlPlaneTracingNamespace}}.svc.{{.Values.clusterDomain}}:55678 +{{ end -}} +{{- end }} diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_validate.tpl b/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_validate.tpl new file mode 100644 index 0000000000..ba772c2fee --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_validate.tpl @@ -0,0 +1,19 @@ +{{- define "linkerd.webhook.validation" -}} + +{{- if and (.injectCaFrom) (.injectCaFromSecret) -}} +{{- fail "injectCaFrom and injectCaFromSecret cannot both be set" -}} +{{- end -}} + +{{- if and (or (.injectCaFrom) (.injectCaFromSecret)) (.caBundle) -}} +{{- fail "injectCaFrom or injectCaFromSecret cannot be set if providing a caBundle" -}} +{{- end -}} + +{{- if and (.externalSecret) (empty .caBundle) (empty .injectCaFrom) (empty .injectCaFromSecret) -}} +{{- fail "if externalSecret is set, then caBundle, injectCaFrom, or injectCaFromSecret must be set" -}} +{{- end }} + +{{- if and (or .injectCaFrom .injectCaFromSecret .caBundle) (not .externalSecret) -}} +{{- fail "if caBundle, injectCaFrom, or injectCaFromSecret is set, then externalSecret must be set" -}} +{{- end -}} + +{{- end -}} diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_volumes.tpl b/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_volumes.tpl new file mode 100644 index 0000000000..9684cf2409 --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/templates/_volumes.tpl @@ -0,0 +1,20 @@ +{{ define "partials.proxy.volumes.identity" -}} +emptyDir: + medium: Memory +name: linkerd-identity-end-entity +{{- end -}} + +{{ define "partials.proxyInit.volumes.xtables" -}} +emptyDir: {} +name: {{ .Values.proxyInit.xtMountPath.name }} +{{- end -}} + +{{- define "partials.proxy.volumes.service-account-token" -}} +name: linkerd-identity-token +projected: + sources: + - serviceAccountToken: + path: linkerd-identity-token + expirationSeconds: 86400 {{- /* # 24 hours */}} + audience: identity.l5d.io +{{- end -}} diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/values.yaml b/charts/linkerd/linkerd-control-plane/2024.8.3/charts/partials/values.yaml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/questions.yaml b/charts/linkerd/linkerd-control-plane/2024.8.3/questions.yaml new file mode 100644 index 0000000000..4ae27870a3 --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/questions.yaml @@ -0,0 +1,19 @@ +questions: +- variable: identityTrustAnchorsPEM + label: "Trust root certificate (ECDSA)" + description: "Root certificate used to support mTLS connections between meshed pods" + required: true + type: multiline + group: Identity +- variable: identity.issuer.tls.crtPEM + label: "Issuer certificate (ECDSA)" + description: "Intermediate certificate, rooted on identityTrustAnchorsPEM, used to sign the Linkerd proxies' CSR" + required: true + type: multiline + group: Identity +- variable: identity.issuer.tls.keyPEM + label: "Key for the issuer certificate (ECDSA)" + description: "Private key for the certificate entered on crtPEM" + required: true + type: multiline + group: Identity diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/templates/NOTES.txt b/charts/linkerd/linkerd-control-plane/2024.8.3/templates/NOTES.txt new file mode 100644 index 0000000000..4bd1be9fc0 --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/templates/NOTES.txt @@ -0,0 +1,19 @@ +The Linkerd control plane was successfully installed 🎉 + +To help you manage your Linkerd service mesh you can install the Linkerd CLI by running: + + curl -sL https://run.linkerd.io/install | sh + +Alternatively, you can download the CLI directly via the Linkerd releases page: + + https://github.com/linkerd/linkerd2/releases/ + +To make sure everything works as expected, run the following: + + linkerd check + +The viz extension can be installed by running: + + helm install linkerd-viz linkerd/linkerd-viz + +Looking for more? Visit https://linkerd.io/2/getting-started/ diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/templates/config-rbac.yaml b/charts/linkerd/linkerd-control-plane/2024.8.3/templates/config-rbac.yaml new file mode 100644 index 0000000000..5f5c34203e --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/templates/config-rbac.yaml @@ -0,0 +1,16 @@ +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} + annotations: + {{ include "partials.annotations.created-by" . }} + name: ext-namespace-metadata-linkerd-config + namespace: {{ .Release.Namespace }} +rules: +- apiGroups: [""] + resources: ["configmaps"] + verbs: ["get"] + resourceNames: ["linkerd-config"] diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/templates/config.yaml b/charts/linkerd/linkerd-control-plane/2024.8.3/templates/config.yaml new file mode 100644 index 0000000000..a9cea5f421 --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/templates/config.yaml @@ -0,0 +1,39 @@ +--- +kind: ConfigMap +apiVersion: v1 +metadata: + name: linkerd-config + namespace: {{ .Release.Namespace }} + labels: + linkerd.io/control-plane-component: controller + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} + annotations: + {{ include "partials.annotations.created-by" . }} +data: + linkerd-crds-chart-version: linkerd-crds-1.0.0-edge + values: | + {{- $values := deepCopy .Values }} + {{- /* + WARNING! All sensitive or private data such as TLS keys must be removed + here to avoid it being publicly readable. + */ -}} + {{- if kindIs "map" $values.identity.issuer.tls -}} + {{- $_ := unset $values.identity.issuer.tls "keyPEM"}} + {{- end -}} + {{- if kindIs "map" $values.profileValidator -}} + {{- $_ := unset $values.profileValidator "keyPEM"}} + {{- end -}} + {{- if kindIs "map" $values.proxyInjector -}} + {{- $_ := unset $values.proxyInjector "keyPEM"}} + {{- end -}} + {{- if kindIs "map" $values.policyValidator -}} + {{- $_ := unset $values.policyValidator "keyPEM"}} + {{- end -}} + {{- if (empty $values.identityTrustDomain) -}} + {{- $_ := set $values "identityTrustDomain" $values.clusterDomain}} + {{- end -}} + {{- $_ := unset $values "partials"}} + {{- $_ := unset $values "configs"}} + {{- $_ := unset $values "stage"}} + {{- toYaml $values | trim | nindent 4 }} diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/templates/destination-rbac.yaml b/charts/linkerd/linkerd-control-plane/2024.8.3/templates/destination-rbac.yaml new file mode 100644 index 0000000000..38488cd048 --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/templates/destination-rbac.yaml @@ -0,0 +1,327 @@ +--- +### +### Destination Controller Service +### +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: linkerd-{{.Release.Namespace}}-destination + labels: + linkerd.io/control-plane-component: destination + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} +rules: +- apiGroups: ["apps"] + resources: ["replicasets"] + verbs: ["list", "get", "watch"] +- apiGroups: ["batch"] + resources: ["jobs"] + verbs: ["list", "get", "watch"] +- apiGroups: [""] + resources: ["pods", "endpoints", "services", "nodes"] + verbs: ["list", "get", "watch"] +- apiGroups: ["linkerd.io"] + resources: ["serviceprofiles"] + verbs: ["list", "get", "watch"] +- apiGroups: ["workload.linkerd.io"] + resources: ["externalworkloads"] + verbs: ["list", "get", "watch"] +- apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["create", "get", "update", "patch"] + {{- if .Values.enableEndpointSlices }} +- apiGroups: ["discovery.k8s.io"] + resources: ["endpointslices"] + verbs: ["list", "get", "watch", "create", "update", "patch", "delete"] + {{- end }} +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: linkerd-{{.Release.Namespace}}-destination + labels: + linkerd.io/control-plane-component: destination + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: linkerd-{{.Release.Namespace}}-destination +subjects: +- kind: ServiceAccount + name: linkerd-destination + namespace: {{.Release.Namespace}} +--- +kind: ServiceAccount +apiVersion: v1 +metadata: + name: linkerd-destination + namespace: {{ .Release.Namespace }} + labels: + linkerd.io/control-plane-component: destination + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} +{{- include "partials.image-pull-secrets" .Values.imagePullSecrets }} +--- +{{- $host := printf "linkerd-sp-validator.%s.svc" .Release.Namespace }} +{{- $ca := genSelfSignedCert $host (list) (list $host) 365 }} +{{- if (not .Values.profileValidator.externalSecret) }} +kind: Secret +apiVersion: v1 +metadata: + name: linkerd-sp-validator-k8s-tls + namespace: {{ .Release.Namespace }} + labels: + linkerd.io/control-plane-component: destination + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} + annotations: + {{ include "partials.annotations.created-by" . }} +type: kubernetes.io/tls +data: + tls.crt: {{ ternary (b64enc (trim $ca.Cert)) (b64enc (trim .Values.profileValidator.crtPEM)) (empty .Values.profileValidator.crtPEM) }} + tls.key: {{ ternary (b64enc (trim $ca.Key)) (b64enc (trim .Values.profileValidator.keyPEM)) (empty .Values.profileValidator.keyPEM) }} +--- +{{- end }} +{{- include "linkerd.webhook.validation" .Values.profileValidator }} +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: linkerd-sp-validator-webhook-config + {{- if or (.Values.profileValidator.injectCaFrom) (.Values.profileValidator.injectCaFromSecret) }} + annotations: + {{- if .Values.profileValidator.injectCaFrom }} + cert-manager.io/inject-ca-from: {{ .Values.profileValidator.injectCaFrom }} + {{- end }} + {{- if .Values.profileValidator.injectCaFromSecret }} + cert-manager.io/inject-ca-from-secret: {{ .Values.profileValidator.injectCaFromSecret }} + {{- end }} + {{- end }} + labels: + linkerd.io/control-plane-component: destination + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} +webhooks: +- name: linkerd-sp-validator.linkerd.io + namespaceSelector: + {{- toYaml .Values.profileValidator.namespaceSelector | trim | nindent 4 }} + clientConfig: + service: + name: linkerd-sp-validator + namespace: {{ .Release.Namespace }} + path: "/" + {{- if and (empty .Values.profileValidator.injectCaFrom) (empty .Values.profileValidator.injectCaFromSecret) }} + caBundle: {{ ternary (b64enc (trim $ca.Cert)) (b64enc (trim .Values.profileValidator.caBundle)) (empty .Values.profileValidator.caBundle) }} + {{- end }} + failurePolicy: {{.Values.webhookFailurePolicy}} + admissionReviewVersions: ["v1", "v1beta1"] + rules: + - operations: ["CREATE", "UPDATE"] + apiGroups: ["linkerd.io"] + apiVersions: ["v1alpha1", "v1alpha2"] + resources: ["serviceprofiles"] + sideEffects: None +--- +{{- $host := printf "linkerd-policy-validator.%s.svc" .Release.Namespace }} +{{- $ca := genSelfSignedCert $host (list) (list $host) 365 }} +{{- if (not .Values.policyValidator.externalSecret) }} +kind: Secret +apiVersion: v1 +metadata: + name: linkerd-policy-validator-k8s-tls + namespace: {{ .Release.Namespace }} + labels: + linkerd.io/control-plane-component: destination + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} + annotations: + {{ include "partials.annotations.created-by" . }} +type: kubernetes.io/tls +data: + tls.crt: {{ ternary (b64enc (trim $ca.Cert)) (b64enc (trim .Values.policyValidator.crtPEM)) (empty .Values.policyValidator.crtPEM) }} + tls.key: {{ ternary (b64enc (trim $ca.Key)) (b64enc (trim .Values.policyValidator.keyPEM)) (empty .Values.policyValidator.keyPEM) }} +--- +{{- end }} +{{- include "linkerd.webhook.validation" .Values.policyValidator }} +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: linkerd-policy-validator-webhook-config + {{- if or (.Values.policyValidator.injectCaFrom) (.Values.policyValidator.injectCaFromSecret) }} + annotations: + {{- if .Values.policyValidator.injectCaFrom }} + cert-manager.io/inject-ca-from: {{ .Values.policyValidator.injectCaFrom }} + {{- end }} + {{- if .Values.policyValidator.injectCaFromSecret }} + cert-manager.io/inject-ca-from-secret: {{ .Values.policyValidator.injectCaFromSecret }} + {{- end }} + {{- end }} + labels: + linkerd.io/control-plane-component: destination + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} +webhooks: +- name: linkerd-policy-validator.linkerd.io + namespaceSelector: + {{- toYaml .Values.policyValidator.namespaceSelector | trim | nindent 4 }} + clientConfig: + service: + name: linkerd-policy-validator + namespace: {{ .Release.Namespace }} + path: "/" + {{- if and (empty .Values.policyValidator.injectCaFrom) (empty .Values.policyValidator.injectCaFromSecret) }} + caBundle: {{ ternary (b64enc (trim $ca.Cert)) (b64enc (trim .Values.policyValidator.caBundle)) (empty .Values.policyValidator.caBundle) }} + {{- end }} + failurePolicy: {{.Values.webhookFailurePolicy}} + admissionReviewVersions: ["v1", "v1beta1"] + rules: + - operations: ["CREATE", "UPDATE"] + apiGroups: ["policy.linkerd.io"] + apiVersions: ["*"] + resources: + - authorizationpolicies + - httproutes + - networkauthentications + - meshtlsauthentications + - serverauthorizations + - servers + - operations: ["CREATE", "UPDATE"] + apiGroups: ["gateway.networking.k8s.io"] + apiVersions: ["*"] + resources: + - httproutes + - grpcroutes + sideEffects: None +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: linkerd-policy + labels: + app.kubernetes.io/part-of: Linkerd + linkerd.io/control-plane-component: destination + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} +rules: + - apiGroups: + - "" + resources: + - pods + verbs: + - get + - list + - watch + - apiGroups: + - apps + resources: + - deployments + verbs: + - get + - apiGroups: + - policy.linkerd.io + resources: + - authorizationpolicies + - httproutes + - meshtlsauthentications + - networkauthentications + - servers + - serverauthorizations + verbs: + - get + - list + - watch + - apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes + - grpcroutes + verbs: + - get + - list + - watch + - apiGroups: + - policy.linkerd.io + resources: + - httproutes/status + verbs: + - patch + - apiGroups: + - gateway.networking.k8s.io + resources: + - httproutes/status + - grpcroutes/status + verbs: + - patch + - apiGroups: + - workload.linkerd.io + resources: + - externalworkloads + verbs: + - get + - list + - watch + - apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - create + - get + - patch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: linkerd-destination-policy + labels: + app.kubernetes.io/part-of: Linkerd + linkerd.io/control-plane-component: destination + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: linkerd-policy +subjects: + - kind: ServiceAccount + name: linkerd-destination + namespace: {{.Release.Namespace}} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: remote-discovery + namespace: {{.Release.Namespace}} + labels: + app.kubernetes.io/part-of: Linkerd + linkerd.io/control-plane-component: destination + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} +rules: + - apiGroups: + - "" + resources: + - secrets + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: linkerd-destination-remote-discovery + namespace: {{.Release.Namespace}} + labels: + app.kubernetes.io/part-of: Linkerd + linkerd.io/control-plane-component: destination + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: remote-discovery +subjects: + - kind: ServiceAccount + name: linkerd-destination + namespace: {{.Release.Namespace}} diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/templates/destination.yaml b/charts/linkerd/linkerd-control-plane/2024.8.3/templates/destination.yaml new file mode 100644 index 0000000000..b214c3c648 --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/templates/destination.yaml @@ -0,0 +1,417 @@ +--- +### +### Destination Controller Service +### +kind: Service +apiVersion: v1 +metadata: + name: linkerd-dst + namespace: {{ .Release.Namespace }} + labels: + linkerd.io/control-plane-component: destination + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} + annotations: + {{ include "partials.annotations.created-by" . }} +spec: + type: ClusterIP + selector: + linkerd.io/control-plane-component: destination + ports: + - name: grpc + port: 8086 + targetPort: 8086 +--- +kind: Service +apiVersion: v1 +metadata: + name: linkerd-dst-headless + namespace: {{ .Release.Namespace }} + labels: + linkerd.io/control-plane-component: destination + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} + annotations: + {{ include "partials.annotations.created-by" . }} +spec: + clusterIP: None + selector: + linkerd.io/control-plane-component: destination + ports: + - name: grpc + port: 8086 + targetPort: 8086 +--- +kind: Service +apiVersion: v1 +metadata: + name: linkerd-sp-validator + namespace: {{ .Release.Namespace }} + labels: + linkerd.io/control-plane-component: destination + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} + annotations: + {{ include "partials.annotations.created-by" . }} +spec: + type: ClusterIP + selector: + linkerd.io/control-plane-component: destination + ports: + - name: sp-validator + port: 443 + targetPort: sp-validator +--- +kind: Service +apiVersion: v1 +metadata: + name: linkerd-policy + namespace: {{ .Release.Namespace }} + labels: + linkerd.io/control-plane-component: destination + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} + annotations: + {{ include "partials.annotations.created-by" . }} +spec: + clusterIP: None + selector: + linkerd.io/control-plane-component: destination + ports: + - name: grpc + port: 8090 + targetPort: 8090 +--- +kind: Service +apiVersion: v1 +metadata: + name: linkerd-policy-validator + namespace: {{ .Release.Namespace }} + labels: + linkerd.io/control-plane-component: destination + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} + annotations: + {{ include "partials.annotations.created-by" . }} +spec: + type: ClusterIP + selector: + linkerd.io/control-plane-component: destination + ports: + - name: policy-https + port: 443 + targetPort: policy-https +{{- if .Values.enablePodDisruptionBudget }} +--- +kind: PodDisruptionBudget +apiVersion: policy/v1 +metadata: + name: linkerd-dst + namespace: {{ .Release.Namespace }} + labels: + linkerd.io/control-plane-component: destination + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} + annotations: + {{ include "partials.annotations.created-by" . }} +spec: + maxUnavailable: {{ .Values.controller.podDisruptionBudget.maxUnavailable }} + selector: + matchLabels: + linkerd.io/control-plane-component: destination +{{- end }} +--- +{{- $tree := deepCopy . }} +{{ $_ := set $tree.Values.proxy "workloadKind" "deployment" -}} +{{ $_ := set $tree.Values.proxy "component" "linkerd-destination" -}} +{{ $_ := set $tree.Values.proxy "waitBeforeExitSeconds" 0 -}} +{{- if not (empty .Values.destinationProxyResources) }} +{{- $c := dig "cores" .Values.proxy.cores .Values.destinationProxyResources }} +{{- $_ := set $tree.Values.proxy "cores" $c }} +{{- $r := merge .Values.destinationProxyResources .Values.proxy.resources }} +{{- $_ := set $tree.Values.proxy "resources" $r }} +{{- end }} +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + {{ include "partials.annotations.created-by" . }} + labels: + app.kubernetes.io/name: destination + app.kubernetes.io/part-of: Linkerd + app.kubernetes.io/version: {{.Values.linkerdVersion}} + linkerd.io/control-plane-component: destination + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} + name: linkerd-destination + namespace: {{ .Release.Namespace }} +spec: + replicas: {{.Values.controllerReplicas}} + revisionHistoryLimit: {{.Values.revisionHistoryLimit}} + selector: + matchLabels: + linkerd.io/control-plane-component: destination + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- include "partials.proxy.labels" $tree.Values.proxy | nindent 6}} + {{- if .Values.deploymentStrategy }} + strategy: + {{- with .Values.deploymentStrategy }}{{ toYaml . | trim | nindent 4 }}{{- end }} + {{- end }} + template: + metadata: + annotations: + checksum/config: {{ include (print $.Template.BasePath "/destination-rbac.yaml") . | sha256sum }} + {{ include "partials.annotations.created-by" . }} + {{- include "partials.proxy.annotations" . | nindent 8}} + {{- with .Values.podAnnotations }}{{ toYaml . | trim | nindent 8 }}{{- end }} + config.linkerd.io/default-inbound-policy: "all-unauthenticated" + labels: + linkerd.io/control-plane-component: destination + linkerd.io/control-plane-ns: {{.Release.Namespace}} + linkerd.io/workload-ns: {{.Release.Namespace}} + {{- include "partials.proxy.labels" $tree.Values.proxy | nindent 8}} + {{- with .Values.podLabels }}{{ toYaml . | trim | nindent 8 }}{{- end }} + spec: + {{- with .Values.runtimeClassName }} + runtimeClassName: {{ . | quote }} + {{- end }} + {{- if .Values.tolerations -}} + {{- include "linkerd.tolerations" . | nindent 6 }} + {{- end -}} + {{- include "linkerd.node-selector" . | nindent 6 }} + {{- $_ := set $tree "component" "destination" -}} + {{- include "linkerd.affinity" $tree | nindent 6 }} + containers: + {{- $_ := set $tree.Values.proxy "await" $tree.Values.proxy.await }} + {{- $_ := set $tree.Values.proxy "loadTrustBundleFromConfigMap" true }} + {{- $_ := set $tree.Values.proxy "podInboundPorts" "8086,8090,8443,9443,9990,9996,9997" }} + {{- $_ := set $tree.Values.proxy "outboundDiscoveryCacheUnusedTimeout" "5s" }} + {{- $_ := set $tree.Values.proxy "inboundDiscoveryCacheUnusedTimeout" "90s" }} + {{- /* + The pod needs to accept webhook traffic, and we can't rely on that originating in the + cluster network. + */}} + {{- $_ := set $tree.Values.proxy "defaultInboundPolicy" "all-unauthenticated" }} + {{- $_ := set $tree.Values.proxy "capabilities" (dict "drop" (list "ALL")) }} + {{- if not $tree.Values.proxy.nativeSidecar }} + - {{- include "partials.proxy" $tree | indent 8 | trimPrefix (repeat 7 " ") }} + {{- end }} + - args: + - destination + - -addr=:8086 + - -controller-namespace={{.Release.Namespace}} + - -enable-h2-upgrade={{.Values.enableH2Upgrade}} + - -log-level={{.Values.controllerLogLevel}} + - -log-format={{.Values.controllerLogFormat}} + - -enable-endpoint-slices={{.Values.enableEndpointSlices}} + - -cluster-domain={{.Values.clusterDomain}} + - -identity-trust-domain={{.Values.identityTrustDomain | default .Values.clusterDomain}} + - -default-opaque-ports={{.Values.proxy.opaquePorts}} + - -enable-ipv6={{not .Values.disableIPv6}} + - -enable-pprof={{.Values.enablePprof | default false}} + {{- if (.Values.destinationController).meshedHttp2ClientProtobuf }} + - --meshed-http2-client-params={{ toJson .Values.destinationController.meshedHttp2ClientProtobuf }} + {{- end }} + {{- range (.Values.destinationController).additionalArgs }} + - {{ . }} + {{- end }} + {{- range (.Values.destinationController).experimentalArgs }} + - {{ . }} + {{- end }} + {{- if or (.Values.destinationController).additionalEnv (.Values.destinationController).experimentalEnv }} + env: + {{- with (.Values.destinationController).additionalEnv }} + {{- toYaml . | nindent 8 -}} + {{- end }} + {{- with (.Values.destinationController).experimentalEnv }} + {{- toYaml . | nindent 8 -}} + {{- end }} + {{- end }} + {{- include "partials.linkerd.trace" . | nindent 8 -}} + image: {{.Values.controllerImage}}:{{.Values.controllerImageVersion | default .Values.linkerdVersion}} + imagePullPolicy: {{.Values.imagePullPolicy}} + livenessProbe: + httpGet: + path: /ping + port: 9996 + initialDelaySeconds: 10 + name: destination + ports: + - containerPort: 8086 + name: grpc + - containerPort: 9996 + name: admin-http + readinessProbe: + failureThreshold: 7 + httpGet: + path: /ready + port: 9996 + {{- if .Values.destinationResources -}} + {{- include "partials.resources" .Values.destinationResources | nindent 8 }} + {{- end }} + securityContext: + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: {{.Values.controllerUID}} + {{- if ge (int .Values.controllerGID) 0 }} + runAsGroup: {{.Values.controllerGID}} + {{- end }} + allowPrivilegeEscalation: false + seccompProfile: + type: RuntimeDefault + - args: + - sp-validator + - -log-level={{.Values.controllerLogLevel}} + - -log-format={{.Values.controllerLogFormat}} + - -enable-pprof={{.Values.enablePprof | default false}} + {{- if or (.Values.spValidator).additionalEnv (.Values.spValidator).experimentalEnv }} + env: + {{- with (.Values.spValidator).additionalEnv }} + {{- toYaml . | nindent 8 -}} + {{- end }} + {{- with (.Values.spValidator).experimentalEnv }} + {{- toYaml . | nindent 8 -}} + {{- end }} + {{- end }} + image: {{.Values.controllerImage}}:{{.Values.controllerImageVersion | default .Values.linkerdVersion}} + imagePullPolicy: {{.Values.imagePullPolicy}} + livenessProbe: + httpGet: + path: /ping + port: 9997 + initialDelaySeconds: 10 + name: sp-validator + ports: + - containerPort: 8443 + name: sp-validator + - containerPort: 9997 + name: admin-http + readinessProbe: + failureThreshold: 7 + httpGet: + path: /ready + port: 9997 + {{- if .Values.spValidatorResources -}} + {{- include "partials.resources" .Values.spValidatorResources | nindent 8 }} + {{- end }} + securityContext: + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: {{.Values.controllerUID}} + {{- if ge (int .Values.controllerGID) 0 }} + runAsGroup: {{.Values.controllerGID}} + {{- end }} + allowPrivilegeEscalation: false + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /var/run/linkerd/tls + name: sp-tls + readOnly: true + - args: + - --admin-addr={{ if .Values.disableIPv6 }}0.0.0.0{{ else }}[::]{{ end }}:9990 + - --control-plane-namespace={{.Release.Namespace}} + - --grpc-addr={{ if .Values.disableIPv6 }}0.0.0.0{{ else }}[::]{{ end }}:8090 + - --server-addr={{ if .Values.disableIPv6 }}0.0.0.0{{ else }}[::]{{ end }}:9443 + - --server-tls-key=/var/run/linkerd/tls/tls.key + - --server-tls-certs=/var/run/linkerd/tls/tls.crt + - --cluster-networks={{.Values.clusterNetworks}} + - --identity-domain={{.Values.identityTrustDomain | default .Values.clusterDomain}} + - --cluster-domain={{.Values.clusterDomain}} + - --default-policy={{.Values.proxy.defaultInboundPolicy}} + - --log-level={{.Values.policyController.logLevel | default "linkerd=info,warn"}} + - --log-format={{.Values.controllerLogFormat}} + - --default-opaque-ports={{.Values.proxy.opaquePorts}} + {{- if .Values.policyController.probeNetworks }} + - --probe-networks={{.Values.policyController.probeNetworks | join ","}} + {{- end}} + {{- range .Values.policyController.additionalArgs }} + - {{ . }} + {{- end }} + {{- range .Values.policyController.experimentalArgs }} + - {{ . }} + {{- end }} + image: {{.Values.policyController.image.name}}:{{.Values.policyController.image.version | default .Values.linkerdVersion}} + imagePullPolicy: {{.Values.policyController.image.pullPolicy | default .Values.imagePullPolicy}} + livenessProbe: + httpGet: + path: /live + port: admin-http + name: policy + ports: + - containerPort: 8090 + name: grpc + - containerPort: 9990 + name: admin-http + - containerPort: 9443 + name: policy-https + readinessProbe: + failureThreshold: 7 + httpGet: + path: /ready + port: admin-http + initialDelaySeconds: 10 + {{- if .Values.policyController.resources }} + {{- include "partials.resources" .Values.policyController.resources | nindent 8 }} + {{- end }} + securityContext: + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: {{.Values.controllerUID}} + {{- if ge (int .Values.controllerGID) 0 }} + runAsGroup: {{.Values.controllerGID}} + {{- end }} + allowPrivilegeEscalation: false + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /var/run/linkerd/tls + name: policy-tls + readOnly: true + initContainers: + {{ if .Values.cniEnabled -}} + - {{- include "partials.network-validator" $tree | indent 8 | trimPrefix (repeat 7 " ") }} + {{ else -}} + {{- /* + The destination controller needs to connect to the Kubernetes API before the proxy is able + to proxy requests, so we always skip these connections. + */}} + {{- $_ := set $tree.Values.proxyInit "ignoreOutboundPorts" .Values.proxyInit.kubeAPIServerPorts -}} + - {{- include "partials.proxy-init" $tree | indent 8 | trimPrefix (repeat 7 " ") }} + {{ end -}} + {{- if $tree.Values.proxy.nativeSidecar }} + {{- $_ := set $tree.Values.proxy "startupProbeInitialDelaySeconds" 35 }} + {{- $_ := set $tree.Values.proxy "startupProbePeriodSeconds" 5 }} + {{- $_ := set $tree.Values.proxy "startupProbeFailureThreshold" 20 }} + - {{- include "partials.proxy" $tree | indent 8 | trimPrefix (repeat 7 " ") }} + {{ end -}} + {{- if .Values.priorityClassName -}} + priorityClassName: {{ .Values.priorityClassName }} + {{ end -}} + securityContext: + seccompProfile: + type: RuntimeDefault + serviceAccountName: linkerd-destination + volumes: + - name: sp-tls + secret: + secretName: linkerd-sp-validator-k8s-tls + - name: policy-tls + secret: + secretName: linkerd-policy-validator-k8s-tls + {{ if not .Values.cniEnabled -}} + - {{- include "partials.proxyInit.volumes.xtables" . | indent 8 | trimPrefix (repeat 7 " ") }} + {{ end -}} + {{if .Values.identity.serviceAccountTokenProjection -}} + - {{- include "partials.proxy.volumes.service-account-token" . | indent 8 | trimPrefix (repeat 7 " ") }} + {{ end -}} + - {{- include "partials.proxy.volumes.identity" . | indent 8 | trimPrefix (repeat 7 " ") }} diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/templates/heartbeat-rbac.yaml b/charts/linkerd/linkerd-control-plane/2024.8.3/templates/heartbeat-rbac.yaml new file mode 100644 index 0000000000..7b127543f4 --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/templates/heartbeat-rbac.yaml @@ -0,0 +1,78 @@ +{{ if not .Values.disableHeartBeat -}} +--- +### +### Heartbeat RBAC +### +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: linkerd-heartbeat + namespace: {{ .Release.Namespace }} + labels: + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} +rules: +- apiGroups: [""] + resources: ["configmaps"] + verbs: ["get"] + resourceNames: ["linkerd-config"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: linkerd-heartbeat + namespace: {{ .Release.Namespace }} + labels: + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} +roleRef: + kind: Role + name: linkerd-heartbeat + apiGroup: rbac.authorization.k8s.io +subjects: +- kind: ServiceAccount + name: linkerd-heartbeat + namespace: {{.Release.Namespace}} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: linkerd-heartbeat + labels: + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} +rules: +- apiGroups: [""] + resources: ["namespaces"] + verbs: ["list"] +- apiGroups: ["linkerd.io"] + resources: ["serviceprofiles"] + verbs: ["list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: linkerd-heartbeat + labels: + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} +roleRef: + kind: ClusterRole + name: linkerd-heartbeat + apiGroup: rbac.authorization.k8s.io +subjects: +- kind: ServiceAccount + name: linkerd-heartbeat + namespace: {{.Release.Namespace}} +--- +kind: ServiceAccount +apiVersion: v1 +metadata: + name: linkerd-heartbeat + namespace: {{ .Release.Namespace }} + labels: + linkerd.io/control-plane-component: heartbeat + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} +{{- include "partials.image-pull-secrets" .Values.imagePullSecrets }} +{{- end }} diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/templates/heartbeat.yaml b/charts/linkerd/linkerd-control-plane/2024.8.3/templates/heartbeat.yaml new file mode 100644 index 0000000000..9565376239 --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/templates/heartbeat.yaml @@ -0,0 +1,94 @@ +{{ if not .Values.disableHeartBeat -}} +--- +### +### Heartbeat +### +apiVersion: batch/v1 +kind: CronJob +metadata: + name: linkerd-heartbeat + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: heartbeat + app.kubernetes.io/part-of: Linkerd + app.kubernetes.io/version: {{.Values.linkerdVersion}} + linkerd.io/control-plane-component: heartbeat + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} + annotations: + {{ include "partials.annotations.created-by" . }} +spec: + concurrencyPolicy: Replace + {{ if .Values.heartbeatSchedule -}} + schedule: "{{.Values.heartbeatSchedule}}" + {{ else -}} + schedule: "{{ dateInZone "04 15 * * *" (now | mustDateModify "+10m") "UTC"}}" + {{ end -}} + successfulJobsHistoryLimit: 0 + jobTemplate: + spec: + template: + metadata: + labels: + linkerd.io/control-plane-component: heartbeat + linkerd.io/workload-ns: {{.Release.Namespace}} + {{- with .Values.podLabels }}{{ toYaml . | trim | nindent 12 }}{{- end }} + annotations: + {{ include "partials.annotations.created-by" . }} + {{- with .Values.podAnnotations }}{{ toYaml . | trim | nindent 12 }}{{- end }} + spec: + {{- if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName }} + {{- end -}} + {{- with .Values.runtimeClassName }} + runtimeClassName: {{ . | quote }} + {{- end }} + {{- if .Values.tolerations -}} + {{- include "linkerd.tolerations" . | nindent 10 }} + {{- end -}} + {{- include "linkerd.node-selector" . | nindent 10 }} + securityContext: + seccompProfile: + type: RuntimeDefault + serviceAccountName: linkerd-heartbeat + restartPolicy: Never + containers: + - name: heartbeat + image: {{.Values.controllerImage}}:{{.Values.controllerImageVersion | default .Values.linkerdVersion}} + imagePullPolicy: {{.Values.imagePullPolicy}} + env: + - name: LINKERD_DISABLED + value: "the heartbeat controller does not use the proxy" + {{- with (.Values.heartbeat).additionalEnv }} + {{- toYaml . | nindent 12 -}} + {{- end }} + {{- with (.Values.heartbeat).experimentalEnv }} + {{- toYaml . | nindent 12 -}} + {{- end }} + args: + - "heartbeat" + - "-controller-namespace={{.Release.Namespace}}" + - "-log-level={{.Values.controllerLogLevel}}" + - "-log-format={{.Values.controllerLogFormat}}" + {{- if .Values.prometheusUrl }} + - "-prometheus-url={{.Values.prometheusUrl}}" + {{- else }} + - "-prometheus-url=http://prometheus.linkerd-viz.svc.{{.Values.clusterDomain}}:9090" + {{- end }} + {{- if .Values.heartbeatResources -}} + {{- include "partials.resources" .Values.heartbeatResources | nindent 12 }} + {{- end }} + securityContext: + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: {{.Values.controllerUID}} + {{- if ge (int .Values.controllerGID) 0 }} + runAsGroup: {{.Values.controllerGID}} + {{- end }} + allowPrivilegeEscalation: false + seccompProfile: + type: RuntimeDefault +{{- end }} diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/templates/identity-rbac.yaml b/charts/linkerd/linkerd-control-plane/2024.8.3/templates/identity-rbac.yaml new file mode 100644 index 0000000000..6efdb4e104 --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/templates/identity-rbac.yaml @@ -0,0 +1,49 @@ +--- +### +### Identity Controller Service RBAC +### +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: linkerd-{{.Release.Namespace}}-identity + labels: + linkerd.io/control-plane-component: identity + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} +rules: +- apiGroups: ["authentication.k8s.io"] + resources: ["tokenreviews"] + verbs: ["create"] +# TODO(ver) Restrict this to the Linkerd namespace. See +# https://github.com/linkerd/linkerd2/issues/9367 +- apiGroups: [""] + resources: ["events"] + verbs: ["create", "patch"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: linkerd-{{.Release.Namespace}}-identity + labels: + linkerd.io/control-plane-component: identity + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: linkerd-{{.Release.Namespace}}-identity +subjects: +- kind: ServiceAccount + name: linkerd-identity + namespace: {{.Release.Namespace}} +--- +kind: ServiceAccount +apiVersion: v1 +metadata: + name: linkerd-identity + namespace: {{ .Release.Namespace }} + labels: + linkerd.io/control-plane-component: identity + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} +{{- include "partials.image-pull-secrets" .Values.imagePullSecrets }} diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/templates/identity.yaml b/charts/linkerd/linkerd-control-plane/2024.8.3/templates/identity.yaml new file mode 100644 index 0000000000..bd3bcbe310 --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/templates/identity.yaml @@ -0,0 +1,267 @@ +{{if .Values.identity -}} +--- +### +### Identity Controller Service +### +{{ if and (.Values.identity.issuer) (eq .Values.identity.issuer.scheme "linkerd.io/tls") -}} +--- +kind: Secret +apiVersion: v1 +metadata: + name: linkerd-identity-issuer + namespace: {{ .Release.Namespace }} + labels: + linkerd.io/control-plane-component: identity + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} + annotations: + {{ include "partials.annotations.created-by" . }} +data: + crt.pem: {{b64enc (required "Please provide the identity issuer certificate" .Values.identity.issuer.tls.crtPEM | trim)}} + key.pem: {{b64enc (required "Please provide the identity issue private key" .Values.identity.issuer.tls.keyPEM | trim)}} +{{- end}} +{{ if not (.Values.identity.externalCA) -}} +--- +kind: ConfigMap +apiVersion: v1 +metadata: + name: linkerd-identity-trust-roots + namespace: {{ .Release.Namespace }} + labels: + linkerd.io/control-plane-component: identity + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} + annotations: + {{ include "partials.annotations.created-by" . }} +data: + ca-bundle.crt: |-{{.Values.identityTrustAnchorsPEM | trim | nindent 4}} +{{- end}} +--- +kind: Service +apiVersion: v1 +metadata: + name: linkerd-identity + namespace: {{ .Release.Namespace }} + labels: + linkerd.io/control-plane-component: identity + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} + annotations: + {{ include "partials.annotations.created-by" . }} +spec: + type: ClusterIP + selector: + linkerd.io/control-plane-component: identity + ports: + - name: grpc + port: 8080 + targetPort: 8080 +--- +kind: Service +apiVersion: v1 +metadata: + name: linkerd-identity-headless + namespace: {{ .Release.Namespace }} + labels: + linkerd.io/control-plane-component: identity + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} + annotations: + {{ include "partials.annotations.created-by" . }} +spec: + clusterIP: None + selector: + linkerd.io/control-plane-component: identity + ports: + - name: grpc + port: 8080 + targetPort: 8080 +{{- if .Values.enablePodDisruptionBudget }} +--- +kind: PodDisruptionBudget +apiVersion: policy/v1 +metadata: + name: linkerd-identity + namespace: {{ .Release.Namespace }} + labels: + linkerd.io/control-plane-component: identity + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} + annotations: + {{ include "partials.annotations.created-by" . }} +spec: + maxUnavailable: {{ .Values.controller.podDisruptionBudget.maxUnavailable }} + selector: + matchLabels: + linkerd.io/control-plane-component: identity +{{- end }} +--- +{{- $tree := deepCopy . }} +{{ $_ := set $tree.Values.proxy "workloadKind" "deployment" -}} +{{ $_ := set $tree.Values.proxy "component" "linkerd-identity" -}} +{{ $_ := set $tree.Values.proxy "waitBeforeExitSeconds" 0 -}} +{{- if not (empty .Values.identityProxyResources) }} +{{- $c := dig "cores" .Values.proxy.cores .Values.identityProxyResources }} +{{- $_ := set $tree.Values.proxy "cores" $c }} +{{- $r := merge .Values.identityProxyResources .Values.proxy.resources }} +{{- $_ := set $tree.Values.proxy "resources" $r }} +{{- end }} +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + {{ include "partials.annotations.created-by" . }} + labels: + app.kubernetes.io/name: identity + app.kubernetes.io/part-of: Linkerd + app.kubernetes.io/version: {{.Values.linkerdVersion}} + linkerd.io/control-plane-component: identity + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} + name: linkerd-identity + namespace: {{ .Release.Namespace }} +spec: + replicas: {{.Values.controllerReplicas}} + revisionHistoryLimit: {{.Values.revisionHistoryLimit}} + selector: + matchLabels: + linkerd.io/control-plane-component: identity + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- include "partials.proxy.labels" $tree.Values.proxy | nindent 6}} + {{- if .Values.deploymentStrategy }} + strategy: + {{- with .Values.deploymentStrategy }}{{ toYaml . | trim | nindent 4 }}{{- end }} + {{- end }} + template: + metadata: + annotations: + {{ include "partials.annotations.created-by" . }} + {{- include "partials.proxy.annotations" . | nindent 8}} + {{- with .Values.podAnnotations }}{{ toYaml . | trim | nindent 8 }}{{- end }} + config.linkerd.io/default-inbound-policy: "all-unauthenticated" + labels: + linkerd.io/control-plane-component: identity + linkerd.io/control-plane-ns: {{.Release.Namespace}} + linkerd.io/workload-ns: {{.Release.Namespace}} + {{- include "partials.proxy.labels" $tree.Values.proxy | nindent 8}} + {{- with .Values.podLabels }}{{ toYaml . | trim | nindent 8 }}{{- end }} + spec: + {{- with .Values.runtimeClassName }} + runtimeClassName: {{ . | quote }} + {{- end }} + {{- if .Values.tolerations -}} + {{- include "linkerd.tolerations" . | nindent 6 }} + {{- end -}} + {{- include "linkerd.node-selector" . | nindent 6 }} + {{- $_ := set $tree "component" "identity" -}} + {{- include "linkerd.affinity" $tree | nindent 6 }} + containers: + - args: + - identity + - -log-level={{.Values.controllerLogLevel}} + - -log-format={{.Values.controllerLogFormat}} + - -controller-namespace={{.Release.Namespace}} + - -identity-trust-domain={{.Values.identityTrustDomain | default .Values.clusterDomain}} + - -identity-issuance-lifetime={{.Values.identity.issuer.issuanceLifetime}} + - -identity-clock-skew-allowance={{.Values.identity.issuer.clockSkewAllowance}} + - -identity-scheme={{.Values.identity.issuer.scheme}} + - -enable-pprof={{.Values.enablePprof | default false}} + - -kube-apiclient-qps={{.Values.identity.kubeAPI.clientQPS}} + - -kube-apiclient-burst={{.Values.identity.kubeAPI.clientBurst}} + {{- include "partials.linkerd.trace" . | nindent 8 -}} + env: + - name: LINKERD_DISABLED + value: "linkerd-await cannot block the identity controller" + {{- with (.Values.identity).additionalEnv }} + {{- toYaml . | nindent 8 -}} + {{- end }} + {{- with (.Values.identity).experimentalEnv }} + {{- toYaml . | nindent 8 -}} + {{- end }} + image: {{.Values.controllerImage}}:{{.Values.controllerImageVersion | default .Values.linkerdVersion}} + imagePullPolicy: {{.Values.imagePullPolicy}} + livenessProbe: + httpGet: + path: /ping + port: 9990 + initialDelaySeconds: 10 + name: identity + ports: + - containerPort: 8080 + name: grpc + - containerPort: 9990 + name: admin-http + readinessProbe: + failureThreshold: 7 + httpGet: + path: /ready + port: 9990 + {{- if .Values.identityResources -}} + {{- include "partials.resources" .Values.identityResources | nindent 8 }} + {{- end }} + securityContext: + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: {{.Values.controllerUID}} + {{- if ge (int .Values.controllerGID) 0 }} + runAsGroup: {{.Values.controllerGID}} + {{- end }} + allowPrivilegeEscalation: false + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /var/run/linkerd/identity/issuer + name: identity-issuer + - mountPath: /var/run/linkerd/identity/trust-roots/ + name: trust-roots + {{- $_ := set $tree.Values.proxy "await" false }} + {{- $_ := set $tree.Values.proxy "loadTrustBundleFromConfigMap" true }} + {{- $_ := set $tree.Values.proxy "podInboundPorts" "8080,9990" }} + {{- $_ := set $tree.Values.proxy "nativeSidecar" false }} + {{- /* + The identity controller cannot discover policies, so we configure it with defaults that + enforce TLS on the identity service. + */}} + {{- $_ := set $tree.Values.proxy "defaultInboundPolicy" "all-unauthenticated" }} + {{- $_ := set $tree.Values.proxy "requireTLSOnInboundPorts" "8080" }} + {{- $_ := set $tree.Values.proxy "capabilities" (dict "drop" (list "ALL")) }} + {{- $_ := set $tree.Values.proxy "outboundDiscoveryCacheUnusedTimeout" "5s" }} + {{- $_ := set $tree.Values.proxy "inboundDiscoveryCacheUnusedTimeout" "90s" }} + - {{- include "partials.proxy" $tree | indent 8 | trimPrefix (repeat 7 " ") }} + initContainers: + {{ if .Values.cniEnabled -}} + - {{- include "partials.network-validator" $tree | indent 8 | trimPrefix (repeat 7 " ") }} + {{ else -}} + {{- /* + The identity controller needs to connect to the Kubernetes API before the proxy is able to + proxy requests, so we always skip these connections. The identity controller makes no other + outbound connections (so it's not important to persist any other skip ports here) + */}} + {{- $_ := set $tree.Values.proxyInit "ignoreOutboundPorts" .Values.proxyInit.kubeAPIServerPorts -}} + - {{- include "partials.proxy-init" $tree | indent 8 | trimPrefix (repeat 7 " ") }} + {{ end -}} + {{- if .Values.priorityClassName -}} + priorityClassName: {{ .Values.priorityClassName }} + {{ end -}} + securityContext: + seccompProfile: + type: RuntimeDefault + serviceAccountName: linkerd-identity + volumes: + - name: identity-issuer + secret: + secretName: linkerd-identity-issuer + - configMap: + name: linkerd-identity-trust-roots + name: trust-roots + {{ if not .Values.cniEnabled -}} + - {{- include "partials.proxyInit.volumes.xtables" . | indent 8 | trimPrefix (repeat 7 " ") }} + {{ end -}} + {{if .Values.identity.serviceAccountTokenProjection -}} + - {{- include "partials.proxy.volumes.service-account-token" . | indent 8 | trimPrefix (repeat 7 " ") }} + {{ end -}} + - {{- include "partials.proxy.volumes.identity" . | indent 8 | trimPrefix (repeat 7 " ") }} +{{end -}} diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/templates/namespace.yaml b/charts/linkerd/linkerd-control-plane/2024.8.3/templates/namespace.yaml new file mode 100644 index 0000000000..61461c1327 --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/templates/namespace.yaml @@ -0,0 +1,18 @@ +{{- if eq .Release.Service "CLI" -}} +--- +### +### Linkerd Namespace +### +kind: Namespace +apiVersion: v1 +metadata: + name: {{ .Release.Namespace }} + annotations: + linkerd.io/inject: disabled + labels: + linkerd.io/is-control-plane: "true" + config.linkerd.io/admission-webhooks: disabled + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- /* linkerd-init requires extended capabilities and so requires priviledged mode */}} + pod-security.kubernetes.io/enforce: {{ ternary "restricted" "privileged" .Values.cniEnabled }} +{{ end -}} diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/templates/podmonitor.yaml b/charts/linkerd/linkerd-control-plane/2024.8.3/templates/podmonitor.yaml new file mode 100644 index 0000000000..fd2b5d6ceb --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/templates/podmonitor.yaml @@ -0,0 +1,128 @@ +{{- $podMonitor := .Values.podMonitor -}} +{{- if and $podMonitor.enabled $podMonitor.controller.enabled }} +--- +### +### Prometheus Operator PodMonitor for Linkerd control-plane +### +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + name: "linkerd-controller" + namespace: {{ .Release.Namespace }} + labels: + linkerd.io/control-plane-ns: {{ .Release.Namespace }} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} + {{- with .Values.podMonitor.labels }}{{ toYaml . | trim | nindent 4 }}{{- end }} + annotations: + {{ include "partials.annotations.created-by" . }} +spec: + namespaceSelector: {{ tpl .Values.podMonitor.controller.namespaceSelector . | nindent 4 }} + selector: + matchLabels: {} + podMetricsEndpoints: + - interval: {{ $podMonitor.scrapeInterval }} + scrapeTimeout: {{ $podMonitor.scrapeTimeout }} + relabelings: + - sourceLabels: + - __meta_kubernetes_pod_container_port_name + action: keep + regex: admin-http + - sourceLabels: + - __meta_kubernetes_pod_container_name + action: replace + targetLabel: component +{{- end }} +{{- if and $podMonitor.enabled $podMonitor.serviceMirror.enabled }} +--- +### +### Prometheus Operator PodMonitor for Linkerd Service Mirror (multi-cluster) +### +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + name: "linkerd-service-mirror" + namespace: {{ .Release.Namespace }} + labels: + linkerd.io/control-plane-ns: {{ .Release.Namespace }} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} + {{- with .Values.podMonitor.labels }}{{ toYaml . | trim | nindent 4 }}{{- end }} + annotations: + {{ include "partials.annotations.created-by" . }} +spec: + namespaceSelector: + any: true + selector: + matchLabels: {} + podMetricsEndpoints: + - interval: {{ $podMonitor.scrapeInterval }} + scrapeTimeout: {{ $podMonitor.scrapeTimeout }} + relabelings: + - sourceLabels: + - __meta_kubernetes_pod_label_linkerd_io_control_plane_component + - __meta_kubernetes_pod_container_port_name + action: keep + regex: linkerd-service-mirror;admin-http$ + - sourceLabels: + - __meta_kubernetes_pod_container_name + action: replace + targetLabel: component +{{- end }} +{{- if and $podMonitor.enabled $podMonitor.proxy.enabled }} +--- +### +### Prometheus Operator PodMonitor Linkerd data-plane +### +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + name: "linkerd-proxy" + namespace: {{ .Release.Namespace }} + labels: + linkerd.io/control-plane-ns: {{ .Release.Namespace }} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} + {{- with .Values.podMonitor.labels }}{{ toYaml . | trim | nindent 4 }}{{- end }} + annotations: + {{ include "partials.annotations.created-by" . }} +spec: + namespaceSelector: + any: true + selector: + matchLabels: {} + podMetricsEndpoints: + - interval: {{ $podMonitor.scrapeInterval }} + scrapeTimeout: {{ $podMonitor.scrapeTimeout }} + relabelings: + - sourceLabels: + - __meta_kubernetes_pod_container_name + - __meta_kubernetes_pod_container_port_name + - __meta_kubernetes_pod_label_linkerd_io_control_plane_ns + action: keep + regex: ^linkerd-proxy;linkerd-admin;{{ .Release.Namespace }}$ + - sourceLabels: [ __meta_kubernetes_namespace ] + action: replace + targetLabel: namespace + - sourceLabels: [ __meta_kubernetes_pod_name ] + action: replace + targetLabel: pod + - sourceLabels: [ __meta_kubernetes_pod_label_linkerd_io_proxy_job ] + action: replace + targetLabel: k8s_job + - action: labeldrop + regex: __meta_kubernetes_pod_label_linkerd_io_proxy_job + - action: labelmap + regex: __meta_kubernetes_pod_label_linkerd_io_proxy_(.+) + - action: labeldrop + regex: __meta_kubernetes_pod_label_linkerd_io_proxy_(.+) + - action: labelmap + regex: __meta_kubernetes_pod_label_linkerd_io_(.+) + - action: labelmap + regex: __meta_kubernetes_pod_label_(.+) + replacement: __tmp_pod_label_$1 + - action: labelmap + regex: __tmp_pod_label_linkerd_io_(.+) + replacement: __tmp_pod_label_$1 + - action: labeldrop + regex: __tmp_pod_label_linkerd_io_(.+) + - action: labelmap + regex: __tmp_pod_label_(.+) +{{- end }} diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/templates/proxy-injector-rbac.yaml b/charts/linkerd/linkerd-control-plane/2024.8.3/templates/proxy-injector-rbac.yaml new file mode 100644 index 0000000000..c2c84c5c17 --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/templates/proxy-injector-rbac.yaml @@ -0,0 +1,120 @@ +--- +### +### Proxy Injector RBAC +### +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: linkerd-{{.Release.Namespace}}-proxy-injector + labels: + linkerd.io/control-plane-component: proxy-injector + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} +rules: +- apiGroups: [""] + resources: ["events"] + verbs: ["create", "patch"] +- apiGroups: [""] + resources: ["namespaces", "replicationcontrollers"] + verbs: ["list", "get", "watch"] +- apiGroups: [""] + resources: ["pods"] + verbs: ["list", "watch"] +- apiGroups: ["extensions", "apps"] + resources: ["deployments", "replicasets", "daemonsets", "statefulsets"] + verbs: ["list", "get", "watch"] +- apiGroups: ["extensions", "batch"] + resources: ["cronjobs", "jobs"] + verbs: ["list", "get", "watch"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: linkerd-{{.Release.Namespace}}-proxy-injector + labels: + linkerd.io/control-plane-component: proxy-injector + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} +subjects: +- kind: ServiceAccount + name: linkerd-proxy-injector + namespace: {{.Release.Namespace}} + apiGroup: "" +roleRef: + kind: ClusterRole + name: linkerd-{{.Release.Namespace}}-proxy-injector + apiGroup: rbac.authorization.k8s.io +--- +kind: ServiceAccount +apiVersion: v1 +metadata: + name: linkerd-proxy-injector + namespace: {{ .Release.Namespace }} + labels: + linkerd.io/control-plane-component: proxy-injector + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} +{{- include "partials.image-pull-secrets" .Values.imagePullSecrets }} +--- +{{- $host := printf "linkerd-proxy-injector.%s.svc" .Release.Namespace }} +{{- $ca := genSelfSignedCert $host (list) (list $host) 365 }} +{{- if (not .Values.proxyInjector.externalSecret) }} +kind: Secret +apiVersion: v1 +metadata: + name: linkerd-proxy-injector-k8s-tls + namespace: {{ .Release.Namespace }} + labels: + linkerd.io/control-plane-component: proxy-injector + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} + annotations: + {{ include "partials.annotations.created-by" . }} +type: kubernetes.io/tls +data: + tls.crt: {{ ternary (b64enc (trim $ca.Cert)) (b64enc (trim .Values.proxyInjector.crtPEM)) (empty .Values.proxyInjector.crtPEM) }} + tls.key: {{ ternary (b64enc (trim $ca.Key)) (b64enc (trim .Values.proxyInjector.keyPEM)) (empty .Values.proxyInjector.keyPEM) }} +--- +{{- end }} +{{- include "linkerd.webhook.validation" .Values.proxyInjector }} +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + name: linkerd-proxy-injector-webhook-config + {{- if or (.Values.proxyInjector.injectCaFrom) (.Values.proxyInjector.injectCaFromSecret) }} + annotations: + {{- if .Values.proxyInjector.injectCaFrom }} + cert-manager.io/inject-ca-from: {{ .Values.proxyInjector.injectCaFrom }} + {{- end }} + {{- if .Values.proxyInjector.injectCaFromSecret }} + cert-manager.io/inject-ca-from-secret: {{ .Values.proxyInjector.injectCaFromSecret }} + {{- end }} + {{- end }} + labels: + linkerd.io/control-plane-component: proxy-injector + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} +webhooks: +- name: linkerd-proxy-injector.linkerd.io + namespaceSelector: + {{- toYaml .Values.proxyInjector.namespaceSelector | trim | nindent 4 }} + objectSelector: + {{- toYaml .Values.proxyInjector.objectSelector | trim | nindent 4 }} + clientConfig: + service: + name: linkerd-proxy-injector + namespace: {{ .Release.Namespace }} + path: "/" + {{- if and (empty .Values.proxyInjector.injectCaFrom) (empty .Values.proxyInjector.injectCaFromSecret) }} + caBundle: {{ ternary (b64enc (trim $ca.Cert)) (b64enc (trim .Values.proxyInjector.caBundle)) (empty .Values.proxyInjector.caBundle) }} + {{- end }} + failurePolicy: {{.Values.webhookFailurePolicy}} + admissionReviewVersions: ["v1", "v1beta1"] + rules: + - operations: [ "CREATE" ] + apiGroups: [""] + apiVersions: ["v1"] + resources: ["pods", "services"] + scope: "Namespaced" + sideEffects: None + timeoutSeconds: {{ .Values.proxyInjector.timeoutSeconds | default 10 }} diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/templates/proxy-injector.yaml b/charts/linkerd/linkerd-control-plane/2024.8.3/templates/proxy-injector.yaml new file mode 100644 index 0000000000..0f6b3bb875 --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/templates/proxy-injector.yaml @@ -0,0 +1,216 @@ +--- +### +### Proxy Injector +### +{{- $tree := deepCopy . }} +{{ $_ := set $tree.Values.proxy "workloadKind" "deployment" -}} +{{ $_ := set $tree.Values.proxy "component" "linkerd-proxy-injector" -}} +{{ $_ := set $tree.Values.proxy "waitBeforeExitSeconds" 0 -}} +{{- if not (empty .Values.proxyInjectorProxyResources) }} +{{- $c := dig "cores" .Values.proxy.cores .Values.proxyInjectorProxyResources }} +{{- $_ := set $tree.Values.proxy "cores" $c }} +{{- $r := merge .Values.proxyInjectorProxyResources .Values.proxy.resources }} +{{- $_ := set $tree.Values.proxy "resources" $r }} +{{- end }} +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + {{ include "partials.annotations.created-by" . }} + labels: + app.kubernetes.io/name: proxy-injector + app.kubernetes.io/part-of: Linkerd + app.kubernetes.io/version: {{.Values.linkerdVersion}} + linkerd.io/control-plane-component: proxy-injector + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} + name: linkerd-proxy-injector + namespace: {{ .Release.Namespace }} +spec: + replicas: {{.Values.controllerReplicas}} + revisionHistoryLimit: {{.Values.revisionHistoryLimit}} + selector: + matchLabels: + linkerd.io/control-plane-component: proxy-injector + {{- if .Values.deploymentStrategy }} + strategy: + {{- with .Values.deploymentStrategy }}{{ toYaml . | trim | nindent 4 }}{{- end }} + {{- end }} + template: + metadata: + annotations: + checksum/config: {{ include (print $.Template.BasePath "/proxy-injector-rbac.yaml") . | sha256sum }} + {{ include "partials.annotations.created-by" . }} + {{- include "partials.proxy.annotations" . | nindent 8}} + {{- with .Values.podAnnotations }}{{ toYaml . | trim | nindent 8 }}{{- end }} + config.linkerd.io/opaque-ports: "8443" + config.linkerd.io/default-inbound-policy: "all-unauthenticated" + labels: + linkerd.io/control-plane-component: proxy-injector + linkerd.io/control-plane-ns: {{.Release.Namespace}} + linkerd.io/workload-ns: {{.Release.Namespace}} + {{- include "partials.proxy.labels" $tree.Values.proxy | nindent 8}} + {{- with .Values.podLabels }}{{ toYaml . | trim | nindent 8 }}{{- end }} + spec: + {{- with .Values.runtimeClassName }} + runtimeClassName: {{ . | quote }} + {{- end }} + {{- if .Values.tolerations -}} + {{- include "linkerd.tolerations" . | nindent 6 }} + {{- end -}} + {{- include "linkerd.node-selector" . | nindent 6 }} + {{- $_ := set $tree "component" "proxy-injector" -}} + {{- include "linkerd.affinity" $tree | nindent 6 }} + containers: + {{- $_ := set $tree.Values.proxy "await" $tree.Values.proxy.await }} + {{- $_ := set $tree.Values.proxy "loadTrustBundleFromConfigMap" true }} + {{- $_ := set $tree.Values.proxy "podInboundPorts" "8443,9995" }} + {{- /* + The pod needs to accept webhook traffic, and we can't rely on that originating in the + cluster network. + */}} + {{- $_ := set $tree.Values.proxy "defaultInboundPolicy" "all-unauthenticated" }} + {{- $_ := set $tree.Values.proxy "capabilities" (dict "drop" (list "ALL")) }} + {{- $_ := set $tree.Values.proxy "outboundDiscoveryCacheUnusedTimeout" "5s" }} + {{- $_ := set $tree.Values.proxy "inboundDiscoveryCacheUnusedTimeout" "90s" }} + {{- if not $tree.Values.proxy.nativeSidecar }} + - {{- include "partials.proxy" $tree | indent 8 | trimPrefix (repeat 7 " ") }} + {{- end }} + - args: + - proxy-injector + - -log-level={{.Values.controllerLogLevel}} + - -log-format={{.Values.controllerLogFormat}} + - -linkerd-namespace={{.Release.Namespace}} + - -enable-pprof={{.Values.enablePprof | default false}} + {{- if or (.Values.proxyInjector).additionalEnv (.Values.proxyInjector).experimentalEnv }} + env: + {{- with (.Values.proxyInjector).additionalEnv }} + {{- toYaml . | nindent 8 -}} + {{- end }} + {{- with (.Values.proxyInjector).experimentalEnv }} + {{- toYaml . | nindent 8 -}} + {{- end }} + {{- end }} + image: {{.Values.controllerImage}}:{{.Values.controllerImageVersion | default .Values.linkerdVersion}} + imagePullPolicy: {{.Values.imagePullPolicy}} + livenessProbe: + httpGet: + path: /ping + port: 9995 + initialDelaySeconds: 10 + name: proxy-injector + ports: + - containerPort: 8443 + name: proxy-injector + - containerPort: 9995 + name: admin-http + readinessProbe: + failureThreshold: 7 + httpGet: + path: /ready + port: 9995 + {{- if .Values.proxyInjectorResources -}} + {{- include "partials.resources" .Values.proxyInjectorResources | nindent 8 }} + {{- end }} + securityContext: + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: {{.Values.controllerUID}} + {{- if ge (int .Values.controllerGID) 0 }} + runAsGroup: {{.Values.controllerGID}} + {{- end }} + allowPrivilegeEscalation: false + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /var/run/linkerd/config + name: config + - mountPath: /var/run/linkerd/identity/trust-roots + name: trust-roots + - mountPath: /var/run/linkerd/tls + name: tls + readOnly: true + initContainers: + {{ if .Values.cniEnabled -}} + - {{- include "partials.network-validator" $tree | indent 8 | trimPrefix (repeat 7 " ") }} + {{ else -}} + {{- /* + The controller needs to connect to the Kubernetes API. There's no reason + to put the proxy in the way of that. + */}} + {{- $_ := set $tree.Values.proxyInit "ignoreOutboundPorts" .Values.proxyInit.kubeAPIServerPorts -}} + - {{- include "partials.proxy-init" $tree | indent 8 | trimPrefix (repeat 7 " ") }} + {{ end -}} + {{- if $tree.Values.proxy.nativeSidecar }} + {{- $_ := set $tree.Values.proxy "startupProbeInitialDelaySeconds" 35 }} + {{- $_ := set $tree.Values.proxy "startupProbePeriodSeconds" 5 }} + {{- $_ := set $tree.Values.proxy "startupProbeFailureThreshold" 20 }} + - {{- include "partials.proxy" $tree | indent 8 | trimPrefix (repeat 7 " ") }} + {{ end -}} + {{- if .Values.priorityClassName -}} + priorityClassName: {{ .Values.priorityClassName }} + {{ end -}} + securityContext: + seccompProfile: + type: RuntimeDefault + serviceAccountName: linkerd-proxy-injector + volumes: + - configMap: + name: linkerd-config + name: config + - configMap: + name: linkerd-identity-trust-roots + name: trust-roots + - name: tls + secret: + secretName: linkerd-proxy-injector-k8s-tls + {{ if not .Values.cniEnabled -}} + - {{- include "partials.proxyInit.volumes.xtables" . | indent 8 | trimPrefix (repeat 7 " ") }} + {{ end -}} + {{if .Values.identity.serviceAccountTokenProjection -}} + - {{- include "partials.proxy.volumes.service-account-token" . | indent 8 | trimPrefix (repeat 7 " ") }} + {{ end -}} + - {{- include "partials.proxy.volumes.identity" . | indent 8 | trimPrefix (repeat 7 " ") }} +--- +kind: Service +apiVersion: v1 +metadata: + name: linkerd-proxy-injector + namespace: {{ .Release.Namespace }} + labels: + linkerd.io/control-plane-component: proxy-injector + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} + annotations: + {{ include "partials.annotations.created-by" . }} + config.linkerd.io/opaque-ports: "443" +spec: + type: ClusterIP + selector: + linkerd.io/control-plane-component: proxy-injector + ports: + - name: proxy-injector + port: 443 + targetPort: proxy-injector +{{- if .Values.enablePodDisruptionBudget }} +--- +kind: PodDisruptionBudget +apiVersion: policy/v1 +metadata: + name: linkerd-proxy-injector + namespace: {{ .Release.Namespace }} + labels: + linkerd.io/control-plane-component: proxy-injector + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} + annotations: + {{ include "partials.annotations.created-by" . }} +spec: + maxUnavailable: {{ .Values.controller.podDisruptionBudget.maxUnavailable }} + selector: + matchLabels: + linkerd.io/control-plane-component: proxy-injector +{{- end }} diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/templates/psp.yaml b/charts/linkerd/linkerd-control-plane/2024.8.3/templates/psp.yaml new file mode 100644 index 0000000000..db91fea675 --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/templates/psp.yaml @@ -0,0 +1,119 @@ +{{ if .Values.enablePSP -}} +--- +### +### Control Plane PSP +### +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: linkerd-{{.Release.Namespace}}-control-plane + annotations: + seccomp.security.alpha.kubernetes.io/allowedProfileNames: "runtime/default" + labels: + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} +spec: + {{- if or .Values.proxyInit.closeWaitTimeoutSecs .Values.proxyInit.runAsRoot }} + allowPrivilegeEscalation: true + {{- else }} + allowPrivilegeEscalation: false + {{- end }} + readOnlyRootFilesystem: true + {{- if empty .Values.cniEnabled }} + allowedCapabilities: + - NET_ADMIN + - NET_RAW + {{- end}} + requiredDropCapabilities: + - ALL + hostNetwork: false + hostIPC: false + hostPID: false + seLinux: + rule: RunAsAny + runAsUser: + {{- if .Values.cniEnabled }} + rule: MustRunAsNonRoot + {{- else }} + rule: RunAsAny + {{- end }} + runAsGroup: + {{- if .Values.cniEnabled }} + rule: MustRunAs + ranges: + - min: 1000 + max: 999999 + {{- else }} + rule: RunAsAny + {{- end }} + supplementalGroups: + rule: MustRunAs + ranges: + {{- if .Values.cniEnabled }} + - min: 10001 + max: 65535 + {{- else }} + - min: 1 + max: 65535 + {{- end }} + fsGroup: + rule: MustRunAs + ranges: + {{- if .Values.cniEnabled }} + - min: 10001 + max: 65535 + {{- else }} + - min: 1 + max: 65535 + {{- end }} + volumes: + - configMap + - emptyDir + - secret + - projected + - downwardAPI + - persistentVolumeClaim +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: linkerd-psp + namespace: {{ .Release.Namespace }} + labels: + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} +rules: +- apiGroups: ['policy', 'extensions'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - linkerd-{{.Release.Namespace}}-control-plane +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: linkerd-psp + namespace: {{ .Release.Namespace }} + labels: + linkerd.io/control-plane-ns: {{.Release.Namespace}} + {{- with .Values.commonLabels }}{{ toYaml . | trim | nindent 4 }}{{- end }} +roleRef: + kind: Role + name: linkerd-psp + apiGroup: rbac.authorization.k8s.io +subjects: +- kind: ServiceAccount + name: linkerd-destination + namespace: {{.Release.Namespace}} +{{ if not .Values.disableHeartBeat -}} +- kind: ServiceAccount + name: linkerd-heartbeat + namespace: {{.Release.Namespace}} +{{ end -}} +- kind: ServiceAccount + name: linkerd-identity + namespace: {{.Release.Namespace}} +- kind: ServiceAccount + name: linkerd-proxy-injector + namespace: {{.Release.Namespace}} +{{ end -}} diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/values-ha.yaml b/charts/linkerd/linkerd-control-plane/2024.8.3/values-ha.yaml new file mode 100644 index 0000000000..e3b8cbc070 --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/values-ha.yaml @@ -0,0 +1,63 @@ +# This values.yaml file contains the values needed to enable HA mode. +# Usage: +# helm install -f values-ha.yaml + +# -- Create PodDisruptionBudget resources for each control plane workload +enablePodDisruptionBudget: true + +controller: + # -- sets pod disruption budget parameter for all deployments + podDisruptionBudget: + # -- Maximum number of pods that can be unavailable during disruption + maxUnavailable: 1 + +# -- Specify a deployment strategy for each control plane workload +deploymentStrategy: + rollingUpdate: + maxUnavailable: 1 + maxSurge: 25% + +# -- add PodAntiAffinity to each control plane workload +enablePodAntiAffinity: true + +# nodeAffinity: + +# proxy configuration +proxy: + resources: + cpu: + request: 100m + memory: + limit: 250Mi + request: 20Mi + +# controller configuration +controllerReplicas: 3 +controllerResources: &controller_resources + cpu: &controller_resources_cpu + limit: "" + request: 100m + memory: + limit: 250Mi + request: 50Mi +destinationResources: *controller_resources + +# identity configuration +identityResources: + cpu: *controller_resources_cpu + memory: + limit: 250Mi + request: 10Mi + +# heartbeat configuration +heartbeatResources: *controller_resources + +# proxy injector configuration +proxyInjectorResources: *controller_resources +webhookFailurePolicy: Fail + +# service profile validator configuration +spValidatorResources: *controller_resources + +# flag for linkerd check +highAvailability: true diff --git a/charts/linkerd/linkerd-control-plane/2024.8.3/values.yaml b/charts/linkerd/linkerd-control-plane/2024.8.3/values.yaml new file mode 100644 index 0000000000..b96b84355b --- /dev/null +++ b/charts/linkerd/linkerd-control-plane/2024.8.3/values.yaml @@ -0,0 +1,638 @@ +# Default values for linkerd. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# -- Kubernetes DNS Domain name to use +clusterDomain: cluster.local + +# -- The cluster networks for which service discovery is performed. This should +# include the pod and service networks, but need not include the node network. +# +# By default, all IPv4 private networks and all accepted IPv6 ULAs are +# specified so that resolution works in typical Kubernetes environments. +clusterNetworks: "10.0.0.0/8,100.64.0.0/10,172.16.0.0/12,192.168.0.0/16,fd00::/8" +# -- Docker image pull policy +imagePullPolicy: IfNotPresent +# -- Specifies the number of old ReplicaSets to retain to allow rollback. +revisionHistoryLimit: 10 +# -- Log level for the control plane components +controllerLogLevel: info +# -- Log format for the control plane components +controllerLogFormat: plain +# -- enables control plane tracing +controlPlaneTracing: false +# -- namespace to send control plane traces to +controlPlaneTracingNamespace: linkerd-jaeger +# -- control plane version. See Proxy section for proxy version +linkerdVersion: edge-24.8.3 +# -- default kubernetes deployment strategy +deploymentStrategy: + rollingUpdate: + maxUnavailable: 25% + maxSurge: 25% +# -- enables the use of EndpointSlice informers for the destination service; +# enableEndpointSlices should be set to true only if EndpointSlice K8s feature +# gate is on +enableEndpointSlices: true +# -- enables pod anti affinity creation on deployments for high availability +enablePodAntiAffinity: false +# -- enables the use of pprof endpoints on control plane component's admin +# servers +enablePprof: false +# -- enables the creation of pod disruption budgets for control plane components +enablePodDisruptionBudget: false +# -- disables routing IPv6 traffic in addition to IPv4 traffic through the +# proxy (IPv6 routing only available as of proxy-init v2.3.0 and linkerd-cni +# v1.4.0) +disableIPv6: true + +controller: + # -- sets pod disruption budget parameter for all deployments + podDisruptionBudget: + # -- Maximum number of pods that can be unavailable during disruption + maxUnavailable: 1 +# -- enabling this omits the NET_ADMIN capability in the PSP +# and the proxy-init container when injecting the proxy; +# requires the linkerd-cni plugin to already be installed +cniEnabled: false +# -- Trust root certificate (ECDSA). It must be provided during install. +identityTrustAnchorsPEM: | +# -- Trust domain used for identity +# @default -- clusterDomain +identityTrustDomain: "" +kubeAPI: &kubeapi + # -- Maximum QPS sent to the kube-apiserver before throttling. + # See [token bucket rate limiter + # implementation](https://github.com/kubernetes/client-go/blob/v12.0.0/util/flowcontrol/throttle.go) + clientQPS: 100 + # -- Burst value over clientQPS + clientBurst: 200 +# -- Additional annotations to add to all pods +podAnnotations: {} +# -- Additional labels to add to all pods +podLabels: {} +# -- Labels to apply to all resources +commonLabels: {} +# -- Kubernetes priorityClassName for the Linkerd Pods +priorityClassName: "" +# -- Runtime Class Name for all the pods +runtimeClassName: "" + +# policy controller configuration +policyController: + image: + # -- Docker image for the policy controller + name: cr.l5d.io/linkerd/policy-controller + # -- Pull policy for the policy controller container image + # @default -- imagePullPolicy + pullPolicy: "" + # -- Tag for the policy controller container image + # @default -- linkerdVersion + version: "" + + # -- Log level for the policy controller + logLevel: info + + # -- The networks from which probes are performed. + # + # By default, all networks are allowed so that all probes are authorized. + probeNetworks: + - 0.0.0.0/0 + - "::/0" + + # -- policy controller resource requests & limits + resources: + cpu: + # -- Maximum amount of CPU units that the policy controller can use + limit: "" + # -- Amount of CPU units that the policy controller requests + request: "" + memory: + # -- Maximum amount of memory that the policy controller can use + limit: "" + # -- Maximum amount of memory that the policy controller requests + request: "" + ephemeral-storage: + # -- Maximum amount of ephemeral storage that the policy controller can use + limit: "" + # -- Amount of ephemeral storage that the policy controller requests + request: "" + +# proxy configuration +proxy: + # -- Enable service profiles for non-Kubernetes services + enableExternalProfiles: false + # -- Maximum time allowed for the proxy to establish an outbound TCP + # connection + outboundConnectTimeout: 1000ms + # -- Maximum time allowed for the proxy to establish an inbound TCP + # connection + inboundConnectTimeout: 100ms + # -- Maximum time allowed before an unused outbound discovery result + # is evicted from the cache + outboundDiscoveryCacheUnusedTimeout: "5s" + # -- Maximum time allowed before an unused inbound discovery result + # is evicted from the cache + inboundDiscoveryCacheUnusedTimeout: "90s" + # -- When set to true, disables the protocol detection timeout on the + # outbound side of the proxy by setting it to a very high value + disableOutboundProtocolDetectTimeout: false + # -- When set to true, disables the protocol detection timeout on the inbound + # side of the proxy by setting it to a very high value + disableInboundProtocolDetectTimeout: false + image: + # -- Docker image for the proxy + name: cr.l5d.io/linkerd/proxy + # -- Pull policy for the proxy container image + # @default -- imagePullPolicy + pullPolicy: "" + # -- Tag for the proxy container image + # @default -- linkerdVersion + version: "" + # -- Enables the proxy's /shutdown admin endpoint + enableShutdownEndpoint: false + # -- Log level for the proxy + logLevel: warn,linkerd=info,hickory=error + # -- Log format (`plain` or `json`) for the proxy + logFormat: plain + # -- (`off` or `insecure`) If set to `off`, will prevent the proxy from + # logging HTTP headers. If set to `insecure`, HTTP headers may be logged + # verbatim. Note that setting this to `insecure` is not alone sufficient to + # log HTTP headers; the proxy logLevel must also be set to debug. + logHTTPHeaders: "off" + ports: + # -- Admin port for the proxy container + admin: 4191 + # -- Control port for the proxy container + control: 4190 + # -- Inbound port for the proxy container + inbound: 4143 + # -- Outbound port for the proxy container + outbound: 4140 + # -- The `cpu.limit` and `cores` should be kept in sync. The value of `cores` + # must be an integer and should typically be set by rounding up from the + # limit. E.g. if cpu.limit is '1500m', cores should be 2. + cores: 0 + resources: + cpu: + # -- Maximum amount of CPU units that the proxy can use + limit: "" + # -- Amount of CPU units that the proxy requests + request: "" + memory: + # -- Maximum amount of memory that the proxy can use + limit: "" + # -- Maximum amount of memory that the proxy requests + request: "" + ephemeral-storage: + # -- Maximum amount of ephemeral storage that the proxy can use + limit: "" + # -- Amount of ephemeral storage that the proxy requests + request: "" + # -- User id under which the proxy runs + uid: 2102 + # -- (int) Optional customisation of the group id under which the proxy runs (the group ID will be omitted if lower than 0) + gid: -1 + + # -- If set the injected proxy sidecars in the data plane will stay alive for + # at least the given period before receiving the SIGTERM signal from + # Kubernetes but no longer than the pod's `terminationGracePeriodSeconds`. + # See [Lifecycle + # hooks](https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks) + # for more info on container lifecycle hooks. + waitBeforeExitSeconds: 0 + # -- If set, the application container will not start until the proxy is + # ready + await: true + requireIdentityOnInboundPorts: "" + # -- Default set of opaque ports + # - SMTP (25,587) server-first + # - MYSQL (3306) server-first + # - Galera (4444) server-first + # - PostgreSQL (5432) server-first + # - Redis (6379) server-first + # - ElasticSearch (9300) server-first + # - Memcached (11211) clients do not issue any preamble, which breaks detection + opaquePorts: "25,587,3306,4444,5432,6379,9300,11211" + # -- Grace period for graceful proxy shutdowns. If this timeout elapses before all open connections have completed, the proxy will terminate forcefully, closing any remaining connections. + shutdownGracePeriod: "" + # -- The default allow policy to use when no `Server` selects a pod. One of: "all-authenticated", + # "all-unauthenticated", "cluster-authenticated", "cluster-unauthenticated", "deny", "audit" + # @default -- "all-unauthenticated" + defaultInboundPolicy: "all-unauthenticated" + # -- Enable KEP-753 native sidecars + # This is an experimental feature. It requires Kubernetes >= 1.29. + # If enabled, .proxy.waitBeforeExitSeconds should not be used. + nativeSidecar: false + # -- Native sidecar proxy startup probe parameters. + # -- LivenessProbe timeout and delay configuration + livenessProbe: + initialDelaySeconds: 10 + timeoutSeconds: 1 + # -- ReadinessProbe timeout and delay configuration + readinessProbe: + initialDelaySeconds: 2 + timeoutSeconds: 1 + startupProbe: + initialDelaySeconds: 0 + periodSeconds: 1 + failureThreshold: 120 + # Configures general properties of the proxy's control plane clients. + control: + # Configures limits on API response streams. + streams: + # -- The timeout for the first update from the control plane. + initialTimeout: "3s" + # -- The timeout between consecutive updates from the control plane. + idleTimeout: "5m" + # -- The maximum duration for a response stream (i.e. before it will be + # reinitialized). + lifetime: "1h" + inbound: + server: + http2: + # -- The interval at which PINGs are issued to remote HTTP/2 clients. + keepAliveInterval: "10s" + # -- The timeout within which keep-alive PINGs must be acknowledged on inbound HTTP/2 connections. + keepAliveTimeout: "3s" + outbound: + server: + http2: + # -- The interval at which PINGs are issued to local application HTTP/2 clients. + keepAliveInterval: "10s" + # -- The timeout within which keep-alive PINGs must be acknowledged on outbound HTTP/2 connections. + keepAliveTimeout: "3s" + +# proxy-init configuration +proxyInit: + # -- Variant of iptables that will be used to configure routing. Currently, + # proxy-init can be run either in 'nft' or in 'legacy' mode. The mode will + # control which utility binary will be called. The host must support + # whichever mode will be used + iptablesMode: "legacy" + # -- Default set of inbound ports to skip via iptables + # - Galera (4567,4568) + ignoreInboundPorts: "4567,4568" + # -- Default set of outbound ports to skip via iptables + # - Galera (4567,4568) + ignoreOutboundPorts: "4567,4568" + # -- Default set of ports to skip via iptables for control plane + # components so they can communicate with the Kubernetes API Server + kubeAPIServerPorts: "443,6443" + # -- Comma-separated list of subnets in valid CIDR format that should be skipped by the proxy + skipSubnets: "" + # -- Log level for the proxy-init + # @default -- info + logLevel: "" + # -- Log format (`plain` or `json`) for the proxy-init + # @default -- plain + logFormat: "" + image: + # -- Docker image for the proxy-init container + name: cr.l5d.io/linkerd/proxy-init + # -- Pull policy for the proxy-init container image + # @default -- imagePullPolicy + pullPolicy: "" + # -- Tag for the proxy-init container image + version: v2.4.1 + closeWaitTimeoutSecs: 0 + # -- Privileged mode allows the container processes to inherit all security + # capabilities and bypass any security limitations enforced by the kubelet. + # When used with 'runAsRoot: true', the container will behave exactly as if + # it was running as root on the host. May escape cgroup limits and see other + # processes and devices on the host. + # @default -- false + privileged: false + # -- Allow overriding the runAsNonRoot behaviour () + runAsRoot: false + # -- This value is used only if runAsRoot is false; otherwise runAsUser will be 0 + runAsUser: 65534 + # -- This value is used only if runAsRoot is false; otherwise runAsGroup will be 0 + runAsGroup: 65534 + xtMountPath: + mountPath: /run + name: linkerd-proxy-init-xtables-lock + +# network validator configuration +# This runs on a host that uses iptables to reroute network traffic. The validator +# ensures that iptables is correctly routing requests before we start linkerd. +networkValidator: + # -- Log level for the network-validator + # @default -- debug + logLevel: debug + # -- Log format (`plain` or `json`) for network-validator + # @default -- plain + logFormat: plain + # -- Address to which the network-validator will attempt to connect. This should be an IP + # that the cluster is expected to be able to reach but a port it should not, e.g., a public IP + # for public clusters and a private IP for air-gapped clusters with a port like 20001. + # If empty, defaults to 1.1.1.1:20001 and [fd00::1]:20001 for IPv4 and IPv6 respectively. + connectAddr: "" + # -- Address to which network-validator listens to requests from itself. + # If empty, defaults to 0.0.0.0:4140 and [::]:4140 for IPv4 and IPv6 respectively. + listenAddr: "" + # -- Timeout before network-validator fails to validate the pod's network connectivity + timeout: "10s" + # -- Include a securityContext in the network-validator pod spec + enableSecurityContext: true + +# -- For Private docker registries, authentication is needed. +# Registry secrets are applied to the respective service accounts +imagePullSecrets: [] +# - name: my-private-docker-registry-login-secret + +# -- Allow proxies to perform transparent HTTP/2 upgrading +enableH2Upgrade: true + +# -- Add a PSP resource and bind it to the control plane ServiceAccounts. Note +# PSP has been deprecated since k8s v1.21 +enablePSP: false + +# -- Failure policy for the proxy injector +webhookFailurePolicy: Ignore + +# controllerImage -- Docker image for the destination and identity components +controllerImage: cr.l5d.io/linkerd/controller +# -- Optionally allow a specific container image Tag (or SHA) to be specified for the controllerImage. +controllerImageVersion: "" + +# -- Number of replicas for each control plane pod +controllerReplicas: 1 +# -- User ID for the control plane components +controllerUID: 2103 +# -- (int) Optional customisation of the group ID for the control plane components (the group ID will be omitted if lower than 0) +controllerGID: -1 + +# destination configuration +# set resources for the sp-validator and its linkerd proxy respectively +# see proxy.resources for details. +# destinationResources -- CPU, Memory and Ephemeral Storage resources required by destination (see `proxy.resources` for sub-fields) +#destinationResources: +# destinationProxyResources -- CPU, Memory and Ephemeral Storage resources required by proxy injected into destination pod (see `proxy.resources` for sub-fields) +#destinationProxyResources: + +destinationController: + meshedHttp2ClientProtobuf: + keep_alive: + interval: + seconds: 10 + timeout: + seconds: 3 + while_idle: true + +# debug configuration +debugContainer: + image: + # -- Docker image for the debug container + name: cr.l5d.io/linkerd/debug + # -- Pull policy for the debug container image + # @default -- imagePullPolicy + pullPolicy: "" + # -- Tag for the debug container image + # @default -- linkerdVersion + version: "" + +identity: + # -- If the linkerd-identity-trust-roots ConfigMap has already been created + externalCA: false + + # -- Use [Service Account token Volume projection](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#service-account-token-volume-projection) for pod validation instead of the default token + serviceAccountTokenProjection: true + + issuer: + scheme: linkerd.io/tls + + # -- Amount of time to allow for clock skew within a Linkerd cluster + clockSkewAllowance: 20s + + # -- Amount of time for which the Identity issuer should certify identity + issuanceLifetime: 24h0m0s + + # -- Which scheme is used for the identity issuer secret format + tls: + # -- Issuer certificate (ECDSA). It must be provided during install. + crtPEM: | + + # -- Key for the issuer certificate (ECDSA). It must be provided during + # install + keyPEM: | + + kubeAPI: *kubeapi + +# -|- CPU, Memory and Ephemeral Storage resources required by the identity controller (see `proxy.resources` for sub-fields) +#identityResources: +# -|- CPU, Memory and Ephemeral Storage resources required by proxy injected into identity pod (see `proxy.resources` for sub-fields) +#identityProxyResources: + +# heartbeat configuration +# disableHeartBeat -- Set to true to not start the heartbeat cronjob +disableHeartBeat: false +# -- Config for the heartbeat cronjob +# heartbeatSchedule: "0 0 * * *" + +# proxy injector configuration +proxyInjector: + # -- Timeout in seconds before the API Server cancels a request to the proxy + # injector. If timeout is exceeded, the webhookfailurePolicy is used. + timeoutSeconds: 10 + # -- Do not create a secret resource for the proxyInjector webhook. + # If this is set to `true`, the value `proxyInjector.caBundle` must be set + # or the ca bundle must injected with cert-manager ca injector using + # `proxyInjector.injectCaFrom` or `proxyInjector.injectCaFromSecret` (see below). + externalSecret: false + + # -- Namespace selector used by admission webhook. + namespaceSelector: + matchExpressions: + - key: config.linkerd.io/admission-webhooks + operator: NotIn + values: + - disabled + - key: kubernetes.io/metadata.name + operator: NotIn + values: + - kube-system + - cert-manager + + # -- Object selector used by admission webhook. + objectSelector: + matchExpressions: + - key: linkerd.io/control-plane-component + operator: DoesNotExist + - key: linkerd.io/cni-resource + operator: DoesNotExist + + # -- Certificate for the proxy injector. If not provided and not using an external secret + # then Helm will generate one. + crtPEM: | + + # -- Certificate key for the proxy injector. If not provided and not using an external secret + # then Helm will generate one. + keyPEM: | + + # -- Bundle of CA certificates for proxy injector. + # If not provided nor injected with cert-manager, + # then Helm will use the certificate generated for `proxyInjector.crtPEM`. + # If `proxyInjector.externalSecret` is set to true, this value, injectCaFrom, or + # injectCaFromSecret must be set, as no certificate will be generated. + # See the cert-manager [CA Injector Docs](https://cert-manager.io/docs/concepts/ca-injector) for more information. + caBundle: | + + # -- Inject the CA bundle from a cert-manager Certificate. + # See the cert-manager [CA Injector Docs](https://cert-manager.io/docs/concepts/ca-injector/#injecting-ca-data-from-a-certificate-resource) + # for more information. + injectCaFrom: "" + + # -- Inject the CA bundle from a Secret. + # If set, the `cert-manager.io/inject-ca-from-secret` annotation will be added to the webhook. + # The Secret must have the CA Bundle stored in the `ca.crt` key and have + # the `cert-manager.io/allow-direct-injection` annotation set to `true`. + # See the cert-manager [CA Injector Docs](https://cert-manager.io/docs/concepts/ca-injector/#injecting-ca-data-from-a-secret-resource) + # for more information. + injectCaFromSecret: "" + +# -|- CPU, Memory and Ephemeral Storage resources required by the proxy injector (see +#`proxy.resources` for sub-fields) +#proxyInjectorResources: +#-|- CPU, Memory and Ephemeral Storage resources required by proxy injected into the proxy injector +#pod (see `proxy.resources` for sub-fields) +#proxyInjectorProxyResources: + +# service profile validator configuration +profileValidator: + # -- Do not create a secret resource for the profileValidator webhook. + # If this is set to `true`, the value `proxyInjector.caBundle` must be set + # or the ca bundle must injected with cert-manager ca injector using + # `proxyInjector.injectCaFrom` or `proxyInjector.injectCaFromSecret` (see below). + externalSecret: false + + # -- Namespace selector used by admission webhook + namespaceSelector: + matchExpressions: + - key: config.linkerd.io/admission-webhooks + operator: NotIn + values: + - disabled + + # -- Certificate for the service profile validator. If not provided and not using an external secret + # then Helm will generate one. + crtPEM: | + + # -- Certificate key for the service profile validator. If not provided and not using an external secret + # then Helm will generate one. + keyPEM: | + + # -- Bundle of CA certificates for proxy injector. + # If not provided nor injected with cert-manager, + # then Helm will use the certificate generated for `profileValidator.crtPEM`. + # If `profileValidator.externalSecret` is set to true, this value, injectCaFrom, or + # injectCaFromSecret must be set, as no certificate will be generated. + # See the cert-manager [CA Injector Docs](https://cert-manager.io/docs/concepts/ca-injector) for more information. + caBundle: | + + # -- Inject the CA bundle from a cert-manager Certificate. + # See the cert-manager [CA Injector Docs](https://cert-manager.io/docs/concepts/ca-injector/#injecting-ca-data-from-a-certificate-resource) + # for more information. + injectCaFrom: "" + + # -- Inject the CA bundle from a Secret. + # If set, the `cert-manager.io/inject-ca-from-secret` annotation will be added to the webhook. + # The Secret must have the CA Bundle stored in the `ca.crt` key and have + # the `cert-manager.io/allow-direct-injection` annotation set to `true`. + # See the cert-manager [CA Injector Docs](https://cert-manager.io/docs/concepts/ca-injector/#injecting-ca-data-from-a-secret-resource) + # for more information. + injectCaFromSecret: "" + +# policy validator configuration +policyValidator: + # -- Do not create a secret resource for the policyValidator webhook. + # If this is set to `true`, the value `policyValidator.caBundle` must be set + # or the ca bundle must injected with cert-manager ca injector using + # `policyValidator.injectCaFrom` or `policyValidator.injectCaFromSecret` (see below). + externalSecret: false + + # -- Namespace selector used by admission webhook + namespaceSelector: + matchExpressions: + - key: config.linkerd.io/admission-webhooks + operator: NotIn + values: + - disabled + + # -- Certificate for the policy validator. If not provided and not using an external secret + # then Helm will generate one. + crtPEM: | + + # -- Certificate key for the policy validator. If not provided and not using an external secret + # then Helm will generate one. + keyPEM: | + + # -- Bundle of CA certificates for proxy injector. + # If not provided nor injected with cert-manager, + # then Helm will use the certificate generated for `policyValidator.crtPEM`. + # If `policyValidator.externalSecret` is set to true, this value, injectCaFrom, or + # injectCaFromSecret must be set, as no certificate will be generated. + # See the cert-manager [CA Injector Docs](https://cert-manager.io/docs/concepts/ca-injector) for more information. + caBundle: | + + # -- Inject the CA bundle from a cert-manager Certificate. + # See the cert-manager [CA Injector Docs](https://cert-manager.io/docs/concepts/ca-injector/#injecting-ca-data-from-a-certificate-resource) + # for more information. + injectCaFrom: "" + + # -- Inject the CA bundle from a Secret. + # If set, the `cert-manager.io/inject-ca-from-secret` annotation will be added to the webhook. + # The Secret must have the CA Bundle stored in the `ca.crt` key and have + # the `cert-manager.io/allow-direct-injection` annotation set to `true`. + # See the cert-manager [CA Injector Docs](https://cert-manager.io/docs/concepts/ca-injector/#injecting-ca-data-from-a-secret-resource) + # for more information. + injectCaFromSecret: "" + +# -- NodeSelector section, See the [K8S +# documentation](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector) +# for more information +nodeSelector: + kubernetes.io/os: linux + +# -|- CPU, Memory and Ephemeral Storage resources required by the SP validator (see +#`proxy.resources` for sub-fields) +#spValidatorResources: + +# -|- Tolerations section, See the +# [K8S documentation](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) +# for more information +#tolerations: + +# -|- NodeAffinity section, See the +# [K8S documentation](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity) +# for more information +#nodeAffinity: + +# -- url of external prometheus instance (used for the heartbeat) +prometheusUrl: "" + +# Prometheus Operator PodMonitor configuration +podMonitor: + # -- Enables the creation of Prometheus Operator [PodMonitor](https://prometheus-operator.dev/docs/operator/api/#monitoring.coreos.com/v1.PodMonitor) + enabled: false + # -- Interval at which metrics should be scraped + scrapeInterval: 10s + # -- Iimeout after which the scrape is ended + scrapeTimeout: 10s + # -- Labels to apply to all pod Monitors + labels: {} + controller: + # -- Enables the creation of PodMonitor for the control-plane + enabled: true + # -- Selector to select which namespaces the Endpoints objects are discovered from + namespaceSelector: | + matchNames: + - {{ .Release.Namespace }} + - linkerd-viz + - linkerd-jaeger + serviceMirror: + # -- Enables the creation of PodMonitor for the Service Mirror component + enabled: true + proxy: + # -- Enables the creation of PodMonitor for the data-plane + enabled: true diff --git a/charts/linkerd/linkerd-crds/2024.8.3/.helmignore b/charts/linkerd/linkerd-crds/2024.8.3/.helmignore new file mode 100644 index 0000000000..79c90a8063 --- /dev/null +++ b/charts/linkerd/linkerd-crds/2024.8.3/.helmignore @@ -0,0 +1,22 @@ +# 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 +OWNERS +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj diff --git a/charts/linkerd/linkerd-crds/2024.8.3/Chart.lock b/charts/linkerd/linkerd-crds/2024.8.3/Chart.lock new file mode 100644 index 0000000000..a62a030631 --- /dev/null +++ b/charts/linkerd/linkerd-crds/2024.8.3/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: partials + repository: file://../partials + version: 0.1.0 +digest: sha256:8e42f9c9d4a2dc883f17f94d6044c97518ced19ad0922f47b8760e47135369ba +generated: "2021-08-17T10:42:52.610449255-05:00" diff --git a/charts/linkerd/linkerd-crds/2024.8.3/Chart.yaml b/charts/linkerd/linkerd-crds/2024.8.3/Chart.yaml new file mode 100644 index 0000000000..e2eb3441c0 --- /dev/null +++ b/charts/linkerd/linkerd-crds/2024.8.3/Chart.yaml @@ -0,0 +1,26 @@ +annotations: + catalog.cattle.io/certified: partner + catalog.cattle.io/display-name: Linkerd CRDs + catalog.cattle.io/kube-version: '>=1.22.0-0' + catalog.cattle.io/release-name: linkerd-crds +apiVersion: v2 +dependencies: +- name: partials + repository: file://./charts/partials + version: 0.1.0 +description: 'Linkerd gives you observability, reliability, and security for your + microservices — with no code change required. ' +home: https://linkerd.io +icon: file://assets/icons/linkerd-crds.png +keywords: +- service-mesh +kubeVersion: '>=1.22.0-0' +maintainers: +- email: cncf-linkerd-dev@lists.cncf.io + name: Linkerd authors + url: https://linkerd.io/ +name: linkerd-crds +sources: +- https://github.com/linkerd/linkerd2/ +type: application +version: 2024.8.3 diff --git a/charts/linkerd/linkerd-crds/2024.8.3/README.md b/charts/linkerd/linkerd-crds/2024.8.3/README.md new file mode 100644 index 0000000000..616f763e38 --- /dev/null +++ b/charts/linkerd/linkerd-crds/2024.8.3/README.md @@ -0,0 +1,71 @@ +# linkerd-crds + +Linkerd gives you observability, reliability, and security +for your microservices — with no code change required. + +![Version: 2024.8.3](https://img.shields.io/badge/Version-2024.8.3-informational?style=flat-square) +![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) + +**Homepage:** + +## Quickstart and documentation + +You can run Linkerd on any Kubernetes cluster in a matter of seconds. See the +[Linkerd Getting Started Guide][getting-started] for how. + +For more comprehensive documentation, start with the [Linkerd +docs][linkerd-docs]. + +## Adding Linkerd's Helm repository + +```bash +# To add the repo for Linkerd edge releases: +helm repo add linkerd https://helm.linkerd.io/edge +``` + +## Installing the linkerd-crds chart + +This installs the `linkerd-crds` chart, which only persists the CRDs that +Linkerd requires. + +After installing this chart, you need then to install the +`linkerd-control-plane` chart in the same namespace, which provides all the +linkerd core control components. + +```bash +helm install linkerd-crds -n linkerd --create-namespace linkerd/linkerd-crds +``` + +## Get involved + +* Check out Linkerd's source code at [GitHub][linkerd2]. +* Join Linkerd's [user mailing list][linkerd-users], [developer mailing + list][linkerd-dev], and [announcements mailing list][linkerd-announce]. +* Follow [@linkerd][twitter] on Twitter. +* Join the [Linkerd Slack][slack]. + +[getting-started]: https://linkerd.io/2/getting-started/ +[linkerd2]: https://github.com/linkerd/linkerd2 +[linkerd-announce]: https://lists.cncf.io/g/cncf-linkerd-announce +[linkerd-dev]: https://lists.cncf.io/g/cncf-linkerd-dev +[linkerd-docs]: https://linkerd.io/2/overview/ +[linkerd-users]: https://lists.cncf.io/g/cncf-linkerd-users +[slack]: http://slack.linkerd.io +[twitter]: https://twitter.com/linkerd + +## Requirements + +Kubernetes: `>=1.22.0-0` + +| Repository | Name | Version | +|------------|------|---------| +| file://../partials | partials | 0.1.0 | + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| enableHttpRoutes | bool | `true` | | + +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.12.0](https://github.com/norwoodj/helm-docs/releases/v1.12.0) diff --git a/charts/linkerd/linkerd-crds/2024.8.3/README.md.gotmpl b/charts/linkerd/linkerd-crds/2024.8.3/README.md.gotmpl new file mode 100644 index 0000000000..88be739549 --- /dev/null +++ b/charts/linkerd/linkerd-crds/2024.8.3/README.md.gotmpl @@ -0,0 +1,59 @@ +{{ template "chart.header" . }} +{{ template "chart.description" . }} + +{{ template "chart.versionBadge" . }} +{{ template "chart.typeBadge" . }} +{{ template "chart.appVersionBadge" . }} + +{{ template "chart.homepageLine" . }} + +## Quickstart and documentation + +You can run Linkerd on any Kubernetes cluster in a matter of seconds. See the +[Linkerd Getting Started Guide][getting-started] for how. + +For more comprehensive documentation, start with the [Linkerd +docs][linkerd-docs]. + +## Adding Linkerd's Helm repository + +```bash +# To add the repo for Linkerd edge releases: +helm repo add linkerd https://helm.linkerd.io/edge +``` + +## Installing the linkerd-crds chart + +This installs the `linkerd-crds` chart, which only persists the CRDs that +Linkerd requires. + +After installing this chart, you need then to install the +`linkerd-control-plane` chart in the same namespace, which provides all the +linkerd core control components. + +```bash +helm install linkerd-crds -n linkerd --create-namespace linkerd/linkerd-crds +``` + +## Get involved + +* Check out Linkerd's source code at [GitHub][linkerd2]. +* Join Linkerd's [user mailing list][linkerd-users], [developer mailing + list][linkerd-dev], and [announcements mailing list][linkerd-announce]. +* Follow [@linkerd][twitter] on Twitter. +* Join the [Linkerd Slack][slack]. + +[getting-started]: https://linkerd.io/2/getting-started/ +[linkerd2]: https://github.com/linkerd/linkerd2 +[linkerd-announce]: https://lists.cncf.io/g/cncf-linkerd-announce +[linkerd-dev]: https://lists.cncf.io/g/cncf-linkerd-dev +[linkerd-docs]: https://linkerd.io/2/overview/ +[linkerd-users]: https://lists.cncf.io/g/cncf-linkerd-users +[slack]: http://slack.linkerd.io +[twitter]: https://twitter.com/linkerd + +{{ template "chart.requirementsSection" . }} + +{{ template "chart.valuesSection" . }} + +{{ template "helm-docs.versionFooter" . }} diff --git a/charts/linkerd/linkerd-crds/2024.8.3/app-readme.md b/charts/linkerd/linkerd-crds/2024.8.3/app-readme.md new file mode 100644 index 0000000000..59010a6b21 --- /dev/null +++ b/charts/linkerd/linkerd-crds/2024.8.3/app-readme.md @@ -0,0 +1,9 @@ +# Linkerd 2 CRDs Chart + +Linkerd is an ultra light, ultra simple, ultra powerful service mesh. Linkerd +adds security, observability, and reliability to Kubernetes, without the +complexity. + +This particular Helm chart only installs Linkerd CRDs. + +Full documentation available at: https://linkerd.io/2/overview/ diff --git a/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/.helmignore b/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/.helmignore new file mode 100644 index 0000000000..f0c1319444 --- /dev/null +++ b/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/.helmignore @@ -0,0 +1,21 @@ +# 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 diff --git a/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/Chart.yaml b/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/Chart.yaml new file mode 100644 index 0000000000..23cfc167e3 --- /dev/null +++ b/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/Chart.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +description: 'A Helm chart containing Linkerd partial templates, depended by the ''linkerd'' + and ''patch'' charts. ' +name: partials +version: 0.1.0 diff --git a/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/README.md b/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/README.md new file mode 100644 index 0000000000..10805c9b94 --- /dev/null +++ b/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/README.md @@ -0,0 +1,9 @@ +# partials + +A Helm chart containing Linkerd partial templates, +depended by the 'linkerd' and 'patch' charts. + +![Version: 0.1.0](https://img.shields.io/badge/Version-0.1.0-informational?style=flat-square) + +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.12.0](https://github.com/norwoodj/helm-docs/releases/v1.12.0) diff --git a/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/README.md.gotmpl b/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/README.md.gotmpl new file mode 100644 index 0000000000..37f5101061 --- /dev/null +++ b/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/README.md.gotmpl @@ -0,0 +1,14 @@ +{{ template "chart.header" . }} +{{ template "chart.description" . }} + +{{ template "chart.versionBadge" . }} +{{ template "chart.typeBadge" . }} +{{ template "chart.appVersionBadge" . }} + +{{ template "chart.homepageLine" . }} + +{{ template "chart.requirementsSection" . }} + +{{ template "chart.valuesSection" . }} + +{{ template "helm-docs.versionFooter" . }} diff --git a/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/NOTES.txt b/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/NOTES.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_affinity.tpl b/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_affinity.tpl new file mode 100644 index 0000000000..5dde1da473 --- /dev/null +++ b/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_affinity.tpl @@ -0,0 +1,38 @@ +{{ define "linkerd.pod-affinity" -}} +podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: {{ default "linkerd.io/control-plane-component" .label }} + operator: In + values: + - {{ .component }} + topologyKey: topology.kubernetes.io/zone + weight: 100 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: {{ default "linkerd.io/control-plane-component" .label }} + operator: In + values: + - {{ .component }} + topologyKey: kubernetes.io/hostname +{{- end }} + +{{ define "linkerd.node-affinity" -}} +nodeAffinity: +{{- toYaml .Values.nodeAffinity | trim | nindent 2 }} +{{- end }} + +{{ define "linkerd.affinity" -}} +{{- if or .Values.enablePodAntiAffinity .Values.nodeAffinity -}} +affinity: +{{- end }} +{{- if .Values.enablePodAntiAffinity -}} +{{- include "linkerd.pod-affinity" . | nindent 2 }} +{{- end }} +{{- if .Values.nodeAffinity -}} +{{- include "linkerd.node-affinity" . | nindent 2 }} +{{- end }} +{{- end }} diff --git a/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_capabilities.tpl b/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_capabilities.tpl new file mode 100644 index 0000000000..a595d74c1f --- /dev/null +++ b/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_capabilities.tpl @@ -0,0 +1,16 @@ +{{- define "partials.proxy.capabilities" -}} +capabilities: + {{- if .Values.proxy.capabilities.add }} + add: + {{- toYaml .Values.proxy.capabilities.add | trim | nindent 4 }} + {{- end }} + {{- if .Values.proxy.capabilities.drop }} + drop: + {{- toYaml .Values.proxy.capabilities.drop | trim | nindent 4 }} + {{- end }} +{{- end -}} + +{{- define "partials.proxy-init.capabilities.drop" -}} +drop: +{{ toYaml .Values.proxyInit.capabilities.drop | trim }} +{{- end -}} diff --git a/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_debug.tpl b/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_debug.tpl new file mode 100644 index 0000000000..4df8cc77bc --- /dev/null +++ b/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_debug.tpl @@ -0,0 +1,15 @@ +{{- define "partials.debug" -}} +image: {{.Values.debugContainer.image.name}}:{{.Values.debugContainer.image.version | default .Values.linkerdVersion}} +imagePullPolicy: {{.Values.debugContainer.image.pullPolicy | default .Values.imagePullPolicy}} +name: linkerd-debug +terminationMessagePolicy: FallbackToLogsOnError +# some environments require probes, so we provide some infallible ones +livenessProbe: + exec: + command: + - "true" +readinessProbe: + exec: + command: + - "true" +{{- end -}} diff --git a/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_helpers.tpl b/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_helpers.tpl new file mode 100644 index 0000000000..b6cdc34d08 --- /dev/null +++ b/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_helpers.tpl @@ -0,0 +1,14 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Splits a coma separated list into a list of string values. +For example "11,22,55,44" will become "11","22","55","44" +*/}} +{{- define "partials.splitStringList" -}} +{{- if gt (len (toString .)) 0 -}} +{{- $ports := toString . | splitList "," -}} +{{- $last := sub (len $ports) 1 -}} +{{- range $i,$port := $ports -}} +"{{$port}}"{{ternary "," "" (ne $i $last)}} +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_metadata.tpl b/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_metadata.tpl new file mode 100644 index 0000000000..04d2f1beab --- /dev/null +++ b/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_metadata.tpl @@ -0,0 +1,17 @@ +{{- define "partials.annotations.created-by" -}} +linkerd.io/created-by: {{ .Values.cliVersion | default (printf "linkerd/helm %s" ( (.Values.image).version | default .Values.linkerdVersion)) }} +{{- end -}} + +{{- define "partials.proxy.annotations" -}} +linkerd.io/proxy-version: {{.Values.proxy.image.version | default .Values.linkerdVersion}} +cluster-autoscaler.kubernetes.io/safe-to-evict: "true" +linkerd.io/trust-root-sha256: {{ .Values.identityTrustAnchorsPEM | sha256sum }} +{{- end -}} + +{{/* +To add labels to the control-plane components, instead update at individual component manifests as +adding here would also update `spec.selector.matchLabels` which are immutable and would fail upgrades. +*/}} +{{- define "partials.proxy.labels" -}} +linkerd.io/proxy-{{.workloadKind}}: {{.component}} +{{- end -}} diff --git a/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_network-validator.tpl b/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_network-validator.tpl new file mode 100644 index 0000000000..276056395f --- /dev/null +++ b/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_network-validator.tpl @@ -0,0 +1,45 @@ +{{- define "partials.network-validator" -}} +name: linkerd-network-validator +image: {{.Values.proxy.image.name}}:{{.Values.proxy.image.version | default .Values.linkerdVersion }} +imagePullPolicy: {{.Values.proxy.image.pullPolicy | default .Values.imagePullPolicy}} +{{ include "partials.resources" .Values.proxy.resources }} +{{- if or .Values.networkValidator.enableSecurityContext }} +securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsGroup: 65534 + runAsNonRoot: true + runAsUser: 65534 + seccompProfile: + type: RuntimeDefault +{{- end }} +command: + - /usr/lib/linkerd/linkerd2-network-validator +args: + - --log-format + - {{ .Values.networkValidator.logFormat }} + - --log-level + - {{ .Values.networkValidator.logLevel }} + - --connect-addr + {{- if .Values.networkValidator.connectAddr }} + - {{ .Values.networkValidator.connectAddr | quote }} + {{- else if .Values.disableIPv6}} + - "1.1.1.1:20001" + {{- else }} + - "[fd00::1]:20001" + {{- end }} + - --listen-addr + {{- if .Values.networkValidator.listenAddr }} + - {{ .Values.networkValidator.listenAddr | quote }} + {{- else if .Values.disableIPv6}} + - "0.0.0.0:4140" + {{- else }} + - "[::]:4140" + {{- end }} + - --timeout + - {{ .Values.networkValidator.timeout }} + +{{- end -}} diff --git a/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_nodeselector.tpl b/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_nodeselector.tpl new file mode 100644 index 0000000000..4cde0ab16e --- /dev/null +++ b/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_nodeselector.tpl @@ -0,0 +1,4 @@ +{{- define "linkerd.node-selector" -}} +nodeSelector: +{{- toYaml .Values.nodeSelector | trim | nindent 2 }} +{{- end -}} diff --git a/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_proxy-config-ann.tpl b/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_proxy-config-ann.tpl new file mode 100644 index 0000000000..9651b3bd1a --- /dev/null +++ b/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_proxy-config-ann.tpl @@ -0,0 +1,18 @@ +{{- define "partials.proxy.config.annotations" -}} +{{- with .cpu }} +{{- with .request -}} +config.linkerd.io/proxy-cpu-request: {{. | quote}} +{{end}} +{{- with .limit -}} +config.linkerd.io/proxy-cpu-limit: {{. | quote}} +{{- end}} +{{- end}} +{{- with .memory }} +{{- with .request }} +config.linkerd.io/proxy-memory-request: {{. | quote}} +{{end}} +{{- with .limit -}} +config.linkerd.io/proxy-memory-limit: {{. | quote}} +{{- end}} +{{- end }} +{{- end }} diff --git a/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_proxy-init.tpl b/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_proxy-init.tpl new file mode 100644 index 0000000000..a307b14073 --- /dev/null +++ b/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_proxy-init.tpl @@ -0,0 +1,98 @@ +{{- define "partials.proxy-init" -}} +args: +{{- if (.Values.proxyInit.iptablesMode | default "legacy" | eq "nft") }} +- --firewall-bin-path +- "iptables-nft" +- --firewall-save-bin-path +- "iptables-nft-save" +{{- else if not (eq .Values.proxyInit.iptablesMode "legacy") }} +{{ fail (printf "Unsupported value \"%s\" for proxyInit.iptablesMode\nValid values: [\"nft\", \"legacy\"]" .Values.proxyInit.iptablesMode) }} +{{end -}} +{{- if .Values.disableIPv6 }} +- --ipv6=false +{{- end }} +- --incoming-proxy-port +- {{.Values.proxy.ports.inbound | quote}} +- --outgoing-proxy-port +- {{.Values.proxy.ports.outbound | quote}} +- --proxy-uid +- {{.Values.proxy.uid | quote}} +{{- if ge (int .Values.proxy.gid) 0 }} +- --proxy-gid +- {{.Values.proxy.gid | quote}} +{{- end }} +- --inbound-ports-to-ignore +- "{{.Values.proxy.ports.control}},{{.Values.proxy.ports.admin}}{{ternary (printf ",%s" (.Values.proxyInit.ignoreInboundPorts | toString)) "" (not (empty .Values.proxyInit.ignoreInboundPorts)) }}" +{{- if .Values.proxyInit.ignoreOutboundPorts }} +- --outbound-ports-to-ignore +- {{.Values.proxyInit.ignoreOutboundPorts | quote}} +{{- end }} +{{- if .Values.proxyInit.closeWaitTimeoutSecs }} +- --timeout-close-wait-secs +- {{ .Values.proxyInit.closeWaitTimeoutSecs | quote}} +{{- end }} +{{- if .Values.proxyInit.logFormat }} +- --log-format +- {{ .Values.proxyInit.logFormat }} +{{- end }} +{{- if .Values.proxyInit.logLevel }} +- --log-level +- {{ .Values.proxyInit.logLevel }} +{{- end }} +{{- if .Values.proxyInit.skipSubnets }} +- --subnets-to-ignore +- {{ .Values.proxyInit.skipSubnets | quote }} +{{- end }} +image: {{.Values.proxyInit.image.name}}:{{.Values.proxyInit.image.version}} +imagePullPolicy: {{.Values.proxyInit.image.pullPolicy | default .Values.imagePullPolicy}} +name: linkerd-init +{{ include "partials.resources" .Values.proxy.resources }} +securityContext: + {{- if or .Values.proxyInit.closeWaitTimeoutSecs .Values.proxyInit.privileged }} + allowPrivilegeEscalation: true + {{- else }} + allowPrivilegeEscalation: false + {{- end }} + capabilities: + add: + - NET_ADMIN + - NET_RAW + {{- if .Values.proxyInit.capabilities -}} + {{- if .Values.proxyInit.capabilities.add }} + {{- toYaml .Values.proxyInit.capabilities.add | trim | nindent 4 }} + {{- end }} + {{- if .Values.proxyInit.capabilities.drop -}} + {{- include "partials.proxy-init.capabilities.drop" . | nindent 4 -}} + {{- end }} + {{- end }} + {{- if or .Values.proxyInit.closeWaitTimeoutSecs .Values.proxyInit.privileged }} + privileged: true + {{- else }} + privileged: false + {{- end }} + {{- if .Values.proxyInit.runAsRoot }} + runAsGroup: 0 + runAsNonRoot: false + runAsUser: 0 + {{- else }} + runAsNonRoot: true + runAsUser: {{ .Values.proxyInit.runAsUser | int | eq 0 | ternary 65534 .Values.proxyInit.runAsUser }} + runAsGroup: {{ .Values.proxyInit.runAsGroup | int | eq 0 | ternary 65534 .Values.proxyInit.runAsGroup }} + {{- end }} + readOnlyRootFilesystem: true + seccompProfile: + type: RuntimeDefault +terminationMessagePolicy: FallbackToLogsOnError +{{- if or (not .Values.cniEnabled) .Values.proxyInit.saMountPath }} +volumeMounts: +{{- end -}} +{{- if not .Values.cniEnabled }} +- mountPath: {{.Values.proxyInit.xtMountPath.mountPath}} + name: {{.Values.proxyInit.xtMountPath.name}} +{{- end -}} +{{- if .Values.proxyInit.saMountPath }} +- mountPath: {{.Values.proxyInit.saMountPath.mountPath}} + name: {{.Values.proxyInit.saMountPath.name}} + readOnly: {{.Values.proxyInit.saMountPath.readOnly}} +{{- end -}} +{{- end -}} diff --git a/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_proxy.tpl b/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_proxy.tpl new file mode 100644 index 0000000000..7880b394c4 --- /dev/null +++ b/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_proxy.tpl @@ -0,0 +1,267 @@ +{{ define "partials.proxy" -}} +{{ if and .Values.proxy.nativeSidecar .Values.proxy.waitBeforeExitSeconds }} +{{ fail "proxy.nativeSidecar and waitBeforeExitSeconds cannot be used simultaneously" }} +{{- end }} +{{- if not (has .Values.proxy.logHTTPHeaders (list "insecure" "off" "")) }} +{{- fail "logHTTPHeaders must be one of: insecure | off" }} +{{- end }} +{{- $trustDomain := (.Values.identityTrustDomain | default .Values.clusterDomain) -}} +env: +- name: _pod_name + valueFrom: + fieldRef: + fieldPath: metadata.name +- name: _pod_ns + valueFrom: + fieldRef: + fieldPath: metadata.namespace +- name: _pod_nodeName + valueFrom: + fieldRef: + fieldPath: spec.nodeName +{{- if .Values.proxy.cores }} +- name: LINKERD2_PROXY_CORES + value: {{.Values.proxy.cores | quote}} +{{- end }} +{{ if .Values.proxy.requireIdentityOnInboundPorts -}} +- name: LINKERD2_PROXY_INBOUND_PORTS_REQUIRE_IDENTITY + value: {{.Values.proxy.requireIdentityOnInboundPorts | quote}} +{{ end -}} +{{ if .Values.proxy.requireTLSOnInboundPorts -}} +- name: LINKERD2_PROXY_INBOUND_PORTS_REQUIRE_TLS + value: {{.Values.proxy.requireTLSOnInboundPorts | quote}} +{{ end -}} +- name: LINKERD2_PROXY_SHUTDOWN_ENDPOINT_ENABLED + value: {{.Values.proxy.enableShutdownEndpoint | quote}} +- name: LINKERD2_PROXY_LOG + value: "{{.Values.proxy.logLevel}}{{ if not (eq .Values.proxy.logHTTPHeaders "insecure") }},[{headers}]=off,[{request}]=off{{ end }}" +- name: LINKERD2_PROXY_LOG_FORMAT + value: {{.Values.proxy.logFormat | quote}} +- name: LINKERD2_PROXY_DESTINATION_SVC_ADDR + value: {{ternary "localhost.:8086" (printf "linkerd-dst-headless.%s.svc.%s.:8086" .Release.Namespace .Values.clusterDomain) (eq (toString .Values.proxy.component) "linkerd-destination")}} +- name: LINKERD2_PROXY_DESTINATION_PROFILE_NETWORKS + value: {{.Values.clusterNetworks | quote}} +- name: LINKERD2_PROXY_POLICY_SVC_ADDR + value: {{ternary "localhost.:8090" (printf "linkerd-policy.%s.svc.%s.:8090" .Release.Namespace .Values.clusterDomain) (eq (toString .Values.proxy.component) "linkerd-destination")}} +- name: LINKERD2_PROXY_POLICY_WORKLOAD + value: | + {"ns":"$(_pod_ns)", "pod":"$(_pod_name)"} +- name: LINKERD2_PROXY_INBOUND_DEFAULT_POLICY + value: {{.Values.proxy.defaultInboundPolicy}} +- name: LINKERD2_PROXY_POLICY_CLUSTER_NETWORKS + value: {{.Values.clusterNetworks | quote}} +- name: LINKERD2_PROXY_CONTROL_STREAM_INITIAL_TIMEOUT + value: {{((.Values.proxy.control).streams).initialTimeout | default "" | quote}} +- name: LINKERD2_PROXY_CONTROL_STREAM_IDLE_TIMEOUT + value: {{((.Values.proxy.control).streams).idleTimeout | default "" | quote}} +- name: LINKERD2_PROXY_CONTROL_STREAM_LIFETIME + value: {{((.Values.proxy.control).streams).lifetime | default "" | quote}} +{{ if .Values.proxy.inboundConnectTimeout -}} +- name: LINKERD2_PROXY_INBOUND_CONNECT_TIMEOUT + value: {{.Values.proxy.inboundConnectTimeout | quote}} +{{ end -}} +{{ if .Values.proxy.outboundConnectTimeout -}} +- name: LINKERD2_PROXY_OUTBOUND_CONNECT_TIMEOUT + value: {{.Values.proxy.outboundConnectTimeout | quote}} +{{ end -}} +{{ if .Values.proxy.outboundDiscoveryCacheUnusedTimeout -}} +- name: LINKERD2_PROXY_OUTBOUND_DISCOVERY_IDLE_TIMEOUT + value: {{.Values.proxy.outboundDiscoveryCacheUnusedTimeout | quote}} +{{ end -}} +{{ if .Values.proxy.inboundDiscoveryCacheUnusedTimeout -}} +- name: LINKERD2_PROXY_INBOUND_DISCOVERY_IDLE_TIMEOUT + value: {{.Values.proxy.inboundDiscoveryCacheUnusedTimeout | quote}} +{{ end -}} +{{ if .Values.proxy.disableOutboundProtocolDetectTimeout -}} +- name: LINKERD2_PROXY_OUTBOUND_DETECT_TIMEOUT + value: "365d" +{{ end -}} +{{ if .Values.proxy.disableInboundProtocolDetectTimeout -}} +- name: LINKERD2_PROXY_INBOUND_DETECT_TIMEOUT + value: "365d" +{{ end -}} +- name: LINKERD2_PROXY_CONTROL_LISTEN_ADDR + value: "{{ if .Values.disableIPv6 }}0.0.0.0{{ else }}[::]{{ end }}:{{.Values.proxy.ports.control}}" +- name: LINKERD2_PROXY_ADMIN_LISTEN_ADDR + value: "{{ if .Values.disableIPv6 }}0.0.0.0{{ else }}[::]{{ end }}:{{.Values.proxy.ports.admin}}" +{{- /* Deprecated, superseded by LINKERD2_PROXY_OUTBOUND_LISTEN_ADDRS since proxy's v2.228.0 (deployed since edge-24.4.5) */}} +- name: LINKERD2_PROXY_OUTBOUND_LISTEN_ADDR + value: "127.0.0.1:{{.Values.proxy.ports.outbound}}" +- name: LINKERD2_PROXY_OUTBOUND_LISTEN_ADDRS + value: "127.0.0.1:{{.Values.proxy.ports.outbound}}{{ if not .Values.disableIPv6}},[::1]:{{.Values.proxy.ports.outbound}}{{ end }}" +- name: LINKERD2_PROXY_INBOUND_LISTEN_ADDR + value: "{{ if .Values.disableIPv6 }}0.0.0.0{{ else }}[::]{{ end }}:{{.Values.proxy.ports.inbound}}" +- name: LINKERD2_PROXY_INBOUND_IPS + valueFrom: + fieldRef: + fieldPath: status.podIPs +- name: LINKERD2_PROXY_INBOUND_PORTS + value: {{ .Values.proxy.podInboundPorts | quote }} +{{ if .Values.proxy.isGateway -}} +- name: LINKERD2_PROXY_INBOUND_GATEWAY_SUFFIXES + value: {{printf "svc.%s." .Values.clusterDomain}} +{{ end -}} +{{ if .Values.proxy.isIngress -}} +- name: LINKERD2_PROXY_INGRESS_MODE + value: "true" +{{ end -}} +- name: LINKERD2_PROXY_DESTINATION_PROFILE_SUFFIXES + {{- $internalDomain := printf "svc.%s." .Values.clusterDomain }} + value: {{ternary "." $internalDomain .Values.proxy.enableExternalProfiles}} +- name: LINKERD2_PROXY_INBOUND_ACCEPT_KEEPALIVE + value: 10000ms +- name: LINKERD2_PROXY_OUTBOUND_CONNECT_KEEPALIVE + value: 10000ms +{{- /* Configure inbound and outbound parameters, e.g. for HTTP/2 servers. */}} +{{ range $proxyK, $proxyV := (dict "inbound" .Values.proxy.inbound "outbound" .Values.proxy.outbound) -}} +{{ range $scopeK, $scopeV := $proxyV -}} +{{ range $protoK, $protoV := $scopeV -}} +{{ range $paramK, $paramV := $protoV -}} +- name: LINKERD2_PROXY_{{snakecase $proxyK | upper}}_{{snakecase $scopeK | upper}}_{{snakecase $protoK | upper}}_{{snakecase $paramK | upper}} + value: {{ quote $paramV }} +{{ end -}} +{{ end -}} +{{ end -}} +{{ end -}} +{{ if .Values.proxy.opaquePorts -}} +- name: LINKERD2_PROXY_INBOUND_PORTS_DISABLE_PROTOCOL_DETECTION + value: {{.Values.proxy.opaquePorts | quote}} +{{ end -}} +- name: LINKERD2_PROXY_DESTINATION_CONTEXT + value: | + {"ns":"$(_pod_ns)", "nodeName":"$(_pod_nodeName)", "pod":"$(_pod_name)"} +- name: _pod_sa + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName +- name: _l5d_ns + value: {{.Release.Namespace}} +- name: _l5d_trustdomain + value: {{$trustDomain}} +- name: LINKERD2_PROXY_IDENTITY_DIR + value: /var/run/linkerd/identity/end-entity +- name: LINKERD2_PROXY_IDENTITY_TRUST_ANCHORS +{{- /* +Pods in the `linkerd` namespace are not injected by the proxy injector and instead obtain +the trust anchor bundle from the `linkerd-identity-trust-roots` configmap. This should not +be used in other contexts. +*/}} +{{- if .Values.proxy.loadTrustBundleFromConfigMap }} + valueFrom: + configMapKeyRef: + name: linkerd-identity-trust-roots + key: ca-bundle.crt +{{ else }} + value: | + {{- required "Please provide the identity trust anchors" .Values.identityTrustAnchorsPEM | trim | nindent 4 }} +{{ end -}} +- name: LINKERD2_PROXY_IDENTITY_TOKEN_FILE +{{- if .Values.identity.serviceAccountTokenProjection }} + value: /var/run/secrets/tokens/linkerd-identity-token +{{ else }} + value: /var/run/secrets/kubernetes.io/serviceaccount/token +{{ end -}} +- name: LINKERD2_PROXY_IDENTITY_SVC_ADDR + value: {{ternary "localhost.:8080" (printf "linkerd-identity-headless.%s.svc.%s.:8080" .Release.Namespace .Values.clusterDomain) (eq (toString .Values.proxy.component) "linkerd-identity")}} +- name: LINKERD2_PROXY_IDENTITY_LOCAL_NAME + value: $(_pod_sa).$(_pod_ns).serviceaccount.identity.{{.Release.Namespace}}.{{$trustDomain}} +- name: LINKERD2_PROXY_IDENTITY_SVC_NAME + value: linkerd-identity.{{.Release.Namespace}}.serviceaccount.identity.{{.Release.Namespace}}.{{$trustDomain}} +- name: LINKERD2_PROXY_DESTINATION_SVC_NAME + value: linkerd-destination.{{.Release.Namespace}}.serviceaccount.identity.{{.Release.Namespace}}.{{$trustDomain}} +- name: LINKERD2_PROXY_POLICY_SVC_NAME + value: linkerd-destination.{{.Release.Namespace}}.serviceaccount.identity.{{.Release.Namespace}}.{{$trustDomain}} +{{ if .Values.proxy.accessLog -}} +- name: LINKERD2_PROXY_ACCESS_LOG + value: {{.Values.proxy.accessLog | quote}} +{{ end -}} +{{ if .Values.proxy.shutdownGracePeriod -}} +- name: LINKERD2_PROXY_SHUTDOWN_GRACE_PERIOD + value: {{.Values.proxy.shutdownGracePeriod | quote}} +{{ end -}} +{{ if .Values.proxy.additionalEnv -}} +{{ toYaml .Values.proxy.additionalEnv }} +{{ end -}} +{{ if .Values.proxy.experimentalEnv -}} +{{ toYaml .Values.proxy.experimentalEnv }} +{{ end -}} +image: {{.Values.proxy.image.name}}:{{.Values.proxy.image.version | default .Values.linkerdVersion}} +imagePullPolicy: {{.Values.proxy.image.pullPolicy | default .Values.imagePullPolicy}} +livenessProbe: + httpGet: + path: /live + port: {{.Values.proxy.ports.admin}} + initialDelaySeconds: {{.Values.proxy.livenessProbe.initialDelaySeconds }} + timeoutSeconds: {{.Values.proxy.livenessProbe.timeoutSeconds }} +name: linkerd-proxy +ports: +- containerPort: {{.Values.proxy.ports.inbound}} + name: linkerd-proxy +- containerPort: {{.Values.proxy.ports.admin}} + name: linkerd-admin +readinessProbe: + httpGet: + path: /ready + port: {{.Values.proxy.ports.admin}} + initialDelaySeconds: {{.Values.proxy.readinessProbe.initialDelaySeconds }} + timeoutSeconds: {{.Values.proxy.readinessProbe.timeoutSeconds }} +{{- if and .Values.proxy.nativeSidecar .Values.proxy.await }} +startupProbe: + httpGet: + path: /ready + port: {{.Values.proxy.ports.admin}} + initialDelaySeconds: {{.Values.proxy.startupProbe.initialDelaySeconds}} + periodSeconds: {{.Values.proxy.startupProbe.periodSeconds}} + failureThreshold: {{.Values.proxy.startupProbe.failureThreshold}} +{{- end }} +{{- if .Values.proxy.resources }} +{{ include "partials.resources" .Values.proxy.resources }} +{{- end }} +securityContext: + allowPrivilegeEscalation: false + {{- if .Values.proxy.capabilities -}} + {{- include "partials.proxy.capabilities" . | nindent 2 -}} + {{- end }} + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: {{.Values.proxy.uid}} +{{- if ge (int .Values.proxy.gid) 0 }} + runAsGroup: {{.Values.proxy.gid}} +{{- end }} + seccompProfile: + type: RuntimeDefault +terminationMessagePolicy: FallbackToLogsOnError +{{- if and (not .Values.proxy.nativeSidecar) (or .Values.proxy.await .Values.proxy.waitBeforeExitSeconds) }} +lifecycle: +{{- if .Values.proxy.await }} + postStart: + exec: + command: + - /usr/lib/linkerd/linkerd-await + - --timeout=2m + - --port={{.Values.proxy.ports.admin}} +{{- end }} +{{- if .Values.proxy.waitBeforeExitSeconds }} + preStop: + exec: + command: + - /bin/sleep + - {{.Values.proxy.waitBeforeExitSeconds | quote}} +{{- end }} +{{- end }} +volumeMounts: +- mountPath: /var/run/linkerd/identity/end-entity + name: linkerd-identity-end-entity +{{- if .Values.identity.serviceAccountTokenProjection }} +- mountPath: /var/run/secrets/tokens + name: linkerd-identity-token +{{- end }} +{{- if .Values.proxy.saMountPath }} +- mountPath: {{.Values.proxy.saMountPath.mountPath}} + name: {{.Values.proxy.saMountPath.name}} + readOnly: {{.Values.proxy.saMountPath.readOnly}} +{{- end -}} +{{- if .Values.proxy.nativeSidecar }} +restartPolicy: Always +{{- end -}} +{{- end }} diff --git a/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_pull-secrets.tpl b/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_pull-secrets.tpl new file mode 100644 index 0000000000..0c9aa4f01c --- /dev/null +++ b/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_pull-secrets.tpl @@ -0,0 +1,6 @@ +{{- define "partials.image-pull-secrets"}} +{{- if . }} +imagePullSecrets: +{{ toYaml . | indent 2 }} +{{- end }} +{{- end -}} diff --git a/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_resources.tpl b/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_resources.tpl new file mode 100644 index 0000000000..1fd6789fd7 --- /dev/null +++ b/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_resources.tpl @@ -0,0 +1,28 @@ +{{- define "partials.resources" -}} +{{- $ephemeralStorage := index . "ephemeral-storage" -}} +resources: + {{- if or (.cpu).limit (.memory).limit ($ephemeralStorage).limit }} + limits: + {{- with (.cpu).limit }} + cpu: {{. | quote}} + {{- end }} + {{- with (.memory).limit }} + memory: {{. | quote}} + {{- end }} + {{- with ($ephemeralStorage).limit }} + ephemeral-storage: {{. | quote}} + {{- end }} + {{- end }} + {{- if or (.cpu).request (.memory).request ($ephemeralStorage).request }} + requests: + {{- with (.cpu).request }} + cpu: {{. | quote}} + {{- end }} + {{- with (.memory).request }} + memory: {{. | quote}} + {{- end }} + {{- with ($ephemeralStorage).request }} + ephemeral-storage: {{. | quote}} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_tolerations.tpl b/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_tolerations.tpl new file mode 100644 index 0000000000..c2292b1464 --- /dev/null +++ b/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_tolerations.tpl @@ -0,0 +1,4 @@ +{{- define "linkerd.tolerations" -}} +tolerations: +{{ toYaml .Values.tolerations | trim | indent 2 }} +{{- end -}} diff --git a/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_trace.tpl b/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_trace.tpl new file mode 100644 index 0000000000..dee059541f --- /dev/null +++ b/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_trace.tpl @@ -0,0 +1,5 @@ +{{ define "partials.linkerd.trace" -}} +{{ if .Values.controlPlaneTracing -}} +- -trace-collector=collector.{{.Values.controlPlaneTracingNamespace}}.svc.{{.Values.clusterDomain}}:55678 +{{ end -}} +{{- end }} diff --git a/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_validate.tpl b/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_validate.tpl new file mode 100644 index 0000000000..ba772c2fee --- /dev/null +++ b/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_validate.tpl @@ -0,0 +1,19 @@ +{{- define "linkerd.webhook.validation" -}} + +{{- if and (.injectCaFrom) (.injectCaFromSecret) -}} +{{- fail "injectCaFrom and injectCaFromSecret cannot both be set" -}} +{{- end -}} + +{{- if and (or (.injectCaFrom) (.injectCaFromSecret)) (.caBundle) -}} +{{- fail "injectCaFrom or injectCaFromSecret cannot be set if providing a caBundle" -}} +{{- end -}} + +{{- if and (.externalSecret) (empty .caBundle) (empty .injectCaFrom) (empty .injectCaFromSecret) -}} +{{- fail "if externalSecret is set, then caBundle, injectCaFrom, or injectCaFromSecret must be set" -}} +{{- end }} + +{{- if and (or .injectCaFrom .injectCaFromSecret .caBundle) (not .externalSecret) -}} +{{- fail "if caBundle, injectCaFrom, or injectCaFromSecret is set, then externalSecret must be set" -}} +{{- end -}} + +{{- end -}} diff --git a/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_volumes.tpl b/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_volumes.tpl new file mode 100644 index 0000000000..9684cf2409 --- /dev/null +++ b/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/templates/_volumes.tpl @@ -0,0 +1,20 @@ +{{ define "partials.proxy.volumes.identity" -}} +emptyDir: + medium: Memory +name: linkerd-identity-end-entity +{{- end -}} + +{{ define "partials.proxyInit.volumes.xtables" -}} +emptyDir: {} +name: {{ .Values.proxyInit.xtMountPath.name }} +{{- end -}} + +{{- define "partials.proxy.volumes.service-account-token" -}} +name: linkerd-identity-token +projected: + sources: + - serviceAccountToken: + path: linkerd-identity-token + expirationSeconds: 86400 {{- /* # 24 hours */}} + audience: identity.l5d.io +{{- end -}} diff --git a/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/values.yaml b/charts/linkerd/linkerd-crds/2024.8.3/charts/partials/values.yaml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/charts/linkerd/linkerd-crds/2024.8.3/templates/NOTES.txt b/charts/linkerd/linkerd-crds/2024.8.3/templates/NOTES.txt new file mode 100644 index 0000000000..4ff5c1818a --- /dev/null +++ b/charts/linkerd/linkerd-crds/2024.8.3/templates/NOTES.txt @@ -0,0 +1,6 @@ +The linkerd-crds chart was successfully installed 🎉 + +To complete the linkerd core installation, please now proceed to install the +linkerd-control-plane chart in the {{ .Release.Namespace }} namespace. + +Looking for more? Visit https://linkerd.io/2/getting-started/ diff --git a/charts/linkerd/linkerd-crds/2024.8.3/templates/gateway.networking.k8s.io_grpcroutes.yaml b/charts/linkerd/linkerd-crds/2024.8.3/templates/gateway.networking.k8s.io_grpcroutes.yaml new file mode 100644 index 0000000000..0050aac88b --- /dev/null +++ b/charts/linkerd/linkerd-crds/2024.8.3/templates/gateway.networking.k8s.io_grpcroutes.yaml @@ -0,0 +1,1507 @@ +{{- if .Values.enableHttpRoutes }} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/1923 + gateway.networking.k8s.io/bundle-version: v0.7.1 + gateway.networking.k8s.io/channel: experimental + {{ include "partials.annotations.created-by" . }} + labels: + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + linkerd.io/control-plane-ns: {{.Release.Namespace}} + creationTimestamp: null + name: grpcroutes.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: GRPCRoute + listKind: GRPCRouteList + plural: grpcroutes + singular: grpcroute + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.hostnames + name: Hostnames + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha2 + schema: + openAPIV3Schema: + description: "GRPCRoute provides a way to route gRPC requests. This includes + the capability to match requests by hostname, gRPC service, gRPC method, + or HTTP/2 header. Filters can be used to specify additional processing steps. + Backends specify where matching requests will be routed. \n GRPCRoute falls + under extended support within the Gateway API. Within the following specification, + the word \"MUST\" indicates that an implementation supporting GRPCRoute + must conform to the indicated requirement, but an implementation not supporting + this route type need not follow the requirement unless explicitly indicated. + \n Implementations supporting `GRPCRoute` with the `HTTPS` `ProtocolType` + MUST accept HTTP/2 connections without an initial upgrade from HTTP/1.1, + i.e. via ALPN. If the implementation does not support this, then it MUST + set the \"Accepted\" condition to \"False\" for the affected listener with + a reason of \"UnsupportedProtocol\". Implementations MAY also accept HTTP/2 + connections with an upgrade from HTTP/1. \n Implementations supporting `GRPCRoute` + with the `HTTP` `ProtocolType` MUST support HTTP/2 over cleartext TCP (h2c, + https://www.rfc-editor.org/rfc/rfc7540#section-3.1) without an initial upgrade + from HTTP/1.1, i.e. with prior knowledge (https://www.rfc-editor.org/rfc/rfc7540#section-3.4). + If the implementation does not support this, then it MUST set the \"Accepted\" + condition to \"False\" for the affected listener with a reason of \"UnsupportedProtocol\". + Implementations MAY also accept HTTP/2 connections with an upgrade from + HTTP/1, i.e. without prior knowledge. \n Support: Extended" + 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 GRPCRoute. + properties: + hostnames: + description: "Hostnames defines a set of hostnames to match against + the GRPC Host header to select a GRPCRoute to process the request. + This matches the RFC 1123 definition of a hostname with 2 notable + exceptions: \n 1. IPs are not allowed. 2. A hostname may be prefixed + with a wildcard label (`*.`). The wildcard label MUST appear by + itself as the first label. \n If a hostname is specified by both + the Listener and GRPCRoute, there MUST be at least one intersecting + hostname for the GRPCRoute to be attached to the Listener. For example: + \n * A Listener with `test.example.com` as the hostname matches + GRPCRoutes that have either not specified any hostnames, or have + specified at least one of `test.example.com` or `*.example.com`. + * A Listener with `*.example.com` as the hostname matches GRPCRoutes + that have either not specified any hostnames or have specified at + least one hostname that matches the Listener hostname. For example, + `test.example.com` and `*.example.com` would both match. On the + other hand, `example.com` and `test.example.net` would not match. + \n Hostnames that are prefixed with a wildcard label (`*.`) are + interpreted as a suffix match. That means that a match for `*.example.com` + would match both `test.example.com`, and `foo.test.example.com`, + but not `example.com`. \n If both the Listener and GRPCRoute have + specified hostnames, any GRPCRoute hostnames that do not match the + Listener hostname MUST be ignored. For example, if a Listener specified + `*.example.com`, and the GRPCRoute specified `test.example.com` + and `test.example.net`, `test.example.net` MUST NOT be considered + for a match. \n If both the Listener and GRPCRoute have specified + hostnames, and none match with the criteria above, then the GRPCRoute + MUST NOT be accepted by the implementation. The implementation MUST + raise an 'Accepted' Condition with a status of `False` in the corresponding + RouteParentStatus. \n If a Route (A) of type HTTPRoute or GRPCRoute + is attached to a Listener and that listener already has another + Route (B) of the other type attached and the intersection of the + hostnames of A and B is non-empty, then the implementation MUST + accept exactly one of these two routes, determined by the following + criteria, in order: \n * The oldest Route based on creation timestamp. + * The Route appearing first in alphabetical order by \"{namespace}/{name}\". + \n The rejected Route MUST raise an 'Accepted' condition with a + status of 'False' in the corresponding RouteParentStatus. \n Support: + Core" + items: + description: "Hostname is the fully qualified domain name of a network + host. This matches the RFC 1123 definition of a hostname with + 2 notable exceptions: \n 1. IPs are not allowed. 2. A hostname + may be prefixed with a wildcard label (`*.`). The wildcard label + must appear by itself as the first label. \n Hostname can be \"precise\" + which is a domain name without the terminating dot of a network + host (e.g. \"foo.example.com\") or \"wildcard\", which is a domain + name prefixed with a single wildcard label (e.g. `*.example.com`). + \n Note that as per RFC1035 and RFC1123, a *label* must consist + of lower case alphanumeric characters or '-', and must start and + end with an alphanumeric character. No other punctuation is allowed." + maxLength: 253 + minLength: 1 + pattern: ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + maxItems: 16 + type: array + parentRefs: + description: "ParentRefs references the resources (usually Gateways) + that a Route wants to be attached to. Note that the referenced parent + resource needs to allow this for the attachment to be complete. + For Gateways, that means the Gateway needs to allow attachment from + Routes of this kind and namespace. \n The only kind of parent resource + with \"Core\" support is Gateway. This API may be extended in the + future to support additional kinds of parent resources such as one + of the route kinds. \n It is invalid to reference an identical parent + more than once. It is valid to reference multiple distinct sections + within the same parent resource, such as 2 Listeners within a Gateway. + \n It is possible to separately reference multiple distinct objects + that may be collapsed by an implementation. For example, some implementations + may choose to merge compatible Gateway Listeners together. If that + is the case, the list of routes attached to those resources should + also be merged. \n Note that for ParentRefs that cross namespace + boundaries, there are specific rules. Cross-namespace references + are only valid if they are explicitly allowed by something in the + namespace they are referring to. For example, Gateway has the AllowedRoutes + field, and ReferenceGrant provides a generic way to enable any other + kind of cross-namespace reference." + items: + description: "ParentReference identifies an API object (usually + a Gateway) that can be considered a parent of this resource (usually + a route). The only kind of parent resource with \"Core\" support + is Gateway. This API may be extended in the future to support + additional kinds of parent resources, such as HTTPRoute. \n The + API object must be valid in the cluster; the Group and Kind must + be registered in the cluster for this reference to be valid." + properties: + group: + default: gateway.networking.k8s.io + description: "Group is the group of the referent. When unspecified, + \"gateway.networking.k8s.io\" is inferred. To set the core + API group (such as for a \"Service\" kind referent), Group + must be explicitly set to \"\" (empty string). \n Support: + Core" + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Gateway + description: "Kind is kind of the referent. \n Support: Core + (Gateway) \n Support: Implementation-specific (Other Resources)" + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: "Name is the name of the referent. \n Support: + Core" + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace of the referent. When + unspecified, this refers to the local namespace of the Route. + \n Note that there are specific rules for ParentRefs which + cross namespace boundaries. Cross-namespace references are + only valid if they are explicitly allowed by something in + the namespace they are referring to. For example: Gateway + has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. + \n Support: Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: "Port is the network port this Route targets. It + can be interpreted differently based on the type of parent + resource. \n When the parent resource is a Gateway, this targets + all listeners listening on the specified port that also support + this kind of Route(and select this Route). It's not recommended + to set `Port` unless the networking behaviors specified in + a Route must apply to a specific port as opposed to a listener(s) + whose port(s) may be changed. When both Port and SectionName + are specified, the name and port of the selected listener + must match both specified values. \n Implementations MAY choose + to support other parent resources. Implementations supporting + other types of parent resources MUST clearly document how/if + Port is interpreted. \n For the purpose of status, an attachment + is considered successful as long as the parent resource accepts + it partially. For example, Gateway listeners can restrict + which Routes can attach to them by Route kind, namespace, + or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this + Route, the Route MUST be considered detached from the Gateway. + \n Support: Extended \n " + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: "SectionName is the name of a section within the + target resource. In the following resources, SectionName is + interpreted as the following: \n * Gateway: Listener Name. + When both Port (experimental) and SectionName are specified, + the name and port of the selected listener must match both + specified values. \n Implementations MAY choose to support + attaching Routes to other resources. If that is the case, + they MUST clearly document how SectionName is interpreted. + \n When unspecified (empty string), this will reference the + entire resource. For the purpose of status, an attachment + is considered successful if at least one section in the parent + resource accepts it. For example, Gateway listeners can restrict + which Routes can attach to them by Route kind, namespace, + or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this + Route, the Route MUST be considered detached from the Gateway. + \n Support: Core" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - name + type: object + maxItems: 32 + type: array + rules: + default: + - matches: + - method: + type: Exact + description: Rules are a list of GRPC matchers, filters and actions. + items: + description: GRPCRouteRule defines the semantics for matching a + gRPC request based on conditions (matches), processing it (filters), + and forwarding the request to an API object (backendRefs). + properties: + backendRefs: + description: "BackendRefs defines the backend(s) where matching + requests should be sent. \n Failure behavior here depends + on how many BackendRefs are specified and how many are invalid. + \n If *all* entries in BackendRefs are invalid, and there + are also no filters specified in this route rule, *all* traffic + which matches this rule MUST receive an `UNAVAILABLE` status. + \n See the GRPCBackendRef definition for the rules about what + makes a single GRPCBackendRef invalid. \n When a GRPCBackendRef + is invalid, `UNAVAILABLE` statuses MUST be returned for requests + that would have otherwise been routed to an invalid backend. + If multiple backends are specified, and some are invalid, + the proportion of requests that would otherwise have been + routed to an invalid backend MUST receive an `UNAVAILABLE` + status. \n For example, if two backends are specified with + equal weights, and one is invalid, 50 percent of traffic MUST + receive an `UNAVAILABLE` status. Implementations may choose + how that 50 percent is determined. \n Support: Core for Kubernetes + Service \n Support: Implementation-specific for any other + resource \n Support for weight: Core" + items: + description: GRPCBackendRef defines how a GRPCRoute forwards + a gRPC request. + properties: + filters: + description: "Filters defined at this level MUST be executed + if and only if the request is being forwarded to the + backend defined here. \n Support: Implementation-specific + (For broader support of filters, use the Filters field + in GRPCRouteRule.)" + items: + description: GRPCRouteFilter defines processing steps + that must be completed during the request or response + lifecycle. GRPCRouteFilters are meant as an extension + point to express processing that may be done in Gateway + implementations. Some examples include request or + response modification, implementing authentication + strategies, rate-limiting, and traffic shaping. API + guarantee/conformance is defined based on the type + of the filter. + properties: + extensionRef: + description: "ExtensionRef is an optional, implementation-specific + extension to the \"filter\" behavior. For example, + resource \"myroutefilter\" in group \"networking.example.net\"). + ExtensionRef MUST NOT be used for core and extended + filters. \n Support: Implementation-specific" + properties: + group: + description: Group is the group of the referent. + For example, "gateway.networking.k8s.io". + When unspecified or empty string, core API + group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: Kind is kind of the referent. For + example "HTTPRoute" or "Service". + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + required: + - group + - kind + - name + type: object + requestHeaderModifier: + description: "RequestHeaderModifier defines a schema + for a filter that modifies request headers. \n + Support: Core" + properties: + add: + description: "Add adds the given header(s) (name, + value) to the request before the action. It + appends to any existing values associated + with the header name. \n Input: GET /foo HTTP/1.1 + my-header: foo \n Config: add: - name: \"my-header\" + value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 + my-header: foo,bar,baz" + items: + description: HTTPHeader represents an HTTP + Header name and value as defined by RFC + 7230. + properties: + name: + description: "Name is the name of the + HTTP Header to be matched. Name matching + MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an + equivalent name MUST be considered for + a match. Subsequent entries with an + equivalent header name MUST be ignored. + Due to the case-insensitivity of header + names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + remove: + description: "Remove the given header(s) from + the HTTP request before the action. The value + of Remove is a list of HTTP header names. + Note that the header names are case-insensitive + (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + \n Input: GET /foo HTTP/1.1 my-header1: foo + my-header2: bar my-header3: baz \n Config: + remove: [\"my-header1\", \"my-header3\"] \n + Output: GET /foo HTTP/1.1 my-header2: bar" + items: + type: string + maxItems: 16 + type: array + set: + description: "Set overwrites the request with + the given header (name, value) before the + action. \n Input: GET /foo HTTP/1.1 my-header: + foo \n Config: set: - name: \"my-header\" + value: \"bar\" \n Output: GET /foo HTTP/1.1 + my-header: bar" + items: + description: HTTPHeader represents an HTTP + Header name and value as defined by RFC + 7230. + properties: + name: + description: "Name is the name of the + HTTP Header to be matched. Name matching + MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an + equivalent name MUST be considered for + a match. Subsequent entries with an + equivalent header name MUST be ignored. + Due to the case-insensitivity of header + names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + requestMirror: + description: "RequestMirror defines a schema for + a filter that mirrors requests. Requests are sent + to the specified destination, but responses from + that destination are ignored. \n Support: Extended" + properties: + backendRef: + description: "BackendRef references a resource + where mirrored requests are sent. \n If the + referent cannot be found, this BackendRef + is invalid and must be dropped from the Gateway. + The controller must ensure the \"ResolvedRefs\" + condition on the Route status is set to `status: + False` and not configure this backend in the + underlying implementation. \n If there is + a cross-namespace reference to an *existing* + object that is not allowed by a ReferenceGrant, + the controller must ensure the \"ResolvedRefs\" + \ condition on the Route is set to `status: + False`, with the \"RefNotPermitted\" reason + and not configure this backend in the underlying + implementation. \n In either error case, the + Message of the `ResolvedRefs` Condition should + be used to provide more detail about the problem. + \n Support: Extended for Kubernetes Service + \n Support: Implementation-specific for any + other resource" + properties: + group: + default: "" + description: Group is the group of the referent. + For example, "gateway.networking.k8s.io". + When unspecified or empty string, core + API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Service + description: "Kind is the Kubernetes resource + kind of the referent. For example \"Service\". + \n Defaults to \"Service\" when not specified. + \n ExternalName services can refer to + CNAME DNS records that may live outside + of the cluster and as such are difficult + to reason about in terms of conformance. + They also may not be safe to forward to + (see CVE-2021-25740 for more information). + Implementations SHOULD NOT support ExternalName + Services. \n Support: Core (Services with + a type other than ExternalName) \n Support: + Implementation-specific (Services with + type ExternalName)" + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace + of the backend. When unspecified, the + local namespace is inferred. \n Note that + when a namespace different than the local + namespace is specified, a ReferenceGrant + object is required in the referent namespace + to allow that namespace's owner to accept + the reference. See the ReferenceGrant + documentation for details. \n Support: + Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: Port specifies the destination + port number to use for this resource. + Port is required when the referent is + a Kubernetes Service. In this case, the + port number is the service port number, + not the target port. For other resources, + destination port might be derived from + the referent resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - name + type: object + required: + - backendRef + type: object + responseHeaderModifier: + description: "ResponseHeaderModifier defines a schema + for a filter that modifies response headers. \n + Support: Extended" + properties: + add: + description: "Add adds the given header(s) (name, + value) to the request before the action. It + appends to any existing values associated + with the header name. \n Input: GET /foo HTTP/1.1 + my-header: foo \n Config: add: - name: \"my-header\" + value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 + my-header: foo,bar,baz" + items: + description: HTTPHeader represents an HTTP + Header name and value as defined by RFC + 7230. + properties: + name: + description: "Name is the name of the + HTTP Header to be matched. Name matching + MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an + equivalent name MUST be considered for + a match. Subsequent entries with an + equivalent header name MUST be ignored. + Due to the case-insensitivity of header + names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + remove: + description: "Remove the given header(s) from + the HTTP request before the action. The value + of Remove is a list of HTTP header names. + Note that the header names are case-insensitive + (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + \n Input: GET /foo HTTP/1.1 my-header1: foo + my-header2: bar my-header3: baz \n Config: + remove: [\"my-header1\", \"my-header3\"] \n + Output: GET /foo HTTP/1.1 my-header2: bar" + items: + type: string + maxItems: 16 + type: array + set: + description: "Set overwrites the request with + the given header (name, value) before the + action. \n Input: GET /foo HTTP/1.1 my-header: + foo \n Config: set: - name: \"my-header\" + value: \"bar\" \n Output: GET /foo HTTP/1.1 + my-header: bar" + items: + description: HTTPHeader represents an HTTP + Header name and value as defined by RFC + 7230. + properties: + name: + description: "Name is the name of the + HTTP Header to be matched. Name matching + MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an + equivalent name MUST be considered for + a match. Subsequent entries with an + equivalent header name MUST be ignored. + Due to the case-insensitivity of header + names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: + description: "Type identifies the type of filter + to apply. As with other API fields, types are + classified into three conformance levels: \n - + Core: Filter types and their corresponding configuration + defined by \"Support: Core\" in this package, + e.g. \"RequestHeaderModifier\". All implementations + supporting GRPCRoute MUST support core filters. + \n - Extended: Filter types and their corresponding + configuration defined by \"Support: Extended\" + in this package, e.g. \"RequestMirror\". Implementers + are encouraged to support extended filters. \n + - Implementation-specific: Filters that are defined + and supported by specific vendors. In the future, + filters showing convergence in behavior across + multiple implementations will be considered for + inclusion in extended or core conformance levels. + Filter-specific configuration for such filters + is specified using the ExtensionRef field. `Type` + MUST be set to \"ExtensionRef\" for custom filters. + \n Implementers are encouraged to define custom + implementation types to extend the core API with + implementation-specific behavior. \n If a reference + to a custom filter type cannot be resolved, the + filter MUST NOT be skipped. Instead, requests + that would have been processed by that filter + MUST receive a HTTP error response. \n " + enum: + - ResponseHeaderModifier + - RequestHeaderModifier + - RequestMirror + - ExtensionRef + type: string + required: + - type + type: object + maxItems: 16 + type: array + group: + default: "" + description: Group is the group of the referent. For example, + "gateway.networking.k8s.io". When unspecified or empty + string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Service + description: "Kind is the Kubernetes resource kind of + the referent. For example \"Service\". \n Defaults to + \"Service\" when not specified. \n ExternalName services + can refer to CNAME DNS records that may live outside + of the cluster and as such are difficult to reason about + in terms of conformance. They also may not be safe to + forward to (see CVE-2021-25740 for more information). + Implementations SHOULD NOT support ExternalName Services. + \n Support: Core (Services with a type other than ExternalName) + \n Support: Implementation-specific (Services with type + ExternalName)" + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace of the backend. + When unspecified, the local namespace is inferred. \n + Note that when a namespace different than the local + namespace is specified, a ReferenceGrant object is required + in the referent namespace to allow that namespace's + owner to accept the reference. See the ReferenceGrant + documentation for details. \n Support: Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: Port specifies the destination port number + to use for this resource. Port is required when the + referent is a Kubernetes Service. In this case, the + port number is the service port number, not the target + port. For other resources, destination port might be + derived from the referent resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + weight: + default: 1 + description: "Weight specifies the proportion of requests + forwarded to the referenced backend. This is computed + as weight/(sum of all weights in this BackendRefs list). + For non-zero values, there may be some epsilon from + the exact proportion defined here depending on the precision + an implementation supports. Weight is not a percentage + and the sum of weights does not need to equal 100. \n + If only one backend is specified and it has a weight + greater than 0, 100% of the traffic is forwarded to + that backend. If weight is set to 0, no traffic should + be forwarded for this entry. If unspecified, weight + defaults to 1. \n Support for this field varies based + on the context where used." + format: int32 + maximum: 1000000 + minimum: 0 + type: integer + required: + - name + type: object + maxItems: 16 + type: array + filters: + description: "Filters define the filters that are applied to + requests that match this rule. \n The effects of ordering + of multiple behaviors are currently unspecified. This can + change in the future based on feedback during the alpha stage. + \n Conformance-levels at this level are defined based on the + type of filter: \n - ALL core filters MUST be supported by + all implementations that support GRPCRoute. - Implementers + are encouraged to support extended filters. - Implementation-specific + custom filters have no API guarantees across implementations. + \n Specifying a core filter multiple times has unspecified + or implementation-specific conformance. Support: Core" + items: + description: GRPCRouteFilter defines processing steps that + must be completed during the request or response lifecycle. + GRPCRouteFilters are meant as an extension point to express + processing that may be done in Gateway implementations. + Some examples include request or response modification, + implementing authentication strategies, rate-limiting, and + traffic shaping. API guarantee/conformance is defined based + on the type of the filter. + properties: + extensionRef: + description: "ExtensionRef is an optional, implementation-specific + extension to the \"filter\" behavior. For example, + resource \"myroutefilter\" in group \"networking.example.net\"). + ExtensionRef MUST NOT be used for core and extended + filters. \n Support: Implementation-specific" + properties: + group: + description: Group is the group of the referent. For + example, "gateway.networking.k8s.io". When unspecified + or empty string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: Kind is kind of the referent. For example + "HTTPRoute" or "Service". + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + required: + - group + - kind + - name + type: object + requestHeaderModifier: + description: "RequestHeaderModifier defines a schema for + a filter that modifies request headers. \n Support: + Core" + properties: + add: + description: "Add adds the given header(s) (name, + value) to the request before the action. It appends + to any existing values associated with the header + name. \n Input: GET /foo HTTP/1.1 my-header: foo + \n Config: add: - name: \"my-header\" value: \"bar,baz\" + \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz" + items: + description: HTTPHeader represents an HTTP Header + name and value as defined by RFC 7230. + properties: + name: + description: "Name is the name of the HTTP Header + to be matched. Name matching MUST be case + insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an equivalent + name MUST be considered for a match. Subsequent + entries with an equivalent header name MUST + be ignored. Due to the case-insensitivity + of header names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + remove: + description: "Remove the given header(s) from the + HTTP request before the action. The value of Remove + is a list of HTTP header names. Note that the header + names are case-insensitive (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: + bar my-header3: baz \n Config: remove: [\"my-header1\", + \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: + bar" + items: + type: string + maxItems: 16 + type: array + set: + description: "Set overwrites the request with the + given header (name, value) before the action. \n + Input: GET /foo HTTP/1.1 my-header: foo \n Config: + set: - name: \"my-header\" value: \"bar\" \n Output: + GET /foo HTTP/1.1 my-header: bar" + items: + description: HTTPHeader represents an HTTP Header + name and value as defined by RFC 7230. + properties: + name: + description: "Name is the name of the HTTP Header + to be matched. Name matching MUST be case + insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an equivalent + name MUST be considered for a match. Subsequent + entries with an equivalent header name MUST + be ignored. Due to the case-insensitivity + of header names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + requestMirror: + description: "RequestMirror defines a schema for a filter + that mirrors requests. Requests are sent to the specified + destination, but responses from that destination are + ignored. \n Support: Extended" + properties: + backendRef: + description: "BackendRef references a resource where + mirrored requests are sent. \n If the referent cannot + be found, this BackendRef is invalid and must be + dropped from the Gateway. The controller must ensure + the \"ResolvedRefs\" condition on the Route status + is set to `status: False` and not configure this + backend in the underlying implementation. \n If + there is a cross-namespace reference to an *existing* + object that is not allowed by a ReferenceGrant, + the controller must ensure the \"ResolvedRefs\" + \ condition on the Route is set to `status: False`, + with the \"RefNotPermitted\" reason and not configure + this backend in the underlying implementation. \n + In either error case, the Message of the `ResolvedRefs` + Condition should be used to provide more detail + about the problem. \n Support: Extended for Kubernetes + Service \n Support: Implementation-specific for + any other resource" + properties: + group: + default: "" + description: Group is the group of the referent. + For example, "gateway.networking.k8s.io". When + unspecified or empty string, core API group + is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Service + description: "Kind is the Kubernetes resource + kind of the referent. For example \"Service\". + \n Defaults to \"Service\" when not specified. + \n ExternalName services can refer to CNAME + DNS records that may live outside of the cluster + and as such are difficult to reason about in + terms of conformance. They also may not be safe + to forward to (see CVE-2021-25740 for more information). + Implementations SHOULD NOT support ExternalName + Services. \n Support: Core (Services with a + type other than ExternalName) \n Support: Implementation-specific + (Services with type ExternalName)" + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace of the + backend. When unspecified, the local namespace + is inferred. \n Note that when a namespace different + than the local namespace is specified, a ReferenceGrant + object is required in the referent namespace + to allow that namespace's owner to accept the + reference. See the ReferenceGrant documentation + for details. \n Support: Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: Port specifies the destination port + number to use for this resource. Port is required + when the referent is a Kubernetes Service. In + this case, the port number is the service port + number, not the target port. For other resources, + destination port might be derived from the referent + resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - name + type: object + required: + - backendRef + type: object + responseHeaderModifier: + description: "ResponseHeaderModifier defines a schema + for a filter that modifies response headers. \n Support: + Extended" + properties: + add: + description: "Add adds the given header(s) (name, + value) to the request before the action. It appends + to any existing values associated with the header + name. \n Input: GET /foo HTTP/1.1 my-header: foo + \n Config: add: - name: \"my-header\" value: \"bar,baz\" + \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz" + items: + description: HTTPHeader represents an HTTP Header + name and value as defined by RFC 7230. + properties: + name: + description: "Name is the name of the HTTP Header + to be matched. Name matching MUST be case + insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an equivalent + name MUST be considered for a match. Subsequent + entries with an equivalent header name MUST + be ignored. Due to the case-insensitivity + of header names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + remove: + description: "Remove the given header(s) from the + HTTP request before the action. The value of Remove + is a list of HTTP header names. Note that the header + names are case-insensitive (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: + bar my-header3: baz \n Config: remove: [\"my-header1\", + \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: + bar" + items: + type: string + maxItems: 16 + type: array + set: + description: "Set overwrites the request with the + given header (name, value) before the action. \n + Input: GET /foo HTTP/1.1 my-header: foo \n Config: + set: - name: \"my-header\" value: \"bar\" \n Output: + GET /foo HTTP/1.1 my-header: bar" + items: + description: HTTPHeader represents an HTTP Header + name and value as defined by RFC 7230. + properties: + name: + description: "Name is the name of the HTTP Header + to be matched. Name matching MUST be case + insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an equivalent + name MUST be considered for a match. Subsequent + entries with an equivalent header name MUST + be ignored. Due to the case-insensitivity + of header names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: + description: "Type identifies the type of filter to apply. + As with other API fields, types are classified into + three conformance levels: \n - Core: Filter types and + their corresponding configuration defined by \"Support: + Core\" in this package, e.g. \"RequestHeaderModifier\". + All implementations supporting GRPCRoute MUST support + core filters. \n - Extended: Filter types and their + corresponding configuration defined by \"Support: Extended\" + in this package, e.g. \"RequestMirror\". Implementers + are encouraged to support extended filters. \n - Implementation-specific: + Filters that are defined and supported by specific vendors. + In the future, filters showing convergence in behavior + across multiple implementations will be considered for + inclusion in extended or core conformance levels. Filter-specific + configuration for such filters is specified using the + ExtensionRef field. `Type` MUST be set to \"ExtensionRef\" + for custom filters. \n Implementers are encouraged to + define custom implementation types to extend the core + API with implementation-specific behavior. \n If a reference + to a custom filter type cannot be resolved, the filter + MUST NOT be skipped. Instead, requests that would have + been processed by that filter MUST receive a HTTP error + response. \n " + enum: + - ResponseHeaderModifier + - RequestHeaderModifier + - RequestMirror + - ExtensionRef + type: string + required: + - type + type: object + maxItems: 16 + type: array + matches: + description: "Matches define conditions used for matching the + rule against incoming gRPC requests. Each match is independent, + i.e. this rule will be matched if **any** one of the matches + is satisfied. \n For example, take the following matches configuration: + \n ``` matches: - method: service: foo.bar headers: values: + version: 2 - method: service: foo.bar.v2 ``` \n For a request + to match against this rule, it MUST satisfy EITHER of the + two conditions: \n - service of foo.bar AND contains the header + `version: 2` - service of foo.bar.v2 \n See the documentation + for GRPCRouteMatch on how to specify multiple match conditions + to be ANDed together. \n If no matches are specified, the + implementation MUST match every gRPC request. \n Proxy or + Load Balancer routing configuration generated from GRPCRoutes + MUST prioritize rules based on the following criteria, continuing + on ties. Merging MUST not be done between GRPCRoutes and HTTPRoutes. + Precedence MUST be given to the rule with the largest number + of: \n * Characters in a matching non-wildcard hostname. * + Characters in a matching hostname. * Characters in a matching + service. * Characters in a matching method. * Header matches. + \n If ties still exist across multiple Routes, matching precedence + MUST be determined in order of the following criteria, continuing + on ties: \n * The oldest Route based on creation timestamp. + * The Route appearing first in alphabetical order by \"{namespace}/{name}\". + \n If ties still exist within the Route that has been given + precedence, matching precedence MUST be granted to the first + matching rule meeting the above criteria." + items: + description: "GRPCRouteMatch defines the predicate used to + match requests to a given action. Multiple match types are + ANDed together, i.e. the match will evaluate to true only + if all conditions are satisfied. \n For example, the match + below will match a gRPC request only if its service is `foo` + AND it contains the `version: v1` header: \n ``` matches: + - method: type: Exact service: \"foo\" headers: - name: + \"version\" value \"v1\" \n ```" + properties: + headers: + description: Headers specifies gRPC request header matchers. + Multiple match values are ANDed together, meaning, a + request MUST match all the specified headers to select + the route. + items: + description: GRPCHeaderMatch describes how to select + a gRPC route by matching gRPC request headers. + properties: + name: + description: "Name is the name of the gRPC Header + to be matched. \n If multiple entries specify + equivalent header names, only the first entry + with an equivalent name MUST be considered for + a match. Subsequent entries with an equivalent + header name MUST be ignored. Due to the case-insensitivity + of header names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + type: + default: Exact + description: Type specifies how to match against + the value of the header. + enum: + - Exact + - RegularExpression + type: string + value: + description: Value is the value of the gRPC Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + method: + description: Method specifies a gRPC request service/method + matcher. If this field is not specified, all services + and methods will match. + properties: + method: + description: "Value of the method to match against. + If left empty or omitted, will match all services. + \n At least one of Service and Method MUST be a + non-empty string." + maxLength: 1024 + type: string + service: + description: "Value of the service to match against. + If left empty or omitted, will match any service. + \n At least one of Service and Method MUST be a + non-empty string." + maxLength: 1024 + type: string + type: + default: Exact + description: "Type specifies how to match against + the service and/or method. Support: Core (Exact + with service and method specified) \n Support: Implementation-specific + (Exact with method specified but no service specified) + \n Support: Implementation-specific (RegularExpression)" + enum: + - Exact + - RegularExpression + type: string + type: object + type: object + maxItems: 8 + type: array + type: object + maxItems: 16 + type: array + type: object + status: + description: Status defines the current state of GRPCRoute. + properties: + parents: + description: "Parents is a list of parent resources (usually Gateways) + that are associated with the route, and the status of the route + with respect to each parent. When this route attaches to a parent, + the controller that manages the parent must add an entry to this + list when the controller first sees the route and should update + the entry as appropriate when the route or gateway is modified. + \n Note that parent references that cannot be resolved by an implementation + of this API will not be added to this list. Implementations of this + API can only populate Route status for the Gateways/parent resources + they are responsible for. \n A maximum of 32 Gateways will be represented + in this list. An empty list means the route has not been attached + to any Gateway." + items: + description: RouteParentStatus describes the status of a route with + respect to an associated Parent. + properties: + conditions: + description: "Conditions describes the status of the route with + respect to the Gateway. Note that the route's availability + is also subject to the Gateway's own status conditions and + listener status. \n If the Route's ParentRef specifies an + existing Gateway that supports Routes of this kind AND that + Gateway's controller has sufficient access, then that Gateway's + controller MUST set the \"Accepted\" condition on the Route, + to indicate whether the route has been accepted or rejected + by the Gateway, and why. \n A Route MUST be considered \"Accepted\" + if at least one of the Route's rules is implemented by the + Gateway. \n There are a number of cases where the \"Accepted\" + condition may not be set due to lack of controller visibility, + that includes when: \n * The Route refers to a non-existent + parent. * The Route is of a type that the controller does + not support. * The Route is in a namespace the controller + does not have access to." + items: + description: "Condition contains details for one aspect of + the current state of this API Resource. --- This struct + is intended for direct use as an array at the field path + .status.conditions. For example, \n type FooStatus struct{ + // Represents the observations of a foo's current state. + // Known .status.conditions.type are: \"Available\", \"Progressing\", + and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge + // +listType=map // +listMapKey=type Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields + }" + 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 + maxItems: 8 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + controllerName: + description: "ControllerName is a domain/path string that indicates + the name of the controller that wrote this status. This corresponds + with the controllerName field on GatewayClass. \n Example: + \"example.net/gateway-controller\". \n The format of this + field is DOMAIN \"/\" PATH, where DOMAIN and PATH are valid + Kubernetes names (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). + \n Controllers MUST populate this field when writing status. + Controllers should ensure that entries to status populated + with their ControllerName are cleaned up when they are no + longer necessary." + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + parentRef: + description: ParentRef corresponds with a ParentRef in the spec + that this RouteParentStatus struct describes the status of. + properties: + group: + default: gateway.networking.k8s.io + description: "Group is the group of the referent. When unspecified, + \"gateway.networking.k8s.io\" is inferred. To set the + core API group (such as for a \"Service\" kind referent), + Group must be explicitly set to \"\" (empty string). \n + Support: Core" + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Gateway + description: "Kind is kind of the referent. \n Support: + Core (Gateway) \n Support: Implementation-specific (Other + Resources)" + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: "Name is the name of the referent. \n Support: + Core" + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace of the referent. + When unspecified, this refers to the local namespace of + the Route. \n Note that there are specific rules for ParentRefs + which cross namespace boundaries. Cross-namespace references + are only valid if they are explicitly allowed by something + in the namespace they are referring to. For example: Gateway + has the AllowedRoutes field, and ReferenceGrant provides + a generic way to enable any other kind of cross-namespace + reference. \n Support: Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: "Port is the network port this Route targets. + It can be interpreted differently based on the type of + parent resource. \n When the parent resource is a Gateway, + this targets all listeners listening on the specified + port that also support this kind of Route(and select this + Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to + a specific port as opposed to a listener(s) whose port(s) + may be changed. When both Port and SectionName are specified, + the name and port of the selected listener must match + both specified values. \n Implementations MAY choose to + support other parent resources. Implementations supporting + other types of parent resources MUST clearly document + how/if Port is interpreted. \n For the purpose of status, + an attachment is considered successful as long as the + parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them + by Route kind, namespace, or hostname. If 1 of 2 Gateway + listeners accept attachment from the referencing Route, + the Route MUST be considered successfully attached. If + no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + \n Support: Extended \n " + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: "SectionName is the name of a section within + the target resource. In the following resources, SectionName + is interpreted as the following: \n * Gateway: Listener + Name. When both Port (experimental) and SectionName are + specified, the name and port of the selected listener + must match both specified values. \n Implementations MAY + choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName + is interpreted. \n When unspecified (empty string), this + will reference the entire resource. For the purpose of + status, an attachment is considered successful if at least + one section in the parent resource accepts it. For example, + Gateway listeners can restrict which Routes can attach + to them by Route kind, namespace, or hostname. If 1 of + 2 Gateway listeners accept attachment from the referencing + Route, the Route MUST be considered successfully attached. + If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + \n Support: Core" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - name + type: object + required: + - controllerName + - parentRef + type: object + maxItems: 32 + type: array + required: + - parents + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null +{{- end }} + diff --git a/charts/linkerd/linkerd-crds/2024.8.3/templates/gateway.networking.k8s.io_httproutes.yaml b/charts/linkerd/linkerd-crds/2024.8.3/templates/gateway.networking.k8s.io_httproutes.yaml new file mode 100644 index 0000000000..b695c51d50 --- /dev/null +++ b/charts/linkerd/linkerd-crds/2024.8.3/templates/gateway.networking.k8s.io_httproutes.yaml @@ -0,0 +1,3881 @@ +{{- if .Values.enableHttpRoutes }} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/1923 + gateway.networking.k8s.io/bundle-version: v0.7.1 + gateway.networking.k8s.io/channel: experimental + {{ include "partials.annotations.created-by" . }} + labels: + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + linkerd.io/control-plane-ns: {{.Release.Namespace}} + creationTimestamp: null + name: httproutes.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: HTTPRoute + listKind: HTTPRouteList + plural: httproutes + singular: httproute + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.hostnames + name: Hostnames + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + deprecated: true + deprecationWarning: The v1alpha2 version of HTTPRoute has been deprecated and + will be removed in a future release of the API. Please upgrade to v1beta1. + name: v1alpha2 + schema: + openAPIV3Schema: + description: HTTPRoute provides a way to route HTTP requests. This includes + the capability to match requests by hostname, path, header, or query param. + Filters can be used to specify additional processing steps. Backends specify + where matching requests should be routed. + 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 HTTPRoute. + properties: + hostnames: + description: "Hostnames defines a set of hostname that should match + against the HTTP Host header to select a HTTPRoute used to process + the request. Implementations MUST ignore any port value specified + in the HTTP Host header while performing a match. \n Valid values + for Hostnames are determined by RFC 1123 definition of a hostname + with 2 notable exceptions: \n 1. IPs are not allowed. 2. A hostname + may be prefixed with a wildcard label (`*.`). The wildcard label + must appear by itself as the first label. \n If a hostname is specified + by both the Listener and HTTPRoute, there must be at least one intersecting + hostname for the HTTPRoute to be attached to the Listener. For example: + \n * A Listener with `test.example.com` as the hostname matches + HTTPRoutes that have either not specified any hostnames, or have + specified at least one of `test.example.com` or `*.example.com`. + * A Listener with `*.example.com` as the hostname matches HTTPRoutes + that have either not specified any hostnames or have specified at + least one hostname that matches the Listener hostname. For example, + `*.example.com`, `test.example.com`, and `foo.test.example.com` + would all match. On the other hand, `example.com` and `test.example.net` + would not match. \n Hostnames that are prefixed with a wildcard + label (`*.`) are interpreted as a suffix match. That means that + a match for `*.example.com` would match both `test.example.com`, + and `foo.test.example.com`, but not `example.com`. \n If both the + Listener and HTTPRoute have specified hostnames, any HTTPRoute hostnames + that do not match the Listener hostname MUST be ignored. For example, + if a Listener specified `*.example.com`, and the HTTPRoute specified + `test.example.com` and `test.example.net`, `test.example.net` must + not be considered for a match. \n If both the Listener and HTTPRoute + have specified hostnames, and none match with the criteria above, + then the HTTPRoute is not accepted. The implementation must raise + an 'Accepted' Condition with a status of `False` in the corresponding + RouteParentStatus. \n In the event that multiple HTTPRoutes specify + intersecting hostnames (e.g. overlapping wildcard matching and exact + matching hostnames), precedence must be given to rules from the + HTTPRoute with the largest number of: \n * Characters in a matching + non-wildcard hostname. * Characters in a matching hostname. \n If + ties exist across multiple Routes, the matching precedence rules + for HTTPRouteMatches takes over. \n Support: Core" + items: + description: "Hostname is the fully qualified domain name of a network + host. This matches the RFC 1123 definition of a hostname with + 2 notable exceptions: \n 1. IPs are not allowed. 2. A hostname + may be prefixed with a wildcard label (`*.`). The wildcard label + must appear by itself as the first label. \n Hostname can be \"precise\" + which is a domain name without the terminating dot of a network + host (e.g. \"foo.example.com\") or \"wildcard\", which is a domain + name prefixed with a single wildcard label (e.g. `*.example.com`). + \n Note that as per RFC1035 and RFC1123, a *label* must consist + of lower case alphanumeric characters or '-', and must start and + end with an alphanumeric character. No other punctuation is allowed." + maxLength: 253 + minLength: 1 + pattern: ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + maxItems: 16 + type: array + parentRefs: + description: "ParentRefs references the resources (usually Gateways) + that a Route wants to be attached to. Note that the referenced parent + resource needs to allow this for the attachment to be complete. + For Gateways, that means the Gateway needs to allow attachment from + Routes of this kind and namespace. \n The only kind of parent resource + with \"Core\" support is Gateway. This API may be extended in the + future to support additional kinds of parent resources such as one + of the route kinds. \n It is invalid to reference an identical parent + more than once. It is valid to reference multiple distinct sections + within the same parent resource, such as 2 Listeners within a Gateway. + \n It is possible to separately reference multiple distinct objects + that may be collapsed by an implementation. For example, some implementations + may choose to merge compatible Gateway Listeners together. If that + is the case, the list of routes attached to those resources should + also be merged. \n Note that for ParentRefs that cross namespace + boundaries, there are specific rules. Cross-namespace references + are only valid if they are explicitly allowed by something in the + namespace they are referring to. For example, Gateway has the AllowedRoutes + field, and ReferenceGrant provides a generic way to enable any other + kind of cross-namespace reference." + items: + description: "ParentReference identifies an API object (usually + a Gateway) that can be considered a parent of this resource (usually + a route). The only kind of parent resource with \"Core\" support + is Gateway. This API may be extended in the future to support + additional kinds of parent resources, such as HTTPRoute. \n The + API object must be valid in the cluster; the Group and Kind must + be registered in the cluster for this reference to be valid." + properties: + group: + default: gateway.networking.k8s.io + description: "Group is the group of the referent. When unspecified, + \"gateway.networking.k8s.io\" is inferred. To set the core + API group (such as for a \"Service\" kind referent), Group + must be explicitly set to \"\" (empty string). \n Support: + Core" + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Gateway + description: "Kind is kind of the referent. \n Support: Core + (Gateway) \n Support: Implementation-specific (Other Resources)" + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: "Name is the name of the referent. \n Support: + Core" + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace of the referent. When + unspecified, this refers to the local namespace of the Route. + \n Note that there are specific rules for ParentRefs which + cross namespace boundaries. Cross-namespace references are + only valid if they are explicitly allowed by something in + the namespace they are referring to. For example: Gateway + has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. + \n Support: Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: "Port is the network port this Route targets. It + can be interpreted differently based on the type of parent + resource. \n When the parent resource is a Gateway, this targets + all listeners listening on the specified port that also support + this kind of Route(and select this Route). It's not recommended + to set `Port` unless the networking behaviors specified in + a Route must apply to a specific port as opposed to a listener(s) + whose port(s) may be changed. When both Port and SectionName + are specified, the name and port of the selected listener + must match both specified values. \n Implementations MAY choose + to support other parent resources. Implementations supporting + other types of parent resources MUST clearly document how/if + Port is interpreted. \n For the purpose of status, an attachment + is considered successful as long as the parent resource accepts + it partially. For example, Gateway listeners can restrict + which Routes can attach to them by Route kind, namespace, + or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this + Route, the Route MUST be considered detached from the Gateway. + \n Support: Extended \n " + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: "SectionName is the name of a section within the + target resource. In the following resources, SectionName is + interpreted as the following: \n * Gateway: Listener Name. + When both Port (experimental) and SectionName are specified, + the name and port of the selected listener must match both + specified values. \n Implementations MAY choose to support + attaching Routes to other resources. If that is the case, + they MUST clearly document how SectionName is interpreted. + \n When unspecified (empty string), this will reference the + entire resource. For the purpose of status, an attachment + is considered successful if at least one section in the parent + resource accepts it. For example, Gateway listeners can restrict + which Routes can attach to them by Route kind, namespace, + or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this + Route, the Route MUST be considered detached from the Gateway. + \n Support: Core" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - name + type: object + maxItems: 32 + type: array + rules: + default: + - matches: + - path: + type: PathPrefix + value: / + description: Rules are a list of HTTP matchers, filters and actions. + items: + description: HTTPRouteRule defines semantics for matching an HTTP + request based on conditions (matches), processing it (filters), + and forwarding the request to an API object (backendRefs). + properties: + backendRefs: + description: "BackendRefs defines the backend(s) where matching + requests should be sent. \n Failure behavior here depends + on how many BackendRefs are specified and how many are invalid. + \n If *all* entries in BackendRefs are invalid, and there + are also no filters specified in this route rule, *all* traffic + which matches this rule MUST receive a 500 status code. \n + See the HTTPBackendRef definition for the rules about what + makes a single HTTPBackendRef invalid. \n When a HTTPBackendRef + is invalid, 500 status codes MUST be returned for requests + that would have otherwise been routed to an invalid backend. + If multiple backends are specified, and some are invalid, + the proportion of requests that would otherwise have been + routed to an invalid backend MUST receive a 500 status code. + \n For example, if two backends are specified with equal weights, + and one is invalid, 50 percent of traffic must receive a 500. + Implementations may choose how that 50 percent is determined. + \n Support: Core for Kubernetes Service \n Support: Extended + for Kubernetes ServiceImport \n Support: Implementation-specific + for any other resource \n Support for weight: Core" + items: + description: HTTPBackendRef defines how a HTTPRoute should + forward an HTTP request. + properties: + filters: + description: "Filters defined at this level should be + executed if and only if the request is being forwarded + to the backend defined here. \n Support: Implementation-specific + (For broader support of filters, use the Filters field + in HTTPRouteRule.)" + items: + description: HTTPRouteFilter defines processing steps + that must be completed during the request or response + lifecycle. HTTPRouteFilters are meant as an extension + point to express processing that may be done in Gateway + implementations. Some examples include request or + response modification, implementing authentication + strategies, rate-limiting, and traffic shaping. API + guarantee/conformance is defined based on the type + of the filter. + properties: + extensionRef: + description: "ExtensionRef is an optional, implementation-specific + extension to the \"filter\" behavior. For example, + resource \"myroutefilter\" in group \"networking.example.net\"). + ExtensionRef MUST NOT be used for core and extended + filters. \n Support: Implementation-specific" + properties: + group: + description: Group is the group of the referent. + For example, "gateway.networking.k8s.io". + When unspecified or empty string, core API + group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: Kind is kind of the referent. For + example "HTTPRoute" or "Service". + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + required: + - group + - kind + - name + type: object + requestHeaderModifier: + description: "RequestHeaderModifier defines a schema + for a filter that modifies request headers. \n + Support: Core" + properties: + add: + description: "Add adds the given header(s) (name, + value) to the request before the action. It + appends to any existing values associated + with the header name. \n Input: GET /foo HTTP/1.1 + my-header: foo \n Config: add: - name: \"my-header\" + value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 + my-header: foo,bar,baz" + items: + description: HTTPHeader represents an HTTP + Header name and value as defined by RFC + 7230. + properties: + name: + description: "Name is the name of the + HTTP Header to be matched. Name matching + MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an + equivalent name MUST be considered for + a match. Subsequent entries with an + equivalent header name MUST be ignored. + Due to the case-insensitivity of header + names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + remove: + description: "Remove the given header(s) from + the HTTP request before the action. The value + of Remove is a list of HTTP header names. + Note that the header names are case-insensitive + (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + \n Input: GET /foo HTTP/1.1 my-header1: foo + my-header2: bar my-header3: baz \n Config: + remove: [\"my-header1\", \"my-header3\"] \n + Output: GET /foo HTTP/1.1 my-header2: bar" + items: + type: string + maxItems: 16 + type: array + set: + description: "Set overwrites the request with + the given header (name, value) before the + action. \n Input: GET /foo HTTP/1.1 my-header: + foo \n Config: set: - name: \"my-header\" + value: \"bar\" \n Output: GET /foo HTTP/1.1 + my-header: bar" + items: + description: HTTPHeader represents an HTTP + Header name and value as defined by RFC + 7230. + properties: + name: + description: "Name is the name of the + HTTP Header to be matched. Name matching + MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an + equivalent name MUST be considered for + a match. Subsequent entries with an + equivalent header name MUST be ignored. + Due to the case-insensitivity of header + names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + requestMirror: + description: "RequestMirror defines a schema for + a filter that mirrors requests. Requests are sent + to the specified destination, but responses from + that destination are ignored. \n Support: Extended" + properties: + backendRef: + description: "BackendRef references a resource + where mirrored requests are sent. \n If the + referent cannot be found, this BackendRef + is invalid and must be dropped from the Gateway. + The controller must ensure the \"ResolvedRefs\" + condition on the Route status is set to `status: + False` and not configure this backend in the + underlying implementation. \n If there is + a cross-namespace reference to an *existing* + object that is not allowed by a ReferenceGrant, + the controller must ensure the \"ResolvedRefs\" + \ condition on the Route is set to `status: + False`, with the \"RefNotPermitted\" reason + and not configure this backend in the underlying + implementation. \n In either error case, the + Message of the `ResolvedRefs` Condition should + be used to provide more detail about the problem. + \n Support: Extended for Kubernetes Service + \n Support: Implementation-specific for any + other resource" + properties: + group: + default: "" + description: Group is the group of the referent. + For example, "gateway.networking.k8s.io". + When unspecified or empty string, core + API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Service + description: "Kind is the Kubernetes resource + kind of the referent. For example \"Service\". + \n Defaults to \"Service\" when not specified. + \n ExternalName services can refer to + CNAME DNS records that may live outside + of the cluster and as such are difficult + to reason about in terms of conformance. + They also may not be safe to forward to + (see CVE-2021-25740 for more information). + Implementations SHOULD NOT support ExternalName + Services. \n Support: Core (Services with + a type other than ExternalName) \n Support: + Implementation-specific (Services with + type ExternalName)" + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace + of the backend. When unspecified, the + local namespace is inferred. \n Note that + when a namespace different than the local + namespace is specified, a ReferenceGrant + object is required in the referent namespace + to allow that namespace's owner to accept + the reference. See the ReferenceGrant + documentation for details. \n Support: + Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: Port specifies the destination + port number to use for this resource. + Port is required when the referent is + a Kubernetes Service. In this case, the + port number is the service port number, + not the target port. For other resources, + destination port might be derived from + the referent resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - name + type: object + required: + - backendRef + type: object + requestRedirect: + description: "RequestRedirect defines a schema for + a filter that responds to the request with an + HTTP redirection. \n Support: Core" + properties: + hostname: + description: "Hostname is the hostname to be + used in the value of the `Location` header + in the response. When empty, the hostname + in the `Host` header of the request is used. + \n Support: Core" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + path: + description: "Path defines parameters used to + modify the path of the incoming request. The + modified path is then used to construct the + `Location` header. When empty, the request + path is used as-is. \n Support: Extended" + properties: + replaceFullPath: + description: ReplaceFullPath specifies the + value with which to replace the full path + of a request during a rewrite or redirect. + maxLength: 1024 + type: string + replacePrefixMatch: + description: "ReplacePrefixMatch specifies + the value with which to replace the prefix + match of a request during a rewrite or + redirect. For example, a request to \"/foo/bar\" + with a prefix match of \"/foo\" would + be modified to \"/bar\". \n Note that + this matches the behavior of the PathPrefix + match type. This matches full path elements. + A path element refers to the list of labels + in the path split by the `/` separator. + When specified, a trailing `/` is ignored. + For example, the paths `/abc`, `/abc/`, + and `/abc/def` would all match the prefix + `/abc`, but the path `/abcd` would not." + maxLength: 1024 + type: string + type: + description: "Type defines the type of path + modifier. Additional types may be added + in a future release of the API. \n Note + that values may be added to this enum, + implementations must ensure that unknown + values will not cause a crash. \n Unknown + values here must result in the implementation + setting the Accepted Condition for the + Route to `status: False`, with a Reason + of `UnsupportedValue`." + enum: + - ReplaceFullPath + - ReplacePrefixMatch + type: string + required: + - type + type: object + port: + description: "Port is the port to be used in + the value of the `Location` header in the + response. \n If no port is specified, the + redirect port MUST be derived using the following + rules: \n * If redirect scheme is not-empty, + the redirect port MUST be the well-known port + associated with the redirect scheme. Specifically + \"http\" to port 80 and \"https\" to port + 443. If the redirect scheme does not have + a well-known port, the listener port of the + Gateway SHOULD be used. * If redirect scheme + is empty, the redirect port MUST be the Gateway + Listener port. \n Implementations SHOULD NOT + add the port number in the 'Location' header + in the following cases: \n * A Location header + that will use HTTP (whether that is determined + via the Listener protocol or the Scheme field) + _and_ use port 80. * A Location header that + will use HTTPS (whether that is determined + via the Listener protocol or the Scheme field) + _and_ use port 443. \n Support: Extended" + format: int32 + maximum: 65535 + minimum: 1 + type: integer + scheme: + description: "Scheme is the scheme to be used + in the value of the `Location` header in the + response. When empty, the scheme of the request + is used. \n Scheme redirects can affect the + port of the redirect, for more information, + refer to the documentation for the port field + of this filter. \n Note that values may be + added to this enum, implementations must ensure + that unknown values will not cause a crash. + \n Unknown values here must result in the + implementation setting the Accepted Condition + for the Route to `status: False`, with a Reason + of `UnsupportedValue`. \n Support: Extended" + enum: + - http + - https + type: string + statusCode: + default: 302 + description: "StatusCode is the HTTP status + code to be used in response. \n Note that + values may be added to this enum, implementations + must ensure that unknown values will not cause + a crash. \n Unknown values here must result + in the implementation setting the Accepted + Condition for the Route to `status: False`, + with a Reason of `UnsupportedValue`. \n Support: + Core" + enum: + - 301 + - 302 + type: integer + type: object + responseHeaderModifier: + description: "ResponseHeaderModifier defines a schema + for a filter that modifies response headers. \n + Support: Extended" + properties: + add: + description: "Add adds the given header(s) (name, + value) to the request before the action. It + appends to any existing values associated + with the header name. \n Input: GET /foo HTTP/1.1 + my-header: foo \n Config: add: - name: \"my-header\" + value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 + my-header: foo,bar,baz" + items: + description: HTTPHeader represents an HTTP + Header name and value as defined by RFC + 7230. + properties: + name: + description: "Name is the name of the + HTTP Header to be matched. Name matching + MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an + equivalent name MUST be considered for + a match. Subsequent entries with an + equivalent header name MUST be ignored. + Due to the case-insensitivity of header + names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + remove: + description: "Remove the given header(s) from + the HTTP request before the action. The value + of Remove is a list of HTTP header names. + Note that the header names are case-insensitive + (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + \n Input: GET /foo HTTP/1.1 my-header1: foo + my-header2: bar my-header3: baz \n Config: + remove: [\"my-header1\", \"my-header3\"] \n + Output: GET /foo HTTP/1.1 my-header2: bar" + items: + type: string + maxItems: 16 + type: array + set: + description: "Set overwrites the request with + the given header (name, value) before the + action. \n Input: GET /foo HTTP/1.1 my-header: + foo \n Config: set: - name: \"my-header\" + value: \"bar\" \n Output: GET /foo HTTP/1.1 + my-header: bar" + items: + description: HTTPHeader represents an HTTP + Header name and value as defined by RFC + 7230. + properties: + name: + description: "Name is the name of the + HTTP Header to be matched. Name matching + MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an + equivalent name MUST be considered for + a match. Subsequent entries with an + equivalent header name MUST be ignored. + Due to the case-insensitivity of header + names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: + description: "Type identifies the type of filter + to apply. As with other API fields, types are + classified into three conformance levels: \n - + Core: Filter types and their corresponding configuration + defined by \"Support: Core\" in this package, + e.g. \"RequestHeaderModifier\". All implementations + must support core filters. \n - Extended: Filter + types and their corresponding configuration defined + by \"Support: Extended\" in this package, e.g. + \"RequestMirror\". Implementers are encouraged + to support extended filters. \n - Implementation-specific: + Filters that are defined and supported by specific + vendors. In the future, filters showing convergence + in behavior across multiple implementations will + be considered for inclusion in extended or core + conformance levels. Filter-specific configuration + for such filters is specified using the ExtensionRef + field. `Type` should be set to \"ExtensionRef\" + for custom filters. \n Implementers are encouraged + to define custom implementation types to extend + the core API with implementation-specific behavior. + \n If a reference to a custom filter type cannot + be resolved, the filter MUST NOT be skipped. Instead, + requests that would have been processed by that + filter MUST receive a HTTP error response. \n + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause + a crash. \n Unknown values here must result in + the implementation setting the Accepted Condition + for the Route to `status: False`, with a Reason + of `UnsupportedValue`." + enum: + - RequestHeaderModifier + - ResponseHeaderModifier + - RequestMirror + - RequestRedirect + - URLRewrite + - ExtensionRef + type: string + urlRewrite: + description: "URLRewrite defines a schema for a + filter that modifies a request during forwarding. + \n Support: Extended" + properties: + hostname: + description: "Hostname is the value to be used + to replace the Host header value during forwarding. + \n Support: Extended" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + path: + description: "Path defines a path rewrite. \n + Support: Extended" + properties: + replaceFullPath: + description: ReplaceFullPath specifies the + value with which to replace the full path + of a request during a rewrite or redirect. + maxLength: 1024 + type: string + replacePrefixMatch: + description: "ReplacePrefixMatch specifies + the value with which to replace the prefix + match of a request during a rewrite or + redirect. For example, a request to \"/foo/bar\" + with a prefix match of \"/foo\" would + be modified to \"/bar\". \n Note that + this matches the behavior of the PathPrefix + match type. This matches full path elements. + A path element refers to the list of labels + in the path split by the `/` separator. + When specified, a trailing `/` is ignored. + For example, the paths `/abc`, `/abc/`, + and `/abc/def` would all match the prefix + `/abc`, but the path `/abcd` would not." + maxLength: 1024 + type: string + type: + description: "Type defines the type of path + modifier. Additional types may be added + in a future release of the API. \n Note + that values may be added to this enum, + implementations must ensure that unknown + values will not cause a crash. \n Unknown + values here must result in the implementation + setting the Accepted Condition for the + Route to `status: False`, with a Reason + of `UnsupportedValue`." + enum: + - ReplaceFullPath + - ReplacePrefixMatch + type: string + required: + - type + type: object + type: object + required: + - type + type: object + maxItems: 16 + type: array + group: + default: "" + description: Group is the group of the referent. For example, + "gateway.networking.k8s.io". When unspecified or empty + string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Service + description: "Kind is the Kubernetes resource kind of + the referent. For example \"Service\". \n Defaults to + \"Service\" when not specified. \n ExternalName services + can refer to CNAME DNS records that may live outside + of the cluster and as such are difficult to reason about + in terms of conformance. They also may not be safe to + forward to (see CVE-2021-25740 for more information). + Implementations SHOULD NOT support ExternalName Services. + \n Support: Core (Services with a type other than ExternalName) + \n Support: Implementation-specific (Services with type + ExternalName)" + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace of the backend. + When unspecified, the local namespace is inferred. \n + Note that when a namespace different than the local + namespace is specified, a ReferenceGrant object is required + in the referent namespace to allow that namespace's + owner to accept the reference. See the ReferenceGrant + documentation for details. \n Support: Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: Port specifies the destination port number + to use for this resource. Port is required when the + referent is a Kubernetes Service. In this case, the + port number is the service port number, not the target + port. For other resources, destination port might be + derived from the referent resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + weight: + default: 1 + description: "Weight specifies the proportion of requests + forwarded to the referenced backend. This is computed + as weight/(sum of all weights in this BackendRefs list). + For non-zero values, there may be some epsilon from + the exact proportion defined here depending on the precision + an implementation supports. Weight is not a percentage + and the sum of weights does not need to equal 100. \n + If only one backend is specified and it has a weight + greater than 0, 100% of the traffic is forwarded to + that backend. If weight is set to 0, no traffic should + be forwarded for this entry. If unspecified, weight + defaults to 1. \n Support for this field varies based + on the context where used." + format: int32 + maximum: 1000000 + minimum: 0 + type: integer + required: + - name + type: object + maxItems: 16 + type: array + filters: + description: "Filters define the filters that are applied to + requests that match this rule. \n The effects of ordering + of multiple behaviors are currently unspecified. This can + change in the future based on feedback during the alpha stage. + \n Conformance-levels at this level are defined based on the + type of filter: \n - ALL core filters MUST be supported by + all implementations. - Implementers are encouraged to support + extended filters. - Implementation-specific custom filters + have no API guarantees across implementations. \n Specifying + a core filter multiple times has unspecified or implementation-specific + conformance. \n All filters are expected to be compatible + with each other except for the URLRewrite and RequestRedirect + filters, which may not be combined. If an implementation can + not support other combinations of filters, they must clearly + document that limitation. In all cases where incompatible + or unsupported filters are specified, implementations MUST + add a warning condition to status. \n Support: Core" + items: + description: HTTPRouteFilter defines processing steps that + must be completed during the request or response lifecycle. + HTTPRouteFilters are meant as an extension point to express + processing that may be done in Gateway implementations. + Some examples include request or response modification, + implementing authentication strategies, rate-limiting, and + traffic shaping. API guarantee/conformance is defined based + on the type of the filter. + properties: + extensionRef: + description: "ExtensionRef is an optional, implementation-specific + extension to the \"filter\" behavior. For example, + resource \"myroutefilter\" in group \"networking.example.net\"). + ExtensionRef MUST NOT be used for core and extended + filters. \n Support: Implementation-specific" + properties: + group: + description: Group is the group of the referent. For + example, "gateway.networking.k8s.io". When unspecified + or empty string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: Kind is kind of the referent. For example + "HTTPRoute" or "Service". + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + required: + - group + - kind + - name + type: object + requestHeaderModifier: + description: "RequestHeaderModifier defines a schema for + a filter that modifies request headers. \n Support: + Core" + properties: + add: + description: "Add adds the given header(s) (name, + value) to the request before the action. It appends + to any existing values associated with the header + name. \n Input: GET /foo HTTP/1.1 my-header: foo + \n Config: add: - name: \"my-header\" value: \"bar,baz\" + \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz" + items: + description: HTTPHeader represents an HTTP Header + name and value as defined by RFC 7230. + properties: + name: + description: "Name is the name of the HTTP Header + to be matched. Name matching MUST be case + insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an equivalent + name MUST be considered for a match. Subsequent + entries with an equivalent header name MUST + be ignored. Due to the case-insensitivity + of header names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + remove: + description: "Remove the given header(s) from the + HTTP request before the action. The value of Remove + is a list of HTTP header names. Note that the header + names are case-insensitive (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: + bar my-header3: baz \n Config: remove: [\"my-header1\", + \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: + bar" + items: + type: string + maxItems: 16 + type: array + set: + description: "Set overwrites the request with the + given header (name, value) before the action. \n + Input: GET /foo HTTP/1.1 my-header: foo \n Config: + set: - name: \"my-header\" value: \"bar\" \n Output: + GET /foo HTTP/1.1 my-header: bar" + items: + description: HTTPHeader represents an HTTP Header + name and value as defined by RFC 7230. + properties: + name: + description: "Name is the name of the HTTP Header + to be matched. Name matching MUST be case + insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an equivalent + name MUST be considered for a match. Subsequent + entries with an equivalent header name MUST + be ignored. Due to the case-insensitivity + of header names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + requestMirror: + description: "RequestMirror defines a schema for a filter + that mirrors requests. Requests are sent to the specified + destination, but responses from that destination are + ignored. \n Support: Extended" + properties: + backendRef: + description: "BackendRef references a resource where + mirrored requests are sent. \n If the referent cannot + be found, this BackendRef is invalid and must be + dropped from the Gateway. The controller must ensure + the \"ResolvedRefs\" condition on the Route status + is set to `status: False` and not configure this + backend in the underlying implementation. \n If + there is a cross-namespace reference to an *existing* + object that is not allowed by a ReferenceGrant, + the controller must ensure the \"ResolvedRefs\" + \ condition on the Route is set to `status: False`, + with the \"RefNotPermitted\" reason and not configure + this backend in the underlying implementation. \n + In either error case, the Message of the `ResolvedRefs` + Condition should be used to provide more detail + about the problem. \n Support: Extended for Kubernetes + Service \n Support: Implementation-specific for + any other resource" + properties: + group: + default: "" + description: Group is the group of the referent. + For example, "gateway.networking.k8s.io". When + unspecified or empty string, core API group + is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Service + description: "Kind is the Kubernetes resource + kind of the referent. For example \"Service\". + \n Defaults to \"Service\" when not specified. + \n ExternalName services can refer to CNAME + DNS records that may live outside of the cluster + and as such are difficult to reason about in + terms of conformance. They also may not be safe + to forward to (see CVE-2021-25740 for more information). + Implementations SHOULD NOT support ExternalName + Services. \n Support: Core (Services with a + type other than ExternalName) \n Support: Implementation-specific + (Services with type ExternalName)" + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace of the + backend. When unspecified, the local namespace + is inferred. \n Note that when a namespace different + than the local namespace is specified, a ReferenceGrant + object is required in the referent namespace + to allow that namespace's owner to accept the + reference. See the ReferenceGrant documentation + for details. \n Support: Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: Port specifies the destination port + number to use for this resource. Port is required + when the referent is a Kubernetes Service. In + this case, the port number is the service port + number, not the target port. For other resources, + destination port might be derived from the referent + resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - name + type: object + required: + - backendRef + type: object + requestRedirect: + description: "RequestRedirect defines a schema for a filter + that responds to the request with an HTTP redirection. + \n Support: Core" + properties: + hostname: + description: "Hostname is the hostname to be used + in the value of the `Location` header in the response. + When empty, the hostname in the `Host` header of + the request is used. \n Support: Core" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + path: + description: "Path defines parameters used to modify + the path of the incoming request. The modified path + is then used to construct the `Location` header. + When empty, the request path is used as-is. \n Support: + Extended" + properties: + replaceFullPath: + description: ReplaceFullPath specifies the value + with which to replace the full path of a request + during a rewrite or redirect. + maxLength: 1024 + type: string + replacePrefixMatch: + description: "ReplacePrefixMatch specifies the + value with which to replace the prefix match + of a request during a rewrite or redirect. For + example, a request to \"/foo/bar\" with a prefix + match of \"/foo\" would be modified to \"/bar\". + \n Note that this matches the behavior of the + PathPrefix match type. This matches full path + elements. A path element refers to the list + of labels in the path split by the `/` separator. + When specified, a trailing `/` is ignored. For + example, the paths `/abc`, `/abc/`, and `/abc/def` + would all match the prefix `/abc`, but the path + `/abcd` would not." + maxLength: 1024 + type: string + type: + description: "Type defines the type of path modifier. + Additional types may be added in a future release + of the API. \n Note that values may be added + to this enum, implementations must ensure that + unknown values will not cause a crash. \n Unknown + values here must result in the implementation + setting the Accepted Condition for the Route + to `status: False`, with a Reason of `UnsupportedValue`." + enum: + - ReplaceFullPath + - ReplacePrefixMatch + type: string + required: + - type + type: object + port: + description: "Port is the port to be used in the value + of the `Location` header in the response. \n If + no port is specified, the redirect port MUST be + derived using the following rules: \n * If redirect + scheme is not-empty, the redirect port MUST be the + well-known port associated with the redirect scheme. + Specifically \"http\" to port 80 and \"https\" to + port 443. If the redirect scheme does not have a + well-known port, the listener port of the Gateway + SHOULD be used. * If redirect scheme is empty, the + redirect port MUST be the Gateway Listener port. + \n Implementations SHOULD NOT add the port number + in the 'Location' header in the following cases: + \n * A Location header that will use HTTP (whether + that is determined via the Listener protocol or + the Scheme field) _and_ use port 80. * A Location + header that will use HTTPS (whether that is determined + via the Listener protocol or the Scheme field) _and_ + use port 443. \n Support: Extended" + format: int32 + maximum: 65535 + minimum: 1 + type: integer + scheme: + description: "Scheme is the scheme to be used in the + value of the `Location` header in the response. + When empty, the scheme of the request is used. \n + Scheme redirects can affect the port of the redirect, + for more information, refer to the documentation + for the port field of this filter. \n Note that + values may be added to this enum, implementations + must ensure that unknown values will not cause a + crash. \n Unknown values here must result in the + implementation setting the Accepted Condition for + the Route to `status: False`, with a Reason of `UnsupportedValue`. + \n Support: Extended" + enum: + - http + - https + type: string + statusCode: + default: 302 + description: "StatusCode is the HTTP status code to + be used in response. \n Note that values may be + added to this enum, implementations must ensure + that unknown values will not cause a crash. \n Unknown + values here must result in the implementation setting + the Accepted Condition for the Route to `status: + False`, with a Reason of `UnsupportedValue`. \n + Support: Core" + enum: + - 301 + - 302 + type: integer + type: object + responseHeaderModifier: + description: "ResponseHeaderModifier defines a schema + for a filter that modifies response headers. \n Support: + Extended" + properties: + add: + description: "Add adds the given header(s) (name, + value) to the request before the action. It appends + to any existing values associated with the header + name. \n Input: GET /foo HTTP/1.1 my-header: foo + \n Config: add: - name: \"my-header\" value: \"bar,baz\" + \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz" + items: + description: HTTPHeader represents an HTTP Header + name and value as defined by RFC 7230. + properties: + name: + description: "Name is the name of the HTTP Header + to be matched. Name matching MUST be case + insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an equivalent + name MUST be considered for a match. Subsequent + entries with an equivalent header name MUST + be ignored. Due to the case-insensitivity + of header names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + remove: + description: "Remove the given header(s) from the + HTTP request before the action. The value of Remove + is a list of HTTP header names. Note that the header + names are case-insensitive (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: + bar my-header3: baz \n Config: remove: [\"my-header1\", + \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: + bar" + items: + type: string + maxItems: 16 + type: array + set: + description: "Set overwrites the request with the + given header (name, value) before the action. \n + Input: GET /foo HTTP/1.1 my-header: foo \n Config: + set: - name: \"my-header\" value: \"bar\" \n Output: + GET /foo HTTP/1.1 my-header: bar" + items: + description: HTTPHeader represents an HTTP Header + name and value as defined by RFC 7230. + properties: + name: + description: "Name is the name of the HTTP Header + to be matched. Name matching MUST be case + insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an equivalent + name MUST be considered for a match. Subsequent + entries with an equivalent header name MUST + be ignored. Due to the case-insensitivity + of header names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: + description: "Type identifies the type of filter to apply. + As with other API fields, types are classified into + three conformance levels: \n - Core: Filter types and + their corresponding configuration defined by \"Support: + Core\" in this package, e.g. \"RequestHeaderModifier\". + All implementations must support core filters. \n - + Extended: Filter types and their corresponding configuration + defined by \"Support: Extended\" in this package, e.g. + \"RequestMirror\". Implementers are encouraged to support + extended filters. \n - Implementation-specific: Filters + that are defined and supported by specific vendors. + In the future, filters showing convergence in behavior + across multiple implementations will be considered for + inclusion in extended or core conformance levels. Filter-specific + configuration for such filters is specified using the + ExtensionRef field. `Type` should be set to \"ExtensionRef\" + for custom filters. \n Implementers are encouraged to + define custom implementation types to extend the core + API with implementation-specific behavior. \n If a reference + to a custom filter type cannot be resolved, the filter + MUST NOT be skipped. Instead, requests that would have + been processed by that filter MUST receive a HTTP error + response. \n Note that values may be added to this enum, + implementations must ensure that unknown values will + not cause a crash. \n Unknown values here must result + in the implementation setting the Accepted Condition + for the Route to `status: False`, with a Reason of `UnsupportedValue`." + enum: + - RequestHeaderModifier + - ResponseHeaderModifier + - RequestMirror + - RequestRedirect + - URLRewrite + - ExtensionRef + type: string + urlRewrite: + description: "URLRewrite defines a schema for a filter + that modifies a request during forwarding. \n Support: + Extended" + properties: + hostname: + description: "Hostname is the value to be used to + replace the Host header value during forwarding. + \n Support: Extended" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + path: + description: "Path defines a path rewrite. \n Support: + Extended" + properties: + replaceFullPath: + description: ReplaceFullPath specifies the value + with which to replace the full path of a request + during a rewrite or redirect. + maxLength: 1024 + type: string + replacePrefixMatch: + description: "ReplacePrefixMatch specifies the + value with which to replace the prefix match + of a request during a rewrite or redirect. For + example, a request to \"/foo/bar\" with a prefix + match of \"/foo\" would be modified to \"/bar\". + \n Note that this matches the behavior of the + PathPrefix match type. This matches full path + elements. A path element refers to the list + of labels in the path split by the `/` separator. + When specified, a trailing `/` is ignored. For + example, the paths `/abc`, `/abc/`, and `/abc/def` + would all match the prefix `/abc`, but the path + `/abcd` would not." + maxLength: 1024 + type: string + type: + description: "Type defines the type of path modifier. + Additional types may be added in a future release + of the API. \n Note that values may be added + to this enum, implementations must ensure that + unknown values will not cause a crash. \n Unknown + values here must result in the implementation + setting the Accepted Condition for the Route + to `status: False`, with a Reason of `UnsupportedValue`." + enum: + - ReplaceFullPath + - ReplacePrefixMatch + type: string + required: + - type + type: object + type: object + required: + - type + type: object + maxItems: 16 + type: array + matches: + default: + - path: + type: PathPrefix + value: / + description: "Matches define conditions used for matching the + rule against incoming HTTP requests. Each match is independent, + i.e. this rule will be matched if **any** one of the matches + is satisfied. \n For example, take the following matches configuration: + \n ``` matches: - path: value: \"/foo\" headers: - name: \"version\" + value: \"v2\" - path: value: \"/v2/foo\" ``` \n For a request + to match against this rule, a request must satisfy EITHER + of the two conditions: \n - path prefixed with `/foo` AND + contains the header `version: v2` - path prefix of `/v2/foo` + \n See the documentation for HTTPRouteMatch on how to specify + multiple match conditions that should be ANDed together. \n + If no matches are specified, the default is a prefix path + match on \"/\", which has the effect of matching every HTTP + request. \n Proxy or Load Balancer routing configuration generated + from HTTPRoutes MUST prioritize matches based on the following + criteria, continuing on ties. Across all rules specified on + applicable Routes, precedence must be given to the match having: + \n * \"Exact\" path match. * \"Prefix\" path match with largest + number of characters. * Method match. * Largest number of + header matches. * Largest number of query param matches. \n + Note: The precedence of RegularExpression path matches are + implementation-specific. \n If ties still exist across multiple + Routes, matching precedence MUST be determined in order of + the following criteria, continuing on ties: \n * The oldest + Route based on creation timestamp. * The Route appearing first + in alphabetical order by \"{namespace}/{name}\". \n If ties + still exist within an HTTPRoute, matching precedence MUST + be granted to the FIRST matching rule (in list order) with + a match meeting the above criteria. \n When no rules matching + a request have been successfully attached to the parent a + request is coming from, a HTTP 404 status code MUST be returned." + items: + description: "HTTPRouteMatch defines the predicate used to + match requests to a given action. Multiple match types are + ANDed together, i.e. the match will evaluate to true only + if all conditions are satisfied. \n For example, the match + below will match a HTTP request only if its path starts + with `/foo` AND it contains the `version: v1` header: \n + ``` match: \n path: value: \"/foo\" headers: - name: \"version\" + value \"v1\" \n ```" + properties: + headers: + description: Headers specifies HTTP request header matchers. + Multiple match values are ANDed together, meaning, a + request must match all the specified headers to select + the route. + items: + description: HTTPHeaderMatch describes how to select + a HTTP route by matching HTTP request headers. + properties: + name: + description: "Name is the name of the HTTP Header + to be matched. Name matching MUST be case insensitive. + (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent header + names, only the first entry with an equivalent + name MUST be considered for a match. Subsequent + entries with an equivalent header name MUST be + ignored. Due to the case-insensitivity of header + names, \"foo\" and \"Foo\" are considered equivalent. + \n When a header is repeated in an HTTP request, + it is implementation-specific behavior as to how + this is represented. Generally, proxies should + follow the guidance from the RFC: https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2.2 + regarding processing a repeated header, with special + handling for \"Set-Cookie\"." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + type: + default: Exact + description: "Type specifies how to match against + the value of the header. \n Support: Core (Exact) + \n Support: Implementation-specific (RegularExpression) + \n Since RegularExpression HeaderMatchType has + implementation-specific conformance, implementations + can support POSIX, PCRE or any other dialects + of regular expressions. Please read the implementation's + documentation to determine the supported dialect." + enum: + - Exact + - RegularExpression + type: string + value: + description: Value is the value of HTTP Header to + be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + method: + description: "Method specifies HTTP method matcher. When + specified, this route will be matched only if the request + has the specified method. \n Support: Extended" + enum: + - GET + - HEAD + - POST + - PUT + - DELETE + - CONNECT + - OPTIONS + - TRACE + - PATCH + type: string + path: + default: + type: PathPrefix + value: / + description: Path specifies a HTTP request path matcher. + If this field is not specified, a default prefix match + on the "/" path is provided. + properties: + type: + default: PathPrefix + description: "Type specifies how to match against + the path Value. \n Support: Core (Exact, PathPrefix) + \n Support: Implementation-specific (RegularExpression)" + enum: + - Exact + - PathPrefix + - RegularExpression + type: string + value: + default: / + description: Value of the HTTP path to match against. + maxLength: 1024 + type: string + type: object + queryParams: + description: "QueryParams specifies HTTP query parameter + matchers. Multiple match values are ANDed together, + meaning, a request must match all the specified query + parameters to select the route. \n Support: Extended" + items: + description: HTTPQueryParamMatch describes how to select + a HTTP route by matching HTTP query parameters. + properties: + name: + description: "Name is the name of the HTTP query + param to be matched. This must be an exact string + match. (See https://tools.ietf.org/html/rfc7230#section-2.7.3). + \n If multiple entries specify equivalent query + param names, only the first entry with an equivalent + name MUST be considered for a match. Subsequent + entries with an equivalent query param name MUST + be ignored. \n If a query param is repeated in + an HTTP request, the behavior is purposely left + undefined, since different data planes have different + capabilities. However, it is *recommended* that + implementations should match against the first + value of the param if the data plane supports + it, as this behavior is expected in other load + balancing contexts outside of the Gateway API. + \n Users SHOULD NOT route traffic based on repeated + query params to guard themselves against potential + differences in the implementations." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + type: + default: Exact + description: "Type specifies how to match against + the value of the query parameter. \n Support: + Extended (Exact) \n Support: Implementation-specific + (RegularExpression) \n Since RegularExpression + QueryParamMatchType has Implementation-specific + conformance, implementations can support POSIX, + PCRE or any other dialects of regular expressions. + Please read the implementation's documentation + to determine the supported dialect." + enum: + - Exact + - RegularExpression + type: string + value: + description: Value is the value of HTTP query param + to be matched. + maxLength: 1024 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + maxItems: 8 + type: array + type: object + maxItems: 16 + type: array + type: object + status: + description: Status defines the current state of HTTPRoute. + properties: + parents: + description: "Parents is a list of parent resources (usually Gateways) + that are associated with the route, and the status of the route + with respect to each parent. When this route attaches to a parent, + the controller that manages the parent must add an entry to this + list when the controller first sees the route and should update + the entry as appropriate when the route or gateway is modified. + \n Note that parent references that cannot be resolved by an implementation + of this API will not be added to this list. Implementations of this + API can only populate Route status for the Gateways/parent resources + they are responsible for. \n A maximum of 32 Gateways will be represented + in this list. An empty list means the route has not been attached + to any Gateway." + items: + description: RouteParentStatus describes the status of a route with + respect to an associated Parent. + properties: + conditions: + description: "Conditions describes the status of the route with + respect to the Gateway. Note that the route's availability + is also subject to the Gateway's own status conditions and + listener status. \n If the Route's ParentRef specifies an + existing Gateway that supports Routes of this kind AND that + Gateway's controller has sufficient access, then that Gateway's + controller MUST set the \"Accepted\" condition on the Route, + to indicate whether the route has been accepted or rejected + by the Gateway, and why. \n A Route MUST be considered \"Accepted\" + if at least one of the Route's rules is implemented by the + Gateway. \n There are a number of cases where the \"Accepted\" + condition may not be set due to lack of controller visibility, + that includes when: \n * The Route refers to a non-existent + parent. * The Route is of a type that the controller does + not support. * The Route is in a namespace the controller + does not have access to." + items: + description: "Condition contains details for one aspect of + the current state of this API Resource. --- This struct + is intended for direct use as an array at the field path + .status.conditions. For example, \n type FooStatus struct{ + // Represents the observations of a foo's current state. + // Known .status.conditions.type are: \"Available\", \"Progressing\", + and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge + // +listType=map // +listMapKey=type Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields + }" + 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 + maxItems: 8 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + controllerName: + description: "ControllerName is a domain/path string that indicates + the name of the controller that wrote this status. This corresponds + with the controllerName field on GatewayClass. \n Example: + \"example.net/gateway-controller\". \n The format of this + field is DOMAIN \"/\" PATH, where DOMAIN and PATH are valid + Kubernetes names (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). + \n Controllers MUST populate this field when writing status. + Controllers should ensure that entries to status populated + with their ControllerName are cleaned up when they are no + longer necessary." + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + parentRef: + description: ParentRef corresponds with a ParentRef in the spec + that this RouteParentStatus struct describes the status of. + properties: + group: + default: gateway.networking.k8s.io + description: "Group is the group of the referent. When unspecified, + \"gateway.networking.k8s.io\" is inferred. To set the + core API group (such as for a \"Service\" kind referent), + Group must be explicitly set to \"\" (empty string). \n + Support: Core" + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Gateway + description: "Kind is kind of the referent. \n Support: + Core (Gateway) \n Support: Implementation-specific (Other + Resources)" + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: "Name is the name of the referent. \n Support: + Core" + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace of the referent. + When unspecified, this refers to the local namespace of + the Route. \n Note that there are specific rules for ParentRefs + which cross namespace boundaries. Cross-namespace references + are only valid if they are explicitly allowed by something + in the namespace they are referring to. For example: Gateway + has the AllowedRoutes field, and ReferenceGrant provides + a generic way to enable any other kind of cross-namespace + reference. \n Support: Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: "Port is the network port this Route targets. + It can be interpreted differently based on the type of + parent resource. \n When the parent resource is a Gateway, + this targets all listeners listening on the specified + port that also support this kind of Route(and select this + Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to + a specific port as opposed to a listener(s) whose port(s) + may be changed. When both Port and SectionName are specified, + the name and port of the selected listener must match + both specified values. \n Implementations MAY choose to + support other parent resources. Implementations supporting + other types of parent resources MUST clearly document + how/if Port is interpreted. \n For the purpose of status, + an attachment is considered successful as long as the + parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them + by Route kind, namespace, or hostname. If 1 of 2 Gateway + listeners accept attachment from the referencing Route, + the Route MUST be considered successfully attached. If + no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + \n Support: Extended \n " + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: "SectionName is the name of a section within + the target resource. In the following resources, SectionName + is interpreted as the following: \n * Gateway: Listener + Name. When both Port (experimental) and SectionName are + specified, the name and port of the selected listener + must match both specified values. \n Implementations MAY + choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName + is interpreted. \n When unspecified (empty string), this + will reference the entire resource. For the purpose of + status, an attachment is considered successful if at least + one section in the parent resource accepts it. For example, + Gateway listeners can restrict which Routes can attach + to them by Route kind, namespace, or hostname. If 1 of + 2 Gateway listeners accept attachment from the referencing + Route, the Route MUST be considered successfully attached. + If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + \n Support: Core" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - name + type: object + required: + - controllerName + - parentRef + type: object + maxItems: 32 + type: array + required: + - parents + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .spec.hostnames + name: Hostnames + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: HTTPRoute provides a way to route HTTP requests. This includes + the capability to match requests by hostname, path, header, or query param. + Filters can be used to specify additional processing steps. Backends specify + where matching requests should be routed. + 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 HTTPRoute. + properties: + hostnames: + description: "Hostnames defines a set of hostname that should match + against the HTTP Host header to select a HTTPRoute used to process + the request. Implementations MUST ignore any port value specified + in the HTTP Host header while performing a match. \n Valid values + for Hostnames are determined by RFC 1123 definition of a hostname + with 2 notable exceptions: \n 1. IPs are not allowed. 2. A hostname + may be prefixed with a wildcard label (`*.`). The wildcard label + must appear by itself as the first label. \n If a hostname is specified + by both the Listener and HTTPRoute, there must be at least one intersecting + hostname for the HTTPRoute to be attached to the Listener. For example: + \n * A Listener with `test.example.com` as the hostname matches + HTTPRoutes that have either not specified any hostnames, or have + specified at least one of `test.example.com` or `*.example.com`. + * A Listener with `*.example.com` as the hostname matches HTTPRoutes + that have either not specified any hostnames or have specified at + least one hostname that matches the Listener hostname. For example, + `*.example.com`, `test.example.com`, and `foo.test.example.com` + would all match. On the other hand, `example.com` and `test.example.net` + would not match. \n Hostnames that are prefixed with a wildcard + label (`*.`) are interpreted as a suffix match. That means that + a match for `*.example.com` would match both `test.example.com`, + and `foo.test.example.com`, but not `example.com`. \n If both the + Listener and HTTPRoute have specified hostnames, any HTTPRoute hostnames + that do not match the Listener hostname MUST be ignored. For example, + if a Listener specified `*.example.com`, and the HTTPRoute specified + `test.example.com` and `test.example.net`, `test.example.net` must + not be considered for a match. \n If both the Listener and HTTPRoute + have specified hostnames, and none match with the criteria above, + then the HTTPRoute is not accepted. The implementation must raise + an 'Accepted' Condition with a status of `False` in the corresponding + RouteParentStatus. \n In the event that multiple HTTPRoutes specify + intersecting hostnames (e.g. overlapping wildcard matching and exact + matching hostnames), precedence must be given to rules from the + HTTPRoute with the largest number of: \n * Characters in a matching + non-wildcard hostname. * Characters in a matching hostname. \n If + ties exist across multiple Routes, the matching precedence rules + for HTTPRouteMatches takes over. \n Support: Core" + items: + description: "Hostname is the fully qualified domain name of a network + host. This matches the RFC 1123 definition of a hostname with + 2 notable exceptions: \n 1. IPs are not allowed. 2. A hostname + may be prefixed with a wildcard label (`*.`). The wildcard label + must appear by itself as the first label. \n Hostname can be \"precise\" + which is a domain name without the terminating dot of a network + host (e.g. \"foo.example.com\") or \"wildcard\", which is a domain + name prefixed with a single wildcard label (e.g. `*.example.com`). + \n Note that as per RFC1035 and RFC1123, a *label* must consist + of lower case alphanumeric characters or '-', and must start and + end with an alphanumeric character. No other punctuation is allowed." + maxLength: 253 + minLength: 1 + pattern: ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + maxItems: 16 + type: array + parentRefs: + description: "ParentRefs references the resources (usually Gateways) + that a Route wants to be attached to. Note that the referenced parent + resource needs to allow this for the attachment to be complete. + For Gateways, that means the Gateway needs to allow attachment from + Routes of this kind and namespace. \n The only kind of parent resource + with \"Core\" support is Gateway. This API may be extended in the + future to support additional kinds of parent resources such as one + of the route kinds. \n It is invalid to reference an identical parent + more than once. It is valid to reference multiple distinct sections + within the same parent resource, such as 2 Listeners within a Gateway. + \n It is possible to separately reference multiple distinct objects + that may be collapsed by an implementation. For example, some implementations + may choose to merge compatible Gateway Listeners together. If that + is the case, the list of routes attached to those resources should + also be merged. \n Note that for ParentRefs that cross namespace + boundaries, there are specific rules. Cross-namespace references + are only valid if they are explicitly allowed by something in the + namespace they are referring to. For example, Gateway has the AllowedRoutes + field, and ReferenceGrant provides a generic way to enable any other + kind of cross-namespace reference." + items: + description: "ParentReference identifies an API object (usually + a Gateway) that can be considered a parent of this resource (usually + a route). The only kind of parent resource with \"Core\" support + is Gateway. This API may be extended in the future to support + additional kinds of parent resources, such as HTTPRoute. \n The + API object must be valid in the cluster; the Group and Kind must + be registered in the cluster for this reference to be valid." + properties: + group: + default: gateway.networking.k8s.io + description: "Group is the group of the referent. When unspecified, + \"gateway.networking.k8s.io\" is inferred. To set the core + API group (such as for a \"Service\" kind referent), Group + must be explicitly set to \"\" (empty string). \n Support: + Core" + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Gateway + description: "Kind is kind of the referent. \n Support: Core + (Gateway) \n Support: Implementation-specific (Other Resources)" + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: "Name is the name of the referent. \n Support: + Core" + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace of the referent. When + unspecified, this refers to the local namespace of the Route. + \n Note that there are specific rules for ParentRefs which + cross namespace boundaries. Cross-namespace references are + only valid if they are explicitly allowed by something in + the namespace they are referring to. For example: Gateway + has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. + \n Support: Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: "Port is the network port this Route targets. It + can be interpreted differently based on the type of parent + resource. \n When the parent resource is a Gateway, this targets + all listeners listening on the specified port that also support + this kind of Route(and select this Route). It's not recommended + to set `Port` unless the networking behaviors specified in + a Route must apply to a specific port as opposed to a listener(s) + whose port(s) may be changed. When both Port and SectionName + are specified, the name and port of the selected listener + must match both specified values. \n Implementations MAY choose + to support other parent resources. Implementations supporting + other types of parent resources MUST clearly document how/if + Port is interpreted. \n For the purpose of status, an attachment + is considered successful as long as the parent resource accepts + it partially. For example, Gateway listeners can restrict + which Routes can attach to them by Route kind, namespace, + or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this + Route, the Route MUST be considered detached from the Gateway. + \n Support: Extended \n " + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: "SectionName is the name of a section within the + target resource. In the following resources, SectionName is + interpreted as the following: \n * Gateway: Listener Name. + When both Port (experimental) and SectionName are specified, + the name and port of the selected listener must match both + specified values. \n Implementations MAY choose to support + attaching Routes to other resources. If that is the case, + they MUST clearly document how SectionName is interpreted. + \n When unspecified (empty string), this will reference the + entire resource. For the purpose of status, an attachment + is considered successful if at least one section in the parent + resource accepts it. For example, Gateway listeners can restrict + which Routes can attach to them by Route kind, namespace, + or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this + Route, the Route MUST be considered detached from the Gateway. + \n Support: Core" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - name + type: object + maxItems: 32 + type: array + rules: + default: + - matches: + - path: + type: PathPrefix + value: / + description: Rules are a list of HTTP matchers, filters and actions. + items: + description: HTTPRouteRule defines semantics for matching an HTTP + request based on conditions (matches), processing it (filters), + and forwarding the request to an API object (backendRefs). + properties: + backendRefs: + description: "BackendRefs defines the backend(s) where matching + requests should be sent. \n Failure behavior here depends + on how many BackendRefs are specified and how many are invalid. + \n If *all* entries in BackendRefs are invalid, and there + are also no filters specified in this route rule, *all* traffic + which matches this rule MUST receive a 500 status code. \n + See the HTTPBackendRef definition for the rules about what + makes a single HTTPBackendRef invalid. \n When a HTTPBackendRef + is invalid, 500 status codes MUST be returned for requests + that would have otherwise been routed to an invalid backend. + If multiple backends are specified, and some are invalid, + the proportion of requests that would otherwise have been + routed to an invalid backend MUST receive a 500 status code. + \n For example, if two backends are specified with equal weights, + and one is invalid, 50 percent of traffic must receive a 500. + Implementations may choose how that 50 percent is determined. + \n Support: Core for Kubernetes Service \n Support: Extended + for Kubernetes ServiceImport \n Support: Implementation-specific + for any other resource \n Support for weight: Core" + items: + description: HTTPBackendRef defines how a HTTPRoute should + forward an HTTP request. + properties: + filters: + description: "Filters defined at this level should be + executed if and only if the request is being forwarded + to the backend defined here. \n Support: Implementation-specific + (For broader support of filters, use the Filters field + in HTTPRouteRule.)" + items: + description: HTTPRouteFilter defines processing steps + that must be completed during the request or response + lifecycle. HTTPRouteFilters are meant as an extension + point to express processing that may be done in Gateway + implementations. Some examples include request or + response modification, implementing authentication + strategies, rate-limiting, and traffic shaping. API + guarantee/conformance is defined based on the type + of the filter. + properties: + extensionRef: + description: "ExtensionRef is an optional, implementation-specific + extension to the \"filter\" behavior. For example, + resource \"myroutefilter\" in group \"networking.example.net\"). + ExtensionRef MUST NOT be used for core and extended + filters. \n Support: Implementation-specific" + properties: + group: + description: Group is the group of the referent. + For example, "gateway.networking.k8s.io". + When unspecified or empty string, core API + group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: Kind is kind of the referent. For + example "HTTPRoute" or "Service". + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + required: + - group + - kind + - name + type: object + requestHeaderModifier: + description: "RequestHeaderModifier defines a schema + for a filter that modifies request headers. \n + Support: Core" + properties: + add: + description: "Add adds the given header(s) (name, + value) to the request before the action. It + appends to any existing values associated + with the header name. \n Input: GET /foo HTTP/1.1 + my-header: foo \n Config: add: - name: \"my-header\" + value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 + my-header: foo,bar,baz" + items: + description: HTTPHeader represents an HTTP + Header name and value as defined by RFC + 7230. + properties: + name: + description: "Name is the name of the + HTTP Header to be matched. Name matching + MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an + equivalent name MUST be considered for + a match. Subsequent entries with an + equivalent header name MUST be ignored. + Due to the case-insensitivity of header + names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + remove: + description: "Remove the given header(s) from + the HTTP request before the action. The value + of Remove is a list of HTTP header names. + Note that the header names are case-insensitive + (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + \n Input: GET /foo HTTP/1.1 my-header1: foo + my-header2: bar my-header3: baz \n Config: + remove: [\"my-header1\", \"my-header3\"] \n + Output: GET /foo HTTP/1.1 my-header2: bar" + items: + type: string + maxItems: 16 + type: array + set: + description: "Set overwrites the request with + the given header (name, value) before the + action. \n Input: GET /foo HTTP/1.1 my-header: + foo \n Config: set: - name: \"my-header\" + value: \"bar\" \n Output: GET /foo HTTP/1.1 + my-header: bar" + items: + description: HTTPHeader represents an HTTP + Header name and value as defined by RFC + 7230. + properties: + name: + description: "Name is the name of the + HTTP Header to be matched. Name matching + MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an + equivalent name MUST be considered for + a match. Subsequent entries with an + equivalent header name MUST be ignored. + Due to the case-insensitivity of header + names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + requestMirror: + description: "RequestMirror defines a schema for + a filter that mirrors requests. Requests are sent + to the specified destination, but responses from + that destination are ignored. \n Support: Extended" + properties: + backendRef: + description: "BackendRef references a resource + where mirrored requests are sent. \n If the + referent cannot be found, this BackendRef + is invalid and must be dropped from the Gateway. + The controller must ensure the \"ResolvedRefs\" + condition on the Route status is set to `status: + False` and not configure this backend in the + underlying implementation. \n If there is + a cross-namespace reference to an *existing* + object that is not allowed by a ReferenceGrant, + the controller must ensure the \"ResolvedRefs\" + \ condition on the Route is set to `status: + False`, with the \"RefNotPermitted\" reason + and not configure this backend in the underlying + implementation. \n In either error case, the + Message of the `ResolvedRefs` Condition should + be used to provide more detail about the problem. + \n Support: Extended for Kubernetes Service + \n Support: Implementation-specific for any + other resource" + properties: + group: + default: "" + description: Group is the group of the referent. + For example, "gateway.networking.k8s.io". + When unspecified or empty string, core + API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Service + description: "Kind is the Kubernetes resource + kind of the referent. For example \"Service\". + \n Defaults to \"Service\" when not specified. + \n ExternalName services can refer to + CNAME DNS records that may live outside + of the cluster and as such are difficult + to reason about in terms of conformance. + They also may not be safe to forward to + (see CVE-2021-25740 for more information). + Implementations SHOULD NOT support ExternalName + Services. \n Support: Core (Services with + a type other than ExternalName) \n Support: + Implementation-specific (Services with + type ExternalName)" + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace + of the backend. When unspecified, the + local namespace is inferred. \n Note that + when a namespace different than the local + namespace is specified, a ReferenceGrant + object is required in the referent namespace + to allow that namespace's owner to accept + the reference. See the ReferenceGrant + documentation for details. \n Support: + Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: Port specifies the destination + port number to use for this resource. + Port is required when the referent is + a Kubernetes Service. In this case, the + port number is the service port number, + not the target port. For other resources, + destination port might be derived from + the referent resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - name + type: object + required: + - backendRef + type: object + requestRedirect: + description: "RequestRedirect defines a schema for + a filter that responds to the request with an + HTTP redirection. \n Support: Core" + properties: + hostname: + description: "Hostname is the hostname to be + used in the value of the `Location` header + in the response. When empty, the hostname + in the `Host` header of the request is used. + \n Support: Core" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + path: + description: "Path defines parameters used to + modify the path of the incoming request. The + modified path is then used to construct the + `Location` header. When empty, the request + path is used as-is. \n Support: Extended" + properties: + replaceFullPath: + description: ReplaceFullPath specifies the + value with which to replace the full path + of a request during a rewrite or redirect. + maxLength: 1024 + type: string + replacePrefixMatch: + description: "ReplacePrefixMatch specifies + the value with which to replace the prefix + match of a request during a rewrite or + redirect. For example, a request to \"/foo/bar\" + with a prefix match of \"/foo\" would + be modified to \"/bar\". \n Note that + this matches the behavior of the PathPrefix + match type. This matches full path elements. + A path element refers to the list of labels + in the path split by the `/` separator. + When specified, a trailing `/` is ignored. + For example, the paths `/abc`, `/abc/`, + and `/abc/def` would all match the prefix + `/abc`, but the path `/abcd` would not." + maxLength: 1024 + type: string + type: + description: "Type defines the type of path + modifier. Additional types may be added + in a future release of the API. \n Note + that values may be added to this enum, + implementations must ensure that unknown + values will not cause a crash. \n Unknown + values here must result in the implementation + setting the Accepted Condition for the + Route to `status: False`, with a Reason + of `UnsupportedValue`." + enum: + - ReplaceFullPath + - ReplacePrefixMatch + type: string + required: + - type + type: object + port: + description: "Port is the port to be used in + the value of the `Location` header in the + response. \n If no port is specified, the + redirect port MUST be derived using the following + rules: \n * If redirect scheme is not-empty, + the redirect port MUST be the well-known port + associated with the redirect scheme. Specifically + \"http\" to port 80 and \"https\" to port + 443. If the redirect scheme does not have + a well-known port, the listener port of the + Gateway SHOULD be used. * If redirect scheme + is empty, the redirect port MUST be the Gateway + Listener port. \n Implementations SHOULD NOT + add the port number in the 'Location' header + in the following cases: \n * A Location header + that will use HTTP (whether that is determined + via the Listener protocol or the Scheme field) + _and_ use port 80. * A Location header that + will use HTTPS (whether that is determined + via the Listener protocol or the Scheme field) + _and_ use port 443. \n Support: Extended" + format: int32 + maximum: 65535 + minimum: 1 + type: integer + scheme: + description: "Scheme is the scheme to be used + in the value of the `Location` header in the + response. When empty, the scheme of the request + is used. \n Scheme redirects can affect the + port of the redirect, for more information, + refer to the documentation for the port field + of this filter. \n Note that values may be + added to this enum, implementations must ensure + that unknown values will not cause a crash. + \n Unknown values here must result in the + implementation setting the Accepted Condition + for the Route to `status: False`, with a Reason + of `UnsupportedValue`. \n Support: Extended" + enum: + - http + - https + type: string + statusCode: + default: 302 + description: "StatusCode is the HTTP status + code to be used in response. \n Note that + values may be added to this enum, implementations + must ensure that unknown values will not cause + a crash. \n Unknown values here must result + in the implementation setting the Accepted + Condition for the Route to `status: False`, + with a Reason of `UnsupportedValue`. \n Support: + Core" + enum: + - 301 + - 302 + type: integer + type: object + responseHeaderModifier: + description: "ResponseHeaderModifier defines a schema + for a filter that modifies response headers. \n + Support: Extended" + properties: + add: + description: "Add adds the given header(s) (name, + value) to the request before the action. It + appends to any existing values associated + with the header name. \n Input: GET /foo HTTP/1.1 + my-header: foo \n Config: add: - name: \"my-header\" + value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 + my-header: foo,bar,baz" + items: + description: HTTPHeader represents an HTTP + Header name and value as defined by RFC + 7230. + properties: + name: + description: "Name is the name of the + HTTP Header to be matched. Name matching + MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an + equivalent name MUST be considered for + a match. Subsequent entries with an + equivalent header name MUST be ignored. + Due to the case-insensitivity of header + names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + remove: + description: "Remove the given header(s) from + the HTTP request before the action. The value + of Remove is a list of HTTP header names. + Note that the header names are case-insensitive + (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + \n Input: GET /foo HTTP/1.1 my-header1: foo + my-header2: bar my-header3: baz \n Config: + remove: [\"my-header1\", \"my-header3\"] \n + Output: GET /foo HTTP/1.1 my-header2: bar" + items: + type: string + maxItems: 16 + type: array + set: + description: "Set overwrites the request with + the given header (name, value) before the + action. \n Input: GET /foo HTTP/1.1 my-header: + foo \n Config: set: - name: \"my-header\" + value: \"bar\" \n Output: GET /foo HTTP/1.1 + my-header: bar" + items: + description: HTTPHeader represents an HTTP + Header name and value as defined by RFC + 7230. + properties: + name: + description: "Name is the name of the + HTTP Header to be matched. Name matching + MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an + equivalent name MUST be considered for + a match. Subsequent entries with an + equivalent header name MUST be ignored. + Due to the case-insensitivity of header + names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: + description: "Type identifies the type of filter + to apply. As with other API fields, types are + classified into three conformance levels: \n - + Core: Filter types and their corresponding configuration + defined by \"Support: Core\" in this package, + e.g. \"RequestHeaderModifier\". All implementations + must support core filters. \n - Extended: Filter + types and their corresponding configuration defined + by \"Support: Extended\" in this package, e.g. + \"RequestMirror\". Implementers are encouraged + to support extended filters. \n - Implementation-specific: + Filters that are defined and supported by specific + vendors. In the future, filters showing convergence + in behavior across multiple implementations will + be considered for inclusion in extended or core + conformance levels. Filter-specific configuration + for such filters is specified using the ExtensionRef + field. `Type` should be set to \"ExtensionRef\" + for custom filters. \n Implementers are encouraged + to define custom implementation types to extend + the core API with implementation-specific behavior. + \n If a reference to a custom filter type cannot + be resolved, the filter MUST NOT be skipped. Instead, + requests that would have been processed by that + filter MUST receive a HTTP error response. \n + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause + a crash. \n Unknown values here must result in + the implementation setting the Accepted Condition + for the Route to `status: False`, with a Reason + of `UnsupportedValue`." + enum: + - RequestHeaderModifier + - ResponseHeaderModifier + - RequestMirror + - RequestRedirect + - URLRewrite + - ExtensionRef + type: string + urlRewrite: + description: "URLRewrite defines a schema for a + filter that modifies a request during forwarding. + \n Support: Extended" + properties: + hostname: + description: "Hostname is the value to be used + to replace the Host header value during forwarding. + \n Support: Extended" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + path: + description: "Path defines a path rewrite. \n + Support: Extended" + properties: + replaceFullPath: + description: ReplaceFullPath specifies the + value with which to replace the full path + of a request during a rewrite or redirect. + maxLength: 1024 + type: string + replacePrefixMatch: + description: "ReplacePrefixMatch specifies + the value with which to replace the prefix + match of a request during a rewrite or + redirect. For example, a request to \"/foo/bar\" + with a prefix match of \"/foo\" would + be modified to \"/bar\". \n Note that + this matches the behavior of the PathPrefix + match type. This matches full path elements. + A path element refers to the list of labels + in the path split by the `/` separator. + When specified, a trailing `/` is ignored. + For example, the paths `/abc`, `/abc/`, + and `/abc/def` would all match the prefix + `/abc`, but the path `/abcd` would not." + maxLength: 1024 + type: string + type: + description: "Type defines the type of path + modifier. Additional types may be added + in a future release of the API. \n Note + that values may be added to this enum, + implementations must ensure that unknown + values will not cause a crash. \n Unknown + values here must result in the implementation + setting the Accepted Condition for the + Route to `status: False`, with a Reason + of `UnsupportedValue`." + enum: + - ReplaceFullPath + - ReplacePrefixMatch + type: string + required: + - type + type: object + type: object + required: + - type + type: object + maxItems: 16 + type: array + group: + default: "" + description: Group is the group of the referent. For example, + "gateway.networking.k8s.io". When unspecified or empty + string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Service + description: "Kind is the Kubernetes resource kind of + the referent. For example \"Service\". \n Defaults to + \"Service\" when not specified. \n ExternalName services + can refer to CNAME DNS records that may live outside + of the cluster and as such are difficult to reason about + in terms of conformance. They also may not be safe to + forward to (see CVE-2021-25740 for more information). + Implementations SHOULD NOT support ExternalName Services. + \n Support: Core (Services with a type other than ExternalName) + \n Support: Implementation-specific (Services with type + ExternalName)" + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace of the backend. + When unspecified, the local namespace is inferred. \n + Note that when a namespace different than the local + namespace is specified, a ReferenceGrant object is required + in the referent namespace to allow that namespace's + owner to accept the reference. See the ReferenceGrant + documentation for details. \n Support: Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: Port specifies the destination port number + to use for this resource. Port is required when the + referent is a Kubernetes Service. In this case, the + port number is the service port number, not the target + port. For other resources, destination port might be + derived from the referent resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + weight: + default: 1 + description: "Weight specifies the proportion of requests + forwarded to the referenced backend. This is computed + as weight/(sum of all weights in this BackendRefs list). + For non-zero values, there may be some epsilon from + the exact proportion defined here depending on the precision + an implementation supports. Weight is not a percentage + and the sum of weights does not need to equal 100. \n + If only one backend is specified and it has a weight + greater than 0, 100% of the traffic is forwarded to + that backend. If weight is set to 0, no traffic should + be forwarded for this entry. If unspecified, weight + defaults to 1. \n Support for this field varies based + on the context where used." + format: int32 + maximum: 1000000 + minimum: 0 + type: integer + required: + - name + type: object + maxItems: 16 + type: array + filters: + description: "Filters define the filters that are applied to + requests that match this rule. \n The effects of ordering + of multiple behaviors are currently unspecified. This can + change in the future based on feedback during the alpha stage. + \n Conformance-levels at this level are defined based on the + type of filter: \n - ALL core filters MUST be supported by + all implementations. - Implementers are encouraged to support + extended filters. - Implementation-specific custom filters + have no API guarantees across implementations. \n Specifying + a core filter multiple times has unspecified or implementation-specific + conformance. \n All filters are expected to be compatible + with each other except for the URLRewrite and RequestRedirect + filters, which may not be combined. If an implementation can + not support other combinations of filters, they must clearly + document that limitation. In all cases where incompatible + or unsupported filters are specified, implementations MUST + add a warning condition to status. \n Support: Core" + items: + description: HTTPRouteFilter defines processing steps that + must be completed during the request or response lifecycle. + HTTPRouteFilters are meant as an extension point to express + processing that may be done in Gateway implementations. + Some examples include request or response modification, + implementing authentication strategies, rate-limiting, and + traffic shaping. API guarantee/conformance is defined based + on the type of the filter. + properties: + extensionRef: + description: "ExtensionRef is an optional, implementation-specific + extension to the \"filter\" behavior. For example, + resource \"myroutefilter\" in group \"networking.example.net\"). + ExtensionRef MUST NOT be used for core and extended + filters. \n Support: Implementation-specific" + properties: + group: + description: Group is the group of the referent. For + example, "gateway.networking.k8s.io". When unspecified + or empty string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: Kind is kind of the referent. For example + "HTTPRoute" or "Service". + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + required: + - group + - kind + - name + type: object + requestHeaderModifier: + description: "RequestHeaderModifier defines a schema for + a filter that modifies request headers. \n Support: + Core" + properties: + add: + description: "Add adds the given header(s) (name, + value) to the request before the action. It appends + to any existing values associated with the header + name. \n Input: GET /foo HTTP/1.1 my-header: foo + \n Config: add: - name: \"my-header\" value: \"bar,baz\" + \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz" + items: + description: HTTPHeader represents an HTTP Header + name and value as defined by RFC 7230. + properties: + name: + description: "Name is the name of the HTTP Header + to be matched. Name matching MUST be case + insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an equivalent + name MUST be considered for a match. Subsequent + entries with an equivalent header name MUST + be ignored. Due to the case-insensitivity + of header names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + remove: + description: "Remove the given header(s) from the + HTTP request before the action. The value of Remove + is a list of HTTP header names. Note that the header + names are case-insensitive (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: + bar my-header3: baz \n Config: remove: [\"my-header1\", + \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: + bar" + items: + type: string + maxItems: 16 + type: array + set: + description: "Set overwrites the request with the + given header (name, value) before the action. \n + Input: GET /foo HTTP/1.1 my-header: foo \n Config: + set: - name: \"my-header\" value: \"bar\" \n Output: + GET /foo HTTP/1.1 my-header: bar" + items: + description: HTTPHeader represents an HTTP Header + name and value as defined by RFC 7230. + properties: + name: + description: "Name is the name of the HTTP Header + to be matched. Name matching MUST be case + insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an equivalent + name MUST be considered for a match. Subsequent + entries with an equivalent header name MUST + be ignored. Due to the case-insensitivity + of header names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + requestMirror: + description: "RequestMirror defines a schema for a filter + that mirrors requests. Requests are sent to the specified + destination, but responses from that destination are + ignored. \n Support: Extended" + properties: + backendRef: + description: "BackendRef references a resource where + mirrored requests are sent. \n If the referent cannot + be found, this BackendRef is invalid and must be + dropped from the Gateway. The controller must ensure + the \"ResolvedRefs\" condition on the Route status + is set to `status: False` and not configure this + backend in the underlying implementation. \n If + there is a cross-namespace reference to an *existing* + object that is not allowed by a ReferenceGrant, + the controller must ensure the \"ResolvedRefs\" + \ condition on the Route is set to `status: False`, + with the \"RefNotPermitted\" reason and not configure + this backend in the underlying implementation. \n + In either error case, the Message of the `ResolvedRefs` + Condition should be used to provide more detail + about the problem. \n Support: Extended for Kubernetes + Service \n Support: Implementation-specific for + any other resource" + properties: + group: + default: "" + description: Group is the group of the referent. + For example, "gateway.networking.k8s.io". When + unspecified or empty string, core API group + is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Service + description: "Kind is the Kubernetes resource + kind of the referent. For example \"Service\". + \n Defaults to \"Service\" when not specified. + \n ExternalName services can refer to CNAME + DNS records that may live outside of the cluster + and as such are difficult to reason about in + terms of conformance. They also may not be safe + to forward to (see CVE-2021-25740 for more information). + Implementations SHOULD NOT support ExternalName + Services. \n Support: Core (Services with a + type other than ExternalName) \n Support: Implementation-specific + (Services with type ExternalName)" + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace of the + backend. When unspecified, the local namespace + is inferred. \n Note that when a namespace different + than the local namespace is specified, a ReferenceGrant + object is required in the referent namespace + to allow that namespace's owner to accept the + reference. See the ReferenceGrant documentation + for details. \n Support: Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: Port specifies the destination port + number to use for this resource. Port is required + when the referent is a Kubernetes Service. In + this case, the port number is the service port + number, not the target port. For other resources, + destination port might be derived from the referent + resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - name + type: object + required: + - backendRef + type: object + requestRedirect: + description: "RequestRedirect defines a schema for a filter + that responds to the request with an HTTP redirection. + \n Support: Core" + properties: + hostname: + description: "Hostname is the hostname to be used + in the value of the `Location` header in the response. + When empty, the hostname in the `Host` header of + the request is used. \n Support: Core" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + path: + description: "Path defines parameters used to modify + the path of the incoming request. The modified path + is then used to construct the `Location` header. + When empty, the request path is used as-is. \n Support: + Extended" + properties: + replaceFullPath: + description: ReplaceFullPath specifies the value + with which to replace the full path of a request + during a rewrite or redirect. + maxLength: 1024 + type: string + replacePrefixMatch: + description: "ReplacePrefixMatch specifies the + value with which to replace the prefix match + of a request during a rewrite or redirect. For + example, a request to \"/foo/bar\" with a prefix + match of \"/foo\" would be modified to \"/bar\". + \n Note that this matches the behavior of the + PathPrefix match type. This matches full path + elements. A path element refers to the list + of labels in the path split by the `/` separator. + When specified, a trailing `/` is ignored. For + example, the paths `/abc`, `/abc/`, and `/abc/def` + would all match the prefix `/abc`, but the path + `/abcd` would not." + maxLength: 1024 + type: string + type: + description: "Type defines the type of path modifier. + Additional types may be added in a future release + of the API. \n Note that values may be added + to this enum, implementations must ensure that + unknown values will not cause a crash. \n Unknown + values here must result in the implementation + setting the Accepted Condition for the Route + to `status: False`, with a Reason of `UnsupportedValue`." + enum: + - ReplaceFullPath + - ReplacePrefixMatch + type: string + required: + - type + type: object + port: + description: "Port is the port to be used in the value + of the `Location` header in the response. \n If + no port is specified, the redirect port MUST be + derived using the following rules: \n * If redirect + scheme is not-empty, the redirect port MUST be the + well-known port associated with the redirect scheme. + Specifically \"http\" to port 80 and \"https\" to + port 443. If the redirect scheme does not have a + well-known port, the listener port of the Gateway + SHOULD be used. * If redirect scheme is empty, the + redirect port MUST be the Gateway Listener port. + \n Implementations SHOULD NOT add the port number + in the 'Location' header in the following cases: + \n * A Location header that will use HTTP (whether + that is determined via the Listener protocol or + the Scheme field) _and_ use port 80. * A Location + header that will use HTTPS (whether that is determined + via the Listener protocol or the Scheme field) _and_ + use port 443. \n Support: Extended" + format: int32 + maximum: 65535 + minimum: 1 + type: integer + scheme: + description: "Scheme is the scheme to be used in the + value of the `Location` header in the response. + When empty, the scheme of the request is used. \n + Scheme redirects can affect the port of the redirect, + for more information, refer to the documentation + for the port field of this filter. \n Note that + values may be added to this enum, implementations + must ensure that unknown values will not cause a + crash. \n Unknown values here must result in the + implementation setting the Accepted Condition for + the Route to `status: False`, with a Reason of `UnsupportedValue`. + \n Support: Extended" + enum: + - http + - https + type: string + statusCode: + default: 302 + description: "StatusCode is the HTTP status code to + be used in response. \n Note that values may be + added to this enum, implementations must ensure + that unknown values will not cause a crash. \n Unknown + values here must result in the implementation setting + the Accepted Condition for the Route to `status: + False`, with a Reason of `UnsupportedValue`. \n + Support: Core" + enum: + - 301 + - 302 + type: integer + type: object + responseHeaderModifier: + description: "ResponseHeaderModifier defines a schema + for a filter that modifies response headers. \n Support: + Extended" + properties: + add: + description: "Add adds the given header(s) (name, + value) to the request before the action. It appends + to any existing values associated with the header + name. \n Input: GET /foo HTTP/1.1 my-header: foo + \n Config: add: - name: \"my-header\" value: \"bar,baz\" + \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz" + items: + description: HTTPHeader represents an HTTP Header + name and value as defined by RFC 7230. + properties: + name: + description: "Name is the name of the HTTP Header + to be matched. Name matching MUST be case + insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an equivalent + name MUST be considered for a match. Subsequent + entries with an equivalent header name MUST + be ignored. Due to the case-insensitivity + of header names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + remove: + description: "Remove the given header(s) from the + HTTP request before the action. The value of Remove + is a list of HTTP header names. Note that the header + names are case-insensitive (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: + bar my-header3: baz \n Config: remove: [\"my-header1\", + \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: + bar" + items: + type: string + maxItems: 16 + type: array + set: + description: "Set overwrites the request with the + given header (name, value) before the action. \n + Input: GET /foo HTTP/1.1 my-header: foo \n Config: + set: - name: \"my-header\" value: \"bar\" \n Output: + GET /foo HTTP/1.1 my-header: bar" + items: + description: HTTPHeader represents an HTTP Header + name and value as defined by RFC 7230. + properties: + name: + description: "Name is the name of the HTTP Header + to be matched. Name matching MUST be case + insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an equivalent + name MUST be considered for a match. Subsequent + entries with an equivalent header name MUST + be ignored. Due to the case-insensitivity + of header names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: + description: "Type identifies the type of filter to apply. + As with other API fields, types are classified into + three conformance levels: \n - Core: Filter types and + their corresponding configuration defined by \"Support: + Core\" in this package, e.g. \"RequestHeaderModifier\". + All implementations must support core filters. \n - + Extended: Filter types and their corresponding configuration + defined by \"Support: Extended\" in this package, e.g. + \"RequestMirror\". Implementers are encouraged to support + extended filters. \n - Implementation-specific: Filters + that are defined and supported by specific vendors. + In the future, filters showing convergence in behavior + across multiple implementations will be considered for + inclusion in extended or core conformance levels. Filter-specific + configuration for such filters is specified using the + ExtensionRef field. `Type` should be set to \"ExtensionRef\" + for custom filters. \n Implementers are encouraged to + define custom implementation types to extend the core + API with implementation-specific behavior. \n If a reference + to a custom filter type cannot be resolved, the filter + MUST NOT be skipped. Instead, requests that would have + been processed by that filter MUST receive a HTTP error + response. \n Note that values may be added to this enum, + implementations must ensure that unknown values will + not cause a crash. \n Unknown values here must result + in the implementation setting the Accepted Condition + for the Route to `status: False`, with a Reason of `UnsupportedValue`." + enum: + - RequestHeaderModifier + - ResponseHeaderModifier + - RequestMirror + - RequestRedirect + - URLRewrite + - ExtensionRef + type: string + urlRewrite: + description: "URLRewrite defines a schema for a filter + that modifies a request during forwarding. \n Support: + Extended" + properties: + hostname: + description: "Hostname is the value to be used to + replace the Host header value during forwarding. + \n Support: Extended" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + path: + description: "Path defines a path rewrite. \n Support: + Extended" + properties: + replaceFullPath: + description: ReplaceFullPath specifies the value + with which to replace the full path of a request + during a rewrite or redirect. + maxLength: 1024 + type: string + replacePrefixMatch: + description: "ReplacePrefixMatch specifies the + value with which to replace the prefix match + of a request during a rewrite or redirect. For + example, a request to \"/foo/bar\" with a prefix + match of \"/foo\" would be modified to \"/bar\". + \n Note that this matches the behavior of the + PathPrefix match type. This matches full path + elements. A path element refers to the list + of labels in the path split by the `/` separator. + When specified, a trailing `/` is ignored. For + example, the paths `/abc`, `/abc/`, and `/abc/def` + would all match the prefix `/abc`, but the path + `/abcd` would not." + maxLength: 1024 + type: string + type: + description: "Type defines the type of path modifier. + Additional types may be added in a future release + of the API. \n Note that values may be added + to this enum, implementations must ensure that + unknown values will not cause a crash. \n Unknown + values here must result in the implementation + setting the Accepted Condition for the Route + to `status: False`, with a Reason of `UnsupportedValue`." + enum: + - ReplaceFullPath + - ReplacePrefixMatch + type: string + required: + - type + type: object + type: object + required: + - type + type: object + maxItems: 16 + type: array + matches: + default: + - path: + type: PathPrefix + value: / + description: "Matches define conditions used for matching the + rule against incoming HTTP requests. Each match is independent, + i.e. this rule will be matched if **any** one of the matches + is satisfied. \n For example, take the following matches configuration: + \n ``` matches: - path: value: \"/foo\" headers: - name: \"version\" + value: \"v2\" - path: value: \"/v2/foo\" ``` \n For a request + to match against this rule, a request must satisfy EITHER + of the two conditions: \n - path prefixed with `/foo` AND + contains the header `version: v2` - path prefix of `/v2/foo` + \n See the documentation for HTTPRouteMatch on how to specify + multiple match conditions that should be ANDed together. \n + If no matches are specified, the default is a prefix path + match on \"/\", which has the effect of matching every HTTP + request. \n Proxy or Load Balancer routing configuration generated + from HTTPRoutes MUST prioritize matches based on the following + criteria, continuing on ties. Across all rules specified on + applicable Routes, precedence must be given to the match having: + \n * \"Exact\" path match. * \"Prefix\" path match with largest + number of characters. * Method match. * Largest number of + header matches. * Largest number of query param matches. \n + Note: The precedence of RegularExpression path matches are + implementation-specific. \n If ties still exist across multiple + Routes, matching precedence MUST be determined in order of + the following criteria, continuing on ties: \n * The oldest + Route based on creation timestamp. * The Route appearing first + in alphabetical order by \"{namespace}/{name}\". \n If ties + still exist within an HTTPRoute, matching precedence MUST + be granted to the FIRST matching rule (in list order) with + a match meeting the above criteria. \n When no rules matching + a request have been successfully attached to the parent a + request is coming from, a HTTP 404 status code MUST be returned." + items: + description: "HTTPRouteMatch defines the predicate used to + match requests to a given action. Multiple match types are + ANDed together, i.e. the match will evaluate to true only + if all conditions are satisfied. \n For example, the match + below will match a HTTP request only if its path starts + with `/foo` AND it contains the `version: v1` header: \n + ``` match: \n path: value: \"/foo\" headers: - name: \"version\" + value \"v1\" \n ```" + properties: + headers: + description: Headers specifies HTTP request header matchers. + Multiple match values are ANDed together, meaning, a + request must match all the specified headers to select + the route. + items: + description: HTTPHeaderMatch describes how to select + a HTTP route by matching HTTP request headers. + properties: + name: + description: "Name is the name of the HTTP Header + to be matched. Name matching MUST be case insensitive. + (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent header + names, only the first entry with an equivalent + name MUST be considered for a match. Subsequent + entries with an equivalent header name MUST be + ignored. Due to the case-insensitivity of header + names, \"foo\" and \"Foo\" are considered equivalent. + \n When a header is repeated in an HTTP request, + it is implementation-specific behavior as to how + this is represented. Generally, proxies should + follow the guidance from the RFC: https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2.2 + regarding processing a repeated header, with special + handling for \"Set-Cookie\"." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + type: + default: Exact + description: "Type specifies how to match against + the value of the header. \n Support: Core (Exact) + \n Support: Implementation-specific (RegularExpression) + \n Since RegularExpression HeaderMatchType has + implementation-specific conformance, implementations + can support POSIX, PCRE or any other dialects + of regular expressions. Please read the implementation's + documentation to determine the supported dialect." + enum: + - Exact + - RegularExpression + type: string + value: + description: Value is the value of HTTP Header to + be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + method: + description: "Method specifies HTTP method matcher. When + specified, this route will be matched only if the request + has the specified method. \n Support: Extended" + enum: + - GET + - HEAD + - POST + - PUT + - DELETE + - CONNECT + - OPTIONS + - TRACE + - PATCH + type: string + path: + default: + type: PathPrefix + value: / + description: Path specifies a HTTP request path matcher. + If this field is not specified, a default prefix match + on the "/" path is provided. + properties: + type: + default: PathPrefix + description: "Type specifies how to match against + the path Value. \n Support: Core (Exact, PathPrefix) + \n Support: Implementation-specific (RegularExpression)" + enum: + - Exact + - PathPrefix + - RegularExpression + type: string + value: + default: / + description: Value of the HTTP path to match against. + maxLength: 1024 + type: string + type: object + queryParams: + description: "QueryParams specifies HTTP query parameter + matchers. Multiple match values are ANDed together, + meaning, a request must match all the specified query + parameters to select the route. \n Support: Extended" + items: + description: HTTPQueryParamMatch describes how to select + a HTTP route by matching HTTP query parameters. + properties: + name: + description: "Name is the name of the HTTP query + param to be matched. This must be an exact string + match. (See https://tools.ietf.org/html/rfc7230#section-2.7.3). + \n If multiple entries specify equivalent query + param names, only the first entry with an equivalent + name MUST be considered for a match. Subsequent + entries with an equivalent query param name MUST + be ignored. \n If a query param is repeated in + an HTTP request, the behavior is purposely left + undefined, since different data planes have different + capabilities. However, it is *recommended* that + implementations should match against the first + value of the param if the data plane supports + it, as this behavior is expected in other load + balancing contexts outside of the Gateway API. + \n Users SHOULD NOT route traffic based on repeated + query params to guard themselves against potential + differences in the implementations." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + type: + default: Exact + description: "Type specifies how to match against + the value of the query parameter. \n Support: + Extended (Exact) \n Support: Implementation-specific + (RegularExpression) \n Since RegularExpression + QueryParamMatchType has Implementation-specific + conformance, implementations can support POSIX, + PCRE or any other dialects of regular expressions. + Please read the implementation's documentation + to determine the supported dialect." + enum: + - Exact + - RegularExpression + type: string + value: + description: Value is the value of HTTP query param + to be matched. + maxLength: 1024 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + maxItems: 8 + type: array + type: object + maxItems: 16 + type: array + type: object + status: + description: Status defines the current state of HTTPRoute. + properties: + parents: + description: "Parents is a list of parent resources (usually Gateways) + that are associated with the route, and the status of the route + with respect to each parent. When this route attaches to a parent, + the controller that manages the parent must add an entry to this + list when the controller first sees the route and should update + the entry as appropriate when the route or gateway is modified. + \n Note that parent references that cannot be resolved by an implementation + of this API will not be added to this list. Implementations of this + API can only populate Route status for the Gateways/parent resources + they are responsible for. \n A maximum of 32 Gateways will be represented + in this list. An empty list means the route has not been attached + to any Gateway." + items: + description: RouteParentStatus describes the status of a route with + respect to an associated Parent. + properties: + conditions: + description: "Conditions describes the status of the route with + respect to the Gateway. Note that the route's availability + is also subject to the Gateway's own status conditions and + listener status. \n If the Route's ParentRef specifies an + existing Gateway that supports Routes of this kind AND that + Gateway's controller has sufficient access, then that Gateway's + controller MUST set the \"Accepted\" condition on the Route, + to indicate whether the route has been accepted or rejected + by the Gateway, and why. \n A Route MUST be considered \"Accepted\" + if at least one of the Route's rules is implemented by the + Gateway. \n There are a number of cases where the \"Accepted\" + condition may not be set due to lack of controller visibility, + that includes when: \n * The Route refers to a non-existent + parent. * The Route is of a type that the controller does + not support. * The Route is in a namespace the controller + does not have access to." + items: + description: "Condition contains details for one aspect of + the current state of this API Resource. --- This struct + is intended for direct use as an array at the field path + .status.conditions. For example, \n type FooStatus struct{ + // Represents the observations of a foo's current state. + // Known .status.conditions.type are: \"Available\", \"Progressing\", + and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge + // +listType=map // +listMapKey=type Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields + }" + 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 + maxItems: 8 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + controllerName: + description: "ControllerName is a domain/path string that indicates + the name of the controller that wrote this status. This corresponds + with the controllerName field on GatewayClass. \n Example: + \"example.net/gateway-controller\". \n The format of this + field is DOMAIN \"/\" PATH, where DOMAIN and PATH are valid + Kubernetes names (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). + \n Controllers MUST populate this field when writing status. + Controllers should ensure that entries to status populated + with their ControllerName are cleaned up when they are no + longer necessary." + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + parentRef: + description: ParentRef corresponds with a ParentRef in the spec + that this RouteParentStatus struct describes the status of. + properties: + group: + default: gateway.networking.k8s.io + description: "Group is the group of the referent. When unspecified, + \"gateway.networking.k8s.io\" is inferred. To set the + core API group (such as for a \"Service\" kind referent), + Group must be explicitly set to \"\" (empty string). \n + Support: Core" + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Gateway + description: "Kind is kind of the referent. \n Support: + Core (Gateway) \n Support: Implementation-specific (Other + Resources)" + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: "Name is the name of the referent. \n Support: + Core" + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace of the referent. + When unspecified, this refers to the local namespace of + the Route. \n Note that there are specific rules for ParentRefs + which cross namespace boundaries. Cross-namespace references + are only valid if they are explicitly allowed by something + in the namespace they are referring to. For example: Gateway + has the AllowedRoutes field, and ReferenceGrant provides + a generic way to enable any other kind of cross-namespace + reference. \n Support: Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: "Port is the network port this Route targets. + It can be interpreted differently based on the type of + parent resource. \n When the parent resource is a Gateway, + this targets all listeners listening on the specified + port that also support this kind of Route(and select this + Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to + a specific port as opposed to a listener(s) whose port(s) + may be changed. When both Port and SectionName are specified, + the name and port of the selected listener must match + both specified values. \n Implementations MAY choose to + support other parent resources. Implementations supporting + other types of parent resources MUST clearly document + how/if Port is interpreted. \n For the purpose of status, + an attachment is considered successful as long as the + parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them + by Route kind, namespace, or hostname. If 1 of 2 Gateway + listeners accept attachment from the referencing Route, + the Route MUST be considered successfully attached. If + no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + \n Support: Extended \n " + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: "SectionName is the name of a section within + the target resource. In the following resources, SectionName + is interpreted as the following: \n * Gateway: Listener + Name. When both Port (experimental) and SectionName are + specified, the name and port of the selected listener + must match both specified values. \n Implementations MAY + choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName + is interpreted. \n When unspecified (empty string), this + will reference the entire resource. For the purpose of + status, an attachment is considered successful if at least + one section in the parent resource accepts it. For example, + Gateway listeners can restrict which Routes can attach + to them by Route kind, namespace, or hostname. If 1 of + 2 Gateway listeners accept attachment from the referencing + Route, the Route MUST be considered successfully attached. + If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + \n Support: Core" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - name + type: object + required: + - controllerName + - parentRef + type: object + maxItems: 32 + type: array + required: + - parents + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null +{{- end }} + diff --git a/charts/linkerd/linkerd-crds/2024.8.3/templates/policy/authorization-policy.yaml b/charts/linkerd/linkerd-crds/2024.8.3/templates/policy/authorization-policy.yaml new file mode 100644 index 0000000000..7d86520e2e --- /dev/null +++ b/charts/linkerd/linkerd-crds/2024.8.3/templates/policy/authorization-policy.yaml @@ -0,0 +1,99 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: authorizationpolicies.policy.linkerd.io + annotations: + {{ include "partials.annotations.created-by" . }} + labels: + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + linkerd.io/control-plane-ns: {{.Release.Namespace}} +spec: + group: policy.linkerd.io + scope: Namespaced + names: + kind: AuthorizationPolicy + plural: authorizationpolicies + singular: authorizationpolicy + shortNames: [authzpolicy] + versions: + - name: v1alpha1 + served: true + storage: true + schema: + openAPIV3Schema: + type: object + required: [spec] + properties: + spec: + description: >- + Authorizes clients to communicate with Linkerd-proxied server + resources. + type: object + required: [targetRef, requiredAuthenticationRefs] + properties: + targetRef: + description: >- + TargetRef references a resource to which the authorization + policy applies. + type: object + required: [kind, name] + # Modified from the gateway API. + # Copyright 2020 The Kubernetes Authors + properties: + group: + description: >- + Group is the group of the referent. When empty, the + Kubernetes core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: >- + Kind is the kind of the referent. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + requiredAuthenticationRefs: + description: >- + RequiredAuthenticationRefs enumerates a set of required + authentications. ALL authentications must be satisfied for + the authorization to apply. If any of the referred objects + cannot be found, the authorization will be ignored. + type: array + items: + type: object + required: [kind, name] + properties: + group: + description: >- + Group is the group of the referent. When empty, the + Kubernetes core API group is inferred." + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: >- + Kind is the kind of the referent. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: >- + Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: >- + Name is the name of the referent. When unspecified, + this authentication refers to the local namespace. + maxLength: 253 + type: string diff --git a/charts/linkerd/linkerd-crds/2024.8.3/templates/policy/httproute.yaml b/charts/linkerd/linkerd-crds/2024.8.3/templates/policy/httproute.yaml new file mode 100644 index 0000000000..6d2e8b07ef --- /dev/null +++ b/charts/linkerd/linkerd-crds/2024.8.3/templates/policy/httproute.yaml @@ -0,0 +1,5328 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: httproutes.policy.linkerd.io + annotations: + {{ include "partials.annotations.created-by" . }} + labels: + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + linkerd.io/control-plane-ns: {{.Release.Namespace}} +spec: + group: policy.linkerd.io + names: + kind: HTTPRoute + listKind: HTTPRouteList + plural: httproutes + singular: httproute + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.hostnames + name: Hostnames + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: HTTPRoute provides a way to route HTTP requests. This includes + the capability to match requests by hostname, path, header, or query param. + Filters can be used to specify additional processing steps. Backends specify + where matching requests should be routed. + 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 HTTPRoute. + properties: + hostnames: + description: "Hostnames defines a set of hostname that should match + against the HTTP Host header to select a HTTPRoute to process the + request. This matches the RFC 1123 definition of a hostname with + 2 notable exceptions: \n 1. IPs are not allowed. 2. A hostname may + be prefixed with a wildcard label (`*.`). The wildcard label + must appear by itself as the first label. \n If a hostname is specified + by both the Listener and HTTPRoute, there must be at least one intersecting + hostname for the HTTPRoute to be attached to the Listener. For example: + \n * A Listener with `test.example.com` as the hostname matches + HTTPRoutes that have either not specified any hostnames, or have + specified at least one of `test.example.com` or `*.example.com`. + * A Listener with `*.example.com` as the hostname matches HTTPRoutes + \ that have either not specified any hostnames or have specified + at least one hostname that matches the Listener hostname. For + example, `*.example.com`, `test.example.com`, and `foo.test.example.com` + would all match. On the other hand, `example.com` and `test.example.net` + would not match. \n Hostnames that are prefixed with a wildcard + label (`*.`) are interpreted as a suffix match. That means that + a match for `*.example.com` would match both `test.example.com`, + and `foo.test.example.com`, but not `example.com`. \n If both the + Listener and HTTPRoute have specified hostnames, any HTTPRoute hostnames + that do not match the Listener hostname MUST be ignored. For example, + if a Listener specified `*.example.com`, and the HTTPRoute specified + `test.example.com` and `test.example.net`, `test.example.net` must + not be considered for a match. \n If both the Listener and HTTPRoute + have specified hostnames, and none match with the criteria above, + then the HTTPRoute is not accepted. The implementation must raise + an 'Accepted' Condition with a status of `False` in the corresponding + RouteParentStatus. \n Support: Core" + items: + description: "Hostname is the fully qualified domain name of a network + host. This matches the RFC 1123 definition of a hostname with + 2 notable exceptions: \n 1. IPs are not allowed. 2. A hostname + may be prefixed with a wildcard label (`*.`). The wildcard label + must appear by itself as the first label. \n Hostname can be \"precise\" + which is a domain name without the terminating dot of a network + host (e.g. \"foo.example.com\") or \"wildcard\", which is a domain + name prefixed with a single wildcard label (e.g. `*.example.com`). + \n Note that as per RFC1035 and RFC1123, a *label* must consist + of lower case alphanumeric characters or '-', and must start and + end with an alphanumeric character. No other punctuation is allowed." + maxLength: 253 + minLength: 1 + pattern: ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + maxItems: 16 + type: array + parentRefs: + description: "ParentRefs references the resources (usually Gateways) + that a Route wants to be attached to. Note that the referenced parent + resource needs to allow this for the attachment to be complete. + For Gateways, that means the Gateway needs to allow attachment from + Routes of this kind and namespace. \n The only kind of parent resource + with \"Core\" support is Gateway. This API may be extended in the + future to support additional kinds of parent resources such as one + of the route kinds. \n It is invalid to reference an identical parent + more than once. It is valid to reference multiple distinct sections + within the same parent resource, such as 2 Listeners within a Gateway. + \n It is possible to separately reference multiple distinct objects + that may be collapsed by an implementation. For example, some implementations + may choose to merge compatible Gateway Listeners together. If that + is the case, the list of routes attached to those resources should + also be merged." + items: + description: "ParentReference identifies an API object (usually + a Gateway) that can be considered a parent of this resource (usually + a route). The only kind of parent resource with \"Core\" support + is Gateway. This API may be extended in the future to support + additional kinds of parent resources, such as HTTPRoute. \n The + API object must be valid in the cluster; the Group and Kind must + be registered in the cluster for this reference to be valid." + properties: + group: + default: policy.linkerd.io + description: "Group is the group of the referent. \n Support: + Core" + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Gateway + description: "Kind is kind of the referent. \n Support: Core + (Gateway) Support: Custom (Other Resources)" + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: "Name is the name of the referent. \n Support: + Core" + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace of the referent. When + unspecified (or empty string), this refers to the local namespace + of the Route. \n Support: Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: "port" + type: integer + sectionName: + description: "SectionName is the name of a section within the + target resource. In the following resources, SectionName is + interpreted as the following: \n * Gateway: Listener Name. + When both Port (experimental) and SectionName are specified, + the name and port of the selected listener must match both + specified values. \n Implementations MAY choose to support + attaching Routes to other resources. If that is the case, + they MUST clearly document how SectionName is interpreted. + \n When unspecified (empty string), this will reference the + entire resource. For the purpose of status, an attachment + is considered successful if at least one section in the parent + resource accepts it. For example, Gateway listeners can restrict + which Routes can attach to them by Route kind, namespace, + or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this + Route, the Route MUST be considered detached from the Gateway. + \n Support: Core" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - name + type: object + maxItems: 32 + type: array + rules: + default: + - matches: + - path: + type: PathPrefix + value: / + description: Rules are a list of HTTP matchers, filters and actions. + items: + description: HTTPRouteRule defines semantics for matching an HTTP + request based on conditions (matches) and processing it (filters). + properties: + backendRefs: + type: array + items: + type: object + properties: + name: + type: string + port: + type: integer + namespace: + type: string + default: "default" + filters: + description: "Filters defined at this level should be + executed if and only if the request is being forwarded + to the backend defined here. \n Support: Implementation-specific + (For broader support of filters, use the Filters field + in HTTPRouteRule.)" + items: + description: HTTPRouteFilter defines processing steps + that must be completed during the request or response + lifecycle. HTTPRouteFilters are meant as an extension + point to express processing that may be done in Gateway + implementations. Some examples include request or + response modification, implementing authentication + strategies, rate-limiting, and traffic shaping. API + guarantee/conformance is defined based on the type + of the filter. + properties: + requestHeaderModifier: + description: "RequestHeaderModifier defines a schema + for a filter that modifies request headers. \n + Support: Core" + properties: + add: + description: "Add adds the given header(s) (name, + value) to the request before the action. It + appends to any existing values associated + with the header name. \n Input: GET /foo HTTP/1.1 + my-header: foo \n Config: add: - name: \"my-header\" + value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 + my-header: foo,bar,baz" + items: + description: HTTPHeader represents an HTTP + Header name and value as defined by RFC + 7230. + properties: + name: + description: "Name is the name of the + HTTP Header to be matched. Name matching + MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an + equivalent name MUST be considered for + a match. Subsequent entries with an + equivalent header name MUST be ignored. + Due to the case-insensitivity of header + names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + remove: + description: "Remove the given header(s) from + the HTTP request before the action. The value + of Remove is a list of HTTP header names. + Note that the header names are case-insensitive + (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + \n Input: GET /foo HTTP/1.1 my-header1: foo + my-header2: bar my-header3: baz \n Config: + remove: [\"my-header1\", \"my-header3\"] \n + Output: GET /foo HTTP/1.1 my-header2: bar" + items: + type: string + maxItems: 16 + type: array + set: + description: "Set overwrites the request with + the given header (name, value) before the + action. \n Input: GET /foo HTTP/1.1 my-header: + foo \n Config: set: - name: \"my-header\" + value: \"bar\" \n Output: GET /foo HTTP/1.1 + my-header: bar" + items: + description: HTTPHeader represents an HTTP + Header name and value as defined by RFC + 7230. + properties: + name: + description: "Name is the name of the + HTTP Header to be matched. Name matching + MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an + equivalent name MUST be considered for + a match. Subsequent entries with an + equivalent header name MUST be ignored. + Due to the case-insensitivity of header + names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + requestRedirect: + description: "RequestRedirect defines a schema for + a filter that responds to the request with an + HTTP redirection. \n Support: Core" + properties: + hostname: + description: "Hostname is the hostname to be + used in the value of the `Location` header + in the response. When empty, the hostname + in the `Host` header of the request is used. + \n Support: Core" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + path: + description: "Path defines parameters used to + modify the path of the incoming request. The + modified path is then used to construct the + `Location` header. When empty, the request + path is used as-is. \n Support: Extended" + properties: + replaceFullPath: + description: ReplaceFullPath specifies the + value with which to replace the full path + of a request during a rewrite or redirect. + maxLength: 1024 + type: string + replacePrefixMatch: + description: "ReplacePrefixMatch specifies + the value with which to replace the prefix + match of a request during a rewrite or + redirect. For example, a request to \"/foo/bar\" + with a prefix match of \"/foo\" and a + ReplacePrefixMatch of \"/xyz\" would be + modified to \"/xyz/bar\". \n Note that + this matches the behavior of the PathPrefix + match type. This matches full path elements. + A path element refers to the list of labels + in the path split by the `/` separator. + When specified, a trailing `/` is ignored. + For example, the paths `/abc`, `/abc/`, + and `/abc/def` would all match the prefix + `/abc`, but the path `/abcd` would not. + \n Request Path | Prefix Match | Replace + Prefix | Modified Path -------------|--------------|----------------|---------- + /foo/bar | /foo | /xyz | + /xyz/bar /foo/bar | /foo | + /xyz/ | /xyz/bar /foo/bar | + /foo/ | /xyz | /xyz/bar + /foo/bar | /foo/ | /xyz/ | + /xyz/bar /foo | /foo | + /xyz | /xyz /foo/ | /foo + \ | /xyz | /xyz/ /foo/bar + \ | /foo | | + /bar /foo/ | /foo | | / /foo | /foo | + | / /foo/ | /foo + \ | / | / /foo | + /foo | / | /" + maxLength: 1024 + type: string + type: + description: "Type defines the type of path + modifier. Additional types may be added + in a future release of the API. \n Note + that values may be added to this enum, + implementations must ensure that unknown + values will not cause a crash. \n Unknown + values here must result in the implementation + setting the Accepted Condition for the + Route to `status: False`, with a Reason + of `UnsupportedValue`." + enum: + - ReplaceFullPath + - ReplacePrefixMatch + type: string + required: + - type + type: object + port: + description: "Port is the port to be used in + the value of the `Location` header in the + response. \n If no port is specified, the + redirect port MUST be derived using the following + rules: \n * If redirect scheme is not-empty, + the redirect port MUST be the well-known port + associated with the redirect scheme. Specifically + \"http\" to port 80 and \"https\" to port + 443. If the redirect scheme does not have + a well-known port, the listener port of the + Gateway SHOULD be used. * If redirect scheme + is empty, the redirect port MUST be the Gateway + Listener port. \n Implementations SHOULD NOT + add the port number in the 'Location' header + in the following cases: \n * A Location header + that will use HTTP (whether that is determined + via the Listener protocol or the Scheme field) + _and_ use port 80. * A Location header that + will use HTTPS (whether that is determined + via the Listener protocol or the Scheme field) + _and_ use port 443. \n Support: Extended" + format: int32 + maximum: 65535 + minimum: 1 + type: integer + scheme: + description: "Scheme is the scheme to be used + in the value of the `Location` header in the + response. When empty, the scheme of the request + is used. \n Scheme redirects can affect the + port of the redirect, for more information, + refer to the documentation for the port field + of this filter. \n Note that values may be + added to this enum, implementations must ensure + that unknown values will not cause a crash. + \n Unknown values here must result in the + implementation setting the Accepted Condition + for the Route to `status: False`, with a Reason + of `UnsupportedValue`. \n Support: Extended" + enum: + - http + - https + type: string + statusCode: + default: 302 + description: "StatusCode is the HTTP status + code to be used in response. \n Note that + values may be added to this enum, implementations + must ensure that unknown values will not cause + a crash. \n Unknown values here must result + in the implementation setting the Accepted + Condition for the Route to `status: False`, + with a Reason of `UnsupportedValue`. \n Support: + Core" + enum: + - 301 + - 302 + type: integer + type: object + responseHeaderModifier: + description: "ResponseHeaderModifier defines a schema + for a filter that modifies response headers. \n + Support: Extended" + properties: + add: + description: "Add adds the given header(s) (name, + value) to the request before the action. It + appends to any existing values associated + with the header name. \n Input: GET /foo HTTP/1.1 + my-header: foo \n Config: add: - name: \"my-header\" + value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 + my-header: foo,bar,baz" + items: + description: HTTPHeader represents an HTTP + Header name and value as defined by RFC + 7230. + properties: + name: + description: "Name is the name of the + HTTP Header to be matched. Name matching + MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an + equivalent name MUST be considered for + a match. Subsequent entries with an + equivalent header name MUST be ignored. + Due to the case-insensitivity of header + names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + remove: + description: "Remove the given header(s) from + the HTTP request before the action. The value + of Remove is a list of HTTP header names. + Note that the header names are case-insensitive + (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + \n Input: GET /foo HTTP/1.1 my-header1: foo + my-header2: bar my-header3: baz \n Config: + remove: [\"my-header1\", \"my-header3\"] \n + Output: GET /foo HTTP/1.1 my-header2: bar" + items: + type: string + maxItems: 16 + type: array + set: + description: "Set overwrites the request with + the given header (name, value) before the + action. \n Input: GET /foo HTTP/1.1 my-header: + foo \n Config: set: - name: \"my-header\" + value: \"bar\" \n Output: GET /foo HTTP/1.1 + my-header: bar" + items: + description: HTTPHeader represents an HTTP + Header name and value as defined by RFC + 7230. + properties: + name: + description: "Name is the name of the + HTTP Header to be matched. Name matching + MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an + equivalent name MUST be considered for + a match. Subsequent entries with an + equivalent header name MUST be ignored. + Due to the case-insensitivity of header + names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: + description: "Type identifies the type of filter + to apply. As with other API fields, types are + classified into three conformance levels: \n - + Core: Filter types and their corresponding configuration + defined by \"Support: Core\" in this package, + e.g. \"RequestHeaderModifier\". All implementations + must support core filters. \n - Extended: Filter + types and their corresponding configuration defined + by \"Support: Extended\" in this package, e.g. + \"RequestMirror\". Implementers are encouraged + to support extended filters. \n - Implementation-specific: + Filters that are defined and supported by specific + vendors. In the future, filters showing convergence + in behavior across multiple implementations will + be considered for inclusion in extended or core + conformance levels. Filter-specific configuration + for such filters is specified using the ExtensionRef + field. `Type` should be set to \"ExtensionRef\" + for custom filters. \n Implementers are encouraged + to define custom implementation types to extend + the core API with implementation-specific behavior. + \n If a reference to a custom filter type cannot + be resolved, the filter MUST NOT be skipped. Instead, + requests that would have been processed by that + filter MUST receive a HTTP error response. \n + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause + a crash. \n Unknown values here must result in + the implementation setting the Accepted Condition + for the Route to `status: False`, with a Reason + of `UnsupportedValue`." + enum: + - RequestHeaderModifier + - ResponseHeaderModifier + - RequestRedirect + type: string + required: + - type + type: object + maxItems: 16 + type: array + filters: + description: "Filters define the filters that are applied to + requests that match this rule. \n The effects of ordering + of multiple behaviors are currently unspecified. This can + change in the future based on feedback during the alpha stage. + \n Conformance-levels at this level are defined based on the + type of filter: \n - ALL core filters MUST be supported by + all implementations. - Implementers are encouraged to support + extended filters. - Implementation-specific custom filters + have no API guarantees across implementations. \n Specifying + a core filter multiple times has unspecified or custom conformance. + \n All filters are expected to be compatible with each other + except for the URLRewrite and RequestRedirect filters, which + may not be combined. If an implementation can not support + other combinations of filters, they must clearly document + that limitation. In all cases where incompatible or unsupported + filters are specified, implementations MUST add a warning + condition to status. \n Support: Core" + items: + description: HTTPRouteFilter defines processing steps that + must be completed during the request or response lifecycle. + HTTPRouteFilters are meant as an extension point to express + processing that may be done in Gateway implementations. + Some examples include request or response modification, + implementing authentication strategies, rate-limiting, and + traffic shaping. API guarantee/conformance is defined based + on the type of the filter. + properties: + requestHeaderModifier: + description: "RequestHeaderModifier defines a schema for + a filter that modifies request headers. \n Support: + Core" + properties: + add: + description: "Add adds the given header(s) (name, + value) to the request before the action. It appends + to any existing values associated with the header + name. \n Input: GET /foo HTTP/1.1 my-header: + foo \n Config: add: - name: \"my-header\" value: + \"bar\" \n Output: GET /foo HTTP/1.1 my-header: + foo my-header: bar" + items: + description: HTTPHeader represents an HTTP Header + name and value as defined by RFC 7230. + properties: + name: + description: "Name is the name of the HTTP Header + to be matched. Name matching MUST be case + insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an equivalent + name MUST be considered for a match. Subsequent + entries with an equivalent header name MUST + be ignored. Due to the case-insensitivity + of header names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + remove: + description: "Remove the given header(s) from the + HTTP request before the action. The value of Remove + is a list of HTTP header names. Note that the header + names are case-insensitive (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + \n Input: GET /foo HTTP/1.1 my-header1: foo + \ my-header2: bar my-header3: baz \n Config: + \ remove: [\"my-header1\", \"my-header3\"] \n Output: + \ GET /foo HTTP/1.1 my-header2: bar" + items: + type: string + maxItems: 16 + type: array + set: + description: "Set overwrites the request with the + given header (name, value) before the action. \n + Input: GET /foo HTTP/1.1 my-header: foo \n Config: + \ set: - name: \"my-header\" value: \"bar\" + \n Output: GET /foo HTTP/1.1 my-header: bar" + items: + description: HTTPHeader represents an HTTP Header + name and value as defined by RFC 7230. + properties: + name: + description: "Name is the name of the HTTP Header + to be matched. Name matching MUST be case + insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an equivalent + name MUST be considered for a match. Subsequent + entries with an equivalent header name MUST + be ignored. Due to the case-insensitivity + of header names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + requestRedirect: + description: "RequestRedirect defines a schema for a filter + that responds to the request with an HTTP redirection. + \n Support: Core" + properties: + hostname: + description: "Hostname is the hostname to be used + in the value of the `Location` header in the response. + When empty, the hostname of the request is used. + \n Support: Core" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + path: + description: "Path defines parameters used to + modify the path of the incoming request. The + modified path is then used to construct the + `Location` header. When empty, the request + path is used as-is. \n Support: Extended" + properties: + replaceFullPath: + description: ReplaceFullPath specifies the + value with which to replace the full path + of a request during a rewrite or redirect. + maxLength: 1024 + type: string + replacePrefixMatch: + description: "ReplacePrefixMatch specifies + the value with which to replace the prefix + match of a request during a rewrite or + redirect. For example, a request to \"/foo/bar\" + with a prefix match of \"/foo\" and a + ReplacePrefixMatch of \"/xyz\" would be + modified to \"/xyz/bar\". \n Note that + this matches the behavior of the PathPrefix + match type. This matches full path elements. + A path element refers to the list of labels + in the path split by the `/` separator. + When specified, a trailing `/` is ignored. + For example, the paths `/abc`, `/abc/`, + and `/abc/def` would all match the prefix + `/abc`, but the path `/abcd` would not. + \n Request Path | Prefix Match | Replace + Prefix | Modified Path -------------|--------------|----------------|---------- + /foo/bar | /foo | /xyz | + /xyz/bar /foo/bar | /foo | + /xyz/ | /xyz/bar /foo/bar | + /foo/ | /xyz | /xyz/bar + /foo/bar | /foo/ | /xyz/ | + /xyz/bar /foo | /foo | + /xyz | /xyz /foo/ | /foo + \ | /xyz | /xyz/ /foo/bar + \ | /foo | | + /bar /foo/ | /foo | | / /foo | /foo | + | / /foo/ | /foo + \ | / | / /foo | + /foo | / | /" + maxLength: 1024 + type: string + type: + description: "Type defines the type of path + modifier. Additional types may be added + in a future release of the API. \n Note + that values may be added to this enum, + implementations must ensure that unknown + values will not cause a crash. \n Unknown + values here must result in the implementation + setting the Accepted Condition for the + Route to `status: False`, with a Reason + of `UnsupportedValue`." + enum: + - ReplaceFullPath + - ReplacePrefixMatch + type: string + required: + - type + type: object + port: + description: "Port is the port to be used in the value + of the `Location` header in the response. When empty, + port (if specified) of the request is used. \n Support: + Extended" + format: int32 + maximum: 65535 + minimum: 1 + type: integer + scheme: + description: "Scheme is the scheme to be used in the + value of the `Location` header in the response. + When empty, the scheme of the request is used. \n + Support: Extended" + enum: + - http + - https + type: string + statusCode: + default: 302 + description: "StatusCode is the HTTP status code to + be used in response. \n Support: Core" + enum: + - 301 + - 302 + type: integer + type: object + type: + description: "Type identifies the type of filter to apply. + As with other API fields, types are classified into + three conformance levels: \n - Core: Filter types and + their corresponding configuration defined by \"Support: + Core\" in this package, e.g. \"RequestHeaderModifier\". + All implementations must support core filters. \n\n " + enum: + - RequestHeaderModifier + - RequestRedirect + type: string + required: + - type + type: object + maxItems: 16 + type: array + matches: + default: + - path: + type: PathPrefix + value: / + description: "Matches define conditions used for matching the + rule against incoming HTTP requests. Each match is independent, + i.e. this rule will be matched if **any** one of the matches + is satisfied. \n For example, take the following matches configuration: + \n ``` matches: - path: value: \"/foo\" headers: - + name: \"version\" value: \"v2\" - path: value: \"/v2/foo\" + ``` \n For a request to match against this rule, a request + must satisfy EITHER of the two conditions: \n - path prefixed + with `/foo` AND contains the header `version: v2` - path prefix + of `/v2/foo` \n See the documentation for HTTPRouteMatch on + how to specify multiple match conditions that should be ANDed + together. \n If no matches are specified, the default is a + prefix path match on \"/\", which has the effect of matching + every HTTP request. \n Proxy or Load Balancer routing configuration + generated from HTTPRoutes MUST prioritize rules based on the + following criteria, continuing on ties. Precedence must be + given to the the Rule with the largest number of: \n * Characters + in a matching non-wildcard hostname. * Characters in a matching + hostname. * Characters in a matching path. * Header matches. + * Query param matches. \n If ties still exist across multiple + Routes, matching precedence MUST be determined in order of + the following criteria, continuing on ties: \n * The oldest + Route based on creation timestamp. * The Route appearing first + in alphabetical order by \"{namespace}/{name}\". \n If ties + still exist within the Route that has been given precedence, + matching precedence MUST be granted to the first matching + rule meeting the above criteria. \n When no rules matching + a request have been successfully attached to the parent a + request is coming from, a HTTP 404 status code MUST be returned." + items: + description: "HTTPRouteMatch defines the predicate used to + match requests to a given action. Multiple match types are + ANDed together, i.e. the match will evaluate to true only + if all conditions are satisfied. \n For example, the match + below will match a HTTP request only if its path starts + with `/foo` AND it contains the `version: v1` header: \n + ``` match: path: value: \"/foo\" headers: - name: + \"version\" value \"v1\" ```" + properties: + headers: + description: Headers specifies HTTP request header matchers. + Multiple match values are ANDed together, meaning, a + request must match all the specified headers to select + the route. + items: + description: HTTPHeaderMatch describes how to select + a HTTP route by matching HTTP request headers. + properties: + name: + description: "Name is the name of the HTTP Header + to be matched. Name matching MUST be case insensitive. + (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent header + names, only the first entry with an equivalent + name MUST be considered for a match. Subsequent + entries with an equivalent header name MUST be + ignored. Due to the case-insensitivity of header + names, \"foo\" and \"Foo\" are considered equivalent. + \n When a header is repeated in an HTTP request, + it is implementation-specific behavior as to how + this is represented. Generally, proxies should + follow the guidance from the RFC: https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2.2 + regarding processing a repeated header, with special + handling for \"Set-Cookie\"." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + type: + default: Exact + description: "Type specifies how to match against + the value of the header. \n Support: Core (Exact) + \n Support: Custom (RegularExpression) \n Since + RegularExpression HeaderMatchType has custom conformance, + implementations can support POSIX, PCRE or any + other dialects of regular expressions. Please + read the implementation's documentation to determine + the supported dialect." + enum: + - Exact + - RegularExpression + type: string + value: + description: Value is the value of HTTP Header to + be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + method: + description: "Method specifies HTTP method matcher. When + specified, this route will be matched only if the request + has the specified method. \n Support: Extended" + enum: + - GET + - HEAD + - POST + - PUT + - DELETE + - CONNECT + - OPTIONS + - TRACE + - PATCH + type: string + path: + default: + type: PathPrefix + value: / + description: Path specifies a HTTP request path matcher. + If this field is not specified, a default prefix match + on the "/" path is provided. + properties: + type: + default: PathPrefix + description: "Type specifies how to match against + the path Value. \n Support: Core (Exact, PathPrefix) + \n Support: Custom (RegularExpression)" + enum: + - Exact + - PathPrefix + - RegularExpression + type: string + value: + default: / + description: Value of the HTTP path to match against. + maxLength: 1024 + type: string + type: object + queryParams: + description: QueryParams specifies HTTP query parameter + matchers. Multiple match values are ANDed together, + meaning, a request must match all the specified query + parameters to select the route. + items: + description: HTTPQueryParamMatch describes how to select + a HTTP route by matching HTTP query parameters. + properties: + name: + description: Name is the name of the HTTP query + param to be matched. This must be an exact string + match. (See https://tools.ietf.org/html/rfc7230#section-2.7.3). + maxLength: 256 + minLength: 1 + type: string + type: + default: Exact + description: "Type specifies how to match against + the value of the query parameter. \n Support: + Extended (Exact) \n Support: Custom (RegularExpression) + \n Since RegularExpression QueryParamMatchType + has custom conformance, implementations can support + POSIX, PCRE or any other dialects of regular expressions. + Please read the implementation's documentation + to determine the supported dialect." + enum: + - Exact + - RegularExpression + type: string + value: + description: Value is the value of HTTP query param + to be matched. + maxLength: 1024 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + maxItems: 8 + type: array + type: object + maxItems: 16 + type: array + type: object + status: + description: Status defines the current state of HTTPRoute. + properties: + parents: + description: "Parents is a list of parent resources (usually Gateways) + that are associated with the route, and the status of the route + with respect to each parent. When this route attaches to a parent, + the controller that manages the parent must add an entry to this + list when the controller first sees the route and should update + the entry as appropriate when the route or gateway is modified. + \n Note that parent references that cannot be resolved by an implementation + of this API will not be added to this list. Implementations of this + API can only populate Route status for the Gateways/parent resources + they are responsible for. \n A maximum of 32 Gateways will be represented + in this list. An empty list means the route has not been attached + to any Gateway." + items: + description: RouteParentStatus describes the status of a route with + respect to an associated Parent. + properties: + conditions: + description: "Conditions describes the status of the route with + respect to the Gateway. Note that the route's availability + is also subject to the Gateway's own status conditions and + listener status. \n If the Route's ParentRef specifies an + existing Gateway that supports Routes of this kind AND that + Gateway's controller has sufficient access, then that Gateway's + controller MUST set the \"Accepted\" condition on the Route, + to indicate whether the route has been accepted or rejected + by the Gateway, and why. \n A Route MUST be considered \"Accepted\" + if at least one of the Route's rules is implemented by the + Gateway. \n There are a number of cases where the \"Accepted\" + condition may not be set due to lack of controller visibility, + that includes when: \n * The Route refers to a non-existent + parent. * The Route is of a type that the controller does + not support. * The Route is in a namespace the the controller + does not have access to." + items: + description: "Condition contains details for one aspect of + the current state of this API Resource. --- This struct + is intended for direct use as an array at the field path + .status.conditions. For example, type FooStatus struct{ + \ // Represents the observations of a foo's current state. + \ // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type + \ // +patchStrategy=merge // +listType=map // + +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` + \n // other fields }" + 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 + maxItems: 8 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + controllerName: + description: "ControllerName is a domain/path string that indicates + the name of the controller that wrote this status. This corresponds + with the controllerName field on GatewayClass. \n Example: + \"example.net/gateway-controller\". \n The format of this + field is DOMAIN \"/\" PATH, where DOMAIN and PATH are valid + Kubernetes names (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). + \n Controllers MUST populate this field when writing status. + Controllers should ensure that entries to status populated + with their ControllerName are cleaned up when they are no + longer necessary." + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + parentRef: + description: ParentRef corresponds with a ParentRef in the spec + that this RouteParentStatus struct describes the status of. + properties: + group: + default: policy.linkerd.io + description: "Group is the group of the referent. \n Support: + Core" + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Gateway + description: "Kind is kind of the referent. \n Support: + Core (Gateway) Support: Custom (Other Resources)" + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: "Name is the name of the referent. \n Support: + Core" + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace of the referent. + When unspecified (or empty string), this refers to the + local namespace of the Route. \n Support: Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: "Port is the network port this Route targets. + It can be interpreted differently based on the type of + parent resource. \n When the parent resource is a Gateway, + this targets all listeners listening on the specified + port that also support this kind of Route(and select this + Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to + a specific port as opposed to a listener(s) whose port(s) + may be changed. When both Port and SectionName are specified, + the name and port of the selected listener must match + both specified values. \n Implementations MAY choose to + support other parent resources. Implementations supporting + other types of parent resources MUST clearly document + how/if Port is interpreted. \n For the purpose of status, + an attachment is considered successful as long as the + parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them + by Route kind, namespace, or hostname. If 1 of 2 Gateway + listeners accept attachment from the referencing Route, + the Route MUST be considered successfully attached. If + no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + \n Support: Extended \n " + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: "SectionName is the name of a section within + the target resource. In the following resources, SectionName + is interpreted as the following: \n * Gateway: Listener + Name. When both Port (experimental) and SectionName are + specified, the name and port of the selected listener + must match both specified values. \n Implementations MAY + choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName + is interpreted. \n When unspecified (empty string), this + will reference the entire resource. For the purpose of + status, an attachment is considered successful if at least + one section in the parent resource accepts it. For example, + Gateway listeners can restrict which Routes can attach + to them by Route kind, namespace, or hostname. If 1 of + 2 Gateway listeners accept attachment from the referencing + Route, the Route MUST be considered successfully attached. + If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + \n Support: Core" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - name + type: object + required: + - controllerName + - parentRef + type: object + maxItems: 32 + type: array + required: + - parents + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .spec.hostnames + name: Hostnames + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: HTTPRoute provides a way to route HTTP requests. This includes + the capability to match requests by hostname, path, header, or query param. + Filters can be used to specify additional processing steps. Backends specify + where matching requests should be routed. + 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 HTTPRoute. + properties: + hostnames: + description: "Hostnames defines a set of hostname that should match + against the HTTP Host header to select a HTTPRoute to process the + request. This matches the RFC 1123 definition of a hostname with + 2 notable exceptions: \n 1. IPs are not allowed. 2. A hostname may + be prefixed with a wildcard label (`*.`). The wildcard label + must appear by itself as the first label. \n If a hostname is specified + by both the Listener and HTTPRoute, there must be at least one intersecting + hostname for the HTTPRoute to be attached to the Listener. For example: + \n * A Listener with `test.example.com` as the hostname matches + HTTPRoutes that have either not specified any hostnames, or have + specified at least one of `test.example.com` or `*.example.com`. + * A Listener with `*.example.com` as the hostname matches HTTPRoutes + \ that have either not specified any hostnames or have specified + at least one hostname that matches the Listener hostname. For + example, `*.example.com`, `test.example.com`, and `foo.test.example.com` + would all match. On the other hand, `example.com` and `test.example.net` + would not match. \n Hostnames that are prefixed with a wildcard + label (`*.`) are interpreted as a suffix match. That means that + a match for `*.example.com` would match both `test.example.com`, + and `foo.test.example.com`, but not `example.com`. \n If both the + Listener and HTTPRoute have specified hostnames, any HTTPRoute hostnames + that do not match the Listener hostname MUST be ignored. For example, + if a Listener specified `*.example.com`, and the HTTPRoute specified + `test.example.com` and `test.example.net`, `test.example.net` must + not be considered for a match. \n If both the Listener and HTTPRoute + have specified hostnames, and none match with the criteria above, + then the HTTPRoute is not accepted. The implementation must raise + an 'Accepted' Condition with a status of `False` in the corresponding + RouteParentStatus. \n Support: Core" + items: + description: "Hostname is the fully qualified domain name of a network + host. This matches the RFC 1123 definition of a hostname with + 2 notable exceptions: \n 1. IPs are not allowed. 2. A hostname + may be prefixed with a wildcard label (`*.`). The wildcard label + must appear by itself as the first label. \n Hostname can be \"precise\" + which is a domain name without the terminating dot of a network + host (e.g. \"foo.example.com\") or \"wildcard\", which is a domain + name prefixed with a single wildcard label (e.g. `*.example.com`). + \n Note that as per RFC1035 and RFC1123, a *label* must consist + of lower case alphanumeric characters or '-', and must start and + end with an alphanumeric character. No other punctuation is allowed." + maxLength: 253 + minLength: 1 + pattern: ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + maxItems: 16 + type: array + parentRefs: + description: "ParentRefs references the resources (usually Gateways) + that a Route wants to be attached to. Note that the referenced parent + resource needs to allow this for the attachment to be complete. + For Gateways, that means the Gateway needs to allow attachment from + Routes of this kind and namespace. \n The only kind of parent resource + with \"Core\" support is Gateway. This API may be extended in the + future to support additional kinds of parent resources such as one + of the route kinds. \n It is invalid to reference an identical parent + more than once. It is valid to reference multiple distinct sections + within the same parent resource, such as 2 Listeners within a Gateway. + \n It is possible to separately reference multiple distinct objects + that may be collapsed by an implementation. For example, some implementations + may choose to merge compatible Gateway Listeners together. If that + is the case, the list of routes attached to those resources should + also be merged." + items: + description: "ParentReference identifies an API object (usually + a Gateway) that can be considered a parent of this resource (usually + a route). The only kind of parent resource with \"Core\" support + is Gateway. This API may be extended in the future to support + additional kinds of parent resources, such as HTTPRoute. \n The + API object must be valid in the cluster; the Group and Kind must + be registered in the cluster for this reference to be valid." + properties: + group: + default: policy.linkerd.io + description: "Group is the group of the referent. \n Support: + Core" + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Gateway + description: "Kind is kind of the referent. \n Support: Core + (Gateway) Support: Custom (Other Resources)" + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: "Name is the name of the referent. \n Support: + Core" + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace of the referent. When + unspecified (or empty string), this refers to the local namespace + of the Route. \n Support: Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: "port" + type: integer + sectionName: + description: "SectionName is the name of a section within the + target resource. In the following resources, SectionName is + interpreted as the following: \n * Gateway: Listener Name. + When both Port (experimental) and SectionName are specified, + the name and port of the selected listener must match both + specified values. \n Implementations MAY choose to support + attaching Routes to other resources. If that is the case, + they MUST clearly document how SectionName is interpreted. + \n When unspecified (empty string), this will reference the + entire resource. For the purpose of status, an attachment + is considered successful if at least one section in the parent + resource accepts it. For example, Gateway listeners can restrict + which Routes can attach to them by Route kind, namespace, + or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this + Route, the Route MUST be considered detached from the Gateway. + \n Support: Core" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - name + type: object + maxItems: 32 + type: array + rules: + default: + - matches: + - path: + type: PathPrefix + value: / + description: Rules are a list of HTTP matchers, filters and actions. + items: + description: HTTPRouteRule defines semantics for matching an HTTP + request based on conditions (matches) and processing it (filters). + properties: + backendRefs: + type: array + items: + type: object + properties: + name: + type: string + port: + type: integer + namespace: + type: string + default: "default" + filters: + description: "Filters defined at this level should be + executed if and only if the request is being forwarded + to the backend defined here. \n Support: Implementation-specific + (For broader support of filters, use the Filters field + in HTTPRouteRule.)" + items: + description: HTTPRouteFilter defines processing steps + that must be completed during the request or response + lifecycle. HTTPRouteFilters are meant as an extension + point to express processing that may be done in Gateway + implementations. Some examples include request or + response modification, implementing authentication + strategies, rate-limiting, and traffic shaping. API + guarantee/conformance is defined based on the type + of the filter. + properties: + requestHeaderModifier: + description: "RequestHeaderModifier defines a schema + for a filter that modifies request headers. \n + Support: Core" + properties: + add: + description: "Add adds the given header(s) (name, + value) to the request before the action. It + appends to any existing values associated + with the header name. \n Input: GET /foo HTTP/1.1 + my-header: foo \n Config: add: - name: \"my-header\" + value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 + my-header: foo,bar,baz" + items: + description: HTTPHeader represents an HTTP + Header name and value as defined by RFC + 7230. + properties: + name: + description: "Name is the name of the + HTTP Header to be matched. Name matching + MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an + equivalent name MUST be considered for + a match. Subsequent entries with an + equivalent header name MUST be ignored. + Due to the case-insensitivity of header + names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + remove: + description: "Remove the given header(s) from + the HTTP request before the action. The value + of Remove is a list of HTTP header names. + Note that the header names are case-insensitive + (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + \n Input: GET /foo HTTP/1.1 my-header1: foo + my-header2: bar my-header3: baz \n Config: + remove: [\"my-header1\", \"my-header3\"] \n + Output: GET /foo HTTP/1.1 my-header2: bar" + items: + type: string + maxItems: 16 + type: array + set: + description: "Set overwrites the request with + the given header (name, value) before the + action. \n Input: GET /foo HTTP/1.1 my-header: + foo \n Config: set: - name: \"my-header\" + value: \"bar\" \n Output: GET /foo HTTP/1.1 + my-header: bar" + items: + description: HTTPHeader represents an HTTP + Header name and value as defined by RFC + 7230. + properties: + name: + description: "Name is the name of the + HTTP Header to be matched. Name matching + MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an + equivalent name MUST be considered for + a match. Subsequent entries with an + equivalent header name MUST be ignored. + Due to the case-insensitivity of header + names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + requestRedirect: + description: "RequestRedirect defines a schema for + a filter that responds to the request with an + HTTP redirection. \n Support: Core" + properties: + hostname: + description: "Hostname is the hostname to be + used in the value of the `Location` header + in the response. When empty, the hostname + in the `Host` header of the request is used. + \n Support: Core" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + path: + description: "Path defines parameters used to + modify the path of the incoming request. The + modified path is then used to construct the + `Location` header. When empty, the request + path is used as-is. \n Support: Extended" + properties: + replaceFullPath: + description: ReplaceFullPath specifies the + value with which to replace the full path + of a request during a rewrite or redirect. + maxLength: 1024 + type: string + replacePrefixMatch: + description: "ReplacePrefixMatch specifies + the value with which to replace the prefix + match of a request during a rewrite or + redirect. For example, a request to \"/foo/bar\" + with a prefix match of \"/foo\" and a + ReplacePrefixMatch of \"/xyz\" would be + modified to \"/xyz/bar\". \n Note that + this matches the behavior of the PathPrefix + match type. This matches full path elements. + A path element refers to the list of labels + in the path split by the `/` separator. + When specified, a trailing `/` is ignored. + For example, the paths `/abc`, `/abc/`, + and `/abc/def` would all match the prefix + `/abc`, but the path `/abcd` would not. + \n Request Path | Prefix Match | Replace + Prefix | Modified Path -------------|--------------|----------------|---------- + /foo/bar | /foo | /xyz | + /xyz/bar /foo/bar | /foo | + /xyz/ | /xyz/bar /foo/bar | + /foo/ | /xyz | /xyz/bar + /foo/bar | /foo/ | /xyz/ | + /xyz/bar /foo | /foo | + /xyz | /xyz /foo/ | /foo + \ | /xyz | /xyz/ /foo/bar + \ | /foo | | + /bar /foo/ | /foo | | / /foo | /foo | + | / /foo/ | /foo + \ | / | / /foo | + /foo | / | /" + maxLength: 1024 + type: string + type: + description: "Type defines the type of path + modifier. Additional types may be added + in a future release of the API. \n Note + that values may be added to this enum, + implementations must ensure that unknown + values will not cause a crash. \n Unknown + values here must result in the implementation + setting the Accepted Condition for the + Route to `status: False`, with a Reason + of `UnsupportedValue`." + enum: + - ReplaceFullPath + - ReplacePrefixMatch + type: string + required: + - type + type: object + port: + description: "Port is the port to be used in + the value of the `Location` header in the + response. \n If no port is specified, the + redirect port MUST be derived using the following + rules: \n * If redirect scheme is not-empty, + the redirect port MUST be the well-known port + associated with the redirect scheme. Specifically + \"http\" to port 80 and \"https\" to port + 443. If the redirect scheme does not have + a well-known port, the listener port of the + Gateway SHOULD be used. * If redirect scheme + is empty, the redirect port MUST be the Gateway + Listener port. \n Implementations SHOULD NOT + add the port number in the 'Location' header + in the following cases: \n * A Location header + that will use HTTP (whether that is determined + via the Listener protocol or the Scheme field) + _and_ use port 80. * A Location header that + will use HTTPS (whether that is determined + via the Listener protocol or the Scheme field) + _and_ use port 443. \n Support: Extended" + format: int32 + maximum: 65535 + minimum: 1 + type: integer + scheme: + description: "Scheme is the scheme to be used + in the value of the `Location` header in the + response. When empty, the scheme of the request + is used. \n Scheme redirects can affect the + port of the redirect, for more information, + refer to the documentation for the port field + of this filter. \n Note that values may be + added to this enum, implementations must ensure + that unknown values will not cause a crash. + \n Unknown values here must result in the + implementation setting the Accepted Condition + for the Route to `status: False`, with a Reason + of `UnsupportedValue`. \n Support: Extended" + enum: + - http + - https + type: string + statusCode: + default: 302 + description: "StatusCode is the HTTP status + code to be used in response. \n Note that + values may be added to this enum, implementations + must ensure that unknown values will not cause + a crash. \n Unknown values here must result + in the implementation setting the Accepted + Condition for the Route to `status: False`, + with a Reason of `UnsupportedValue`. \n Support: + Core" + enum: + - 301 + - 302 + type: integer + type: object + responseHeaderModifier: + description: "ResponseHeaderModifier defines a schema + for a filter that modifies response headers. \n + Support: Extended" + properties: + add: + description: "Add adds the given header(s) (name, + value) to the request before the action. It + appends to any existing values associated + with the header name. \n Input: GET /foo HTTP/1.1 + my-header: foo \n Config: add: - name: \"my-header\" + value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 + my-header: foo,bar,baz" + items: + description: HTTPHeader represents an HTTP + Header name and value as defined by RFC + 7230. + properties: + name: + description: "Name is the name of the + HTTP Header to be matched. Name matching + MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an + equivalent name MUST be considered for + a match. Subsequent entries with an + equivalent header name MUST be ignored. + Due to the case-insensitivity of header + names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + remove: + description: "Remove the given header(s) from + the HTTP request before the action. The value + of Remove is a list of HTTP header names. + Note that the header names are case-insensitive + (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + \n Input: GET /foo HTTP/1.1 my-header1: foo + my-header2: bar my-header3: baz \n Config: + remove: [\"my-header1\", \"my-header3\"] \n + Output: GET /foo HTTP/1.1 my-header2: bar" + items: + type: string + maxItems: 16 + type: array + set: + description: "Set overwrites the request with + the given header (name, value) before the + action. \n Input: GET /foo HTTP/1.1 my-header: + foo \n Config: set: - name: \"my-header\" + value: \"bar\" \n Output: GET /foo HTTP/1.1 + my-header: bar" + items: + description: HTTPHeader represents an HTTP + Header name and value as defined by RFC + 7230. + properties: + name: + description: "Name is the name of the + HTTP Header to be matched. Name matching + MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an + equivalent name MUST be considered for + a match. Subsequent entries with an + equivalent header name MUST be ignored. + Due to the case-insensitivity of header + names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: + description: "Type identifies the type of filter + to apply. As with other API fields, types are + classified into three conformance levels: \n - + Core: Filter types and their corresponding configuration + defined by \"Support: Core\" in this package, + e.g. \"RequestHeaderModifier\". All implementations + must support core filters. \n - Extended: Filter + types and their corresponding configuration defined + by \"Support: Extended\" in this package, e.g. + \"RequestMirror\". Implementers are encouraged + to support extended filters. \n - Implementation-specific: + Filters that are defined and supported by specific + vendors. In the future, filters showing convergence + in behavior across multiple implementations will + be considered for inclusion in extended or core + conformance levels. Filter-specific configuration + for such filters is specified using the ExtensionRef + field. `Type` should be set to \"ExtensionRef\" + for custom filters. \n Implementers are encouraged + to define custom implementation types to extend + the core API with implementation-specific behavior. + \n If a reference to a custom filter type cannot + be resolved, the filter MUST NOT be skipped. Instead, + requests that would have been processed by that + filter MUST receive a HTTP error response. \n + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause + a crash. \n Unknown values here must result in + the implementation setting the Accepted Condition + for the Route to `status: False`, with a Reason + of `UnsupportedValue`." + enum: + - RequestHeaderModifier + - ResponseHeaderModifier + - RequestRedirect + type: string + required: + - type + type: object + maxItems: 16 + type: array + filters: + description: "Filters define the filters that are applied to + requests that match this rule. \n The effects of ordering + of multiple behaviors are currently unspecified. This can + change in the future based on feedback during the alpha stage. + \n Conformance-levels at this level are defined based on the + type of filter: \n - ALL core filters MUST be supported by + all implementations. - Implementers are encouraged to support + extended filters. - Implementation-specific custom filters + have no API guarantees across implementations. \n Specifying + a core filter multiple times has unspecified or custom conformance. + \n All filters are expected to be compatible with each other + except for the URLRewrite and RequestRedirect filters, which + may not be combined. If an implementation can not support + other combinations of filters, they must clearly document + that limitation. In all cases where incompatible or unsupported + filters are specified, implementations MUST add a warning + condition to status. \n Support: Core" + items: + description: HTTPRouteFilter defines processing steps that + must be completed during the request or response lifecycle. + HTTPRouteFilters are meant as an extension point to express + processing that may be done in Gateway implementations. + Some examples include request or response modification, + implementing authentication strategies, rate-limiting, and + traffic shaping. API guarantee/conformance is defined based + on the type of the filter. + properties: + requestHeaderModifier: + description: "RequestHeaderModifier defines a schema for + a filter that modifies request headers. \n Support: + Core" + properties: + add: + description: "Add adds the given header(s) (name, + value) to the request before the action. It appends + to any existing values associated with the header + name. \n Input: GET /foo HTTP/1.1 my-header: + foo \n Config: add: - name: \"my-header\" value: + \"bar\" \n Output: GET /foo HTTP/1.1 my-header: + foo my-header: bar" + items: + description: HTTPHeader represents an HTTP Header + name and value as defined by RFC 7230. + properties: + name: + description: "Name is the name of the HTTP Header + to be matched. Name matching MUST be case + insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an equivalent + name MUST be considered for a match. Subsequent + entries with an equivalent header name MUST + be ignored. Due to the case-insensitivity + of header names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + remove: + description: "Remove the given header(s) from the + HTTP request before the action. The value of Remove + is a list of HTTP header names. Note that the header + names are case-insensitive (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + \n Input: GET /foo HTTP/1.1 my-header1: foo + \ my-header2: bar my-header3: baz \n Config: + \ remove: [\"my-header1\", \"my-header3\"] \n Output: + \ GET /foo HTTP/1.1 my-header2: bar" + items: + type: string + maxItems: 16 + type: array + set: + description: "Set overwrites the request with the + given header (name, value) before the action. \n + Input: GET /foo HTTP/1.1 my-header: foo \n Config: + \ set: - name: \"my-header\" value: \"bar\" + \n Output: GET /foo HTTP/1.1 my-header: bar" + items: + description: HTTPHeader represents an HTTP Header + name and value as defined by RFC 7230. + properties: + name: + description: "Name is the name of the HTTP Header + to be matched. Name matching MUST be case + insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an equivalent + name MUST be considered for a match. Subsequent + entries with an equivalent header name MUST + be ignored. Due to the case-insensitivity + of header names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + requestRedirect: + description: "RequestRedirect defines a schema for a filter + that responds to the request with an HTTP redirection. + \n Support: Core" + properties: + hostname: + description: "Hostname is the hostname to be used + in the value of the `Location` header in the response. + When empty, the hostname of the request is used. + \n Support: Core" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + path: + description: "Path defines parameters used to + modify the path of the incoming request. The + modified path is then used to construct the + `Location` header. When empty, the request + path is used as-is. \n Support: Extended" + properties: + replaceFullPath: + description: ReplaceFullPath specifies the + value with which to replace the full path + of a request during a rewrite or redirect. + maxLength: 1024 + type: string + replacePrefixMatch: + description: "ReplacePrefixMatch specifies + the value with which to replace the prefix + match of a request during a rewrite or + redirect. For example, a request to \"/foo/bar\" + with a prefix match of \"/foo\" and a + ReplacePrefixMatch of \"/xyz\" would be + modified to \"/xyz/bar\". \n Note that + this matches the behavior of the PathPrefix + match type. This matches full path elements. + A path element refers to the list of labels + in the path split by the `/` separator. + When specified, a trailing `/` is ignored. + For example, the paths `/abc`, `/abc/`, + and `/abc/def` would all match the prefix + `/abc`, but the path `/abcd` would not. + \n Request Path | Prefix Match | Replace + Prefix | Modified Path -------------|--------------|----------------|---------- + /foo/bar | /foo | /xyz | + /xyz/bar /foo/bar | /foo | + /xyz/ | /xyz/bar /foo/bar | + /foo/ | /xyz | /xyz/bar + /foo/bar | /foo/ | /xyz/ | + /xyz/bar /foo | /foo | + /xyz | /xyz /foo/ | /foo + \ | /xyz | /xyz/ /foo/bar + \ | /foo | | + /bar /foo/ | /foo | | / /foo | /foo | + | / /foo/ | /foo + \ | / | / /foo | + /foo | / | /" + maxLength: 1024 + type: string + type: + description: "Type defines the type of path + modifier. Additional types may be added + in a future release of the API. \n Note + that values may be added to this enum, + implementations must ensure that unknown + values will not cause a crash. \n Unknown + values here must result in the implementation + setting the Accepted Condition for the + Route to `status: False`, with a Reason + of `UnsupportedValue`." + enum: + - ReplaceFullPath + - ReplacePrefixMatch + type: string + required: + - type + type: object + port: + description: "Port is the port to be used in the value + of the `Location` header in the response. When empty, + port (if specified) of the request is used. \n Support: + Extended" + format: int32 + maximum: 65535 + minimum: 1 + type: integer + scheme: + description: "Scheme is the scheme to be used in the + value of the `Location` header in the response. + When empty, the scheme of the request is used. \n + Support: Extended" + enum: + - http + - https + type: string + statusCode: + default: 302 + description: "StatusCode is the HTTP status code to + be used in response. \n Support: Core" + enum: + - 301 + - 302 + type: integer + type: object + type: + description: "Type identifies the type of filter to apply. + As with other API fields, types are classified into + three conformance levels: \n - Core: Filter types and + their corresponding configuration defined by \"Support: + Core\" in this package, e.g. \"RequestHeaderModifier\"." + enum: + - RequestHeaderModifier + - RequestRedirect + type: string + required: + - type + type: object + maxItems: 16 + type: array + matches: + default: + - path: + type: PathPrefix + value: / + description: "Matches define conditions used for matching the + rule against incoming HTTP requests. Each match is independent, + i.e. this rule will be matched if **any** one of the matches + is satisfied. \n For example, take the following matches configuration: + \n ``` matches: - path: value: \"/foo\" headers: - + name: \"version\" value: \"v2\" - path: value: \"/v2/foo\" + ``` \n For a request to match against this rule, a request + must satisfy EITHER of the two conditions: \n - path prefixed + with `/foo` AND contains the header `version: v2` - path prefix + of `/v2/foo` \n See the documentation for HTTPRouteMatch on + how to specify multiple match conditions that should be ANDed + together. \n If no matches are specified, the default is a + prefix path match on \"/\", which has the effect of matching + every HTTP request. \n Proxy or Load Balancer routing configuration + generated from HTTPRoutes MUST prioritize rules based on the + following criteria, continuing on ties. Precedence must be + given to the the Rule with the largest number of: \n * Characters + in a matching non-wildcard hostname. * Characters in a matching + hostname. * Characters in a matching path. * Header matches. + * Query param matches. \n If ties still exist across multiple + Routes, matching precedence MUST be determined in order of + the following criteria, continuing on ties: \n * The oldest + Route based on creation timestamp. * The Route appearing first + in alphabetical order by \"{namespace}/{name}\". \n If ties + still exist within the Route that has been given precedence, + matching precedence MUST be granted to the first matching + rule meeting the above criteria. \n When no rules matching + a request have been successfully attached to the parent a + request is coming from, a HTTP 404 status code MUST be returned." + items: + description: "HTTPRouteMatch defines the predicate used to + match requests to a given action. Multiple match types are + ANDed together, i.e. the match will evaluate to true only + if all conditions are satisfied. \n For example, the match + below will match a HTTP request only if its path starts + with `/foo` AND it contains the `version: v1` header: \n + ``` match: path: value: \"/foo\" headers: - name: + \"version\" value \"v1\" ```" + properties: + headers: + description: Headers specifies HTTP request header matchers. + Multiple match values are ANDed together, meaning, a + request must match all the specified headers to select + the route. + items: + description: HTTPHeaderMatch describes how to select + a HTTP route by matching HTTP request headers. + properties: + name: + description: "Name is the name of the HTTP Header + to be matched. Name matching MUST be case insensitive. + (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent header + names, only the first entry with an equivalent + name MUST be considered for a match. Subsequent + entries with an equivalent header name MUST be + ignored. Due to the case-insensitivity of header + names, \"foo\" and \"Foo\" are considered equivalent. + \n When a header is repeated in an HTTP request, + it is implementation-specific behavior as to how + this is represented. Generally, proxies should + follow the guidance from the RFC: https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2.2 + regarding processing a repeated header, with special + handling for \"Set-Cookie\"." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + type: + default: Exact + description: "Type specifies how to match against + the value of the header. \n Support: Core (Exact) + \n Support: Custom (RegularExpression) \n Since + RegularExpression HeaderMatchType has custom conformance, + implementations can support POSIX, PCRE or any + other dialects of regular expressions. Please + read the implementation's documentation to determine + the supported dialect." + enum: + - Exact + - RegularExpression + type: string + value: + description: Value is the value of HTTP Header to + be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + method: + description: "Method specifies HTTP method matcher. When + specified, this route will be matched only if the request + has the specified method. \n Support: Extended" + enum: + - GET + - HEAD + - POST + - PUT + - DELETE + - CONNECT + - OPTIONS + - TRACE + - PATCH + type: string + path: + default: + type: PathPrefix + value: / + description: Path specifies a HTTP request path matcher. + If this field is not specified, a default prefix match + on the "/" path is provided. + properties: + type: + default: PathPrefix + description: "Type specifies how to match against + the path Value. \n Support: Core (Exact, PathPrefix) + \n Support: Custom (RegularExpression)" + enum: + - Exact + - PathPrefix + - RegularExpression + type: string + value: + default: / + description: Value of the HTTP path to match against. + maxLength: 1024 + type: string + type: object + queryParams: + description: QueryParams specifies HTTP query parameter + matchers. Multiple match values are ANDed together, + meaning, a request must match all the specified query + parameters to select the route. + items: + description: HTTPQueryParamMatch describes how to select + a HTTP route by matching HTTP query parameters. + properties: + name: + description: Name is the name of the HTTP query + param to be matched. This must be an exact string + match. (See https://tools.ietf.org/html/rfc7230#section-2.7.3). + maxLength: 256 + minLength: 1 + type: string + type: + default: Exact + description: "Type specifies how to match against + the value of the query parameter. \n Support: + Extended (Exact) \n Support: Custom (RegularExpression) + \n Since RegularExpression QueryParamMatchType + has custom conformance, implementations can support + POSIX, PCRE or any other dialects of regular expressions. + Please read the implementation's documentation + to determine the supported dialect." + enum: + - Exact + - RegularExpression + type: string + value: + description: Value is the value of HTTP query param + to be matched. + maxLength: 1024 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + maxItems: 8 + type: array + type: object + maxItems: 16 + type: array + type: object + status: + description: Status defines the current state of HTTPRoute. + properties: + parents: + description: "Parents is a list of parent resources (usually Gateways) + that are associated with the route, and the status of the route + with respect to each parent. When this route attaches to a parent, + the controller that manages the parent must add an entry to this + list when the controller first sees the route and should update + the entry as appropriate when the route or gateway is modified. + \n Note that parent references that cannot be resolved by an implementation + of this API will not be added to this list. Implementations of this + API can only populate Route status for the Gateways/parent resources + they are responsible for. \n A maximum of 32 Gateways will be represented + in this list. An empty list means the route has not been attached + to any Gateway." + items: + description: RouteParentStatus describes the status of a route with + respect to an associated Parent. + properties: + conditions: + description: "Conditions describes the status of the route with + respect to the Gateway. Note that the route's availability + is also subject to the Gateway's own status conditions and + listener status. \n If the Route's ParentRef specifies an + existing Gateway that supports Routes of this kind AND that + Gateway's controller has sufficient access, then that Gateway's + controller MUST set the \"Accepted\" condition on the Route, + to indicate whether the route has been accepted or rejected + by the Gateway, and why. \n A Route MUST be considered \"Accepted\" + if at least one of the Route's rules is implemented by the + Gateway. \n There are a number of cases where the \"Accepted\" + condition may not be set due to lack of controller visibility, + that includes when: \n * The Route refers to a non-existent + parent. * The Route is of a type that the controller does + not support. * The Route is in a namespace the the controller + does not have access to." + items: + description: "Condition contains details for one aspect of + the current state of this API Resource. --- This struct + is intended for direct use as an array at the field path + .status.conditions. For example, type FooStatus struct{ + \ // Represents the observations of a foo's current state. + \ // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type + \ // +patchStrategy=merge // +listType=map // + +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` + \n // other fields }" + 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 + maxItems: 8 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + controllerName: + description: "ControllerName is a domain/path string that indicates + the name of the controller that wrote this status. This corresponds + with the controllerName field on GatewayClass. \n Example: + \"example.net/gateway-controller\". \n The format of this + field is DOMAIN \"/\" PATH, where DOMAIN and PATH are valid + Kubernetes names (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). + \n Controllers MUST populate this field when writing status. + Controllers should ensure that entries to status populated + with their ControllerName are cleaned up when they are no + longer necessary." + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + parentRef: + description: ParentRef corresponds with a ParentRef in the spec + that this RouteParentStatus struct describes the status of. + properties: + group: + default: policy.linkerd.io + description: "Group is the group of the referent. \n Support: + Core" + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Gateway + description: "Kind is kind of the referent. \n Support: + Core (Gateway) Support: Custom (Other Resources)" + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: "Name is the name of the referent. \n Support: + Core" + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace of the referent. + When unspecified (or empty string), this refers to the + local namespace of the Route. \n Support: Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: "Port is the network port this Route targets. + It can be interpreted differently based on the type of + parent resource. \n When the parent resource is a Gateway, + this targets all listeners listening on the specified + port that also support this kind of Route(and select this + Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to + a specific port as opposed to a listener(s) whose port(s) + may be changed. When both Port and SectionName are specified, + the name and port of the selected listener must match + both specified values. \n Implementations MAY choose to + support other parent resources. Implementations supporting + other types of parent resources MUST clearly document + how/if Port is interpreted. \n For the purpose of status, + an attachment is considered successful as long as the + parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them + by Route kind, namespace, or hostname. If 1 of 2 Gateway + listeners accept attachment from the referencing Route, + the Route MUST be considered successfully attached. If + no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + \n Support: Extended \n " + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: "SectionName is the name of a section within + the target resource. In the following resources, SectionName + is interpreted as the following: \n * Gateway: Listener + Name. When both Port (experimental) and SectionName are + specified, the name and port of the selected listener + must match both specified values. \n Implementations MAY + choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName + is interpreted. \n When unspecified (empty string), this + will reference the entire resource. For the purpose of + status, an attachment is considered successful if at least + one section in the parent resource accepts it. For example, + Gateway listeners can restrict which Routes can attach + to them by Route kind, namespace, or hostname. If 1 of + 2 Gateway listeners accept attachment from the referencing + Route, the Route MUST be considered successfully attached. + If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + \n Support: Core" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - name + type: object + required: + - controllerName + - parentRef + type: object + maxItems: 32 + type: array + required: + - parents + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .spec.hostnames + name: Hostnames + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta2 + schema: + openAPIV3Schema: + description: HTTPRoute provides a way to route HTTP requests. This includes + the capability to match requests by hostname, path, header, or query param. + Filters can be used to specify additional processing steps. Backends specify + where matching requests should be routed. + 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 HTTPRoute. + properties: + hostnames: + description: "Hostnames defines a set of hostname that should match + against the HTTP Host header to select a HTTPRoute to process the + request. This matches the RFC 1123 definition of a hostname with + 2 notable exceptions: \n 1. IPs are not allowed. 2. A hostname may + be prefixed with a wildcard label (`*.`). The wildcard label + must appear by itself as the first label. \n If a hostname is specified + by both the Listener and HTTPRoute, there must be at least one intersecting + hostname for the HTTPRoute to be attached to the Listener. For example: + \n * A Listener with `test.example.com` as the hostname matches + HTTPRoutes that have either not specified any hostnames, or have + specified at least one of `test.example.com` or `*.example.com`. + * A Listener with `*.example.com` as the hostname matches HTTPRoutes + \ that have either not specified any hostnames or have specified + at least one hostname that matches the Listener hostname. For + example, `*.example.com`, `test.example.com`, and `foo.test.example.com` + would all match. On the other hand, `example.com` and `test.example.net` + would not match. \n Hostnames that are prefixed with a wildcard + label (`*.`) are interpreted as a suffix match. That means that + a match for `*.example.com` would match both `test.example.com`, + and `foo.test.example.com`, but not `example.com`. \n If both the + Listener and HTTPRoute have specified hostnames, any HTTPRoute hostnames + that do not match the Listener hostname MUST be ignored. For example, + if a Listener specified `*.example.com`, and the HTTPRoute specified + `test.example.com` and `test.example.net`, `test.example.net` must + not be considered for a match. \n If both the Listener and HTTPRoute + have specified hostnames, and none match with the criteria above, + then the HTTPRoute is not accepted. The implementation must raise + an 'Accepted' Condition with a status of `False` in the corresponding + RouteParentStatus. \n Support: Core" + items: + description: "Hostname is the fully qualified domain name of a network + host. This matches the RFC 1123 definition of a hostname with + 2 notable exceptions: \n 1. IPs are not allowed. 2. A hostname + may be prefixed with a wildcard label (`*.`). The wildcard label + must appear by itself as the first label. \n Hostname can be \"precise\" + which is a domain name without the terminating dot of a network + host (e.g. \"foo.example.com\") or \"wildcard\", which is a domain + name prefixed with a single wildcard label (e.g. `*.example.com`). + \n Note that as per RFC1035 and RFC1123, a *label* must consist + of lower case alphanumeric characters or '-', and must start and + end with an alphanumeric character. No other punctuation is allowed." + maxLength: 253 + minLength: 1 + pattern: ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + maxItems: 16 + type: array + parentRefs: + description: "ParentRefs references the resources (usually Gateways) + that a Route wants to be attached to. Note that the referenced parent + resource needs to allow this for the attachment to be complete. + For Gateways, that means the Gateway needs to allow attachment from + Routes of this kind and namespace. \n The only kind of parent resource + with \"Core\" support is Gateway. This API may be extended in the + future to support additional kinds of parent resources such as one + of the route kinds. \n It is invalid to reference an identical parent + more than once. It is valid to reference multiple distinct sections + within the same parent resource, such as 2 Listeners within a Gateway. + \n It is possible to separately reference multiple distinct objects + that may be collapsed by an implementation. For example, some implementations + may choose to merge compatible Gateway Listeners together. If that + is the case, the list of routes attached to those resources should + also be merged." + items: + description: "ParentReference identifies an API object (usually + a Gateway) that can be considered a parent of this resource (usually + a route). The only kind of parent resource with \"Core\" support + is Gateway. This API may be extended in the future to support + additional kinds of parent resources, such as HTTPRoute. \n The + API object must be valid in the cluster; the Group and Kind must + be registered in the cluster for this reference to be valid." + properties: + group: + default: policy.linkerd.io + description: "Group is the group of the referent. \n Support: + Core" + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Gateway + description: "Kind is kind of the referent. \n Support: Core + (Gateway) Support: Custom (Other Resources)" + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: "Name is the name of the referent. \n Support: + Core" + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace of the referent. When + unspecified (or empty string), this refers to the local namespace + of the Route. \n Support: Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: "Port specifies the destination + port number to use for this resource. + Port is required when the referent is + a Kubernetes Service. In this case, the + port number is the service port number, + not the target port. For other resources, + destination port might be derived from + the referent resource or this field. \n Support: Extended" + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: "SectionName is the name of a section within the + target resource. In the following resources, SectionName is + interpreted as the following: \n * Gateway: Listener Name. + When both Port (experimental) and SectionName are specified, + the name and port of the selected listener must match both + specified values. \n Implementations MAY choose to support + attaching Routes to other resources. If that is the case, + they MUST clearly document how SectionName is interpreted. + \n When unspecified (empty string), this will reference the + entire resource. For the purpose of status, an attachment + is considered successful if at least one section in the parent + resource accepts it. For example, Gateway listeners can restrict + which Routes can attach to them by Route kind, namespace, + or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this + Route, the Route MUST be considered detached from the Gateway. + \n Support: Core" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - name + type: object + maxItems: 32 + type: array + rules: + default: + - matches: + - path: + type: PathPrefix + value: / + description: Rules are a list of HTTP matchers, filters and actions. + items: + description: HTTPRouteRule defines semantics for matching an HTTP + request based on conditions (matches) and processing it (filters). + properties: + backendRefs: + description: "BackendRefs defines the backend(s) where matching + requests should be sent. \n Failure behavior here depends + on how many BackendRefs are specified and how many are invalid. + \n If *all* entries in BackendRefs are invalid, and there + are also no filters specified in this route rule, *all* traffic + which matches this rule MUST receive a 500 status code. \n + See the HTTPBackendRef definition for the rules about what + makes a single HTTPBackendRef invalid. \n When a HTTPBackendRef + is invalid, 500 status codes MUST be returned for requests + that would have otherwise been routed to an invalid backend. + If multiple backends are specified, and some are invalid, + the proportion of requests that would otherwise have been + routed to an invalid backend MUST receive a 500 status code. + \n For example, if two backends are specified with equal weights, + and one is invalid, 50 percent of traffic must receive a 500. + Implementations may choose how that 50 percent is determined. + \n Support: Core for Kubernetes Service \n Support: Implementation-specific + for any other resource \n Support for weight: Core" + items: + description: HTTPBackendRef defines how a HTTPRoute should + forward an HTTP request. + properties: + group: + default: "" + description: Group is the group of the referent. For example, + "gateway.networking.k8s.io". When unspecified or empty + string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Service + description: Kind is kind of the referent. For example + "HTTPRoute" or "Service". Defaults to "Service" when + not specified. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace of the backend. + When unspecified, the local namespace is inferred. \n + Note that when a namespace is specified, a ReferenceGrant + object is required in the referent namespace to allow + that namespace's owner to accept the reference. See + the ReferenceGrant documentation for details. \n Support: + Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: Port specifies the destination port number + to use for this resource. Port is required when the + referent is a Kubernetes Service. In this case, the + port number is the service port number, not the target + port. For other resources, destination port might be + derived from the referent resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + weight: + default: 1 + description: "Weight specifies the proportion of requests + forwarded to the referenced backend. This is computed + as weight/(sum of all weights in this BackendRefs list). + For non-zero values, there may be some epsilon from + the exact proportion defined here depending on the precision + an implementation supports. Weight is not a percentage + and the sum of weights does not need to equal 100. \n + If only one backend is specified and it has a weight + greater than 0, 100% of the traffic is forwarded to + that backend. If weight is set to 0, no traffic should + be forwarded for this entry. If unspecified, weight + defaults to 1. \n Support for this field varies based + on the context where used." + format: int32 + maximum: 1000000 + minimum: 0 + type: integer + filters: + description: "Filters defined at this level should be + executed if and only if the request is being forwarded + to the backend defined here. \n Support: Implementation-specific + (For broader support of filters, use the Filters field + in HTTPRouteRule.)" + items: + description: HTTPRouteFilter defines processing steps + that must be completed during the request or response + lifecycle. HTTPRouteFilters are meant as an extension + point to express processing that may be done in Gateway + implementations. Some examples include request or + response modification, implementing authentication + strategies, rate-limiting, and traffic shaping. API + guarantee/conformance is defined based on the type + of the filter. + properties: + requestHeaderModifier: + description: "RequestHeaderModifier defines a schema + for a filter that modifies request headers. \n + Support: Core" + properties: + add: + description: "Add adds the given header(s) (name, + value) to the request before the action. It + appends to any existing values associated + with the header name. \n Input: GET /foo HTTP/1.1 + my-header: foo \n Config: add: - name: \"my-header\" + value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 + my-header: foo,bar,baz" + items: + description: HTTPHeader represents an HTTP + Header name and value as defined by RFC + 7230. + properties: + name: + description: "Name is the name of the + HTTP Header to be matched. Name matching + MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an + equivalent name MUST be considered for + a match. Subsequent entries with an + equivalent header name MUST be ignored. + Due to the case-insensitivity of header + names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + remove: + description: "Remove the given header(s) from + the HTTP request before the action. The value + of Remove is a list of HTTP header names. + Note that the header names are case-insensitive + (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + \n Input: GET /foo HTTP/1.1 my-header1: foo + my-header2: bar my-header3: baz \n Config: + remove: [\"my-header1\", \"my-header3\"] \n + Output: GET /foo HTTP/1.1 my-header2: bar" + items: + type: string + maxItems: 16 + type: array + set: + description: "Set overwrites the request with + the given header (name, value) before the + action. \n Input: GET /foo HTTP/1.1 my-header: + foo \n Config: set: - name: \"my-header\" + value: \"bar\" \n Output: GET /foo HTTP/1.1 + my-header: bar" + items: + description: HTTPHeader represents an HTTP + Header name and value as defined by RFC + 7230. + properties: + name: + description: "Name is the name of the + HTTP Header to be matched. Name matching + MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an + equivalent name MUST be considered for + a match. Subsequent entries with an + equivalent header name MUST be ignored. + Due to the case-insensitivity of header + names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + requestRedirect: + description: "RequestRedirect defines a schema for + a filter that responds to the request with an + HTTP redirection. \n Support: Core" + properties: + hostname: + description: "Hostname is the hostname to be + used in the value of the `Location` header + in the response. When empty, the hostname + in the `Host` header of the request is used. + \n Support: Core" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + path: + description: "Path defines parameters used to + modify the path of the incoming request. The + modified path is then used to construct the + `Location` header. When empty, the request + path is used as-is. \n Support: Extended" + properties: + replaceFullPath: + description: ReplaceFullPath specifies the + value with which to replace the full path + of a request during a rewrite or redirect. + maxLength: 1024 + type: string + replacePrefixMatch: + description: "ReplacePrefixMatch specifies + the value with which to replace the prefix + match of a request during a rewrite or + redirect. For example, a request to \"/foo/bar\" + with a prefix match of \"/foo\" and a + ReplacePrefixMatch of \"/xyz\" would be + modified to \"/xyz/bar\". \n Note that + this matches the behavior of the PathPrefix + match type. This matches full path elements. + A path element refers to the list of labels + in the path split by the `/` separator. + When specified, a trailing `/` is ignored. + For example, the paths `/abc`, `/abc/`, + and `/abc/def` would all match the prefix + `/abc`, but the path `/abcd` would not. + \n Request Path | Prefix Match | Replace + Prefix | Modified Path -------------|--------------|----------------|---------- + /foo/bar | /foo | /xyz | + /xyz/bar /foo/bar | /foo | + /xyz/ | /xyz/bar /foo/bar | + /foo/ | /xyz | /xyz/bar + /foo/bar | /foo/ | /xyz/ | + /xyz/bar /foo | /foo | + /xyz | /xyz /foo/ | /foo + \ | /xyz | /xyz/ /foo/bar + \ | /foo | | + /bar /foo/ | /foo | | / /foo | /foo | + | / /foo/ | /foo + \ | / | / /foo | + /foo | / | /" + maxLength: 1024 + type: string + type: + description: "Type defines the type of path + modifier. Additional types may be added + in a future release of the API. \n Note + that values may be added to this enum, + implementations must ensure that unknown + values will not cause a crash. \n Unknown + values here must result in the implementation + setting the Accepted Condition for the + Route to `status: False`, with a Reason + of `UnsupportedValue`." + enum: + - ReplaceFullPath + - ReplacePrefixMatch + type: string + required: + - type + type: object + port: + description: "Port is the port to be used in + the value of the `Location` header in the + response. \n If no port is specified, the + redirect port MUST be derived using the following + rules: \n * If redirect scheme is not-empty, + the redirect port MUST be the well-known port + associated with the redirect scheme. Specifically + \"http\" to port 80 and \"https\" to port + 443. If the redirect scheme does not have + a well-known port, the listener port of the + Gateway SHOULD be used. * If redirect scheme + is empty, the redirect port MUST be the Gateway + Listener port. \n Implementations SHOULD NOT + add the port number in the 'Location' header + in the following cases: \n * A Location header + that will use HTTP (whether that is determined + via the Listener protocol or the Scheme field) + _and_ use port 80. * A Location header that + will use HTTPS (whether that is determined + via the Listener protocol or the Scheme field) + _and_ use port 443. \n Support: Extended" + format: int32 + maximum: 65535 + minimum: 1 + type: integer + scheme: + description: "Scheme is the scheme to be used + in the value of the `Location` header in the + response. When empty, the scheme of the request + is used. \n Scheme redirects can affect the + port of the redirect, for more information, + refer to the documentation for the port field + of this filter. \n Note that values may be + added to this enum, implementations must ensure + that unknown values will not cause a crash. + \n Unknown values here must result in the + implementation setting the Accepted Condition + for the Route to `status: False`, with a Reason + of `UnsupportedValue`. \n Support: Extended" + enum: + - http + - https + type: string + statusCode: + default: 302 + description: "StatusCode is the HTTP status + code to be used in response. \n Note that + values may be added to this enum, implementations + must ensure that unknown values will not cause + a crash. \n Unknown values here must result + in the implementation setting the Accepted + Condition for the Route to `status: False`, + with a Reason of `UnsupportedValue`. \n Support: + Core" + enum: + - 301 + - 302 + type: integer + type: object + responseHeaderModifier: + description: "ResponseHeaderModifier defines a schema + for a filter that modifies response headers. \n + Support: Extended" + properties: + add: + description: "Add adds the given header(s) (name, + value) to the request before the action. It + appends to any existing values associated + with the header name. \n Input: GET /foo HTTP/1.1 + my-header: foo \n Config: add: - name: \"my-header\" + value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 + my-header: foo,bar,baz" + items: + description: HTTPHeader represents an HTTP + Header name and value as defined by RFC + 7230. + properties: + name: + description: "Name is the name of the + HTTP Header to be matched. Name matching + MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an + equivalent name MUST be considered for + a match. Subsequent entries with an + equivalent header name MUST be ignored. + Due to the case-insensitivity of header + names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + remove: + description: "Remove the given header(s) from + the HTTP request before the action. The value + of Remove is a list of HTTP header names. + Note that the header names are case-insensitive + (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + \n Input: GET /foo HTTP/1.1 my-header1: foo + my-header2: bar my-header3: baz \n Config: + remove: [\"my-header1\", \"my-header3\"] \n + Output: GET /foo HTTP/1.1 my-header2: bar" + items: + type: string + maxItems: 16 + type: array + set: + description: "Set overwrites the request with + the given header (name, value) before the + action. \n Input: GET /foo HTTP/1.1 my-header: + foo \n Config: set: - name: \"my-header\" + value: \"bar\" \n Output: GET /foo HTTP/1.1 + my-header: bar" + items: + description: HTTPHeader represents an HTTP + Header name and value as defined by RFC + 7230. + properties: + name: + description: "Name is the name of the + HTTP Header to be matched. Name matching + MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an + equivalent name MUST be considered for + a match. Subsequent entries with an + equivalent header name MUST be ignored. + Due to the case-insensitivity of header + names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: + description: "Type identifies the type of filter + to apply. As with other API fields, types are + classified into three conformance levels: \n - + Core: Filter types and their corresponding configuration + defined by \"Support: Core\" in this package, + e.g. \"RequestHeaderModifier\". All implementations + must support core filters. \n - Extended: Filter + types and their corresponding configuration defined + by \"Support: Extended\" in this package, e.g. + \"RequestMirror\". Implementers are encouraged + to support extended filters. \n - Implementation-specific: + Filters that are defined and supported by specific + vendors. In the future, filters showing convergence + in behavior across multiple implementations will + be considered for inclusion in extended or core + conformance levels. Filter-specific configuration + for such filters is specified using the ExtensionRef + field. `Type` should be set to \"ExtensionRef\" + for custom filters. \n Implementers are encouraged + to define custom implementation types to extend + the core API with implementation-specific behavior. + \n If a reference to a custom filter type cannot + be resolved, the filter MUST NOT be skipped. Instead, + requests that would have been processed by that + filter MUST receive a HTTP error response. \n + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause + a crash. \n Unknown values here must result in + the implementation setting the Accepted Condition + for the Route to `status: False`, with a Reason + of `UnsupportedValue`." + enum: + - RequestHeaderModifier + - ResponseHeaderModifier + - RequestRedirect + type: string + required: + - type + type: object + maxItems: 16 + type: array + required: + - name + type: object + maxItems: 16 + type: array + filters: + description: "Filters define the filters that are applied to + requests that match this rule. \n The effects of ordering + of multiple behaviors are currently unspecified. This can + change in the future based on feedback during the alpha stage. + \n Conformance-levels at this level are defined based on the + type of filter: \n - ALL core filters MUST be supported by + all implementations. - Implementers are encouraged to support + extended filters. - Implementation-specific custom filters + have no API guarantees across implementations. \n Specifying + a core filter multiple times has unspecified or custom conformance. + \n All filters are expected to be compatible with each other + except for the URLRewrite and RequestRedirect filters, which + may not be combined. If an implementation can not support + other combinations of filters, they must clearly document + that limitation. In all cases where incompatible or unsupported + filters are specified, implementations MUST add a warning + condition to status. \n Support: Core" + items: + description: HTTPRouteFilter defines processing steps that + must be completed during the request or response lifecycle. + HTTPRouteFilters are meant as an extension point to express + processing that may be done in Gateway implementations. + Some examples include request or response modification, + implementing authentication strategies, rate-limiting, and + traffic shaping. API guarantee/conformance is defined based + on the type of the filter. + properties: + requestHeaderModifier: + description: "RequestHeaderModifier defines a schema for + a filter that modifies request headers. \n Support: + Core" + properties: + add: + description: "Add adds the given header(s) (name, + value) to the request before the action. It appends + to any existing values associated with the header + name. \n Input: GET /foo HTTP/1.1 my-header: + foo \n Config: add: - name: \"my-header\" value: + \"bar\" \n Output: GET /foo HTTP/1.1 my-header: + foo my-header: bar" + items: + description: HTTPHeader represents an HTTP Header + name and value as defined by RFC 7230. + properties: + name: + description: "Name is the name of the HTTP Header + to be matched. Name matching MUST be case + insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an equivalent + name MUST be considered for a match. Subsequent + entries with an equivalent header name MUST + be ignored. Due to the case-insensitivity + of header names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + remove: + description: "Remove the given header(s) from the + HTTP request before the action. The value of Remove + is a list of HTTP header names. Note that the header + names are case-insensitive (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + \n Input: GET /foo HTTP/1.1 my-header1: foo + \ my-header2: bar my-header3: baz \n Config: + \ remove: [\"my-header1\", \"my-header3\"] \n Output: + \ GET /foo HTTP/1.1 my-header2: bar" + items: + type: string + maxItems: 16 + type: array + set: + description: "Set overwrites the request with the + given header (name, value) before the action. \n + Input: GET /foo HTTP/1.1 my-header: foo \n Config: + \ set: - name: \"my-header\" value: \"bar\" + \n Output: GET /foo HTTP/1.1 my-header: bar" + items: + description: HTTPHeader represents an HTTP Header + name and value as defined by RFC 7230. + properties: + name: + description: "Name is the name of the HTTP Header + to be matched. Name matching MUST be case + insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an equivalent + name MUST be considered for a match. Subsequent + entries with an equivalent header name MUST + be ignored. Due to the case-insensitivity + of header names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + requestRedirect: + description: "RequestRedirect defines a schema for a filter + that responds to the request with an HTTP redirection. + \n Support: Core" + properties: + hostname: + description: "Hostname is the hostname to be used + in the value of the `Location` header in the response. + When empty, the hostname of the request is used. + \n Support: Core" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + path: + description: "Path defines parameters used to + modify the path of the incoming request. The + modified path is then used to construct the + `Location` header. When empty, the request + path is used as-is. \n Support: Extended" + properties: + replaceFullPath: + description: ReplaceFullPath specifies the + value with which to replace the full path + of a request during a rewrite or redirect. + maxLength: 1024 + type: string + replacePrefixMatch: + description: "ReplacePrefixMatch specifies + the value with which to replace the prefix + match of a request during a rewrite or + redirect. For example, a request to \"/foo/bar\" + with a prefix match of \"/foo\" and a + ReplacePrefixMatch of \"/xyz\" would be + modified to \"/xyz/bar\". \n Note that + this matches the behavior of the PathPrefix + match type. This matches full path elements. + A path element refers to the list of labels + in the path split by the `/` separator. + When specified, a trailing `/` is ignored. + For example, the paths `/abc`, `/abc/`, + and `/abc/def` would all match the prefix + `/abc`, but the path `/abcd` would not. + \n Request Path | Prefix Match | Replace + Prefix | Modified Path -------------|--------------|----------------|---------- + /foo/bar | /foo | /xyz | + /xyz/bar /foo/bar | /foo | + /xyz/ | /xyz/bar /foo/bar | + /foo/ | /xyz | /xyz/bar + /foo/bar | /foo/ | /xyz/ | + /xyz/bar /foo | /foo | + /xyz | /xyz /foo/ | /foo + \ | /xyz | /xyz/ /foo/bar + \ | /foo | | + /bar /foo/ | /foo | | / /foo | /foo | + | / /foo/ | /foo + \ | / | / /foo | + /foo | / | /" + maxLength: 1024 + type: string + type: + description: "Type defines the type of path + modifier. Additional types may be added + in a future release of the API. \n Note + that values may be added to this enum, + implementations must ensure that unknown + values will not cause a crash. \n Unknown + values here must result in the implementation + setting the Accepted Condition for the + Route to `status: False`, with a Reason + of `UnsupportedValue`." + enum: + - ReplaceFullPath + - ReplacePrefixMatch + type: string + required: + - type + type: object + port: + description: "Port is the port to be used in the value + of the `Location` header in the response. When empty, + port (if specified) of the request is used. \n Support: + Extended" + format: int32 + maximum: 65535 + minimum: 1 + type: integer + scheme: + description: "Scheme is the scheme to be used in the + value of the `Location` header in the response. + When empty, the scheme of the request is used. \n + Support: Extended" + enum: + - http + - https + type: string + statusCode: + default: 302 + description: "StatusCode is the HTTP status code to + be used in response. \n Support: Core" + enum: + - 301 + - 302 + type: integer + type: object + type: + description: "Type identifies the type of filter to apply. + As with other API fields, types are classified into + three conformance levels: \n - Core: Filter types and + their corresponding configuration defined by \"Support: + Core\" in this package, e.g. \"RequestHeaderModifier\"." + enum: + - RequestHeaderModifier + - RequestRedirect + type: string + required: + - type + type: object + maxItems: 16 + type: array + matches: + default: + - path: + type: PathPrefix + value: / + description: "Matches define conditions used for matching the + rule against incoming HTTP requests. Each match is independent, + i.e. this rule will be matched if **any** one of the matches + is satisfied. \n For example, take the following matches configuration: + \n ``` matches: - path: value: \"/foo\" headers: - + name: \"version\" value: \"v2\" - path: value: \"/v2/foo\" + ``` \n For a request to match against this rule, a request + must satisfy EITHER of the two conditions: \n - path prefixed + with `/foo` AND contains the header `version: v2` - path prefix + of `/v2/foo` \n See the documentation for HTTPRouteMatch on + how to specify multiple match conditions that should be ANDed + together. \n If no matches are specified, the default is a + prefix path match on \"/\", which has the effect of matching + every HTTP request. \n Proxy or Load Balancer routing configuration + generated from HTTPRoutes MUST prioritize rules based on the + following criteria, continuing on ties. Precedence must be + given to the the Rule with the largest number of: \n * Characters + in a matching non-wildcard hostname. * Characters in a matching + hostname. * Characters in a matching path. * Header matches. + * Query param matches. \n If ties still exist across multiple + Routes, matching precedence MUST be determined in order of + the following criteria, continuing on ties: \n * The oldest + Route based on creation timestamp. * The Route appearing first + in alphabetical order by \"{namespace}/{name}\". \n If ties + still exist within the Route that has been given precedence, + matching precedence MUST be granted to the first matching + rule meeting the above criteria. \n When no rules matching + a request have been successfully attached to the parent a + request is coming from, a HTTP 404 status code MUST be returned." + items: + description: "HTTPRouteMatch defines the predicate used to + match requests to a given action. Multiple match types are + ANDed together, i.e. the match will evaluate to true only + if all conditions are satisfied. \n For example, the match + below will match a HTTP request only if its path starts + with `/foo` AND it contains the `version: v1` header: \n + ``` match: path: value: \"/foo\" headers: - name: + \"version\" value \"v1\" ```" + properties: + headers: + description: Headers specifies HTTP request header matchers. + Multiple match values are ANDed together, meaning, a + request must match all the specified headers to select + the route. + items: + description: HTTPHeaderMatch describes how to select + a HTTP route by matching HTTP request headers. + properties: + name: + description: "Name is the name of the HTTP Header + to be matched. Name matching MUST be case insensitive. + (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent header + names, only the first entry with an equivalent + name MUST be considered for a match. Subsequent + entries with an equivalent header name MUST be + ignored. Due to the case-insensitivity of header + names, \"foo\" and \"Foo\" are considered equivalent. + \n When a header is repeated in an HTTP request, + it is implementation-specific behavior as to how + this is represented. Generally, proxies should + follow the guidance from the RFC: https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2.2 + regarding processing a repeated header, with special + handling for \"Set-Cookie\"." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + type: + default: Exact + description: "Type specifies how to match against + the value of the header. \n Support: Core (Exact) + \n Support: Custom (RegularExpression) \n Since + RegularExpression HeaderMatchType has custom conformance, + implementations can support POSIX, PCRE or any + other dialects of regular expressions. Please + read the implementation's documentation to determine + the supported dialect." + enum: + - Exact + - RegularExpression + type: string + value: + description: Value is the value of HTTP Header to + be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + method: + description: "Method specifies HTTP method matcher. When + specified, this route will be matched only if the request + has the specified method. \n Support: Extended" + enum: + - GET + - HEAD + - POST + - PUT + - DELETE + - CONNECT + - OPTIONS + - TRACE + - PATCH + type: string + path: + default: + type: PathPrefix + value: / + description: Path specifies a HTTP request path matcher. + If this field is not specified, a default prefix match + on the "/" path is provided. + properties: + type: + default: PathPrefix + description: "Type specifies how to match against + the path Value. \n Support: Core (Exact, PathPrefix) + \n Support: Custom (RegularExpression)" + enum: + - Exact + - PathPrefix + - RegularExpression + type: string + value: + default: / + description: Value of the HTTP path to match against. + maxLength: 1024 + type: string + type: object + queryParams: + description: QueryParams specifies HTTP query parameter + matchers. Multiple match values are ANDed together, + meaning, a request must match all the specified query + parameters to select the route. + items: + description: HTTPQueryParamMatch describes how to select + a HTTP route by matching HTTP query parameters. + properties: + name: + description: Name is the name of the HTTP query + param to be matched. This must be an exact string + match. (See https://tools.ietf.org/html/rfc7230#section-2.7.3). + maxLength: 256 + minLength: 1 + type: string + type: + default: Exact + description: "Type specifies how to match against + the value of the query parameter. \n Support: + Extended (Exact) \n Support: Custom (RegularExpression) + \n Since RegularExpression QueryParamMatchType + has custom conformance, implementations can support + POSIX, PCRE or any other dialects of regular expressions. + Please read the implementation's documentation + to determine the supported dialect." + enum: + - Exact + - RegularExpression + type: string + value: + description: Value is the value of HTTP query param + to be matched. + maxLength: 1024 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + maxItems: 8 + type: array + type: object + maxItems: 16 + type: array + type: object + status: + description: Status defines the current state of HTTPRoute. + properties: + parents: + description: "Parents is a list of parent resources (usually Gateways) + that are associated with the route, and the status of the route + with respect to each parent. When this route attaches to a parent, + the controller that manages the parent must add an entry to this + list when the controller first sees the route and should update + the entry as appropriate when the route or gateway is modified. + \n Note that parent references that cannot be resolved by an implementation + of this API will not be added to this list. Implementations of this + API can only populate Route status for the Gateways/parent resources + they are responsible for. \n A maximum of 32 Gateways will be represented + in this list. An empty list means the route has not been attached + to any Gateway." + items: + description: RouteParentStatus describes the status of a route with + respect to an associated Parent. + properties: + conditions: + description: "Conditions describes the status of the route with + respect to the Gateway. Note that the route's availability + is also subject to the Gateway's own status conditions and + listener status. \n If the Route's ParentRef specifies an + existing Gateway that supports Routes of this kind AND that + Gateway's controller has sufficient access, then that Gateway's + controller MUST set the \"Accepted\" condition on the Route, + to indicate whether the route has been accepted or rejected + by the Gateway, and why. \n A Route MUST be considered \"Accepted\" + if at least one of the Route's rules is implemented by the + Gateway. \n There are a number of cases where the \"Accepted\" + condition may not be set due to lack of controller visibility, + that includes when: \n * The Route refers to a non-existent + parent. * The Route is of a type that the controller does + not support. * The Route is in a namespace the the controller + does not have access to." + items: + description: "Condition contains details for one aspect of + the current state of this API Resource. --- This struct + is intended for direct use as an array at the field path + .status.conditions. For example, type FooStatus struct{ + \ // Represents the observations of a foo's current state. + \ // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type + \ // +patchStrategy=merge // +listType=map // + +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` + \n // other fields }" + 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 + maxItems: 8 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + controllerName: + description: "ControllerName is a domain/path string that indicates + the name of the controller that wrote this status. This corresponds + with the controllerName field on GatewayClass. \n Example: + \"example.net/gateway-controller\". \n The format of this + field is DOMAIN \"/\" PATH, where DOMAIN and PATH are valid + Kubernetes names (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). + \n Controllers MUST populate this field when writing status. + Controllers should ensure that entries to status populated + with their ControllerName are cleaned up when they are no + longer necessary." + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + parentRef: + description: ParentRef corresponds with a ParentRef in the spec + that this RouteParentStatus struct describes the status of. + properties: + group: + default: policy.linkerd.io + description: "Group is the group of the referent. \n Support: + Core" + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Gateway + description: "Kind is kind of the referent. \n Support: + Core (Gateway) Support: Custom (Other Resources)" + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: "Name is the name of the referent. \n Support: + Core" + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace of the referent. + When unspecified (or empty string), this refers to the + local namespace of the Route. \n Support: Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: "Port is the network port this Route targets. + It can be interpreted differently based on the type of + parent resource. \n When the parent resource is a Gateway, + this targets all listeners listening on the specified + port that also support this kind of Route(and select this + Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to + a specific port as opposed to a listener(s) whose port(s) + may be changed. When both Port and SectionName are specified, + the name and port of the selected listener must match + both specified values. \n Implementations MAY choose to + support other parent resources. Implementations supporting + other types of parent resources MUST clearly document + how/if Port is interpreted. \n For the purpose of status, + an attachment is considered successful as long as the + parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them + by Route kind, namespace, or hostname. If 1 of 2 Gateway + listeners accept attachment from the referencing Route, + the Route MUST be considered successfully attached. If + no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + \n Support: Extended \n " + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: "SectionName is the name of a section within + the target resource. In the following resources, SectionName + is interpreted as the following: \n * Gateway: Listener + Name. When both Port (experimental) and SectionName are + specified, the name and port of the selected listener + must match both specified values. \n Implementations MAY + choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName + is interpreted. \n When unspecified (empty string), this + will reference the entire resource. For the purpose of + status, an attachment is considered successful if at least + one section in the parent resource accepts it. For example, + Gateway listeners can restrict which Routes can attach + to them by Route kind, namespace, or hostname. If 1 of + 2 Gateway listeners accept attachment from the referencing + Route, the Route MUST be considered successfully attached. + If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + \n Support: Core" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - name + type: object + required: + - controllerName + - parentRef + type: object + maxItems: 32 + type: array + required: + - parents + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .spec.hostnames + name: Hostnames + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta3 + schema: + openAPIV3Schema: + description: HTTPRoute provides a way to route HTTP requests. This includes + the capability to match requests by hostname, path, header, or query param. + Filters can be used to specify additional processing steps. Backends specify + where matching requests should be routed. + 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 HTTPRoute. + properties: + hostnames: + description: "Hostnames defines a set of hostname that should match + against the HTTP Host header to select a HTTPRoute to process the + request. This matches the RFC 1123 definition of a hostname with + 2 notable exceptions: \n 1. IPs are not allowed. 2. A hostname may + be prefixed with a wildcard label (`*.`). The wildcard label + must appear by itself as the first label. \n If a hostname is specified + by both the Listener and HTTPRoute, there must be at least one intersecting + hostname for the HTTPRoute to be attached to the Listener. For example: + \n * A Listener with `test.example.com` as the hostname matches + HTTPRoutes that have either not specified any hostnames, or have + specified at least one of `test.example.com` or `*.example.com`. + * A Listener with `*.example.com` as the hostname matches HTTPRoutes + \ that have either not specified any hostnames or have specified + at least one hostname that matches the Listener hostname. For + example, `*.example.com`, `test.example.com`, and `foo.test.example.com` + would all match. On the other hand, `example.com` and `test.example.net` + would not match. \n Hostnames that are prefixed with a wildcard + label (`*.`) are interpreted as a suffix match. That means that + a match for `*.example.com` would match both `test.example.com`, + and `foo.test.example.com`, but not `example.com`. \n If both the + Listener and HTTPRoute have specified hostnames, any HTTPRoute hostnames + that do not match the Listener hostname MUST be ignored. For example, + if a Listener specified `*.example.com`, and the HTTPRoute specified + `test.example.com` and `test.example.net`, `test.example.net` must + not be considered for a match. \n If both the Listener and HTTPRoute + have specified hostnames, and none match with the criteria above, + then the HTTPRoute is not accepted. The implementation must raise + an 'Accepted' Condition with a status of `False` in the corresponding + RouteParentStatus. \n Support: Core" + items: + description: "Hostname is the fully qualified domain name of a network + host. This matches the RFC 1123 definition of a hostname with + 2 notable exceptions: \n 1. IPs are not allowed. 2. A hostname + may be prefixed with a wildcard label (`*.`). The wildcard label + must appear by itself as the first label. \n Hostname can be \"precise\" + which is a domain name without the terminating dot of a network + host (e.g. \"foo.example.com\") or \"wildcard\", which is a domain + name prefixed with a single wildcard label (e.g. `*.example.com`). + \n Note that as per RFC1035 and RFC1123, a *label* must consist + of lower case alphanumeric characters or '-', and must start and + end with an alphanumeric character. No other punctuation is allowed." + maxLength: 253 + minLength: 1 + pattern: ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + maxItems: 16 + type: array + parentRefs: + description: "ParentRefs references the resources (usually Gateways) + that a Route wants to be attached to. Note that the referenced parent + resource needs to allow this for the attachment to be complete. + For Gateways, that means the Gateway needs to allow attachment from + Routes of this kind and namespace. \n The only kind of parent resource + with \"Core\" support is Gateway. This API may be extended in the + future to support additional kinds of parent resources such as one + of the route kinds. \n It is invalid to reference an identical parent + more than once. It is valid to reference multiple distinct sections + within the same parent resource, such as 2 Listeners within a Gateway. + \n It is possible to separately reference multiple distinct objects + that may be collapsed by an implementation. For example, some implementations + may choose to merge compatible Gateway Listeners together. If that + is the case, the list of routes attached to those resources should + also be merged." + items: + description: "ParentReference identifies an API object (usually + a Gateway) that can be considered a parent of this resource (usually + a route). The only kind of parent resource with \"Core\" support + is Gateway. This API may be extended in the future to support + additional kinds of parent resources, such as HTTPRoute. \n The + API object must be valid in the cluster; the Group and Kind must + be registered in the cluster for this reference to be valid." + properties: + group: + default: policy.linkerd.io + description: "Group is the group of the referent. \n Support: + Core" + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Gateway + description: "Kind is kind of the referent. \n Support: Core + (Gateway) Support: Custom (Other Resources)" + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: "Name is the name of the referent. \n Support: + Core" + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace of the referent. When + unspecified (or empty string), this refers to the local namespace + of the Route. \n Support: Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: "Port specifies the destination + port number to use for this resource. + Port is required when the referent is + a Kubernetes Service. In this case, the + port number is the service port number, + not the target port. For other resources, + destination port might be derived from + the referent resource or this field. \n Support: Extended" + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: "SectionName is the name of a section within the + target resource. In the following resources, SectionName is + interpreted as the following: \n * Gateway: Listener Name. + When both Port (experimental) and SectionName are specified, + the name and port of the selected listener must match both + specified values. \n Implementations MAY choose to support + attaching Routes to other resources. If that is the case, + they MUST clearly document how SectionName is interpreted. + \n When unspecified (empty string), this will reference the + entire resource. For the purpose of status, an attachment + is considered successful if at least one section in the parent + resource accepts it. For example, Gateway listeners can restrict + which Routes can attach to them by Route kind, namespace, + or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this + Route, the Route MUST be considered detached from the Gateway. + \n Support: Core" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - name + type: object + maxItems: 32 + type: array + rules: + default: + - matches: + - path: + type: PathPrefix + value: / + description: Rules are a list of HTTP matchers, filters and actions. + items: + description: HTTPRouteRule defines semantics for matching an HTTP + request based on conditions (matches) and processing it (filters). + properties: + backendRefs: + description: "BackendRefs defines the backend(s) where matching + requests should be sent. \n Failure behavior here depends + on how many BackendRefs are specified and how many are invalid. + \n If *all* entries in BackendRefs are invalid, and there + are also no filters specified in this route rule, *all* traffic + which matches this rule MUST receive a 500 status code. \n + See the HTTPBackendRef definition for the rules about what + makes a single HTTPBackendRef invalid. \n When a HTTPBackendRef + is invalid, 500 status codes MUST be returned for requests + that would have otherwise been routed to an invalid backend. + If multiple backends are specified, and some are invalid, + the proportion of requests that would otherwise have been + routed to an invalid backend MUST receive a 500 status code. + \n For example, if two backends are specified with equal weights, + and one is invalid, 50 percent of traffic must receive a 500. + Implementations may choose how that 50 percent is determined. + \n Support: Core for Kubernetes Service \n Support: Implementation-specific + for any other resource \n Support for weight: Core" + items: + description: HTTPBackendRef defines how a HTTPRoute should + forward an HTTP request. + properties: + group: + default: "" + description: Group is the group of the referent. For example, + "gateway.networking.k8s.io". When unspecified or empty + string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Service + description: Kind is kind of the referent. For example + "HTTPRoute" or "Service". Defaults to "Service" when + not specified. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace of the backend. + When unspecified, the local namespace is inferred. \n + Note that when a namespace is specified, a ReferenceGrant + object is required in the referent namespace to allow + that namespace's owner to accept the reference. See + the ReferenceGrant documentation for details. \n Support: + Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: Port specifies the destination port number + to use for this resource. Port is required when the + referent is a Kubernetes Service. In this case, the + port number is the service port number, not the target + port. For other resources, destination port might be + derived from the referent resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + weight: + default: 1 + description: "Weight specifies the proportion of requests + forwarded to the referenced backend. This is computed + as weight/(sum of all weights in this BackendRefs list). + For non-zero values, there may be some epsilon from + the exact proportion defined here depending on the precision + an implementation supports. Weight is not a percentage + and the sum of weights does not need to equal 100. \n + If only one backend is specified and it has a weight + greater than 0, 100% of the traffic is forwarded to + that backend. If weight is set to 0, no traffic should + be forwarded for this entry. If unspecified, weight + defaults to 1. \n Support for this field varies based + on the context where used." + format: int32 + maximum: 1000000 + minimum: 0 + type: integer + filters: + description: "Filters defined at this level should be + executed if and only if the request is being forwarded + to the backend defined here. \n Support: Implementation-specific + (For broader support of filters, use the Filters field + in HTTPRouteRule.)" + items: + description: HTTPRouteFilter defines processing steps + that must be completed during the request or response + lifecycle. HTTPRouteFilters are meant as an extension + point to express processing that may be done in Gateway + implementations. Some examples include request or + response modification, implementing authentication + strategies, rate-limiting, and traffic shaping. API + guarantee/conformance is defined based on the type + of the filter. + properties: + requestHeaderModifier: + description: "RequestHeaderModifier defines a schema + for a filter that modifies request headers. \n + Support: Core" + properties: + add: + description: "Add adds the given header(s) (name, + value) to the request before the action. It + appends to any existing values associated + with the header name. \n Input: GET /foo HTTP/1.1 + my-header: foo \n Config: add: - name: \"my-header\" + value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 + my-header: foo,bar,baz" + items: + description: HTTPHeader represents an HTTP + Header name and value as defined by RFC + 7230. + properties: + name: + description: "Name is the name of the + HTTP Header to be matched. Name matching + MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an + equivalent name MUST be considered for + a match. Subsequent entries with an + equivalent header name MUST be ignored. + Due to the case-insensitivity of header + names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + remove: + description: "Remove the given header(s) from + the HTTP request before the action. The value + of Remove is a list of HTTP header names. + Note that the header names are case-insensitive + (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + \n Input: GET /foo HTTP/1.1 my-header1: foo + my-header2: bar my-header3: baz \n Config: + remove: [\"my-header1\", \"my-header3\"] \n + Output: GET /foo HTTP/1.1 my-header2: bar" + items: + type: string + maxItems: 16 + type: array + set: + description: "Set overwrites the request with + the given header (name, value) before the + action. \n Input: GET /foo HTTP/1.1 my-header: + foo \n Config: set: - name: \"my-header\" + value: \"bar\" \n Output: GET /foo HTTP/1.1 + my-header: bar" + items: + description: HTTPHeader represents an HTTP + Header name and value as defined by RFC + 7230. + properties: + name: + description: "Name is the name of the + HTTP Header to be matched. Name matching + MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an + equivalent name MUST be considered for + a match. Subsequent entries with an + equivalent header name MUST be ignored. + Due to the case-insensitivity of header + names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + requestRedirect: + description: "RequestRedirect defines a schema for + a filter that responds to the request with an + HTTP redirection. \n Support: Core" + properties: + hostname: + description: "Hostname is the hostname to be + used in the value of the `Location` header + in the response. When empty, the hostname + in the `Host` header of the request is used. + \n Support: Core" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + path: + description: "Path defines parameters used to + modify the path of the incoming request. The + modified path is then used to construct the + `Location` header. When empty, the request + path is used as-is. \n Support: Extended" + properties: + replaceFullPath: + description: ReplaceFullPath specifies the + value with which to replace the full path + of a request during a rewrite or redirect. + maxLength: 1024 + type: string + replacePrefixMatch: + description: "ReplacePrefixMatch specifies + the value with which to replace the prefix + match of a request during a rewrite or + redirect. For example, a request to \"/foo/bar\" + with a prefix match of \"/foo\" and a + ReplacePrefixMatch of \"/xyz\" would be + modified to \"/xyz/bar\". \n Note that + this matches the behavior of the PathPrefix + match type. This matches full path elements. + A path element refers to the list of labels + in the path split by the `/` separator. + When specified, a trailing `/` is ignored. + For example, the paths `/abc`, `/abc/`, + and `/abc/def` would all match the prefix + `/abc`, but the path `/abcd` would not. + \n Request Path | Prefix Match | Replace + Prefix | Modified Path -------------|--------------|----------------|---------- + /foo/bar | /foo | /xyz | + /xyz/bar /foo/bar | /foo | + /xyz/ | /xyz/bar /foo/bar | + /foo/ | /xyz | /xyz/bar + /foo/bar | /foo/ | /xyz/ | + /xyz/bar /foo | /foo | + /xyz | /xyz /foo/ | /foo + \ | /xyz | /xyz/ /foo/bar + \ | /foo | | + /bar /foo/ | /foo | | / /foo | /foo | + | / /foo/ | /foo + \ | / | / /foo | + /foo | / | /" + maxLength: 1024 + type: string + type: + description: "Type defines the type of path + modifier. Additional types may be added + in a future release of the API. \n Note + that values may be added to this enum, + implementations must ensure that unknown + values will not cause a crash. \n Unknown + values here must result in the implementation + setting the Accepted Condition for the + Route to `status: False`, with a Reason + of `UnsupportedValue`." + enum: + - ReplaceFullPath + - ReplacePrefixMatch + type: string + required: + - type + type: object + port: + description: "Port is the port to be used in + the value of the `Location` header in the + response. \n If no port is specified, the + redirect port MUST be derived using the following + rules: \n * If redirect scheme is not-empty, + the redirect port MUST be the well-known port + associated with the redirect scheme. Specifically + \"http\" to port 80 and \"https\" to port + 443. If the redirect scheme does not have + a well-known port, the listener port of the + Gateway SHOULD be used. * If redirect scheme + is empty, the redirect port MUST be the Gateway + Listener port. \n Implementations SHOULD NOT + add the port number in the 'Location' header + in the following cases: \n * A Location header + that will use HTTP (whether that is determined + via the Listener protocol or the Scheme field) + _and_ use port 80. * A Location header that + will use HTTPS (whether that is determined + via the Listener protocol or the Scheme field) + _and_ use port 443. \n Support: Extended" + format: int32 + maximum: 65535 + minimum: 1 + type: integer + scheme: + description: "Scheme is the scheme to be used + in the value of the `Location` header in the + response. When empty, the scheme of the request + is used. \n Scheme redirects can affect the + port of the redirect, for more information, + refer to the documentation for the port field + of this filter. \n Note that values may be + added to this enum, implementations must ensure + that unknown values will not cause a crash. + \n Unknown values here must result in the + implementation setting the Accepted Condition + for the Route to `status: False`, with a Reason + of `UnsupportedValue`. \n Support: Extended" + enum: + - http + - https + type: string + statusCode: + default: 302 + description: "StatusCode is the HTTP status + code to be used in response. \n Note that + values may be added to this enum, implementations + must ensure that unknown values will not cause + a crash. \n Unknown values here must result + in the implementation setting the Accepted + Condition for the Route to `status: False`, + with a Reason of `UnsupportedValue`. \n Support: + Core" + enum: + - 301 + - 302 + type: integer + type: object + responseHeaderModifier: + description: "ResponseHeaderModifier defines a schema + for a filter that modifies response headers. \n + Support: Extended" + properties: + add: + description: "Add adds the given header(s) (name, + value) to the request before the action. It + appends to any existing values associated + with the header name. \n Input: GET /foo HTTP/1.1 + my-header: foo \n Config: add: - name: \"my-header\" + value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 + my-header: foo,bar,baz" + items: + description: HTTPHeader represents an HTTP + Header name and value as defined by RFC + 7230. + properties: + name: + description: "Name is the name of the + HTTP Header to be matched. Name matching + MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an + equivalent name MUST be considered for + a match. Subsequent entries with an + equivalent header name MUST be ignored. + Due to the case-insensitivity of header + names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + remove: + description: "Remove the given header(s) from + the HTTP request before the action. The value + of Remove is a list of HTTP header names. + Note that the header names are case-insensitive + (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + \n Input: GET /foo HTTP/1.1 my-header1: foo + my-header2: bar my-header3: baz \n Config: + remove: [\"my-header1\", \"my-header3\"] \n + Output: GET /foo HTTP/1.1 my-header2: bar" + items: + type: string + maxItems: 16 + type: array + set: + description: "Set overwrites the request with + the given header (name, value) before the + action. \n Input: GET /foo HTTP/1.1 my-header: + foo \n Config: set: - name: \"my-header\" + value: \"bar\" \n Output: GET /foo HTTP/1.1 + my-header: bar" + items: + description: HTTPHeader represents an HTTP + Header name and value as defined by RFC + 7230. + properties: + name: + description: "Name is the name of the + HTTP Header to be matched. Name matching + MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an + equivalent name MUST be considered for + a match. Subsequent entries with an + equivalent header name MUST be ignored. + Due to the case-insensitivity of header + names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: + description: "Type identifies the type of filter + to apply. As with other API fields, types are + classified into three conformance levels: \n - + Core: Filter types and their corresponding configuration + defined by \"Support: Core\" in this package, + e.g. \"RequestHeaderModifier\". All implementations + must support core filters. \n - Extended: Filter + types and their corresponding configuration defined + by \"Support: Extended\" in this package, e.g. + \"RequestMirror\". Implementers are encouraged + to support extended filters. \n - Implementation-specific: + Filters that are defined and supported by specific + vendors. In the future, filters showing convergence + in behavior across multiple implementations will + be considered for inclusion in extended or core + conformance levels. Filter-specific configuration + for such filters is specified using the ExtensionRef + field. `Type` should be set to \"ExtensionRef\" + for custom filters. \n Implementers are encouraged + to define custom implementation types to extend + the core API with implementation-specific behavior. + \n If a reference to a custom filter type cannot + be resolved, the filter MUST NOT be skipped. Instead, + requests that would have been processed by that + filter MUST receive a HTTP error response. \n + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause + a crash. \n Unknown values here must result in + the implementation setting the Accepted Condition + for the Route to `status: False`, with a Reason + of `UnsupportedValue`." + enum: + - RequestHeaderModifier + - ResponseHeaderModifier + - RequestRedirect + type: string + required: + - type + type: object + maxItems: 16 + type: array + required: + - name + type: object + maxItems: 16 + type: array + filters: + description: "Filters define the filters that are applied to + requests that match this rule. \n The effects of ordering + of multiple behaviors are currently unspecified. This can + change in the future based on feedback during the alpha stage. + \n Conformance-levels at this level are defined based on the + type of filter: \n - ALL core filters MUST be supported by + all implementations. - Implementers are encouraged to support + extended filters. - Implementation-specific custom filters + have no API guarantees across implementations. \n Specifying + a core filter multiple times has unspecified or custom conformance. + \n All filters are expected to be compatible with each other + except for the URLRewrite and RequestRedirect filters, which + may not be combined. If an implementation can not support + other combinations of filters, they must clearly document + that limitation. In all cases where incompatible or unsupported + filters are specified, implementations MUST add a warning + condition to status. \n Support: Core" + items: + description: HTTPRouteFilter defines processing steps that + must be completed during the request or response lifecycle. + HTTPRouteFilters are meant as an extension point to express + processing that may be done in Gateway implementations. + Some examples include request or response modification, + implementing authentication strategies, rate-limiting, and + traffic shaping. API guarantee/conformance is defined based + on the type of the filter. + properties: + requestHeaderModifier: + description: "RequestHeaderModifier defines a schema for + a filter that modifies request headers. \n Support: + Core" + properties: + add: + description: "Add adds the given header(s) (name, + value) to the request before the action. It appends + to any existing values associated with the header + name. \n Input: GET /foo HTTP/1.1 my-header: + foo \n Config: add: - name: \"my-header\" value: + \"bar\" \n Output: GET /foo HTTP/1.1 my-header: + foo my-header: bar" + items: + description: HTTPHeader represents an HTTP Header + name and value as defined by RFC 7230. + properties: + name: + description: "Name is the name of the HTTP Header + to be matched. Name matching MUST be case + insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an equivalent + name MUST be considered for a match. Subsequent + entries with an equivalent header name MUST + be ignored. Due to the case-insensitivity + of header names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + remove: + description: "Remove the given header(s) from the + HTTP request before the action. The value of Remove + is a list of HTTP header names. Note that the header + names are case-insensitive (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + \n Input: GET /foo HTTP/1.1 my-header1: foo + \ my-header2: bar my-header3: baz \n Config: + \ remove: [\"my-header1\", \"my-header3\"] \n Output: + \ GET /foo HTTP/1.1 my-header2: bar" + items: + type: string + maxItems: 16 + type: array + set: + description: "Set overwrites the request with the + given header (name, value) before the action. \n + Input: GET /foo HTTP/1.1 my-header: foo \n Config: + \ set: - name: \"my-header\" value: \"bar\" + \n Output: GET /foo HTTP/1.1 my-header: bar" + items: + description: HTTPHeader represents an HTTP Header + name and value as defined by RFC 7230. + properties: + name: + description: "Name is the name of the HTTP Header + to be matched. Name matching MUST be case + insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent + header names, the first entry with an equivalent + name MUST be considered for a match. Subsequent + entries with an equivalent header name MUST + be ignored. Due to the case-insensitivity + of header names, \"foo\" and \"Foo\" are considered + equivalent." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + requestRedirect: + description: "RequestRedirect defines a schema for a filter + that responds to the request with an HTTP redirection. + \n Support: Core" + properties: + hostname: + description: "Hostname is the hostname to be used + in the value of the `Location` header in the response. + When empty, the hostname of the request is used. + \n Support: Core" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + path: + description: "Path defines parameters used to + modify the path of the incoming request. The + modified path is then used to construct the + `Location` header. When empty, the request + path is used as-is. \n Support: Extended" + properties: + replaceFullPath: + description: ReplaceFullPath specifies the + value with which to replace the full path + of a request during a rewrite or redirect. + maxLength: 1024 + type: string + replacePrefixMatch: + description: "ReplacePrefixMatch specifies + the value with which to replace the prefix + match of a request during a rewrite or + redirect. For example, a request to \"/foo/bar\" + with a prefix match of \"/foo\" and a + ReplacePrefixMatch of \"/xyz\" would be + modified to \"/xyz/bar\". \n Note that + this matches the behavior of the PathPrefix + match type. This matches full path elements. + A path element refers to the list of labels + in the path split by the `/` separator. + When specified, a trailing `/` is ignored. + For example, the paths `/abc`, `/abc/`, + and `/abc/def` would all match the prefix + `/abc`, but the path `/abcd` would not. + \n Request Path | Prefix Match | Replace + Prefix | Modified Path -------------|--------------|----------------|---------- + /foo/bar | /foo | /xyz | + /xyz/bar /foo/bar | /foo | + /xyz/ | /xyz/bar /foo/bar | + /foo/ | /xyz | /xyz/bar + /foo/bar | /foo/ | /xyz/ | + /xyz/bar /foo | /foo | + /xyz | /xyz /foo/ | /foo + \ | /xyz | /xyz/ /foo/bar + \ | /foo | | + /bar /foo/ | /foo | | / /foo | /foo | + | / /foo/ | /foo + \ | / | / /foo | + /foo | / | /" + maxLength: 1024 + type: string + type: + description: "Type defines the type of path + modifier. Additional types may be added + in a future release of the API. \n Note + that values may be added to this enum, + implementations must ensure that unknown + values will not cause a crash. \n Unknown + values here must result in the implementation + setting the Accepted Condition for the + Route to `status: False`, with a Reason + of `UnsupportedValue`." + enum: + - ReplaceFullPath + - ReplacePrefixMatch + type: string + required: + - type + type: object + port: + description: "Port is the port to be used in the value + of the `Location` header in the response. When empty, + port (if specified) of the request is used. \n Support: + Extended" + format: int32 + maximum: 65535 + minimum: 1 + type: integer + scheme: + description: "Scheme is the scheme to be used in the + value of the `Location` header in the response. + When empty, the scheme of the request is used. \n + Support: Extended" + enum: + - http + - https + type: string + statusCode: + default: 302 + description: "StatusCode is the HTTP status code to + be used in response. \n Support: Core" + enum: + - 301 + - 302 + type: integer + type: object + type: + description: "Type identifies the type of filter to apply. + As with other API fields, types are classified into + three conformance levels: \n - Core: Filter types and + their corresponding configuration defined by \"Support: + Core\" in this package, e.g. \"RequestHeaderModifier\"." + enum: + - RequestHeaderModifier + - RequestRedirect + type: string + required: + - type + type: object + maxItems: 16 + type: array + matches: + default: + - path: + type: PathPrefix + value: / + description: "Matches define conditions used for matching the + rule against incoming HTTP requests. Each match is independent, + i.e. this rule will be matched if **any** one of the matches + is satisfied. \n For example, take the following matches configuration: + \n ``` matches: - path: value: \"/foo\" headers: - + name: \"version\" value: \"v2\" - path: value: \"/v2/foo\" + ``` \n For a request to match against this rule, a request + must satisfy EITHER of the two conditions: \n - path prefixed + with `/foo` AND contains the header `version: v2` - path prefix + of `/v2/foo` \n See the documentation for HTTPRouteMatch on + how to specify multiple match conditions that should be ANDed + together. \n If no matches are specified, the default is a + prefix path match on \"/\", which has the effect of matching + every HTTP request. \n Proxy or Load Balancer routing configuration + generated from HTTPRoutes MUST prioritize rules based on the + following criteria, continuing on ties. Precedence must be + given to the the Rule with the largest number of: \n * Characters + in a matching non-wildcard hostname. * Characters in a matching + hostname. * Characters in a matching path. * Header matches. + * Query param matches. \n If ties still exist across multiple + Routes, matching precedence MUST be determined in order of + the following criteria, continuing on ties: \n * The oldest + Route based on creation timestamp. * The Route appearing first + in alphabetical order by \"{namespace}/{name}\". \n If ties + still exist within the Route that has been given precedence, + matching precedence MUST be granted to the first matching + rule meeting the above criteria. \n When no rules matching + a request have been successfully attached to the parent a + request is coming from, a HTTP 404 status code MUST be returned." + items: + description: "HTTPRouteMatch defines the predicate used to + match requests to a given action. Multiple match types are + ANDed together, i.e. the match will evaluate to true only + if all conditions are satisfied. \n For example, the match + below will match a HTTP request only if its path starts + with `/foo` AND it contains the `version: v1` header: \n + ``` match: path: value: \"/foo\" headers: - name: + \"version\" value \"v1\" ```" + properties: + headers: + description: Headers specifies HTTP request header matchers. + Multiple match values are ANDed together, meaning, a + request must match all the specified headers to select + the route. + items: + description: HTTPHeaderMatch describes how to select + a HTTP route by matching HTTP request headers. + properties: + name: + description: "Name is the name of the HTTP Header + to be matched. Name matching MUST be case insensitive. + (See https://tools.ietf.org/html/rfc7230#section-3.2). + \n If multiple entries specify equivalent header + names, only the first entry with an equivalent + name MUST be considered for a match. Subsequent + entries with an equivalent header name MUST be + ignored. Due to the case-insensitivity of header + names, \"foo\" and \"Foo\" are considered equivalent. + \n When a header is repeated in an HTTP request, + it is implementation-specific behavior as to how + this is represented. Generally, proxies should + follow the guidance from the RFC: https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2.2 + regarding processing a repeated header, with special + handling for \"Set-Cookie\"." + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + type: + default: Exact + description: "Type specifies how to match against + the value of the header. \n Support: Core (Exact) + \n Support: Custom (RegularExpression) \n Since + RegularExpression HeaderMatchType has custom conformance, + implementations can support POSIX, PCRE or any + other dialects of regular expressions. Please + read the implementation's documentation to determine + the supported dialect." + enum: + - Exact + - RegularExpression + type: string + value: + description: Value is the value of HTTP Header to + be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + method: + description: "Method specifies HTTP method matcher. When + specified, this route will be matched only if the request + has the specified method. \n Support: Extended" + enum: + - GET + - HEAD + - POST + - PUT + - DELETE + - CONNECT + - OPTIONS + - TRACE + - PATCH + type: string + path: + default: + type: PathPrefix + value: / + description: Path specifies a HTTP request path matcher. + If this field is not specified, a default prefix match + on the "/" path is provided. + properties: + type: + default: PathPrefix + description: "Type specifies how to match against + the path Value. \n Support: Core (Exact, PathPrefix) + \n Support: Custom (RegularExpression)" + enum: + - Exact + - PathPrefix + - RegularExpression + type: string + value: + default: / + description: Value of the HTTP path to match against. + maxLength: 1024 + type: string + type: object + queryParams: + description: QueryParams specifies HTTP query parameter + matchers. Multiple match values are ANDed together, + meaning, a request must match all the specified query + parameters to select the route. + items: + description: HTTPQueryParamMatch describes how to select + a HTTP route by matching HTTP query parameters. + properties: + name: + description: Name is the name of the HTTP query + param to be matched. This must be an exact string + match. (See https://tools.ietf.org/html/rfc7230#section-2.7.3). + maxLength: 256 + minLength: 1 + type: string + type: + default: Exact + description: "Type specifies how to match against + the value of the query parameter. \n Support: + Extended (Exact) \n Support: Custom (RegularExpression) + \n Since RegularExpression QueryParamMatchType + has custom conformance, implementations can support + POSIX, PCRE or any other dialects of regular expressions. + Please read the implementation's documentation + to determine the supported dialect." + enum: + - Exact + - RegularExpression + type: string + value: + description: Value is the value of HTTP query param + to be matched. + maxLength: 1024 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + maxItems: 8 + type: array + timeouts: + description: "Timeouts defines the timeouts that can be configured + for an HTTP request. \n Support: Core \n " + properties: + backendRequest: + description: "BackendRequest specifies a timeout for an + individual request from the gateway to a backend service. + Typically used in conjunction with automatic retries, + if supported by an implementation. Default is the value + of Request timeout. \n Support: Extended" + format: duration + type: string + request: + description: "Request specifies a timeout for responding + to client HTTP requests, disabled by default. \n For example, + the following rule will timeout if a client request is + taking longer than 10 seconds to complete: \n ``` rules: + - timeouts: request: 10s backendRefs: ... ``` \n Support: + Core" + format: duration + type: string + type: object + type: object + maxItems: 16 + type: array + type: object + status: + description: Status defines the current state of HTTPRoute. + properties: + parents: + description: "Parents is a list of parent resources (usually Gateways) + that are associated with the route, and the status of the route + with respect to each parent. When this route attaches to a parent, + the controller that manages the parent must add an entry to this + list when the controller first sees the route and should update + the entry as appropriate when the route or gateway is modified. + \n Note that parent references that cannot be resolved by an implementation + of this API will not be added to this list. Implementations of this + API can only populate Route status for the Gateways/parent resources + they are responsible for. \n A maximum of 32 Gateways will be represented + in this list. An empty list means the route has not been attached + to any Gateway." + items: + description: RouteParentStatus describes the status of a route with + respect to an associated Parent. + properties: + conditions: + description: "Conditions describes the status of the route with + respect to the Gateway. Note that the route's availability + is also subject to the Gateway's own status conditions and + listener status. \n If the Route's ParentRef specifies an + existing Gateway that supports Routes of this kind AND that + Gateway's controller has sufficient access, then that Gateway's + controller MUST set the \"Accepted\" condition on the Route, + to indicate whether the route has been accepted or rejected + by the Gateway, and why. \n A Route MUST be considered \"Accepted\" + if at least one of the Route's rules is implemented by the + Gateway. \n There are a number of cases where the \"Accepted\" + condition may not be set due to lack of controller visibility, + that includes when: \n * The Route refers to a non-existent + parent. * The Route is of a type that the controller does + not support. * The Route is in a namespace the the controller + does not have access to." + items: + description: "Condition contains details for one aspect of + the current state of this API Resource. --- This struct + is intended for direct use as an array at the field path + .status.conditions. For example, type FooStatus struct{ + \ // Represents the observations of a foo's current state. + \ // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type + \ // +patchStrategy=merge // +listType=map // + +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` + \n // other fields }" + 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 + maxItems: 8 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + controllerName: + description: "ControllerName is a domain/path string that indicates + the name of the controller that wrote this status. This corresponds + with the controllerName field on GatewayClass. \n Example: + \"example.net/gateway-controller\". \n The format of this + field is DOMAIN \"/\" PATH, where DOMAIN and PATH are valid + Kubernetes names (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). + \n Controllers MUST populate this field when writing status. + Controllers should ensure that entries to status populated + with their ControllerName are cleaned up when they are no + longer necessary." + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + parentRef: + description: ParentRef corresponds with a ParentRef in the spec + that this RouteParentStatus struct describes the status of. + properties: + group: + default: policy.linkerd.io + description: "Group is the group of the referent. \n Support: + Core" + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Gateway + description: "Kind is kind of the referent. \n Support: + Core (Gateway) Support: Custom (Other Resources)" + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: "Name is the name of the referent. \n Support: + Core" + maxLength: 253 + minLength: 1 + type: string + namespace: + description: "Namespace is the namespace of the referent. + When unspecified (or empty string), this refers to the + local namespace of the Route. \n Support: Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: "Port is the network port this Route targets. + It can be interpreted differently based on the type of + parent resource. \n When the parent resource is a Gateway, + this targets all listeners listening on the specified + port that also support this kind of Route(and select this + Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to + a specific port as opposed to a listener(s) whose port(s) + may be changed. When both Port and SectionName are specified, + the name and port of the selected listener must match + both specified values. \n Implementations MAY choose to + support other parent resources. Implementations supporting + other types of parent resources MUST clearly document + how/if Port is interpreted. \n For the purpose of status, + an attachment is considered successful as long as the + parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them + by Route kind, namespace, or hostname. If 1 of 2 Gateway + listeners accept attachment from the referencing Route, + the Route MUST be considered successfully attached. If + no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + \n Support: Extended \n " + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: "SectionName is the name of a section within + the target resource. In the following resources, SectionName + is interpreted as the following: \n * Gateway: Listener + Name. When both Port (experimental) and SectionName are + specified, the name and port of the selected listener + must match both specified values. \n Implementations MAY + choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName + is interpreted. \n When unspecified (empty string), this + will reference the entire resource. For the purpose of + status, an attachment is considered successful if at least + one section in the parent resource accepts it. For example, + Gateway listeners can restrict which Routes can attach + to them by Route kind, namespace, or hostname. If 1 of + 2 Gateway listeners accept attachment from the referencing + Route, the Route MUST be considered successfully attached. + If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + \n Support: Core" + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - name + type: object + required: + - controllerName + - parentRef + type: object + maxItems: 32 + type: array + required: + - parents + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/charts/linkerd/linkerd-crds/2024.8.3/templates/policy/meshtls-authentication.yaml b/charts/linkerd/linkerd-crds/2024.8.3/templates/policy/meshtls-authentication.yaml new file mode 100644 index 0000000000..58ee815f59 --- /dev/null +++ b/charts/linkerd/linkerd-crds/2024.8.3/templates/policy/meshtls-authentication.yaml @@ -0,0 +1,87 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: meshtlsauthentications.policy.linkerd.io + annotations: + {{ include "partials.annotations.created-by" . }} + labels: + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + linkerd.io/control-plane-ns: {{.Release.Namespace}} +spec: + group: policy.linkerd.io + scope: Namespaced + names: + kind: MeshTLSAuthentication + plural: meshtlsauthentications + singular: meshtlsauthentication + shortNames: [meshtlsauthn] + versions: + - name: v1alpha1 + served: true + storage: true + schema: + openAPIV3Schema: + type: object + required: [spec] + properties: + spec: + description: >- + MeshTLSAuthentication defines a list of authenticated client IDs + to be referenced by an `AuthorizationPolicy`. If a client + connection has the mutually-authenticated identity that matches + ANY of the of the provided identities, the connection is + considered authenticated. + type: object + oneOf: + - required: [identities] + - required: [identityRefs] + properties: + identities: + description: >- + Authorizes clients with the provided proxy identity strings + (as provided via MTLS) + + The `*` prefix can be used to match all identities in + a domain. An identity string of `*` indicates that + all authentication clients are authorized. + type: array + minItems: 1 + items: + type: string + identityRefs: + type: array + minItems: 1 + items: + type: object + required: + - kind + properties: + group: + description: >- + Group is the group of the referent. When empty, the + Kubernetes core API group is inferred." + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: >- + Kind is the kind of the referent. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: >- + Name is the name of the referent. When unspecified, + this refers to all resources of the specified Group + and Kind in the specified namespace. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: >- + Name is the name of the referent. When unspecified, + this authentication refers to the local namespace. + maxLength: 253 + type: string diff --git a/charts/linkerd/linkerd-crds/2024.8.3/templates/policy/network-authentication.yaml b/charts/linkerd/linkerd-crds/2024.8.3/templates/policy/network-authentication.yaml new file mode 100644 index 0000000000..cef15d3c40 --- /dev/null +++ b/charts/linkerd/linkerd-crds/2024.8.3/templates/policy/network-authentication.yaml @@ -0,0 +1,53 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: networkauthentications.policy.linkerd.io + annotations: + {{ include "partials.annotations.created-by" . }} + labels: + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + linkerd.io/control-plane-ns: {{.Release.Namespace}} +spec: + group: policy.linkerd.io + scope: Namespaced + names: + kind: NetworkAuthentication + plural: networkauthentications + singular: networkauthentication + shortNames: [netauthn, networkauthn] + versions: + - name: v1alpha1 + served: true + storage: true + schema: + openAPIV3Schema: + type: object + required: [spec] + properties: + spec: + description: >- + NetworkAuthentication defines a list of authenticated client + networks to be referenced by an `AuthorizationPolicy`. If a + client connection originates from ANY of the of the provided + networks, the connection is considered authenticated. + type: object + required: [networks] + properties: + networks: + type: array + items: + type: object + required: [cidr] + properties: + cidr: + description: >- + The CIDR of the network to be authorized. + type: string + except: + description: >- + A list of IP networks/addresses not to be included in + the above `cidr`. + type: array + items: + type: string diff --git a/charts/linkerd/linkerd-crds/2024.8.3/templates/policy/server-authorization.yaml b/charts/linkerd/linkerd-crds/2024.8.3/templates/policy/server-authorization.yaml new file mode 100644 index 0000000000..33fb659002 --- /dev/null +++ b/charts/linkerd/linkerd-crds/2024.8.3/templates/policy/server-authorization.yaml @@ -0,0 +1,266 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: serverauthorizations.policy.linkerd.io + annotations: + {{ include "partials.annotations.created-by" . }} + labels: + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + linkerd.io/control-plane-ns: {{.Release.Namespace}} +spec: + group: policy.linkerd.io + scope: Namespaced + names: + kind: ServerAuthorization + plural: serverauthorizations + singular: serverauthorization + shortNames: [saz, serverauthz, srvauthz] + versions: + - name: v1alpha1 + served: true + storage: false + deprecated: true + deprecationWarning: "policy.linkerd.io/v1alpha1 ServerAuthorization is deprecated; use policy.linkerd.io/v1beta1 ServerAuthorization" + schema: + openAPIV3Schema: + type: object + required: [spec] + properties: + spec: + description: >- + Authorizes clients to communicate with Linkerd-proxied servers. + type: object + required: [server, client] + properties: + server: + description: >- + Identifies servers in the same namespace for which this + authorization applies. + + Only one of `name` or `selector` may be specified. + type: object + oneOf: + - required: [name] + - required: [selector] + properties: + name: + description: References a `Server` instance by name + type: string + pattern: '^[a-z0-9]([-a-z0-9]*[a-z0-9])?$' + selector: + description: >- + A label query over servers on which this authorization applies. + type: object + properties: + matchLabels: + type: object + x-kubernetes-preserve-unknown-fields: true + matchExpressions: + type: array + items: + type: object + required: [key, operator] + properties: + key: + type: string + operator: + type: string + enum: [In, NotIn, Exists, DoesNotExist] + values: + type: array + items: + type: string + client: + description: Describes clients authorized to access a server. + type: object + properties: + networks: + description: >- + Limits the client IP addresses to which this + authorization applies. If unset, the server chooses a + default (typically, all IPs or the cluster's pod + network). + type: array + items: + type: object + required: [cidr] + properties: + cidr: + type: string + except: + type: array + items: + type: string + unauthenticated: + description: >- + Authorizes unauthenticated clients to access a server. + type: boolean + meshTLS: + type: object + properties: + unauthenticatedTLS: + type: boolean + description: >- + Indicates that no client identity is required for + communication. + + This is mostly important for the identity + controller, which must terminate TLS connections + from clients that do not yet have a certificate. + identities: + description: >- + Authorizes clients with the provided proxy identity + strings (as provided via MTLS) + + The `*` prefix can be used to match all identities in + a domain. An identity string of `*` indicates that + all authentication clients are authorized. + type: array + items: + type: string + pattern: '^(\*|[a-z0-9]([-a-z0-9]*[a-z0-9])?)(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$' + serviceAccounts: + description: >- + Authorizes clients with the provided proxy identity + service accounts (as provided via MTLS) + type: array + items: + type: object + required: [name] + properties: + name: + description: The ServiceAccount's name. + type: string + pattern: '^[a-z0-9]([-a-z0-9]*[a-z0-9])?$' + namespace: + description: >- + The ServiceAccount's namespace. If unset, the + authorization's namespace is used. + type: string + pattern: '^[a-z0-9]([-a-z0-9]*[a-z0-9])?$' + - name: v1beta1 + served: true + storage: true + schema: + openAPIV3Schema: + type: object + required: [spec] + properties: + spec: + description: >- + Authorizes clients to communicate with Linkerd-proxied servers. + type: object + required: [server, client] + properties: + server: + description: >- + Identifies servers in the same namespace for which this + authorization applies. + + Only one of `name` or `selector` may be specified. + type: object + oneOf: + - required: [name] + - required: [selector] + properties: + name: + description: References a `Server` instance by name + type: string + pattern: '^[a-z0-9]([-a-z0-9]*[a-z0-9])?$' + selector: + description: >- + A label query over servers on which this authorization applies. + type: object + properties: + matchLabels: + type: object + x-kubernetes-preserve-unknown-fields: true + matchExpressions: + type: array + items: + type: object + required: [key, operator] + properties: + key: + type: string + operator: + type: string + enum: [In, NotIn, Exists, DoesNotExist] + values: + type: array + items: + type: string + client: + description: Describes clients authorized to access a server. + type: object + properties: + networks: + description: >- + Limits the client IP addresses to which this + authorization applies. If unset, the server chooses a + default (typically, all IPs or the cluster's pod + network). + type: array + items: + type: object + required: [cidr] + properties: + cidr: + type: string + except: + type: array + items: + type: string + unauthenticated: + description: >- + Authorizes unauthenticated clients to access a server. + type: boolean + meshTLS: + type: object + properties: + unauthenticatedTLS: + type: boolean + description: >- + Indicates that no client identity is required for + communication. + + This is mostly important for the identity + controller, which must terminate TLS connections + from clients that do not yet have a certificate. + identities: + description: >- + Authorizes clients with the provided proxy identity + strings (as provided via MTLS) + + The `*` prefix can be used to match all identities in + a domain. An identity string of `*` indicates that + all authentication clients are authorized. + type: array + items: + type: string + pattern: '^(\*|[a-z0-9]([-a-z0-9]*[a-z0-9])?)(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$' + serviceAccounts: + description: >- + Authorizes clients with the provided proxy identity + service accounts (as provided via MTLS) + type: array + items: + type: object + required: [name] + properties: + name: + description: The ServiceAccount's name. + type: string + pattern: '^[a-z0-9]([-a-z0-9]*[a-z0-9])?$' + namespace: + description: >- + The ServiceAccount's namespace. If unset, the + authorization's namespace is used. + type: string + pattern: '^[a-z0-9]([-a-z0-9]*[a-z0-9])?$' + additionalPrinterColumns: + - name: Server + type: string + description: The server that this grants access to + jsonPath: .spec.server.name diff --git a/charts/linkerd/linkerd-crds/2024.8.3/templates/policy/server.yaml b/charts/linkerd/linkerd-crds/2024.8.3/templates/policy/server.yaml new file mode 100644 index 0000000000..0af41224a0 --- /dev/null +++ b/charts/linkerd/linkerd-crds/2024.8.3/templates/policy/server.yaml @@ -0,0 +1,319 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: servers.policy.linkerd.io + annotations: + {{ include "partials.annotations.created-by" . }} + labels: + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + linkerd.io/control-plane-ns: {{.Release.Namespace}} +spec: + group: policy.linkerd.io + names: + kind: Server + plural: servers + singular: server + shortNames: [srv] + scope: Namespaced + versions: + - name: v1alpha1 + served: true + storage: false + deprecated: true + deprecationWarning: "policy.linkerd.io/v1alpha1 Server is deprecated; use policy.linkerd.io/v1beta1 Server" + schema: + openAPIV3Schema: + type: object + required: [spec] + properties: + spec: + type: object + required: + - podSelector + - port + properties: + podSelector: + type: object + description: >- + Selects pods in the same namespace. + oneOf: + - required: [matchExpressions] + - required: [matchLabels] + properties: + matchLabels: + type: object + x-kubernetes-preserve-unknown-fields: true + matchExpressions: + type: array + items: + type: object + required: [key, operator] + properties: + key: + type: string + operator: + type: string + enum: [In, NotIn, Exists, DoesNotExist] + values: + type: array + items: + type: string + port: + description: >- + A port name or number. Must exist in a pod spec. + x-kubernetes-int-or-string: true + proxyProtocol: + description: >- + Configures protocol discovery for inbound connections. + + Supersedes the `config.linkerd.io/opaque-ports` annotation. + type: string + default: unknown + - name: v1beta1 + served: true + storage: false + deprecated: true + deprecationWarning: "policy.linkerd.io/v1alpha1 Server is deprecated; use policy.linkerd.io/v1beta3 Server" + schema: + openAPIV3Schema: + type: object + required: [spec] + properties: + spec: + type: object + required: + - podSelector + - port + properties: + podSelector: + type: object + description: >- + Selects pods in the same namespace. + + The result of matchLabels and matchExpressions are ANDed. + Selects all if empty. + properties: + matchLabels: + type: object + x-kubernetes-preserve-unknown-fields: true + matchExpressions: + type: array + items: + type: object + required: [key, operator] + properties: + key: + type: string + operator: + type: string + enum: [In, NotIn, Exists, DoesNotExist] + values: + type: array + items: + type: string + port: + description: >- + A port name or number. Must exist in a pod spec. + x-kubernetes-int-or-string: true + proxyProtocol: + description: >- + Configures protocol discovery for inbound connections. + + Supersedes the `config.linkerd.io/opaque-ports` annotation. + type: string + default: unknown + additionalPrinterColumns: + - name: Port + type: string + description: The port the server is listening on + jsonPath: .spec.port + - name: Protocol + type: string + description: The protocol of the server + jsonPath: .spec.proxyProtocol + - name: v1beta2 + served: true + storage: false + schema: + openAPIV3Schema: + type: object + required: [spec] + properties: + spec: + type: object + required: + - port + oneOf: + - required: [podSelector] + - required: [externalWorkloadSelector] + properties: + podSelector: + type: object + description: >- + Selects pods in the same namespace. + + The result of matchLabels and matchExpressions are ANDed. + Selects all if empty. + properties: + matchLabels: + type: object + x-kubernetes-preserve-unknown-fields: true + matchExpressions: + type: array + items: + type: object + required: [key, operator] + properties: + key: + type: string + operator: + type: string + enum: [In, NotIn, Exists, DoesNotExist] + values: + type: array + items: + type: string + externalWorkloadSelector: + type: object + description: >- + Selects ExternalWorkloads in the same namespace. + + The result of matchLabels and matchExpressions are ANDed. + Selects all if empty. + properties: + matchLabels: + type: object + x-kubernetes-preserve-unknown-fields: true + matchExpressions: + type: array + items: + type: object + required: [key, operator] + properties: + key: + type: string + operator: + type: string + enum: [In, NotIn, Exists, DoesNotExist] + values: + type: array + items: + type: string + port: + description: >- + A port name or number. Must exist in a pod spec. + x-kubernetes-int-or-string: true + proxyProtocol: + description: >- + Configures protocol discovery for inbound connections. + + Supersedes the `config.linkerd.io/opaque-ports` annotation. + type: string + default: unknown + additionalPrinterColumns: + - name: Port + type: string + description: The port the server is listening on + jsonPath: .spec.port + - name: Protocol + type: string + description: The protocol of the server + jsonPath: .spec.proxyProtocol + - name: v1beta3 + served: true + storage: true + schema: + openAPIV3Schema: + type: object + required: [spec] + properties: + spec: + type: object + required: + - port + oneOf: + - required: [podSelector] + - required: [externalWorkloadSelector] + properties: + accessPolicy: + type: string + default: deny + description: >- + Default access policy to apply when the traffic doesn't match any of the policy rules. + podSelector: + type: object + description: >- + Selects pods in the same namespace. + + The result of matchLabels and matchExpressions are ANDed. + Selects all if empty. + properties: + matchLabels: + type: object + x-kubernetes-preserve-unknown-fields: true + matchExpressions: + type: array + items: + type: object + required: [key, operator] + properties: + key: + type: string + operator: + type: string + enum: [In, NotIn, Exists, DoesNotExist] + values: + type: array + items: + type: string + externalWorkloadSelector: + type: object + description: >- + Selects ExternalWorkloads in the same namespace. + + The result of matchLabels and matchExpressions are ANDed. + Selects all if empty. + properties: + matchLabels: + type: object + x-kubernetes-preserve-unknown-fields: true + matchExpressions: + type: array + items: + type: object + required: [key, operator] + properties: + key: + type: string + operator: + type: string + enum: [In, NotIn, Exists, DoesNotExist] + values: + type: array + items: + type: string + port: + description: >- + A port name or number. Must exist in a pod spec. + x-kubernetes-int-or-string: true + proxyProtocol: + description: >- + Configures protocol discovery for inbound connections. + + Supersedes the `config.linkerd.io/opaque-ports` annotation. + type: string + default: unknown + additionalPrinterColumns: + - name: Port + type: string + description: The port the server is listening on + jsonPath: .spec.port + - name: Protocol + type: string + description: The protocol of the server + jsonPath: .spec.proxyProtocol + - name: Access Policy + type: string + description: The default access policy applied when the traffic doesn't match any of the policy rules + jsonPath: .spec.accessPolicy diff --git a/charts/linkerd/linkerd-crds/2024.8.3/templates/serviceprofile.yaml b/charts/linkerd/linkerd-crds/2024.8.3/templates/serviceprofile.yaml new file mode 100644 index 0000000000..ad12c96a3a --- /dev/null +++ b/charts/linkerd/linkerd-crds/2024.8.3/templates/serviceprofile.yaml @@ -0,0 +1,274 @@ +--- +### +### Service Profile CRD +### +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: serviceprofiles.linkerd.io + annotations: + {{ include "partials.annotations.created-by" . }} + labels: + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + linkerd.io/control-plane-ns: {{.Release.Namespace}} +spec: + group: linkerd.io + versions: + - name: v1alpha1 + served: true + storage: false + schema: + openAPIV3Schema: + type: object + properties: + spec: + type: object + description: Spec is the custom resource spec + required: + - routes + properties: + dstOverrides: + type: array + required: + - authority + - weight + items: + type: object + description: WeightedDst is a weighted alternate destination. + properties: + authority: + type: string + weight: + x-kubernetes-int-or-string: true + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + opaquePorts: + type: array + items: + type: string + retryBudget: + type: object + required: + - minRetriesPerSecond + - retryRatio + - ttl + description: RetryBudget describes the maximum number of retries that should be issued to this service. + properties: + minRetriesPerSecond: + format: int32 + type: integer + retryRatio: + type: number + format: float + ttl: + type: string + routes: + type: array + items: + type: object + description: RouteSpec specifies a Route resource. + required: + - condition + - name + properties: + condition: + type: object + description: RequestMatch describes the conditions under which to match a Route. + properties: + pathRegex: + type: string + method: + type: string + all: + type: array + items: + type: object + x-kubernetes-preserve-unknown-fields: true + any: + type: array + items: + type: object + x-kubernetes-preserve-unknown-fields: true + not: + type: array + items: + type: object + x-kubernetes-preserve-unknown-fields: true + isRetryable: + type: boolean + name: + type: string + timeout: + type: string + responseClasses: + type: array + items: + type: object + required: + - condition + description: ResponseClass describes how to classify a response (e.g. success or failures). + properties: + condition: + type: object + description: ResponseMatch describes the conditions under + which to classify a response. + properties: + all: + type: array + items: + type: object + x-kubernetes-preserve-unknown-fields: true + any: + type: array + items: + type: object + x-kubernetes-preserve-unknown-fields: true + not: + type: object + x-kubernetes-preserve-unknown-fields: true + status: + type: object + description: Range describes a range of integers (e.g. status codes). + properties: + max: + format: int32 + type: integer + min: + format: int32 + type: integer + isFailure: + type: boolean + - name: v1alpha2 + served: true + storage: true + schema: + openAPIV3Schema: + type: object + properties: + spec: + type: object + description: Spec is the custom resource spec + properties: + dstOverrides: + type: array + required: + - authority + - weight + items: + type: object + description: WeightedDst is a weighted alternate destination. + properties: + authority: + type: string + weight: + x-kubernetes-int-or-string: true + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + opaquePorts: + type: array + items: + type: string + retryBudget: + type: object + required: + - minRetriesPerSecond + - retryRatio + - ttl + description: RetryBudget describes the maximum number of retries that should be issued to this service. + properties: + minRetriesPerSecond: + format: int32 + type: integer + retryRatio: + type: number + format: float + ttl: + type: string + routes: + type: array + items: + type: object + description: RouteSpec specifies a Route resource. + required: + - condition + - name + properties: + condition: + type: object + description: RequestMatch describes the conditions under which to match a Route. + properties: + pathRegex: + type: string + method: + type: string + all: + type: array + items: + type: object + x-kubernetes-preserve-unknown-fields: true + any: + type: array + items: + type: object + x-kubernetes-preserve-unknown-fields: true + not: + type: array + items: + type: object + x-kubernetes-preserve-unknown-fields: true + isRetryable: + type: boolean + name: + type: string + timeout: + type: string + responseClasses: + type: array + items: + type: object + required: + - condition + description: ResponseClass describes how to classify a response (e.g. success or failures). + properties: + condition: + type: object + description: ResponseMatch describes the conditions under + which to classify a response. + properties: + all: + type: array + items: + type: object + x-kubernetes-preserve-unknown-fields: true + any: + type: array + items: + type: object + x-kubernetes-preserve-unknown-fields: true + not: + type: object + x-kubernetes-preserve-unknown-fields: true + status: + type: object + description: Range describes a range of integers (e.g. status codes). + properties: + max: + format: int32 + type: integer + min: + format: int32 + type: integer + isFailure: + type: boolean + scope: Namespaced + preserveUnknownFields: false + names: + plural: serviceprofiles + singular: serviceprofile + kind: ServiceProfile + shortNames: + - sp diff --git a/charts/linkerd/linkerd-crds/2024.8.3/templates/workload/external-workload.yaml b/charts/linkerd/linkerd-crds/2024.8.3/templates/workload/external-workload.yaml new file mode 100644 index 0000000000..715e779aa1 --- /dev/null +++ b/charts/linkerd/linkerd-crds/2024.8.3/templates/workload/external-workload.yaml @@ -0,0 +1,303 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: externalworkloads.workload.linkerd.io + annotations: + {{ include "partials.annotations.created-by" . }} + labels: + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + linkerd.io/control-plane-ns: {{.Release.Namespace}} +spec: + group: workload.linkerd.io + names: + categories: + - external + kind: ExternalWorkload + listKind: ExternalWorkloadList + plural: externalworkloads + singular: externalworkload + scope: Namespaced + versions: + - name: v1alpha1 + served: true + storage: false + schema: + openAPIV3Schema: + description: >- + An ExternalWorkload describes a single workload (i.e. a deployable unit) external + to the cluster that should be enrolled in the mesh. + type: object + required: [spec] + properties: + apiVerson: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + meshTls: + description: meshTls describes TLS settings associated with an + external workload. + properties: + identity: + type: string + description: identity of the workload. Corresponds to the + identity used in the workload's certificate. It is used + by peers to perform verification in the mTLS handshake. + minLength: 1 + maxLength: 253 + serverName: + type: string + description: serverName is the name of the workload in DNS + format. It is used by the workload to terminate TLS using + SNI. + minLength: 1 + maxLength: 253 + type: object + required: + - identity + - serverName + ports: + type: array + description: ports describes a list of ports exposed by the + workload + items: + properties: + name: + type: string + description: name must be an IANA_SVC_NAME and unique + within the ports set. Each named port can be referred + to by services. + port: + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + description: protocol exposed by the port. Must be UDP or + TCP. Defaults to TCP. + type: string + default: "TCP" + type: object + required: + - port + workloadIPs: + type: array + description: workloadIPs contains a list of IP addresses that + can be used to send traffic to the workload. + items: + type: object + properties: + ip: + type: string + # TODO: relax this in the future when ipv6 is supported + # an external workload (like a pod) should only + # support 2 interfaces + maxItems: 1 + type: object + required: + - meshTls + status: + type: object + properties: + conditions: + type: array + items: + type: object + properties: + lastProbeTime: + description: lastProbeTime is the last time the + healthcheck endpoint was probed. + format: date-time + type: string + lastTransitionTime: + description: lastTransitionTime is the last time the + condition transitioned from one status to another. + format: date-time + type: string + status: + description: status of the condition (one of True, False, Unknown) + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of the condition in CamelCase or in + foo.example.com/CamelCase. + 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 + 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 + message: + description: message is a human readable message + indicating details about the transition. This may be an + empty string. + maxLength: 32768 + type: string + required: + - status + - type + additionalPrinterColumns: + - jsonPath: .spec.meshTls.identity + name: Identity + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - name: v1beta1 + served: true + storage: true + subresources: + status: {} + schema: + openAPIV3Schema: + description: >- + An ExternalWorkload describes a single workload (i.e. a deployable unit) external + to the cluster that should be enrolled in the mesh. + type: object + required: [spec] + properties: + apiVerson: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + meshTLS: + description: meshTLS describes TLS settings associated with an + external workload. + properties: + identity: + type: string + description: identity of the workload. Corresponds to the + identity used in the workload's certificate. It is used + by peers to perform verification in the mTLS handshake. + minLength: 1 + maxLength: 253 + serverName: + type: string + description: serverName is the name of the workload in DNS + format. It is used by the workload to terminate TLS using + SNI. + minLength: 1 + maxLength: 253 + type: object + required: + - identity + - serverName + ports: + type: array + description: ports describes a list of ports exposed by the + workload + items: + properties: + name: + type: string + description: name must be an IANA_SVC_NAME and unique + within the ports set. Each named port can be referred + to by services. + port: + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + description: protocol exposed by the port. Must be UDP or + TCP. Defaults to TCP. + type: string + default: "TCP" + type: object + required: + - port + workloadIPs: + type: array + description: workloadIPs contains a list of IP addresses that + can be used to send traffic to the workload. + items: + type: object + properties: + ip: + type: string + # TODO: relax this in the future when ipv6 is supported + # an external workload (like a pod) should only + # support 2 interfaces + maxItems: 1 + type: object + required: + - meshTLS + status: + type: object + properties: + conditions: + type: array + items: + type: object + properties: + lastProbeTime: + description: lastProbeTime is the last time the + healthcheck endpoint was probed. + format: date-time + type: string + lastTransitionTime: + description: lastTransitionTime is the last time the + condition transitioned from one status to another. + format: date-time + type: string + status: + description: status of the condition (one of True, False, Unknown) + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of the condition in CamelCase or in + foo.example.com/CamelCase. + 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 + 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 + message: + description: message is a human readable message + indicating details about the transition. This may be an + empty string. + maxLength: 32768 + type: string + required: + - status + - type + additionalPrinterColumns: + - jsonPath: .spec.meshTLS.identity + name: Identity + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date diff --git a/charts/linkerd/linkerd-crds/2024.8.3/values.yaml b/charts/linkerd/linkerd-crds/2024.8.3/values.yaml new file mode 100644 index 0000000000..362145168d --- /dev/null +++ b/charts/linkerd/linkerd-crds/2024.8.3/values.yaml @@ -0,0 +1 @@ +enableHttpRoutes: true diff --git a/charts/redpanda/redpanda/5.9.2/.helmignore b/charts/redpanda/redpanda/5.9.2/.helmignore new file mode 100644 index 0000000000..d5bb5e6ba6 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/.helmignore @@ -0,0 +1,28 @@ +# 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 +README.md.gotmpl +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ + +*.go +testdata/ +ci/ diff --git a/charts/redpanda/redpanda/5.9.2/Chart.lock b/charts/redpanda/redpanda/5.9.2/Chart.lock new file mode 100644 index 0000000000..7ef309e93e --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/Chart.lock @@ -0,0 +1,9 @@ +dependencies: +- name: console + repository: https://charts.redpanda.com + version: 0.7.29 +- name: connectors + repository: https://charts.redpanda.com + version: 0.1.12 +digest: sha256:ed0641d28d6174d865544a5948fdaddb3b766a27473b07b0cca979efc6c3c024 +generated: "2024-08-28T15:46:40.176857+02:00" diff --git a/charts/redpanda/redpanda/5.9.2/Chart.yaml b/charts/redpanda/redpanda/5.9.2/Chart.yaml new file mode 100644 index 0000000000..89bae8a059 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/Chart.yaml @@ -0,0 +1,40 @@ +annotations: + artifacthub.io/images: | + - name: redpanda + image: docker.redpanda.com/redpandadata/redpanda:v24.2.3 + - name: busybox + image: busybox:latest + - name: mintel/docker-alpine-bash-curl-jq + image: mintel/docker-alpine-bash-curl-jq:latest + artifacthub.io/license: Apache-2.0 + artifacthub.io/links: | + - name: Documentation + url: https://docs.redpanda.com + - name: "Helm (>= 3.10.0)" + url: https://helm.sh/docs/intro/install/ + catalog.cattle.io/certified: partner + catalog.cattle.io/display-name: Redpanda + catalog.cattle.io/kube-version: '>=1.21-0' + catalog.cattle.io/release-name: redpanda +apiVersion: v2 +appVersion: v24.2.3 +dependencies: +- condition: console.enabled + name: console + repository: file://./charts/console + version: '>=0.5 <1.0' +- condition: connectors.enabled + name: connectors + repository: file://./charts/connectors + version: '>=0.1.2 <1.0' +description: Redpanda is the real-time engine for modern apps. +icon: file://assets/icons/redpanda.svg +kubeVersion: '>=1.21-0' +maintainers: +- name: redpanda-data + url: https://github.com/orgs/redpanda-data/people +name: redpanda +sources: +- https://github.com/redpanda-data/helm-charts +type: application +version: 5.9.2 diff --git a/charts/redpanda/redpanda/5.9.2/LICENSE b/charts/redpanda/redpanda/5.9.2/LICENSE new file mode 100644 index 0000000000..261eeb9e9f --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/charts/redpanda/redpanda/5.9.2/README.md b/charts/redpanda/redpanda/5.9.2/README.md new file mode 100644 index 0000000000..a4678a0e03 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/README.md @@ -0,0 +1,1300 @@ +# Redpanda Helm Chart Specification +--- +description: Find the default values and descriptions of settings in the Redpanda Helm chart. +--- + +![Version: 5.9.2](https://img.shields.io/badge/Version-5.9.2-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v24.2.3](https://img.shields.io/badge/AppVersion-v24.2.3-informational?style=flat-square) + +This page describes the official Redpanda Helm Chart. In particular, this page describes the contents of the chart’s [`values.yaml` file](https://github.com/redpanda-data/helm-charts/blob/main/charts/redpanda/values.yaml). Each of the settings is listed and described on this page, along with any default values. + +For instructions on how to install and use the chart, including how to override and customize the chart’s values, refer to the [deployment documentation](https://docs.redpanda.com/docs/deploy/deployment-option/self-hosted/kubernetes/kubernetes-deploy/). + +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) + +## Source Code + +* + +## Requirements + +Kubernetes: `^1.21.0-0` + +| Repository | Name | Version | +|------------|------|---------| +| https://charts.redpanda.com | connectors | >=0.1.2 <1.0 | +| https://charts.redpanda.com | console | >=0.5 <1.0 | + +## Settings + +### [affinity](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=affinity) + +Affinity constraints for scheduling Pods, can override this for StatefulSets and Jobs. For details, see the [Kubernetes documentation](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity). + +**Default:** `{}` + +### [auditLogging](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=auditLogging) + +Audit logging for a redpanda cluster, must have enabled sasl and have one kafka listener supporting sasl authentication for audit logging to work. Note this feature is only available for redpanda versions >= v23.3.0. + +**Default:** + +``` +{"clientMaxBufferSize":16777216,"enabled":false,"enabledEventTypes":null,"excludedPrincipals":null,"excludedTopics":null,"listener":"internal","partitions":12,"queueDrainIntervalMs":500,"queueMaxBufferSizePerShard":1048576,"replicationFactor":null} +``` + +### [auditLogging.clientMaxBufferSize](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=auditLogging.clientMaxBufferSize) + +Defines the number of bytes (in bytes) allocated by the internal audit client for audit messages. + +**Default:** `16777216` + +### [auditLogging.enabled](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=auditLogging.enabled) + +Enable or disable audit logging, for production clusters we suggest you enable, however, this will only work if you also enable sasl and a listener with sasl enabled. + +**Default:** `false` + +### [auditLogging.enabledEventTypes](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=auditLogging.enabledEventTypes) + +Event types that should be captured by audit logs, default is [`admin`, `authenticate`, `management`]. + +**Default:** `nil` + +### [auditLogging.excludedPrincipals](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=auditLogging.excludedPrincipals) + +List of principals to exclude from auditing, default is null. + +**Default:** `nil` + +### [auditLogging.excludedTopics](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=auditLogging.excludedTopics) + +List of topics to exclude from auditing, default is null. + +**Default:** `nil` + +### [auditLogging.listener](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=auditLogging.listener) + +Kafka listener name, note that it must have `authenticationMethod` set to `sasl`. For external listeners, use the external listener name, such as `default`. + +**Default:** `"internal"` + +### [auditLogging.partitions](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=auditLogging.partitions) + +Integer value defining the number of partitions used by a newly created audit topic. + +**Default:** `12` + +### [auditLogging.queueDrainIntervalMs](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=auditLogging.queueDrainIntervalMs) + +In ms, frequency in which per shard audit logs are batched to client for write to audit log. + +**Default:** `500` + +### [auditLogging.queueMaxBufferSizePerShard](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=auditLogging.queueMaxBufferSizePerShard) + +Defines the maximum amount of memory used (in bytes) by the audit buffer in each shard. + +**Default:** `1048576` + +### [auditLogging.replicationFactor](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=auditLogging.replicationFactor) + +Defines the replication factor for a newly created audit log topic. This configuration applies only to the audit log topic and may be different from the cluster or other topic configurations. This cannot be altered for existing audit log topics. Setting this value is optional. If a value is not provided, Redpanda will use the `internal_topic_replication_factor cluster` config value. Default is `null` + +**Default:** `nil` + +### [auth](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=auth) + +Authentication settings. For details, see the [SASL documentation](https://docs.redpanda.com/docs/manage/kubernetes/security/sasl-kubernetes/). + +**Default:** + +``` +{"sasl":{"enabled":false,"mechanism":"SCRAM-SHA-512","secretRef":"redpanda-users","users":[]}} +``` + +### [auth.sasl.enabled](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=auth.sasl.enabled) + +Enable SASL authentication. If you enable SASL authentication, you must provide a Secret in `auth.sasl.secretRef`. + +**Default:** `false` + +### [auth.sasl.mechanism](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=auth.sasl.mechanism) + +The authentication mechanism to use for the superuser. Options are `SCRAM-SHA-256` and `SCRAM-SHA-512`. + +**Default:** `"SCRAM-SHA-512"` + +### [auth.sasl.secretRef](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=auth.sasl.secretRef) + +A Secret that contains your superuser credentials. For details, see the [SASL documentation](https://docs.redpanda.com/docs/manage/kubernetes/security/sasl-kubernetes/#use-secrets). + +**Default:** `"redpanda-users"` + +### [auth.sasl.users](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=auth.sasl.users) + +Optional list of superusers. These superusers will be created in the Secret whose name is defined in `auth.sasl.secretRef`. If this list is empty, the Secret in `auth.sasl.secretRef` must already exist in the cluster before you deploy the chart. Uncomment the sample list if you wish to try adding sample sasl users or override to use your own. + +**Default:** `[]` + +### [clusterDomain](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=clusterDomain) + +Default Kubernetes cluster domain. + +**Default:** `"cluster.local"` + +### [commonLabels](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=commonLabels) + +Additional labels to add to all Kubernetes objects. For example, `my.k8s.service: redpanda`. + +**Default:** `{}` + +### [config](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=config) + +This section contains various settings supported by Redpanda that may not work correctly in a Kubernetes cluster. Changing these settings comes with some risk. Use these settings to customize various Redpanda configurations that are not covered in other sections. These values have no impact on the configuration or behavior of the Kubernetes objects deployed by Helm, and therefore should not be modified for the purpose of configuring those objects. Instead, these settings get passed directly to the Redpanda binary at startup. For descriptions of these properties, see the [configuration documentation](https://docs.redpanda.com/docs/cluster-administration/configuration/). + +**Default:** + +``` +{"cluster":{"default_topic_replications":3},"node":{"crash_loop_limit":5},"pandaproxy_client":{},"rpk":{},"schema_registry_client":{},"tunable":{"compacted_log_segment_size":67108864,"group_topic_partitions":16,"kafka_batch_max_bytes":1048576,"kafka_connection_rate_limit":1000,"log_segment_size":134217728,"log_segment_size_max":268435456,"log_segment_size_min":16777216,"max_compacted_log_segment_size":536870912,"topic_partitions_per_shard":1000}} +``` + +### [config.node](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=config.node) + +Node (broker) properties. See the [property reference documentation](https://docs.redpanda.com/docs/reference/node-properties/). + +**Default:** `{"crash_loop_limit":5}` + +### [config.node.crash_loop_limit](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=config.node.crash_loop_limit) + +Crash loop limit A limit on the number of consecutive times a broker can crash within one hour before its crash-tracking logic is reset. This limit prevents a broker from getting stuck in an infinite cycle of crashes. User can disable this crash loop limit check by the following action: * One hour elapses since the last crash * The node configuration file, redpanda.yaml, is updated via config.cluster or config.node or config.tunable objects * The startup_log file in the node’s data_directory is manually deleted Default to 5 REF: https://docs.redpanda.com/current/reference/node-properties/#crash_loop_limit + +**Default:** `5` + +### [config.tunable](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=config.tunable) + +Tunable cluster properties. + +**Default:** + +``` +{"compacted_log_segment_size":67108864,"group_topic_partitions":16,"kafka_batch_max_bytes":1048576,"kafka_connection_rate_limit":1000,"log_segment_size":134217728,"log_segment_size_max":268435456,"log_segment_size_min":16777216,"max_compacted_log_segment_size":536870912,"topic_partitions_per_shard":1000} +``` + +### [config.tunable.compacted_log_segment_size](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=config.tunable.compacted_log_segment_size) + +See the [property reference documentation](https://docs.redpanda.com/docs/reference/tunable-properties/#compacted_log_segment_size). + +**Default:** `67108864` + +### [config.tunable.group_topic_partitions](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=config.tunable.group_topic_partitions) + +See the [property reference documentation](https://docs.redpanda.com/docs/reference/tunable-properties/#group_topic_partitions). + +**Default:** `16` + +### [config.tunable.kafka_batch_max_bytes](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=config.tunable.kafka_batch_max_bytes) + +See the [property reference documentation](https://docs.redpanda.com/docs/reference/tunable-properties/#kafka_batch_max_bytes). + +**Default:** `1048576` + +### [config.tunable.kafka_connection_rate_limit](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=config.tunable.kafka_connection_rate_limit) + +See the [property reference documentation](https://docs.redpanda.com/docs/reference/cluster-properties/#kafka_connection_rate_limit). + +**Default:** `1000` + +### [config.tunable.log_segment_size](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=config.tunable.log_segment_size) + +See the [property reference documentation](https://docs.redpanda.com/docs/reference/tunable-properties/#log_segment_size). + +**Default:** `134217728` + +### [config.tunable.log_segment_size_max](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=config.tunable.log_segment_size_max) + +See the [property reference documentation](https://docs.redpanda.com/docs/reference/tunable-properties/#log_segment_size_max). + +**Default:** `268435456` + +### [config.tunable.log_segment_size_min](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=config.tunable.log_segment_size_min) + +See the [property reference documentation](https://docs.redpanda.com/docs/reference/tunable-properties/#log_segment_size_min). + +**Default:** `16777216` + +### [config.tunable.max_compacted_log_segment_size](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=config.tunable.max_compacted_log_segment_size) + +See the [property reference documentation](https://docs.redpanda.com/docs/reference/tunable-properties/#max_compacted_log_segment_size). + +**Default:** `536870912` + +### [config.tunable.topic_partitions_per_shard](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=config.tunable.topic_partitions_per_shard) + +See the [property reference documentation](https://docs.redpanda.com/docs/reference/tunable-properties/#topic_partitions_per_shard). + +**Default:** `1000` + +### [connectors](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=connectors) + +Redpanda Managed Connectors settings For a reference of configuration settings, see the [Redpanda Connectors documentation](https://docs.redpanda.com/docs/deploy/deployment-option/cloud/managed-connectors/). + +**Default:** + +``` +{"deployment":{"create":false},"enabled":false,"test":{"create":false}} +``` + +### [console](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=console) + +Redpanda Console settings. For a reference of configuration settings, see the [Redpanda Console documentation](https://docs.redpanda.com/docs/reference/console/config/). + +**Default:** + +``` +{"config":{},"configmap":{"create":false},"deployment":{"create":false},"enabled":true,"secret":{"create":false}} +``` + +### [enterprise](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=enterprise) + +Enterprise (optional) For details, see the [License documentation](https://docs.redpanda.com/docs/get-started/licenses/?platform=kubernetes#redpanda-enterprise-edition). + +**Default:** + +``` +{"license":"","licenseSecretRef":{}} +``` + +### [enterprise.license](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=enterprise.license) + +license (optional). + +**Default:** `""` + +### [enterprise.licenseSecretRef](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=enterprise.licenseSecretRef) + +Secret name and key where the license key is stored. + +**Default:** `{}` + +### [external](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=external) + +External access settings. For details, see the [Networking and Connectivity documentation](https://docs.redpanda.com/docs/manage/kubernetes/networking/networking-and-connectivity/). + +**Default:** + +``` +{"enabled":true,"service":{"enabled":true},"type":"NodePort"} +``` + +### [external.enabled](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=external.enabled) + +Enable external access for each Service. You can toggle external access for each listener in `listeners..external..enabled`. + +**Default:** `true` + +### [external.service](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=external.service) + +Service allows you to manage the creation of an external kubernetes service object + +**Default:** `{"enabled":true}` + +### [external.service.enabled](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=external.service.enabled) + +Enabled if set to false will not create the external service type You can still set your cluster with external access but not create the supporting service (NodePort/LoadBalander). Set this to false if you rather manage your own service. + +**Default:** `true` + +### [external.type](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=external.type) + +External access type. Only `NodePort` and `LoadBalancer` are supported. If undefined, then advertised listeners will be configured in Redpanda, but the helm chart will not create a Service. You must create a Service manually. Warning: If you use LoadBalancers, you will likely experience higher latency and increased packet loss. NodePort is recommended in cases where latency is a priority. + +**Default:** `"NodePort"` + +### [fullnameOverride](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=fullnameOverride) + +Override `redpanda.fullname` template. + +**Default:** `""` + +### [image](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=image) + +Redpanda Docker image settings. + +**Default:** + +``` +{"pullPolicy":"IfNotPresent","repository":"docker.redpanda.com/redpandadata/redpanda","tag":""} +``` + +### [image.pullPolicy](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=image.pullPolicy) + +The imagePullPolicy. If `image.tag` is 'latest', the default is `Always`. + +**Default:** `"IfNotPresent"` + +### [image.repository](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=image.repository) + +Docker repository from which to pull the Redpanda Docker image. + +**Default:** + +``` +"docker.redpanda.com/redpandadata/redpanda" +``` + +### [image.tag](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=image.tag) + +The Redpanda version. See DockerHub for: [All stable versions](https://hub.docker.com/r/redpandadata/redpanda/tags) and [all unstable versions](https://hub.docker.com/r/redpandadata/redpanda-unstable/tags). + +**Default:** `Chart.appVersion`. + +### [imagePullSecrets](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=imagePullSecrets) + +Pull secrets may be used to provide credentials to image repositories See the [Kubernetes documentation](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/). + +**Default:** `[]` + +### [license_key](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=license_key) + +DEPRECATED Enterprise license key (optional). For details, see the [License documentation](https://docs.redpanda.com/docs/get-started/licenses/?platform=kubernetes#redpanda-enterprise-edition). + +**Default:** `""` + +### [license_secret_ref](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=license_secret_ref) + +DEPRECATED Secret name and secret key where the license key is stored. + +**Default:** `{}` + +### [listeners](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=listeners) + +Listener settings. Override global settings configured above for individual listeners. For details, see the [listeners documentation](https://docs.redpanda.com/docs/manage/kubernetes/networking/configure-listeners/). + +**Default:** + +``` +{"admin":{"external":{"default":{"advertisedPorts":[31644],"port":9645,"tls":{"cert":"external"}}},"port":9644,"tls":{"cert":"default","requireClientAuth":false}},"http":{"authenticationMethod":null,"enabled":true,"external":{"default":{"advertisedPorts":[30082],"authenticationMethod":null,"port":8083,"tls":{"cert":"external","requireClientAuth":false}}},"kafkaEndpoint":"default","port":8082,"tls":{"cert":"default","requireClientAuth":false}},"kafka":{"authenticationMethod":null,"external":{"default":{"advertisedPorts":[31092],"authenticationMethod":null,"port":9094,"tls":{"cert":"external"}}},"port":9093,"tls":{"cert":"default","requireClientAuth":false}},"rpc":{"port":33145,"tls":{"cert":"default","requireClientAuth":false}},"schemaRegistry":{"authenticationMethod":null,"enabled":true,"external":{"default":{"advertisedPorts":[30081],"authenticationMethod":null,"port":8084,"tls":{"cert":"external","requireClientAuth":false}}},"kafkaEndpoint":"default","port":8081,"tls":{"cert":"default","requireClientAuth":false}}} +``` + +### [listeners.admin](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=listeners.admin) + +Admin API listener (only one). + +**Default:** + +``` +{"external":{"default":{"advertisedPorts":[31644],"port":9645,"tls":{"cert":"external"}}},"port":9644,"tls":{"cert":"default","requireClientAuth":false}} +``` + +### [listeners.admin.external](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=listeners.admin.external) + +Optional external access settings. + +**Default:** + +``` +{"default":{"advertisedPorts":[31644],"port":9645,"tls":{"cert":"external"}}} +``` + +### [listeners.admin.external.default](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=listeners.admin.external.default) + +Name of the external listener. + +**Default:** + +``` +{"advertisedPorts":[31644],"port":9645,"tls":{"cert":"external"}} +``` + +### [listeners.admin.external.default.tls](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=listeners.admin.external.default.tls) + +The port advertised to this listener's external clients. List one port if you want to use the same port for each broker (would be the case when using NodePort service). Otherwise, list the port you want to use for each broker in order of StatefulSet replicas. If undefined, `listeners.admin.port` is used. + +**Default:** `{"cert":"external"}` + +### [listeners.admin.port](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=listeners.admin.port) + +The port for both internal and external connections to the Admin API. + +**Default:** `9644` + +### [listeners.admin.tls](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=listeners.admin.tls) + +Optional TLS section (required if global TLS is enabled) + +**Default:** + +``` +{"cert":"default","requireClientAuth":false} +``` + +### [listeners.admin.tls.cert](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=listeners.admin.tls.cert) + +Name of the Certificate used for TLS (must match a Certificate name that is registered in tls.certs). + +**Default:** `"default"` + +### [listeners.admin.tls.requireClientAuth](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=listeners.admin.tls.requireClientAuth) + +If true, the truststore file for this listener is included in the ConfigMap. + +**Default:** `false` + +### [listeners.http](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=listeners.http) + +HTTP API listeners (aka PandaProxy). + +**Default:** + +``` +{"authenticationMethod":null,"enabled":true,"external":{"default":{"advertisedPorts":[30082],"authenticationMethod":null,"port":8083,"tls":{"cert":"external","requireClientAuth":false}}},"kafkaEndpoint":"default","port":8082,"tls":{"cert":"default","requireClientAuth":false}} +``` + +### [listeners.kafka](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=listeners.kafka) + +Kafka API listeners. + +**Default:** + +``` +{"authenticationMethod":null,"external":{"default":{"advertisedPorts":[31092],"authenticationMethod":null,"port":9094,"tls":{"cert":"external"}}},"port":9093,"tls":{"cert":"default","requireClientAuth":false}} +``` + +### [listeners.kafka.external.default.advertisedPorts](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=listeners.kafka.external.default.advertisedPorts) + +If undefined, `listeners.kafka.external.default.port` is used. + +**Default:** `[31092]` + +### [listeners.kafka.external.default.port](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=listeners.kafka.external.default.port) + +The port used for external client connections. + +**Default:** `9094` + +### [listeners.kafka.port](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=listeners.kafka.port) + +The port for internal client connections. + +**Default:** `9093` + +### [listeners.rpc](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=listeners.rpc) + +RPC listener (this is never externally accessible). + +**Default:** + +``` +{"port":33145,"tls":{"cert":"default","requireClientAuth":false}} +``` + +### [listeners.schemaRegistry](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=listeners.schemaRegistry) + +Schema registry listeners. + +**Default:** + +``` +{"authenticationMethod":null,"enabled":true,"external":{"default":{"advertisedPorts":[30081],"authenticationMethod":null,"port":8084,"tls":{"cert":"external","requireClientAuth":false}}},"kafkaEndpoint":"default","port":8081,"tls":{"cert":"default","requireClientAuth":false}} +``` + +### [logging](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=logging) + +Log-level settings. + +**Default:** + +``` +{"logLevel":"info","usageStats":{"enabled":true}} +``` + +### [logging.logLevel](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=logging.logLevel) + +Log level Valid values (from least to most verbose) are: `warn`, `info`, `debug`, and `trace`. + +**Default:** `"info"` + +### [logging.usageStats](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=logging.usageStats) + +Send usage statistics back to Redpanda Data. For details, see the [stats reporting documentation](https://docs.redpanda.com/docs/cluster-administration/monitoring/#stats-reporting). + +**Default:** `{"enabled":true}` + +### [monitoring](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=monitoring) + +Monitoring. This will create a ServiceMonitor that can be used by Prometheus-Operator or VictoriaMetrics-Operator to scrape the metrics. + +**Default:** + +``` +{"enabled":false,"labels":{},"scrapeInterval":"30s"} +``` + +### [nameOverride](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=nameOverride) + +Override `redpanda.name` template. + +**Default:** `""` + +### [nodeSelector](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=nodeSelector) + +Node selection constraints for scheduling Pods, can override this for StatefulSets. For details, see the [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector). + +**Default:** `{}` + +### [post_install_job.affinity](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=post_install_job.affinity) + +**Default:** `{}` + +### [post_install_job.enabled](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=post_install_job.enabled) + +**Default:** `true` + +### [post_install_job.podTemplate.annotations](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=post_install_job.podTemplate.annotations) + +Additional annotations to apply to the Pods of this Job. + +**Default:** `{}` + +### [post_install_job.podTemplate.labels](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=post_install_job.podTemplate.labels) + +Additional labels to apply to the Pods of this Job. + +**Default:** `{}` + +### [post_install_job.podTemplate.spec](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=post_install_job.podTemplate.spec) + +A subset of Kubernetes' PodSpec type that will be merged into the final PodSpec. See [Merge Semantics](#merging-semantics) for details. + +**Default:** + +``` +{"containers":[{"env":[],"name":"post-install","securityContext":{}}],"securityContext":{}} +``` + +### [post_upgrade_job.affinity](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=post_upgrade_job.affinity) + +**Default:** `{}` + +### [post_upgrade_job.enabled](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=post_upgrade_job.enabled) + +**Default:** `true` + +### [post_upgrade_job.podTemplate.annotations](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=post_upgrade_job.podTemplate.annotations) + +Additional annotations to apply to the Pods of this Job. + +**Default:** `{}` + +### [post_upgrade_job.podTemplate.labels](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=post_upgrade_job.podTemplate.labels) + +Additional labels to apply to the Pods of this Job. + +**Default:** `{}` + +### [post_upgrade_job.podTemplate.spec](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=post_upgrade_job.podTemplate.spec) + +A subset of Kubernetes' PodSpec type that will be merged into the final PodSpec. See [Merge Semantics](#merging-semantics) for details. + +**Default:** + +``` +{"containers":[{"env":[],"name":"post-upgrade","securityContext":{}}],"securityContext":{}} +``` + +### [rackAwareness](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=rackAwareness) + +Rack Awareness settings. For details, see the [Rack Awareness documentation](https://docs.redpanda.com/docs/manage/kubernetes/kubernetes-rack-awareness/). + +**Default:** + +``` +{"enabled":false,"nodeAnnotation":"topology.kubernetes.io/zone"} +``` + +### [rackAwareness.enabled](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=rackAwareness.enabled) + +When running in multiple racks or availability zones, use a Kubernetes Node annotation value as the Redpanda rack value. Enabling this requires running with a service account with "get" Node permissions. To have the Helm chart configure these permissions, set `serviceAccount.create=true` and `rbac.enabled=true`. + +**Default:** `false` + +### [rackAwareness.nodeAnnotation](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=rackAwareness.nodeAnnotation) + +The common well-known annotation to use as the rack ID. Override this only if you use a custom Node annotation. + +**Default:** + +``` +"topology.kubernetes.io/zone" +``` + +### [rbac](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=rbac) + +Role Based Access Control. + +**Default:** + +``` +{"annotations":{},"enabled":false} +``` + +### [rbac.annotations](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=rbac.annotations) + +Annotations to add to the `rbac` resources. + +**Default:** `{}` + +### [rbac.enabled](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=rbac.enabled) + +Enable for features that need extra privileges. If you use the Redpanda Operator, you must deploy it with the `--set rbac.createRPKBundleCRs=true` flag to give it the required ClusterRoles. + +**Default:** `false` + +### [resources](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=resources) + +Pod resource management. This section simplifies resource allocation by providing a single location where resources are defined. Helm sets these resource values within the `statefulset.yaml` and `configmap.yaml` templates. The default values are for a development environment. Production-level values and other considerations are documented, where those values are different from the default. For details, see the [Pod resources documentation](https://docs.redpanda.com/docs/manage/kubernetes/manage-resources/). + +**Default:** + +``` +{"cpu":{"cores":1},"memory":{"container":{"max":"2.5Gi"}}} +``` + +### [resources.cpu](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=resources.cpu) + +CPU resources. For details, see the [Pod resources documentation](https://docs.redpanda.com/docs/manage/kubernetes/manage-resources/#configure-cpu-resources). + +**Default:** `{"cores":1}` + +### [resources.cpu.cores](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=resources.cpu.cores) + +Redpanda makes use of a thread per core model. For details, see this [blog](https://redpanda.com/blog/tpc-buffers). For this reason, Redpanda should only be given full cores. Note: You can increase cores, but decreasing cores is not currently supported. See the [GitHub issue](https://github.com/redpanda-data/redpanda/issues/350). This setting is equivalent to `--smp`, `resources.requests.cpu`, and `resources.limits.cpu`. For production, use `4` or greater. To maximize efficiency, use the `static` CPU manager policy by specifying an even integer for CPU resource requests and limits. This policy gives the Pods running Redpanda brokers access to exclusive CPUs on the node. See https://kubernetes.io/docs/tasks/administer-cluster/cpu-management-policies/#static-policy. + +**Default:** `1` + +### [resources.memory](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=resources.memory) + +Memory resources For details, see the [Pod resources documentation](https://docs.redpanda.com/docs/manage/kubernetes/manage-resources/#configure-memory-resources). + +**Default:** + +``` +{"container":{"max":"2.5Gi"}} +``` + +### [resources.memory.container](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=resources.memory.container) + +Enables memory locking. For production, set to `true`. enable_memory_locking: false It is recommended to have at least 2Gi of memory per core for the Redpanda binary. This memory is taken from the total memory given to each container. The Helm chart allocates 80% of the container's memory to Redpanda, leaving the rest for the Seastar subsystem (reserveMemory) and other container processes. So at least 2.5Gi per core is recommended in order to ensure Redpanda has a full 2Gi. These values affect `--memory` and `--reserve-memory` flags passed to Redpanda and the memory requests/limits in the StatefulSet. Valid suffixes: k, M, G, T, P, Ki, Mi, Gi, Ti, Pi To create `Guaranteed` Pod QoS for Redpanda brokers, provide both container max and min values for the container. For details, see https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/#create-a-pod-that-gets-assigned-a-qos-class-of-guaranteed * Every container in the Pod must have a memory limit and a memory request. * For every container in the Pod, the memory limit must equal the memory request. + +**Default:** `{"max":"2.5Gi"}` + +### [resources.memory.container.max](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=resources.memory.container.max) + +Maximum memory count for each Redpanda broker. Equivalent to `resources.limits.memory`. For production, use `10Gi` or greater. + +**Default:** `"2.5Gi"` + +### [serviceAccount](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=serviceAccount) + +Service account management. + +**Default:** + +``` +{"annotations":{},"create":false,"name":""} +``` + +### [serviceAccount.annotations](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=serviceAccount.annotations) + +Annotations to add to the service account. + +**Default:** `{}` + +### [serviceAccount.create](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=serviceAccount.create) + +Specifies whether a service account should be created. + +**Default:** `false` + +### [serviceAccount.name](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=serviceAccount.name) + +The name of the service account to use. If not set and `serviceAccount.create` is `true`, a name is generated using the `redpanda.fullname` template. + +**Default:** `""` + +### [statefulset.additionalRedpandaCmdFlags](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.additionalRedpandaCmdFlags) + +Additional flags to pass to redpanda, + +**Default:** `[]` + +### [statefulset.additionalSelectorLabels](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.additionalSelectorLabels) + +Additional labels to be added to statefulset label selector. For example, `my.k8s.service: redpanda`. + +**Default:** `{}` + +### [statefulset.annotations](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.annotations) + +DEPRECATED Please use statefulset.podTemplate.annotations. Annotations are used only for `Statefulset.spec.template.metadata.annotations`. The StatefulSet does not have any dedicated annotation. + +**Default:** `{}` + +### [statefulset.budget.maxUnavailable](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.budget.maxUnavailable) + +**Default:** `1` + +### [statefulset.extraVolumeMounts](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.extraVolumeMounts) + +**Default:** `""` + +### [statefulset.extraVolumes](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.extraVolumes) + +**Default:** `""` + +### [statefulset.initContainerImage.repository](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.initContainerImage.repository) + +**Default:** `"busybox"` + +### [statefulset.initContainerImage.tag](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.initContainerImage.tag) + +**Default:** `"latest"` + +### [statefulset.initContainers.configurator.extraVolumeMounts](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.initContainers.configurator.extraVolumeMounts) + +**Default:** `""` + +### [statefulset.initContainers.configurator.resources](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.initContainers.configurator.resources) + +To create `Guaranteed` Pods for Redpanda brokers, provide both requests and limits for CPU and memory. For details, see https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/#create-a-pod-that-gets-assigned-a-qos-class-of-guaranteed * Every container in the Pod must have a CPU limit and a CPU request. * For every container in the Pod, the CPU limit must equal the CPU request. + +**Default:** `{}` + +### [statefulset.initContainers.extraInitContainers](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.initContainers.extraInitContainers) + +**Default:** `""` + +### [statefulset.initContainers.fsValidator.enabled](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.initContainers.fsValidator.enabled) + +**Default:** `false` + +### [statefulset.initContainers.fsValidator.expectedFS](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.initContainers.fsValidator.expectedFS) + +**Default:** `"xfs"` + +### [statefulset.initContainers.fsValidator.extraVolumeMounts](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.initContainers.fsValidator.extraVolumeMounts) + +**Default:** `""` + +### [statefulset.initContainers.fsValidator.resources](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.initContainers.fsValidator.resources) + +To create `Guaranteed` Pods for Redpanda brokers, provide both requests and limits for CPU and memory. For details, see https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/#create-a-pod-that-gets-assigned-a-qos-class-of-guaranteed * Every container in the Pod must have a CPU limit and a CPU request. * For every container in the Pod, the CPU limit must equal the CPU request. + +**Default:** `{}` + +### [statefulset.initContainers.setDataDirOwnership.enabled](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.initContainers.setDataDirOwnership.enabled) + +In environments where root is not allowed, you cannot change the ownership of files and directories. Enable `setDataDirOwnership` when using default minikube cluster configuration. + +**Default:** `false` + +### [statefulset.initContainers.setDataDirOwnership.extraVolumeMounts](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.initContainers.setDataDirOwnership.extraVolumeMounts) + +**Default:** `""` + +### [statefulset.initContainers.setDataDirOwnership.resources](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.initContainers.setDataDirOwnership.resources) + +To create `Guaranteed` Pods for Redpanda brokers, provide both requests and limits for CPU and memory. For details, see https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/#create-a-pod-that-gets-assigned-a-qos-class-of-guaranteed * Every container in the Pod must have a CPU limit and a CPU request. * For every container in the Pod, the CPU limit must equal the CPU request. + +**Default:** `{}` + +### [statefulset.initContainers.setTieredStorageCacheDirOwnership.extraVolumeMounts](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.initContainers.setTieredStorageCacheDirOwnership.extraVolumeMounts) + +**Default:** `""` + +### [statefulset.initContainers.setTieredStorageCacheDirOwnership.resources](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.initContainers.setTieredStorageCacheDirOwnership.resources) + +To create `Guaranteed` Pods for Redpanda brokers, provide both requests and limits for CPU and memory. For details, see https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/#create-a-pod-that-gets-assigned-a-qos-class-of-guaranteed * Every container in the Pod must have a CPU limit and a CPU request. * For every container in the Pod, the CPU limit must equal the CPU request. + +**Default:** `{}` + +### [statefulset.initContainers.tuning.extraVolumeMounts](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.initContainers.tuning.extraVolumeMounts) + +**Default:** `""` + +### [statefulset.initContainers.tuning.resources](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.initContainers.tuning.resources) + +To create `Guaranteed` Pods for Redpanda brokers, provide both requests and limits for CPU and memory. For details, see https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/#create-a-pod-that-gets-assigned-a-qos-class-of-guaranteed * Every container in the Pod must have a CPU limit and a CPU request. * For every container in the Pod, the CPU limit must equal the CPU request. + +**Default:** `{}` + +### [statefulset.livenessProbe.failureThreshold](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.livenessProbe.failureThreshold) + +**Default:** `3` + +### [statefulset.livenessProbe.initialDelaySeconds](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.livenessProbe.initialDelaySeconds) + +**Default:** `10` + +### [statefulset.livenessProbe.periodSeconds](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.livenessProbe.periodSeconds) + +**Default:** `10` + +### [statefulset.nodeSelector](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.nodeSelector) + +Node selection constraints for scheduling Pods of this StatefulSet. These constraints override the global `nodeSelector` value. For details, see the [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector). + +**Default:** `{}` + +### [statefulset.podAffinity](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.podAffinity) + +Inter-Pod Affinity rules for scheduling Pods of this StatefulSet. For details, see the [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#inter-pod-affinity-and-anti-affinity). + +**Default:** `{}` + +### [statefulset.podAntiAffinity](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.podAntiAffinity) + +Anti-affinity rules for scheduling Pods of this StatefulSet. For details, see the [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#inter-pod-affinity-and-anti-affinity). You may either edit the default settings for anti-affinity rules, or specify new anti-affinity rules to use instead of the defaults. + +**Default:** + +``` +{"custom":{},"topologyKey":"kubernetes.io/hostname","type":"hard","weight":100} +``` + +### [statefulset.podAntiAffinity.custom](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.podAntiAffinity.custom) + +Change `podAntiAffinity.type` to `custom` and provide your own podAntiAffinity rules here. + +**Default:** `{}` + +### [statefulset.podAntiAffinity.topologyKey](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.podAntiAffinity.topologyKey) + +The topologyKey to be used. Can be used to spread across different nodes, AZs, regions etc. + +**Default:** `"kubernetes.io/hostname"` + +### [statefulset.podAntiAffinity.type](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.podAntiAffinity.type) + +Valid anti-affinity types are `soft`, `hard`, or `custom`. Use `custom` if you want to supply your own anti-affinity rules in the `podAntiAffinity.custom` object. + +**Default:** `"hard"` + +### [statefulset.podAntiAffinity.weight](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.podAntiAffinity.weight) + +Weight for `soft` anti-affinity rules. Does not apply to other anti-affinity types. + +**Default:** `100` + +### [statefulset.podTemplate.annotations](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.podTemplate.annotations) + +Additional annotations to apply to the Pods of the StatefulSet. + +**Default:** `{}` + +### [statefulset.podTemplate.labels](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.podTemplate.labels) + +Additional labels to apply to the Pods of the StatefulSet. + +**Default:** `{}` + +### [statefulset.podTemplate.spec](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.podTemplate.spec) + +A subset of Kubernetes' PodSpec type that will be merged into the final PodSpec. See [Merge Semantics](#merging-semantics) for details. + +**Default:** + +``` +{"containers":[{"env":[],"name":"redpanda","securityContext":{}}],"securityContext":{}} +``` + +### [statefulset.priorityClassName](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.priorityClassName) + +PriorityClassName given to Pods of this StatefulSet. For details, see the [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#priorityclass). + +**Default:** `""` + +### [statefulset.readinessProbe.failureThreshold](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.readinessProbe.failureThreshold) + +**Default:** `3` + +### [statefulset.readinessProbe.initialDelaySeconds](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.readinessProbe.initialDelaySeconds) + +**Default:** `1` + +### [statefulset.readinessProbe.periodSeconds](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.readinessProbe.periodSeconds) + +**Default:** `10` + +### [statefulset.readinessProbe.successThreshold](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.readinessProbe.successThreshold) + +**Default:** `1` + +### [statefulset.replicas](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.replicas) + +Number of Redpanda brokers (Redpanda Data recommends setting this to the number of worker nodes in the cluster) + +**Default:** `3` + +### [statefulset.securityContext](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.securityContext) + +DEPRECATED: Prefer to use podTemplate.spec.securityContext or podTemplate.spec.containers[0].securityContext. + +**Default:** + +``` +{"fsGroup":101,"fsGroupChangePolicy":"OnRootMismatch","runAsUser":101} +``` + +### [statefulset.sideCars.configWatcher.enabled](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.sideCars.configWatcher.enabled) + +**Default:** `true` + +### [statefulset.sideCars.configWatcher.extraVolumeMounts](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.sideCars.configWatcher.extraVolumeMounts) + +**Default:** `""` + +### [statefulset.sideCars.configWatcher.resources](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.sideCars.configWatcher.resources) + +To create `Guaranteed` Pods for Redpanda brokers, provide both requests and limits for CPU and memory. For details, see https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/#create-a-pod-that-gets-assigned-a-qos-class-of-guaranteed * Every container in the Pod must have a memory limit and a memory request. * For every container in the Pod, the memory limit must equal the memory request. * Every container in the Pod must have a CPU limit and a CPU request. * For every container in the Pod, the CPU limit must equal the CPU request. To maximize efficiency, use the `static` CPU manager policy by specifying an even integer for CPU resource requests and limits. This policy gives the Pods running Redpanda brokers access to exclusive CPUs on the node. For details, see https://kubernetes.io/docs/tasks/administer-cluster/cpu-management-policies/#static-policy + +**Default:** `{}` + +### [statefulset.sideCars.configWatcher.securityContext](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.sideCars.configWatcher.securityContext) + +**Default:** `{}` + +### [statefulset.sideCars.controllers.createRBAC](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.sideCars.controllers.createRBAC) + +**Default:** `true` + +### [statefulset.sideCars.controllers.enabled](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.sideCars.controllers.enabled) + +**Default:** `false` + +### [statefulset.sideCars.controllers.healthProbeAddress](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.sideCars.controllers.healthProbeAddress) + +**Default:** `":8085"` + +### [statefulset.sideCars.controllers.image.repository](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.sideCars.controllers.image.repository) + +**Default:** + +``` +"docker.redpanda.com/redpandadata/redpanda-operator" +``` + +### [statefulset.sideCars.controllers.image.tag](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.sideCars.controllers.image.tag) + +**Default:** `"v2.1.10-23.2.18"` + +### [statefulset.sideCars.controllers.metricsAddress](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.sideCars.controllers.metricsAddress) + +**Default:** `":9082"` + +### [statefulset.sideCars.controllers.resources](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.sideCars.controllers.resources) + +To create `Guaranteed` Pods for Redpanda brokers, provide both requests and limits for CPU and memory. For details, see https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/#create-a-pod-that-gets-assigned-a-qos-class-of-guaranteed * Every container in the Pod must have a CPU limit and a CPU request. * For every container in the Pod, the CPU limit must equal the CPU request. * Every container in the Pod must have a CPU limit and a CPU request. * For every container in the Pod, the CPU limit must equal the CPU request. To maximize efficiency, use the `static` CPU manager policy by specifying an even integer for CPU resource requests and limits. This policy gives the Pods running Redpanda brokers access to exclusive CPUs on the node. For details, see https://kubernetes.io/docs/tasks/administer-cluster/cpu-management-policies/#static-policy + +**Default:** `{}` + +### [statefulset.sideCars.controllers.run[0]](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.sideCars.controllers.run[0]) + +**Default:** `"all"` + +### [statefulset.sideCars.controllers.securityContext](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.sideCars.controllers.securityContext) + +**Default:** `{}` + +### [statefulset.startupProbe](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.startupProbe) + +Adjust the period for your probes to meet your needs. For details, see the [Kubernetes documentation](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes). + +**Default:** + +``` +{"failureThreshold":120,"initialDelaySeconds":1,"periodSeconds":10} +``` + +### [statefulset.terminationGracePeriodSeconds](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.terminationGracePeriodSeconds) + +Termination grace period in seconds is time required to execute preStop hook which puts particular Redpanda Pod (process/container) into maintenance mode. Before settle down on particular value please put Redpanda under load and perform rolling upgrade or rolling restart. That value needs to accommodate two processes: * preStop hook needs to put Redpanda into maintenance mode * after preStop hook Redpanda needs to handle gracefully SIGTERM signal Both processes are executed sequentially where preStop hook has hard deadline in the middle of terminationGracePeriodSeconds. REF: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#hook-handler-execution https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-termination + +**Default:** `90` + +### [statefulset.tolerations](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.tolerations) + +Taints to be tolerated by Pods of this StatefulSet. These tolerations override the global tolerations value. For details, see the [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/). + +**Default:** `[]` + +### [statefulset.topologySpreadConstraints[0].maxSkew](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.topologySpreadConstraints[0].maxSkew) + +**Default:** `1` + +### [statefulset.topologySpreadConstraints[0].topologyKey](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.topologySpreadConstraints[0].topologyKey) + +**Default:** + +``` +"topology.kubernetes.io/zone" +``` + +### [statefulset.topologySpreadConstraints[0].whenUnsatisfiable](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.topologySpreadConstraints[0].whenUnsatisfiable) + +**Default:** `"ScheduleAnyway"` + +### [statefulset.updateStrategy.type](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=statefulset.updateStrategy.type) + +**Default:** `"RollingUpdate"` + +### [storage](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=storage) + +Persistence settings. For details, see the [storage documentation](https://docs.redpanda.com/docs/manage/kubernetes/configure-storage/). + +**Default:** + +``` +{"hostPath":"","persistentVolume":{"annotations":{},"enabled":true,"labels":{},"nameOverwrite":"","size":"20Gi","storageClass":""},"tiered":{"config":{"cloud_storage_access_key":"","cloud_storage_api_endpoint":"","cloud_storage_azure_container":null,"cloud_storage_azure_managed_identity_id":null,"cloud_storage_azure_shared_key":null,"cloud_storage_azure_storage_account":null,"cloud_storage_bucket":"","cloud_storage_cache_size":5368709120,"cloud_storage_credentials_source":"config_file","cloud_storage_enable_remote_read":true,"cloud_storage_enable_remote_write":true,"cloud_storage_enabled":false,"cloud_storage_region":"","cloud_storage_secret_key":""},"credentialsSecretRef":{"accessKey":{"configurationKey":"cloud_storage_access_key"},"secretKey":{"configurationKey":"cloud_storage_secret_key"}},"hostPath":"","mountType":"emptyDir","persistentVolume":{"annotations":{},"labels":{},"storageClass":""}}} +``` + +### [storage.hostPath](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=storage.hostPath) + +Absolute path on the host to store Redpanda's data. If unspecified, then an `emptyDir` volume is used. If specified but `persistentVolume.enabled` is true, `storage.hostPath` has no effect. + +**Default:** `""` + +### [storage.persistentVolume](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=storage.persistentVolume) + +If `persistentVolume.enabled` is true, a PersistentVolumeClaim is created and used to store Redpanda's data. Otherwise, `storage.hostPath` is used. + +**Default:** + +``` +{"annotations":{},"enabled":true,"labels":{},"nameOverwrite":"","size":"20Gi","storageClass":""} +``` + +### [storage.persistentVolume.annotations](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=storage.persistentVolume.annotations) + +Additional annotations to apply to the created PersistentVolumeClaims. + +**Default:** `{}` + +### [storage.persistentVolume.labels](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=storage.persistentVolume.labels) + +Additional labels to apply to the created PersistentVolumeClaims. + +**Default:** `{}` + +### [storage.persistentVolume.nameOverwrite](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=storage.persistentVolume.nameOverwrite) + +Option to change volume claim template name for tiered storage persistent volume if tiered.mountType is set to `persistentVolume` + +**Default:** `""` + +### [storage.persistentVolume.storageClass](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=storage.persistentVolume.storageClass) + +To disable dynamic provisioning, set to `-`. If undefined or empty (default), then no storageClassName spec is set, and the default dynamic provisioner is chosen (gp2 on AWS, standard on GKE, AWS & OpenStack). + +**Default:** `""` + +### [storage.tiered.config](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=storage.tiered.config) + +Tiered Storage settings Requires `enterprise.licenseKey` or `enterprised.licenseSecretRef` For details, see the [Tiered Storage documentation](https://docs.redpanda.com/docs/manage/kubernetes/tiered-storage/). + +**Default:** + +``` +{"cloud_storage_access_key":"","cloud_storage_api_endpoint":"","cloud_storage_azure_container":null,"cloud_storage_azure_managed_identity_id":null,"cloud_storage_azure_shared_key":null,"cloud_storage_azure_storage_account":null,"cloud_storage_bucket":"","cloud_storage_cache_size":5368709120,"cloud_storage_credentials_source":"config_file","cloud_storage_enable_remote_read":true,"cloud_storage_enable_remote_write":true,"cloud_storage_enabled":false,"cloud_storage_region":"","cloud_storage_secret_key":""} +``` + +### [storage.tiered.config.cloud_storage_access_key](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=storage.tiered.config.cloud_storage_access_key) + +AWS or GCP access key (required for AWS and GCP authentication with access keys). See the [property reference documentation](https://docs.redpanda.com/docs/reference/cluster-properties/#cloud_storage_access_key). + +**Default:** `""` + +### [storage.tiered.config.cloud_storage_api_endpoint](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=storage.tiered.config.cloud_storage_api_endpoint) + +AWS or GCP API endpoint. * For AWS, this can be left blank as it is generated automatically using the bucket and region. For example, `.s3..amazonaws.com`. * For GCP, use `storage.googleapis.com` See the [property reference documentation](https://docs.redpanda.com/docs/reference/cluster-properties/#cloud_storage_api_endpoint). + +**Default:** `""` + +### [storage.tiered.config.cloud_storage_azure_container](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=storage.tiered.config.cloud_storage_azure_container) + +Name of the Azure container to use with Tiered Storage (required for ABS/ADLS). Note that the container must belong to the account specified by `cloud_storage_azure_storage_account`. See the [property reference documentation](https://docs.redpanda.com/docs/reference/cluster-properties/#cloud_storage_azure_container). + +**Default:** `nil` + +### [storage.tiered.config.cloud_storage_azure_shared_key](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=storage.tiered.config.cloud_storage_azure_shared_key) + +Shared key to be used for Azure Shared Key authentication with the Azure storage account specified by `cloud_storage_azure_storage_account`. Note that the key should be base64 encoded. See the [property reference documentation](https://docs.redpanda.com/docs/reference/cluster-properties/#cloud_storage_azure_shared_key). + +**Default:** `nil` + +### [storage.tiered.config.cloud_storage_azure_storage_account](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=storage.tiered.config.cloud_storage_azure_storage_account) + +Name of the Azure storage account to use with Tiered Storage (required for ABS/ADLS). See the [property reference documentation](https://docs.redpanda.com/docs/reference/cluster-properties/#cloud_storage_azure_storage_account). + +**Default:** `nil` + +### [storage.tiered.config.cloud_storage_bucket](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=storage.tiered.config.cloud_storage_bucket) + +AWS or GCP bucket name used for Tiered Storage (required for AWS and GCP). See the [property reference documentation](https://docs.redpanda.com/docs/reference/cluster-properties/#cloud_storage_bucket). + +**Default:** `""` + +### [storage.tiered.config.cloud_storage_cache_size](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=storage.tiered.config.cloud_storage_cache_size) + +Maximum size of the disk cache used by Tiered Storage. Default is 20 GiB. See the [property reference documentation](https://docs.redpanda.com/docs/reference/cluster-properties/#cloud_storage_cache_size). + +**Default:** `5368709120` + +### [storage.tiered.config.cloud_storage_credentials_source](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=storage.tiered.config.cloud_storage_credentials_source) + +Source of credentials used to connect to cloud services (required for AWS and GCP authentication with IAM roles). * `config_file` * `aws_instance_metadata` * `sts` * `gcp_instance_metadata` * `azure_aks_oidc_federation` * `azure_vm_instance_metadata` See the [property reference documentation](https://docs.redpanda.com/docs/reference/cluster-properties/#cloud_storage_credentials_source). + +**Default:** `"config_file"` + +### [storage.tiered.config.cloud_storage_enable_remote_read](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=storage.tiered.config.cloud_storage_enable_remote_read) + +Cluster level default remote read configuration for new topics. See the [property reference documentation](https://docs.redpanda.com/docs/reference/tunable-properties/#cloud_storage_enable_remote_read). + +**Default:** `true` + +### [storage.tiered.config.cloud_storage_enable_remote_write](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=storage.tiered.config.cloud_storage_enable_remote_write) + +Cluster level default remote write configuration for new topics. See the [property reference documentation](https://docs.redpanda.com/docs/reference/tunable-properties/#cloud_storage_enable_remote_write). + +**Default:** `true` + +### [storage.tiered.config.cloud_storage_enabled](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=storage.tiered.config.cloud_storage_enabled) + +Global flag that enables Tiered Storage if a license key is provided. See the [property reference documentation](https://docs.redpanda.com/docs/reference/cluster-properties/#cloud_storage_enabled). + +**Default:** `false` + +### [storage.tiered.config.cloud_storage_region](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=storage.tiered.config.cloud_storage_region) + +AWS or GCP region for where the bucket used for Tiered Storage is located (required for AWS and GCP). See the [property reference documentation](https://docs.redpanda.com/docs/reference/cluster-properties/#cloud_storage_region). + +**Default:** `""` + +### [storage.tiered.config.cloud_storage_secret_key](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=storage.tiered.config.cloud_storage_secret_key) + +AWS or GCP secret key (required for AWS and GCP authentication with access keys). See the [property reference documentation](https://docs.redpanda.com/docs/reference/cluster-properties/#cloud_storage_secret_key). + +**Default:** `""` + +### [storage.tiered.hostPath](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=storage.tiered.hostPath) + +Absolute path on the host to store Redpanda's Tiered Storage cache. + +**Default:** `""` + +### [storage.tiered.persistentVolume.annotations](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=storage.tiered.persistentVolume.annotations) + +Additional annotations to apply to the created PersistentVolumeClaims. + +**Default:** `{}` + +### [storage.tiered.persistentVolume.labels](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=storage.tiered.persistentVolume.labels) + +Additional labels to apply to the created PersistentVolumeClaims. + +**Default:** `{}` + +### [storage.tiered.persistentVolume.storageClass](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=storage.tiered.persistentVolume.storageClass) + +To disable dynamic provisioning, set to "-". If undefined or empty (default), then no storageClassName spec is set, and the default dynamic provisioner is chosen (gp2 on AWS, standard on GKE, AWS & OpenStack). + +**Default:** `""` + +### [tests.enabled](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=tests.enabled) + +**Default:** `true` + +### [tls](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=tls) + +TLS settings. For details, see the [TLS documentation](https://docs.redpanda.com/docs/manage/kubernetes/security/kubernetes-tls/). + +**Default:** + +``` +{"certs":{"default":{"caEnabled":true},"external":{"caEnabled":true}},"enabled":true} +``` + +### [tls.certs](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=tls.certs) + +List all Certificates here, then you can reference a specific Certificate's name in each listener's `listeners..tls.cert` setting. + +**Default:** + +``` +{"default":{"caEnabled":true},"external":{"caEnabled":true}} +``` + +### [tls.certs.default](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=tls.certs.default) + +This key is the Certificate name. To apply the Certificate to a specific listener, reference the Certificate's name in `listeners..tls.cert`. + +**Default:** `{"caEnabled":true}` + +### [tls.certs.default.caEnabled](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=tls.certs.default.caEnabled) + +Set the `caEnabled` flag to `true` only for Certificates that are not authenticated using public authorities. + +**Default:** `true` + +### [tls.certs.external](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=tls.certs.external) + +Example external tls configuration uncomment and set the right key to the listeners that require them also enable the tls setting for those listeners. + +**Default:** `{"caEnabled":true}` + +### [tls.certs.external.caEnabled](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=tls.certs.external.caEnabled) + +Set the `caEnabled` flag to `true` only for Certificates that are not authenticated using public authorities. + +**Default:** `true` + +### [tls.enabled](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=tls.enabled) + +Enable TLS globally for all listeners. Each listener must include a Certificate name in its `.tls` object. To allow you to enable TLS for individual listeners, Certificates in `auth.tls.certs` are always loaded, even if `tls.enabled` is `false`. See `listeners..tls.enabled`. + +**Default:** `true` + +### [tolerations](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=tolerations) + +Taints to be tolerated by Pods, can override this for StatefulSets. For details, see the [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/). + +**Default:** `[]` + +### [tuning](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=tuning) + +Redpanda tuning settings. Each is set to their default values in Redpanda. + +**Default:** `{"tune_aio_events":true}` + +### [tuning.tune_aio_events](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=tuning.tune_aio_events) + +Increase the maximum number of outstanding asynchronous IO operations if the current value is below a certain threshold. This allows Redpanda to make as many simultaneous IO requests as possible, increasing throughput. When this option is enabled, Helm creates a privileged container. If your security profile does not allow this, you can disable this container by setting `tune_aio_events` to `false`. For more details, see the [tuning documentation](https://docs.redpanda.com/docs/deploy/deployment-option/self-hosted/kubernetes/kubernetes-tune-workers/). + +**Default:** `true` + +## Merging Semantics + +The redpanda chart implements a form of object merging that's roughly a +middleground of [JSON Merge Patch][k8s.jsonmp] and [Kubernetes' Strategic Merge +Patch][k8s.smp]. This is done to aid end users in setting or overriding fields +that are not directly exposed via the chart. + +- Directives are not supported. +- List fields that are merged by a unique key in Kubernetes' SMP (e.g. + `containers`, `env`) will be merged in a similar awy. +- Only fields explicitly allowed by the chart's JSON schema will be merged. +- Additional containers that are not present in the original value will NOT be added. + +[k8s.smp]: https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/#use-a-strategic-merge-patch-to-update-a-deployment +[k8s.jsonmp]: https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/#use-a-json-merge-patch-to-update-a-deployment diff --git a/charts/redpanda/redpanda/5.9.2/charts/connectors/.helmignore b/charts/redpanda/redpanda/5.9.2/charts/connectors/.helmignore new file mode 100644 index 0000000000..04ecd888b5 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/connectors/.helmignore @@ -0,0 +1,24 @@ +# 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 +README.md.gotmpl +# 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/redpanda/redpanda/5.9.2/charts/connectors/Chart.yaml b/charts/redpanda/redpanda/5.9.2/charts/connectors/Chart.yaml new file mode 100644 index 0000000000..100b252b9d --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/connectors/Chart.yaml @@ -0,0 +1,25 @@ +annotations: + artifacthub.io/images: | + - name: connectors + image: docker.redpanda.com/redpandadata/connectors:v1.0.29 + - name: rpk + image: docker.redpanda.com/redpandadata/redpanda:latest + artifacthub.io/license: Apache-2.0 + artifacthub.io/links: | + - name: Documentation + url: https://docs.redpanda.com + - name: "Helm (>= 3.6.0)" + url: https://helm.sh/docs/intro/install/ +apiVersion: v2 +appVersion: v1.0.29 +description: Redpanda managed Connectors helm chart +icon: https://images.ctfassets.net/paqvtpyf8rwu/3cYHw5UzhXCbKuR24GDFGO/73fb682e6157d11c10d5b2b5da1d5af0/skate-stand-panda.svg +kubeVersion: ^1.21.0-0 +maintainers: +- name: redpanda-data + url: https://github.com/orgs/redpanda-data/people +name: connectors +sources: +- https://github.com/redpanda-data/helm-charts +type: application +version: 0.1.12 diff --git a/charts/redpanda/redpanda/5.9.2/charts/connectors/LICENSE b/charts/redpanda/redpanda/5.9.2/charts/connectors/LICENSE new file mode 100644 index 0000000000..261eeb9e9f --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/connectors/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/charts/redpanda/redpanda/5.9.2/charts/connectors/README.md b/charts/redpanda/redpanda/5.9.2/charts/connectors/README.md new file mode 100644 index 0000000000..c48f682b98 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/connectors/README.md @@ -0,0 +1,574 @@ +# Redpanda Connectors Helm Chart Specification +--- +description: Find the default values and descriptions of settings in the Redpanda Connectors Helm chart. +--- + +![Version: 0.1.12](https://img.shields.io/badge/Version-0.1.12-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v1.0.29](https://img.shields.io/badge/AppVersion-v1.0.29-informational?style=flat-square) + +This page describes the official Redpanda Connectors Helm Chart. In particular, this page describes the contents of the chart’s [`values.yaml` file](https://github.com/redpanda-data/helm-charts/blob/main/charts/connectors/values.yaml). Each of the settings is listed and described on this page, along with any default values. + +For instructions on how to install and use the chart, including how to override and customize the chart’s values, refer to the [deployment documentation](https://docs.redpanda.com/current/deploy/deployment-option/self-hosted/kubernetes/k-deploy-connectors/). + +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) + +## Source Code + +* + +## Requirements + +Kubernetes: `^1.21.0-0` + +## Settings + +### [auth](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=auth) + +Authentication settings. For details, see the [SASL documentation](https://docs.redpanda.com/docs/manage/kubernetes/security/sasl-kubernetes/). The first line of the secret file is used. So the first superuser is used to authenticate to the Redpanda cluster. + +**Default:** + +``` +{"sasl":{"enabled":false,"mechanism":"scram-sha-512","secretRef":"","userName":""}} +``` + +### [auth.sasl.mechanism](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=auth.sasl.mechanism) + +The authentication mechanism to use for the superuser. Options are `scram-sha-256` and `scram-sha-512`. + +**Default:** `"scram-sha-512"` + +### [auth.sasl.secretRef](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=auth.sasl.secretRef) + +A Secret that contains your SASL user password. + +**Default:** `""` + +### [commonLabels](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=commonLabels) + +Additional labels to add to all Kubernetes objects. For example, `my.k8s.service: redpanda`. + +**Default:** `{}` + +### [connectors.additionalConfiguration](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=connectors.additionalConfiguration) + +A placeholder for any Java configuration settings for Kafka Connect that are not explicitly defined in this Helm chart. Java configuration settings are passed to the Kafka Connect startup script. + +**Default:** `""` + +### [connectors.bootstrapServers](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=connectors.bootstrapServers) + +A comma-separated list of Redpanda broker addresses in the format of IP:Port or DNS:Port. Kafka Connect uses this to connect to the Redpanda/Kafka cluster. + +**Default:** `""` + +### [connectors.brokerTLS.ca.secretNameOverwrite](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=connectors.brokerTLS.ca.secretNameOverwrite) + +If `secretRef` points to a Secret where the certificate authority (CA) is not under the `ca.crt` key, use `secretNameOverwrite` to overwrite it e.g. `corp-ca.crt`. + +**Default:** `""` + +### [connectors.brokerTLS.ca.secretRef](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=connectors.brokerTLS.ca.secretRef) + +The name of the Secret where the ca.crt file content is located. + +**Default:** `""` + +### [connectors.brokerTLS.cert.secretNameOverwrite](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=connectors.brokerTLS.cert.secretNameOverwrite) + +If secretRef points to secret where client signed certificate is not under tls.crt key then please use secretNameOverwrite to overwrite it e.g. corp-tls.crt + +**Default:** `""` + +### [connectors.brokerTLS.cert.secretRef](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=connectors.brokerTLS.cert.secretRef) + +The name of the secret where client signed certificate is located + +**Default:** `""` + +### [connectors.brokerTLS.enabled](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=connectors.brokerTLS.enabled) + +**Default:** `false` + +### [connectors.brokerTLS.key.secretNameOverwrite](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=connectors.brokerTLS.key.secretNameOverwrite) + +If secretRef points to secret where client private key is not under tls.key key then please use secretNameOverwrite to overwrite it e.g. corp-tls.key + +**Default:** `""` + +### [connectors.brokerTLS.key.secretRef](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=connectors.brokerTLS.key.secretRef) + +The name of the secret where client private key is located + +**Default:** `""` + +### [connectors.groupID](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=connectors.groupID) + +A unique string that identifies the Kafka Connect cluster. It's used in the formation of the internal topic names, ensuring that multiple Kafka Connect clusters can connect to the same Redpanda cluster without interfering with each other. + +**Default:** `"connectors-cluster"` + +### [connectors.producerBatchSize](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=connectors.producerBatchSize) + +The number of bytes of records a producer will attempt to batch together before sending to Redpanda. Batching improves throughput. + +**Default:** `131072` + +### [connectors.producerLingerMS](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=connectors.producerLingerMS) + +The time, in milliseconds, that a producer will wait before sending a batch of records. Waiting allows the producer to gather more records in the same batch and improve throughput. + +**Default:** `1` + +### [connectors.restPort](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=connectors.restPort) + +The port on which the Kafka Connect REST API listens. The API is used for administrative tasks. + +**Default:** `8083` + +### [connectors.schemaRegistryURL](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=connectors.schemaRegistryURL) + +**Default:** `""` + +### [connectors.secretManager.connectorsPrefix](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=connectors.secretManager.connectorsPrefix) + +**Default:** `""` + +### [connectors.secretManager.consolePrefix](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=connectors.secretManager.consolePrefix) + +**Default:** `""` + +### [connectors.secretManager.enabled](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=connectors.secretManager.enabled) + +**Default:** `false` + +### [connectors.secretManager.region](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=connectors.secretManager.region) + +**Default:** `""` + +### [connectors.storage.remote](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=connectors.storage.remote) + +Indicates if read and write operations for the respective topics are allowed remotely. + +**Default:** + +``` +{"read":{"config":false,"offset":false,"status":false},"write":{"config":false,"offset":false,"status":false}} +``` + +### [connectors.storage.replicationFactor](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=connectors.storage.replicationFactor) + +The number of replicas for each of the internal topics that Kafka Connect uses. + +**Default:** + +``` +{"config":-1,"offset":-1,"status":-1} +``` + +### [connectors.storage.replicationFactor.config](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=connectors.storage.replicationFactor.config) + +Replication factor for the configuration topic. + +**Default:** `-1` + +### [connectors.storage.replicationFactor.offset](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=connectors.storage.replicationFactor.offset) + +Replication factor for the offset topic. + +**Default:** `-1` + +### [connectors.storage.replicationFactor.status](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=connectors.storage.replicationFactor.status) + +Replication factor for the status topic. + +**Default:** `-1` + +### [connectors.storage.topic.config](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=connectors.storage.topic.config) + +The name of the internal topic that Kafka Connect uses to store connector and task configurations. + +**Default:** + +``` +"_internal_connectors_configs" +``` + +### [connectors.storage.topic.offset](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=connectors.storage.topic.offset) + +The name of the internal topic that Kafka Connect uses to store source connector offsets. + +**Default:** + +``` +"_internal_connectors_offsets" +``` + +### [connectors.storage.topic.status](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=connectors.storage.topic.status) + +The name of the internal topic that Kafka Connect uses to store connector and task status updates. + +**Default:** + +``` +"_internal_connectors_status" +``` + +### [container.javaGCLogEnabled](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=container.javaGCLogEnabled) + +**Default:** `"false"` + +### [container.resources](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=container.resources) + +Pod resource management. + +**Default:** + +``` +{"javaMaxHeapSize":"2G","limits":{"cpu":"1","memory":"2350Mi"},"request":{"cpu":"1","memory":"2350Mi"}} +``` + +### [container.resources.javaMaxHeapSize](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=container.resources.javaMaxHeapSize) + +Java maximum heap size must not be greater than `container.resources.limits.memory`. + +**Default:** `"2G"` + +### [container.securityContext](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=container.securityContext) + +Security context for the Redpanda Connectors container. See also `deployment.securityContext` for Pod-level settings. + +**Default:** + +``` +{"allowPrivilegeEscalation":false} +``` + +### [deployment.annotations](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=deployment.annotations) + +Additional annotations to apply to the Pods of this Deployment. + +**Default:** `{}` + +### [deployment.budget.maxUnavailable](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=deployment.budget.maxUnavailable) + +**Default:** `1` + +### [deployment.create](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=deployment.create) + +**Default:** `true` + +### [deployment.extraEnv](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=deployment.extraEnv) + +Additional environment variables for the Pods. + +**Default:** `[]` + +### [deployment.extraEnvFrom](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=deployment.extraEnvFrom) + +Configure extra environment variables from Secrets and ConfigMaps. + +**Default:** `[]` + +### [deployment.livenessProbe](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=deployment.livenessProbe) + +Adjust the period for your probes to meet your needs. For details, see the [Kubernetes documentation](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes). + +**Default:** + +``` +{"failureThreshold":3,"initialDelaySeconds":10,"periodSeconds":10,"successThreshold":1,"timeoutSeconds":1} +``` + +### [deployment.nodeAffinity](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=deployment.nodeAffinity) + +Node Affinity rules for scheduling Pods of this Deployment. The suggestion would be to spread Pods according to topology zone. For details, see the [Kubernetes documentation](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity). + +**Default:** `{}` + +### [deployment.nodeSelector](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=deployment.nodeSelector) + +Node selection constraints for scheduling Pods of this Deployment. These constraints override the global `nodeSelector` value. For details, see the [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector). + +**Default:** `{}` + +### [deployment.podAffinity](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=deployment.podAffinity) + +Inter-Pod Affinity rules for scheduling Pods of this Deployment. For details, see the [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#inter-pod-affinity-and-anti-affinity). + +**Default:** `{}` + +### [deployment.podAntiAffinity](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=deployment.podAntiAffinity) + +Anti-affinity rules for scheduling Pods of this Deployment. For details, see the [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#inter-pod-affinity-and-anti-affinity). You may either edit the default settings for anti-affinity rules, or specify new anti-affinity rules to use instead of the defaults. + +**Default:** + +``` +{"custom":{},"topologyKey":"kubernetes.io/hostname","type":"hard","weight":100} +``` + +### [deployment.podAntiAffinity.custom](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=deployment.podAntiAffinity.custom) + +Change `podAntiAffinity.type` to `custom` and provide your own podAntiAffinity rules here. + +**Default:** `{}` + +### [deployment.podAntiAffinity.topologyKey](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=deployment.podAntiAffinity.topologyKey) + +The `topologyKey` to be used. Can be used to spread across different nodes, AZs, regions etc. + +**Default:** `"kubernetes.io/hostname"` + +### [deployment.podAntiAffinity.type](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=deployment.podAntiAffinity.type) + +Valid anti-affinity types are `soft`, `hard`, or `custom`. Use `custom` if you want to supply your own anti-affinity rules in the `podAntiAffinity.custom` object. + +**Default:** `"hard"` + +### [deployment.podAntiAffinity.weight](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=deployment.podAntiAffinity.weight) + +Weight for `soft` anti-affinity rules. Does not apply for other anti-affinity types. + +**Default:** `100` + +### [deployment.priorityClassName](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=deployment.priorityClassName) + +PriorityClassName given to Pods of this Deployment. For details, see the [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#priorityclass). + +**Default:** `""` + +### [deployment.progressDeadlineSeconds](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=deployment.progressDeadlineSeconds) + +The maximum time in seconds for a deployment to make progress before it is considered to be failed. The deployment controller will continue to process failed deployments and a condition with a ProgressDeadlineExceeded reason will be surfaced in the deployment status. Note that progress will not be estimated during the time a deployment is paused. + +**Default:** `600` + +### [deployment.readinessProbe.failureThreshold](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=deployment.readinessProbe.failureThreshold) + +**Default:** `2` + +### [deployment.readinessProbe.initialDelaySeconds](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=deployment.readinessProbe.initialDelaySeconds) + +**Default:** `60` + +### [deployment.readinessProbe.periodSeconds](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=deployment.readinessProbe.periodSeconds) + +**Default:** `10` + +### [deployment.readinessProbe.successThreshold](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=deployment.readinessProbe.successThreshold) + +**Default:** `3` + +### [deployment.readinessProbe.timeoutSeconds](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=deployment.readinessProbe.timeoutSeconds) + +**Default:** `5` + +### [deployment.restartPolicy](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=deployment.restartPolicy) + +**Default:** `"Always"` + +### [deployment.revisionHistoryLimit](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=deployment.revisionHistoryLimit) + +The number of old ReplicaSets to retain to allow rollback. This is a pointer to distinguish between explicit zero and not specified. + +**Default:** `10` + +### [deployment.schedulerName](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=deployment.schedulerName) + +**Default:** `""` + +### [deployment.securityContext.fsGroup](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=deployment.securityContext.fsGroup) + +**Default:** `101` + +### [deployment.securityContext.fsGroupChangePolicy](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=deployment.securityContext.fsGroupChangePolicy) + +**Default:** `"OnRootMismatch"` + +### [deployment.securityContext.runAsUser](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=deployment.securityContext.runAsUser) + +**Default:** `101` + +### [deployment.strategy.type](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=deployment.strategy.type) + +**Default:** `"RollingUpdate"` + +### [deployment.terminationGracePeriodSeconds](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=deployment.terminationGracePeriodSeconds) + +**Default:** `30` + +### [deployment.tolerations](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=deployment.tolerations) + +Taints to be tolerated by Pods of this Deployment. These tolerations override the global tolerations value. For details, see the [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/). + +**Default:** `[]` + +### [deployment.topologySpreadConstraints[0].maxSkew](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=deployment.topologySpreadConstraints[0].maxSkew) + +**Default:** `1` + +### [deployment.topologySpreadConstraints[0].topologyKey](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=deployment.topologySpreadConstraints[0].topologyKey) + +**Default:** + +``` +"topology.kubernetes.io/zone" +``` + +### [deployment.topologySpreadConstraints[0].whenUnsatisfiable](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=deployment.topologySpreadConstraints[0].whenUnsatisfiable) + +**Default:** `"ScheduleAnyway"` + +### [fullnameOverride](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=fullnameOverride) + +Override `connectors.fullname` template. + +**Default:** `""` + +### [image](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=image) + +Redpanda Docker image settings. + +**Default:** + +``` +{"pullPolicy":"IfNotPresent","repository":"docker.redpanda.com/redpandadata/connectors","tag":""} +``` + +### [image.pullPolicy](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=image.pullPolicy) + +The imagePullPolicy. If `image.tag` is 'latest', the default is `Always`. + +**Default:** `"IfNotPresent"` + +### [image.repository](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=image.repository) + +Docker repository from which to pull the Redpanda Docker image. + +**Default:** + +``` +"docker.redpanda.com/redpandadata/connectors" +``` + +### [image.tag](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=image.tag) + +The Redpanda version. See DockerHub for: [All stable versions](https://hub.docker.com/r/redpandadata/redpanda/tags) and [all unstable versions](https://hub.docker.com/r/redpandadata/redpanda-unstable/tags). + +**Default:** `Chart.appVersion`. + +### [imagePullSecrets](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=imagePullSecrets) + +Pull secrets may be used to provide credentials to image repositories See https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + +**Default:** `[]` + +### [logging](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=logging) + +Log-level settings. + +**Default:** `{"level":"warn"}` + +### [logging.level](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=logging.level) + +Log level Valid values (from least to most verbose) are: `error`, `warn`, `info` and `debug`. + +**Default:** `"warn"` + +### [monitoring](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=monitoring) + +Monitoring. When set to `true`, the Helm chart creates a PodMonitor that can be used by Prometheus-Operator or VictoriaMetrics-Operator to scrape the metrics. + +**Default:** + +``` +{"annotations":{},"enabled":false,"labels":{},"namespaceSelector":{"any":true},"scrapeInterval":"30s"} +``` + +### [nameOverride](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=nameOverride) + +Override `connectors.name` template. + +**Default:** `""` + +### [service](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=service) + +Service management. + +**Default:** + +``` +{"annotations":{},"name":"","ports":[{"name":"prometheus","port":9404}]} +``` + +### [service.annotations](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=service.annotations) + +Annotations to add to the Service. + +**Default:** `{}` + +### [service.name](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=service.name) + +The name of the service to use. If not set, a name is generated using the `connectors.fullname` template. + +**Default:** `""` + +### [serviceAccount](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=serviceAccount) + +ServiceAccount management. + +**Default:** + +``` +{"annotations":{},"create":false,"name":""} +``` + +### [serviceAccount.annotations](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=serviceAccount.annotations) + +Annotations to add to the ServiceAccount. + +**Default:** `{}` + +### [serviceAccount.create](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=serviceAccount.create) + +Specifies whether a ServiceAccount should be created. + +**Default:** `false` + +### [serviceAccount.name](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=serviceAccount.name) + +The name of the ServiceAccount to use. If not set and `serviceAccount.create` is `true`, a name is generated using the `connectors.fullname` template. + +**Default:** `""` + +### [storage.volumeMounts[0].mountPath](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=storage.volumeMounts[0].mountPath) + +**Default:** `"/tmp"` + +### [storage.volumeMounts[0].name](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=storage.volumeMounts[0].name) + +**Default:** `"rp-connect-tmp"` + +### [storage.volume[0].emptyDir.medium](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=storage.volume[0].emptyDir.medium) + +**Default:** `"Memory"` + +### [storage.volume[0].emptyDir.sizeLimit](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=storage.volume[0].emptyDir.sizeLimit) + +**Default:** `"5Mi"` + +### [storage.volume[0].name](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=storage.volume[0].name) + +**Default:** `"rp-connect-tmp"` + +### [test.create](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=test.create) + +**Default:** `true` + +### [tolerations](https://artifacthub.io/packages/helm/redpanda-data/connectors?modal=values&path=tolerations) + +Taints to be tolerated by Pods. For details, see the [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/). + +**Default:** `[]` + diff --git a/charts/redpanda/redpanda/5.9.2/charts/connectors/chart_test.go b/charts/redpanda/redpanda/5.9.2/charts/connectors/chart_test.go new file mode 100644 index 0000000000..d56e956e27 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/connectors/chart_test.go @@ -0,0 +1,144 @@ +package connectors + +import ( + "encoding/json" + "fmt" + "os" + "regexp" + "slices" + "testing" + + fuzz "github.com/google/gofuzz" + "github.com/redpanda-data/helm-charts/pkg/helm" + "github.com/redpanda-data/helm-charts/pkg/testutil" + "github.com/stretchr/testify/require" + "golang.org/x/tools/txtar" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/yaml" +) + +// TestValues asserts that the chart's values.yaml file can be losslessly +// loaded into our type [Values] struct. +// NB: values.yaml should round trip through [Values], not [PartialValues], as +// [Values]'s omitempty tags are models after values.yaml. +func TestValues(t *testing.T) { + var typedValues Values + var unstructuredValues map[string]any + + require.NoError(t, yaml.Unmarshal(DefaultValuesYAML, &typedValues)) + require.NoError(t, yaml.Unmarshal(DefaultValuesYAML, &unstructuredValues)) + + typedValuesJSON, err := json.Marshal(typedValues) + require.NoError(t, err) + + unstructuredValuesJSON, err := json.Marshal(unstructuredValues) + require.NoError(t, err) + + require.JSONEq(t, string(unstructuredValuesJSON), string(typedValuesJSON)) +} + +func TestTemplate(t *testing.T) { + ctx := testutil.Context(t) + client, err := helm.New(helm.Options{ConfigHome: testutil.TempDir(t)}) + require.NoError(t, err) + + casesArchive, err := txtar.ParseFile("testdata/template-cases.txtar") + require.NoError(t, err) + + generatedCasesArchive, err := txtar.ParseFile("testdata/template-cases-generated.txtar") + require.NoError(t, err) + + goldens := testutil.NewTxTar(t, "testdata/template-cases.golden.txtar") + + for _, tc := range append(casesArchive.Files, generatedCasesArchive.Files...) { + tc := tc + t.Run(tc.Name, func(t *testing.T) { + var values PartialValues + require.NoError(t, yaml.Unmarshal(tc.Data, &values)) + + out, err := client.Template(ctx, ".", helm.TemplateOptions{ + Name: "console", + Values: values, + Set: []string{ + // Tests utilize rng; Can't have that in snapshot testing + // so always disable them. + "test.create=false", + }, + }) + require.NoError(t, err) + goldens.AssertGolden(t, testutil.YAML, fmt.Sprintf("testdata/%s.yaml.golden", tc.Name), out) + }) + } +} + +// TestGenerateCases is not a test case (sorry) but a test case generator for +// the console chart. +func TestGenerateCases(t *testing.T) { + // Nasty hack to avoid making a main function somewhere. Sorry not sorry. + if !slices.Contains(os.Args, fmt.Sprintf("-test.run=%s", t.Name())) { + t.Skipf("%s will only run if explicitly specified (-run %q)", t.Name(), t.Name()) + } + + // Makes strings easier to read. + asciiStrs := func(s *string, c fuzz.Continue) { + const alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + var x []byte + for i := 0; i < c.Intn(25); i++ { + x = append(x, alphabet[c.Intn(len(alphabet))]) + } + *s = string(x) + } + smallInts := func(s *int, c fuzz.Continue) { + *s = c.Intn(501) + } + + fuzzer := fuzz.New().NumElements(0, 3).SkipFieldsWithPattern( + regexp.MustCompile("^(SELinuxOptions|WindowsOptions|SeccompProfile|TCPSocket|HTTPHeaders|VolumeSource|Image)$"), + ).Funcs( + asciiStrs, + smallInts, + func(t *corev1.ServiceType, c fuzz.Continue) { + types := []corev1.ServiceType{ + corev1.ServiceTypeClusterIP, + corev1.ServiceTypeExternalName, + corev1.ServiceTypeNodePort, + corev1.ServiceTypeLoadBalancer, + } + *t = types[c.Intn(len(types))] + }, + func(s *corev1.ResourceName, c fuzz.Continue) { asciiStrs((*string)(s), c) }, + func(_ *any, c fuzz.Continue) {}, + func(_ *[]corev1.ResourceClaim, c fuzz.Continue) {}, + func(_ *[]metav1.ManagedFieldsEntry, c fuzz.Continue) {}, + ) + + nilChance := float64(0.8) + + files := make([]txtar.File, 0, 50) + for i := 0; i < 50; i++ { + // Every 5 iterations, decrease nil chance to ensure that we're biased + // towards exploring most cases. + if i%5 == 0 && nilChance > .1 { + nilChance -= .1 + } + + var values PartialValues + fuzzer.NilChance(nilChance).Fuzz(&values) + + out, err := yaml.Marshal(values) + require.NoError(t, err) + + files = append(files, txtar.File{ + Name: fmt.Sprintf("case-%03d", i), + Data: out, + }) + } + + archive := txtar.Format(&txtar.Archive{ + Comment: []byte(fmt.Sprintf(`Generated by %s`, t.Name())), + Files: files, + }) + + require.NoError(t, os.WriteFile("testdata/template-cases-generated.txtar", archive, 0o644)) +} diff --git a/charts/redpanda/redpanda/5.9.2/charts/connectors/ci/01-default-values.yaml b/charts/redpanda/redpanda/5.9.2/charts/connectors/ci/01-default-values.yaml new file mode 100644 index 0000000000..d0dbb71c23 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/connectors/ci/01-default-values.yaml @@ -0,0 +1,34 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You 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. +--- +connectors: + bootstrapServers: "redpanda-0.redpanda.redpanda.svc.cluster.local.:9093,redpanda-1.redpanda.redpanda.svc.cluster.local.:9093,redpanda-2.redpanda.redpanda.svc.cluster.local.:9093" + brokerTLS: + enabled: true + ca: + secretRef: redpanda-default-cert + +logging: + level: trace + +deployment: + annotations: + test: test + test2: test2 + +service: + annotations: + test: test + test2: test2 diff --git a/charts/redpanda/redpanda/5.9.2/charts/connectors/ci/02-broker-tls-values.yaml b/charts/redpanda/redpanda/5.9.2/charts/connectors/ci/02-broker-tls-values.yaml new file mode 100644 index 0000000000..42f0ebc173 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/connectors/ci/02-broker-tls-values.yaml @@ -0,0 +1,28 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You 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. +--- +connectors: + bootstrapServers: "redpanda-0.redpanda.redpanda.svc.cluster.local.:9093,redpanda-1.redpanda.redpanda.svc.cluster.local.:9093,redpanda-2.redpanda.redpanda.svc.cluster.local.:9093" + brokerTLS: + enabled: true + ca: + secretRef: redpanda-default-cert + cert: + secretRef: redpanda-default-cert + key: + secretRef: redpanda-default-cert + +logging: + level: trace diff --git a/charts/redpanda/redpanda/5.9.2/charts/connectors/deployment.go b/charts/redpanda/redpanda/5.9.2/charts/connectors/deployment.go new file mode 100644 index 0000000000..2580668adf --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/connectors/deployment.go @@ -0,0 +1,394 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You 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. +// +// +gotohelm:filename=_deployment.go.tpl +package connectors + +import ( + "fmt" + + "github.com/redpanda-data/helm-charts/pkg/gotohelm/helmette" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/utils/ptr" +) + +func Deployment(dot *helmette.Dot) *appsv1.Deployment { + values := helmette.Unwrap[Values](dot.Values) + + if !values.Deployment.Create { + return nil + } + + var topologySpreadConstraints []corev1.TopologySpreadConstraint + for _, spread := range values.Deployment.TopologySpreadConstraints { + topologySpreadConstraints = append(topologySpreadConstraints, corev1.TopologySpreadConstraint{ + LabelSelector: &metav1.LabelSelector{ + MatchLabels: PodLabels(dot), + }, + MaxSkew: spread.MaxSkew, + TopologyKey: spread.TopologyKey, + WhenUnsatisfiable: spread.WhenUnsatisfiable, + }) + } + + ports := []corev1.ContainerPort{ + { + ContainerPort: values.Connectors.RestPort, + Name: "rest-api", + Protocol: corev1.ProtocolTCP, + }, + } + + for _, port := range values.Service.Ports { + ports = append(ports, corev1.ContainerPort{ + Name: port.Name, + ContainerPort: port.Port, + Protocol: corev1.ProtocolTCP, + }) + } + + var podAntiAffinity *corev1.PodAntiAffinity + if values.Deployment.PodAntiAffinity != nil { + if values.Deployment.PodAntiAffinity.Type == "hard" { + podAntiAffinity = &corev1.PodAntiAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: []corev1.PodAffinityTerm{{ + TopologyKey: values.Deployment.PodAntiAffinity.TopologyKey, + Namespaces: []string{dot.Release.Namespace}, + LabelSelector: &metav1.LabelSelector{ + MatchLabels: PodLabels(dot), + }, + }}, + } + } else if values.Deployment.PodAntiAffinity.Type == "soft" { + podAntiAffinity = &corev1.PodAntiAffinity{ + PreferredDuringSchedulingIgnoredDuringExecution: []corev1.WeightedPodAffinityTerm{{ + Weight: *values.Deployment.PodAntiAffinity.Weight, + PodAffinityTerm: corev1.PodAffinityTerm{ + TopologyKey: values.Deployment.PodAntiAffinity.TopologyKey, + Namespaces: []string{dot.Release.Namespace}, + LabelSelector: &metav1.LabelSelector{ + MatchLabels: PodLabels(dot), + }, + }, + }}, + } + } else if values.Deployment.PodAntiAffinity.Type == "custom" { + podAntiAffinity = values.Deployment.PodAntiAffinity.Custom + } + } + + return &appsv1.Deployment{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "apps/v1", + Kind: "Deployment", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: Fullname(dot), + Labels: helmette.Merge(FullLabels(dot), values.Deployment.Annotations), + }, + Spec: appsv1.DeploymentSpec{ + Replicas: values.Deployment.Replicas, + ProgressDeadlineSeconds: &values.Deployment.ProgressDeadlineSeconds, + RevisionHistoryLimit: values.Deployment.RevisionHistoryLimit, + Selector: &metav1.LabelSelector{ + MatchLabels: PodLabels(dot), + }, + Strategy: values.Deployment.Strategy, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: values.Deployment.Annotations, + Labels: PodLabels(dot), + }, + Spec: corev1.PodSpec{ + TerminationGracePeriodSeconds: values.Deployment.TerminationGracePeriodSeconds, + Affinity: &corev1.Affinity{ + NodeAffinity: values.Deployment.NodeAffinity, + PodAffinity: values.Deployment.PodAffinity, + PodAntiAffinity: podAntiAffinity, + }, + ServiceAccountName: ServiceAccountName(dot), + Containers: []corev1.Container{ + { + Name: "connectors-cluster", + Image: fmt.Sprintf("%s:%s", values.Image.Repository, Tag(dot)), + ImagePullPolicy: values.Image.PullPolicy, + SecurityContext: &values.Container.SecurityContext, + Command: values.Deployment.Command, + Env: env(&values), + EnvFrom: values.Deployment.ExtraEnvFrom, + LivenessProbe: &corev1.Probe{ + ProbeHandler: corev1.ProbeHandler{ + HTTPGet: &corev1.HTTPGetAction{ + Path: "/", + Port: intstr.FromString("rest-api"), + Scheme: corev1.URISchemeHTTP, + }, + }, + InitialDelaySeconds: values.Deployment.LivenessProbe.InitialDelaySeconds, + TimeoutSeconds: values.Deployment.LivenessProbe.TimeoutSeconds, + PeriodSeconds: values.Deployment.LivenessProbe.PeriodSeconds, + SuccessThreshold: values.Deployment.LivenessProbe.SuccessThreshold, + FailureThreshold: values.Deployment.LivenessProbe.FailureThreshold, + }, + ReadinessProbe: &corev1.Probe{ + ProbeHandler: corev1.ProbeHandler{ + HTTPGet: &corev1.HTTPGetAction{ + Path: "/connectors", + Port: intstr.FromString("rest-api"), + Scheme: corev1.URISchemeHTTP, + }, + }, + InitialDelaySeconds: values.Deployment.ReadinessProbe.InitialDelaySeconds, + TimeoutSeconds: values.Deployment.ReadinessProbe.TimeoutSeconds, + PeriodSeconds: values.Deployment.ReadinessProbe.PeriodSeconds, + SuccessThreshold: values.Deployment.ReadinessProbe.SuccessThreshold, + FailureThreshold: values.Deployment.ReadinessProbe.FailureThreshold, + }, + Ports: ports, + Resources: corev1.ResourceRequirements{ + Requests: values.Container.Resources.Request, + Limits: values.Container.Resources.Limits, + }, + TerminationMessagePath: "/dev/termination-log", + TerminationMessagePolicy: "File", + VolumeMounts: volumeMountss(&values), + }, + }, + DNSPolicy: corev1.DNSClusterFirst, + RestartPolicy: values.Deployment.RestartPolicy, + SchedulerName: values.Deployment.SchedulerName, + NodeSelector: values.Deployment.NodeSelector, + ImagePullSecrets: values.ImagePullSecrets, + SecurityContext: values.Deployment.SecurityContext, + Tolerations: values.Deployment.Tolerations, + TopologySpreadConstraints: topologySpreadConstraints, + Volumes: volumes(&values), + }, + }, + }, + } +} + +func env(values *Values) []corev1.EnvVar { + env := []corev1.EnvVar{ + { + Name: "CONNECT_CONFIGURATION", + Value: connectorConfiguration(values), + }, + { + Name: "CONNECT_ADDITIONAL_CONFIGURATION", + Value: values.Connectors.AdditionalConfiguration, + }, + { + Name: "CONNECT_BOOTSTRAP_SERVERS", + Value: values.Connectors.BootstrapServers, + }, + } + + if !helmette.Empty(values.Connectors.SchemaRegistryURL) { + env = append(env, corev1.EnvVar{ + Name: "SCHEMA_REGISTRY_URL", + Value: values.Connectors.SchemaRegistryURL, + }) + } + + env = append(env, corev1.EnvVar{ + Name: "CONNECT_GC_LOG_ENABLED", + Value: values.Container.JavaGCLogEnabled, + }, corev1.EnvVar{ + Name: "CONNECT_HEAP_OPTS", + Value: fmt.Sprintf("-Xms256M -Xmx%s", values.Container.Resources.JavaMaxHeapSize), + }, corev1.EnvVar{ + Name: "CONNECT_LOG_LEVEL", + Value: values.Logging.Level, + }) + + if values.Auth.SASLEnabled() { + env = append(env, corev1.EnvVar{ + Name: "CONNECT_SASL_USERNAME", + Value: values.Auth.SASL.UserName, + }, corev1.EnvVar{ + Name: "CONNECT_SASL_MECHANISM", + Value: values.Auth.SASL.Mechanism, + }, corev1.EnvVar{ + Name: "CONNECT_SASL_PASSWORD_FILE", + Value: "rc-credentials/password", + }) + } + + env = append(env, corev1.EnvVar{ + Name: "CONNECT_TLS_ENABLED", + Value: fmt.Sprintf("%v", values.Connectors.BrokerTLS.Enabled), + }) + + if !helmette.Empty(values.Connectors.BrokerTLS.CA.SecretRef) { + ca := helmette.Default("ca.crt", values.Connectors.BrokerTLS.CA.SecretNameOverwrite) + env = append(env, corev1.EnvVar{ + Name: "CONNECT_TRUSTED_CERTS", + Value: fmt.Sprintf("ca/%s", ca), + }) + } + + if !helmette.Empty(values.Connectors.BrokerTLS.Cert.SecretRef) { + cert := helmette.Default("tls.crt", values.Connectors.BrokerTLS.Cert.SecretNameOverwrite) + env = append(env, corev1.EnvVar{ + Name: "CONNECT_TLS_AUTH_CERT", + Value: fmt.Sprintf("cert/%s", cert), + }) + } + + if !helmette.Empty(values.Connectors.BrokerTLS.Key.SecretRef) { + key := helmette.Default("tls.key", values.Connectors.BrokerTLS.Key.SecretNameOverwrite) + env = append(env, corev1.EnvVar{ + Name: "CONNECT_TLS_AUTH_KEY", + Value: fmt.Sprintf("key/%s", key), + }) + } + + return append(env, values.Deployment.ExtraEnv...) +} + +func connectorConfiguration(values *Values) string { + lines := []string{ + fmt.Sprintf("rest.advertised.port=%d", values.Connectors.RestPort), + fmt.Sprintf("rest.port=%d", values.Connectors.RestPort), + "key.converter=org.apache.kafka.connect.converters.ByteArrayConverter", + "value.converter=org.apache.kafka.connect.converters.ByteArrayConverter", + fmt.Sprintf("group.id=%s", values.Connectors.GroupID), + fmt.Sprintf("offset.storage.topic=%s", values.Connectors.Storage.Topic.Offset), + fmt.Sprintf("config.storage.topic=%s", values.Connectors.Storage.Topic.Config), + fmt.Sprintf("status.storage.topic=%s", values.Connectors.Storage.Topic.Status), + fmt.Sprintf("offset.storage.redpanda.remote.read=%t", values.Connectors.Storage.Remote.Read.Offset), + fmt.Sprintf("offset.storage.redpanda.remote.write=%t", values.Connectors.Storage.Remote.Write.Offset), + fmt.Sprintf("config.storage.redpanda.remote.read=%t", values.Connectors.Storage.Remote.Read.Config), + fmt.Sprintf("config.storage.redpanda.remote.write=%t", values.Connectors.Storage.Remote.Write.Config), + fmt.Sprintf("status.storage.redpanda.remote.read=%t", values.Connectors.Storage.Remote.Read.Status), + fmt.Sprintf("status.storage.redpanda.remote.write=%t", values.Connectors.Storage.Remote.Write.Status), + fmt.Sprintf("offset.storage.replication.factor=%d", values.Connectors.Storage.ReplicationFactor.Offset), + fmt.Sprintf("config.storage.replication.factor=%d", values.Connectors.Storage.ReplicationFactor.Config), + fmt.Sprintf("status.storage.replication.factor=%d", values.Connectors.Storage.ReplicationFactor.Status), + fmt.Sprintf("producer.linger.ms=%d", values.Connectors.ProducerLingerMS), + fmt.Sprintf("producer.batch.size=%d", values.Connectors.ProducerBatchSize), + "config.providers=file,secretsManager,env", + "config.providers.file.class=org.apache.kafka.common.config.provider.FileConfigProvider", + } + + if values.Connectors.SecretManager.Enabled { + lines = append( + lines, + "config.providers.secretsManager.class=com.github.jcustenborder.kafka.config.aws.SecretsManagerConfigProvider", + fmt.Sprintf("config.providers.secretsManager.param.secret.prefix=%s%s", values.Connectors.SecretManager.ConsolePrefix, values.Connectors.SecretManager.ConnectorsPrefix), + fmt.Sprintf("config.providers.secretsManager.param.aws.region=%s", values.Connectors.SecretManager.Region), + ) + } + + lines = append( + lines, + "config.providers.env.class=org.apache.kafka.common.config.provider.EnvVarConfigProvider", + ) + + return helmette.Join("\n", lines) +} + +func volumes(values *Values) []corev1.Volume { + var volumes []corev1.Volume + if !helmette.Empty(values.Connectors.BrokerTLS.CA.SecretRef) { + volumes = append(volumes, corev1.Volume{ + Name: "truststore", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + DefaultMode: ptr.To[int32](0o444), + SecretName: values.Connectors.BrokerTLS.CA.SecretRef, + }, + }, + }) + } + if !helmette.Empty(values.Connectors.BrokerTLS.Cert.SecretRef) { + volumes = append(volumes, corev1.Volume{ + Name: "cert", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + DefaultMode: ptr.To[int32](0o444), + SecretName: values.Connectors.BrokerTLS.Cert.SecretRef, + }, + }, + }) + } + if !helmette.Empty(values.Connectors.BrokerTLS.Key.SecretRef) { + volumes = append(volumes, corev1.Volume{ + Name: "key", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + DefaultMode: ptr.To[int32](0o444), + SecretName: values.Connectors.BrokerTLS.Key.SecretRef, + }, + }, + }) + } + + if values.Auth.SASLEnabled() { + volumes = append(volumes, corev1.Volume{ + Name: "rc-credentials", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + DefaultMode: ptr.To[int32](0o444), + SecretName: values.Auth.SASL.SecretRef, + }, + }, + }) + } + + return append(volumes, values.Storage.Volume...) +} + +func volumeMountss(values *Values) []corev1.VolumeMount { + var mounts []corev1.VolumeMount + + if values.Auth.SASLEnabled() { + mounts = append(mounts, corev1.VolumeMount{ + MountPath: "/opt/kafka/connect-password/rc-credentials", + Name: "rc-credentials", + }) + } + + if !helmette.Empty(values.Connectors.BrokerTLS.CA.SecretRef) { + // The /opt/kafka/connect-certs is fixed path within Connectors + mounts = append(mounts, corev1.VolumeMount{ + Name: "truststore", + MountPath: "/opt/kafka/connect-certs/ca", + }) + } + + if !helmette.Empty(values.Connectors.BrokerTLS.Cert.SecretRef) { + // The /opt/kafka/connect-certs is fixed path within Connectors + mounts = append(mounts, corev1.VolumeMount{ + Name: "cert", + MountPath: "/opt/kafka/connect-certs/cert", + }) + } + + if !helmette.Empty(values.Connectors.BrokerTLS.Key.SecretRef) { + // The /opt/kafka/connect-certs is fixed path within Connectors + mounts = append(mounts, corev1.VolumeMount{ + Name: "key", + MountPath: "/opt/kafka/connect-certs/key", + }) + } + + return append(mounts, values.Storage.VolumeMounts...) +} diff --git a/charts/redpanda/redpanda/5.9.2/charts/connectors/helpers.go b/charts/redpanda/redpanda/5.9.2/charts/connectors/helpers.go new file mode 100644 index 0000000000..9440b61e28 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/connectors/helpers.go @@ -0,0 +1,101 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You 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. +// +// +gotohelm:filename=_helpers.go.tpl +package connectors + +import ( + "fmt" + + "github.com/redpanda-data/helm-charts/pkg/gotohelm/helmette" +) + +func Name(dot *helmette.Dot) string { + values := helmette.Unwrap[Values](dot.Values) + name := helmette.Default(dot.Chart.Name, values.NameOverride) + return trunc(name) +} + +func Fullname(dot *helmette.Dot) string { + values := helmette.Unwrap[Values](dot.Values) + + if !helmette.Empty(values.FullnameOverride) { + return trunc(values.FullnameOverride) + } + + name := helmette.Default(dot.Chart.Name, values.NameOverride) + + if helmette.Contains(name, dot.Release.Name) { + return trunc(dot.Release.Name) + } + return trunc(fmt.Sprintf("%s-%s", dot.Release.Name, name)) +} + +func FullLabels(dot *helmette.Dot) map[string]string { + return helmette.Merge(map[string]string{ + "helm.sh/chart": Chart(dot), + "app.kubernetes.io/managed-by": dot.Release.Service, + }, PodLabels(dot)) +} + +func PodLabels(dot *helmette.Dot) map[string]string { + values := helmette.Unwrap[Values](dot.Values) + return helmette.Merge(map[string]string{ + "app.kubernetes.io/name": Name(dot), + "app.kubernetes.io/instance": dot.Release.Name, + "app.kubernetes.io/component": Name(dot), + }, values.CommonLabels) +} + +func Chart(dot *helmette.Dot) string { + chart := fmt.Sprintf("%s-%s", dot.Chart.Name, dot.Chart.Version) + return trunc(helmette.Replace("+", "_", chart)) +} + +func Semver(dot *helmette.Dot) string { + return helmette.TrimPrefix("v", Tag(dot)) +} + +func ServiceAccountName(dot *helmette.Dot) string { + values := helmette.Unwrap[Values](dot.Values) + if values.ServiceAccount.Create { + return helmette.Default(Fullname(dot), values.ServiceAccount.Name) + } + return helmette.Default("default", values.ServiceAccount.Name) +} + +func ServiceName(dot *helmette.Dot) string { + values := helmette.Unwrap[Values](dot.Values) + return helmette.Default(Fullname(dot), values.Service.Name) +} + +func Tag(dot *helmette.Dot) string { + values := helmette.Unwrap[Values](dot.Values) + + tag := helmette.Default(dot.Chart.AppVersion, values.Image.Tag) + matchString := "^v(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$" + + if !helmette.MustRegexMatch(matchString, tag) { + // This error message is for end users. This can also occur if + // AppVersion doesn't start with a 'v' in Chart.yaml. + panic("image.tag must start with a 'v' and be a valid semver") + } + + return tag +} + +func trunc(s string) string { + return helmette.TrimSuffix("-", helmette.Trunc(63, s)) +} diff --git a/charts/redpanda/redpanda/5.9.2/charts/connectors/podmonitor.go b/charts/redpanda/redpanda/5.9.2/charts/connectors/podmonitor.go new file mode 100644 index 0000000000..fbee5c59e5 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/connectors/podmonitor.go @@ -0,0 +1,56 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You 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. +// +// +gotohelm:filename=_pod-monitor.go.tpl +package connectors + +import ( + monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" + "github.com/redpanda-data/helm-charts/pkg/gotohelm/helmette" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func PodMonitor(dot *helmette.Dot) *monitoringv1.PodMonitor { + values := helmette.Unwrap[Values](dot.Values) + + // TODO Add check for .Capabilities.APIVersions.Has "monitoring.coreos.com/v1" + if !values.Monitoring.Enabled { + return nil + } + + return &monitoringv1.PodMonitor{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "monitoring.coreos.com/v1", + Kind: "PodMonitor", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: Fullname(dot), + Labels: values.Monitoring.Labels, + Annotations: values.Monitoring.Annotations, + }, + Spec: monitoringv1.PodMonitorSpec{ + NamespaceSelector: values.Monitoring.NamespaceSelector, + PodMetricsEndpoints: []monitoringv1.PodMetricsEndpoint{ + { + Path: "/", + Port: "prometheus", + }, + }, + Selector: metav1.LabelSelector{ + MatchLabels: PodLabels(dot), + }, + }, + } +} diff --git a/charts/redpanda/redpanda/5.9.2/charts/connectors/service.go b/charts/redpanda/redpanda/5.9.2/charts/connectors/service.go new file mode 100644 index 0000000000..17d39fba8b --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/connectors/service.go @@ -0,0 +1,74 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You 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. +// +// +gotohelm:filename=_service.go.tpl +package connectors + +import ( + "github.com/redpanda-data/helm-charts/pkg/gotohelm/helmette" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/utils/ptr" +) + +func Service(dot *helmette.Dot) *corev1.Service { + values := helmette.Unwrap[Values](dot.Values) + + ports := []corev1.ServicePort{ + { + Name: "rest-api", + Port: values.Connectors.RestPort, + TargetPort: intstr.FromInt32(values.Connectors.RestPort), + Protocol: corev1.ProtocolTCP, + }, + } + + for _, port := range values.Service.Ports { + ports = append(ports, corev1.ServicePort{ + Name: port.Name, + Port: port.Port, + TargetPort: intstr.FromInt32(port.Port), + Protocol: corev1.ProtocolTCP, + }) + } + + return &corev1.Service{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "v1", + Kind: "Service", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: ServiceName(dot), + // TODO this isn't 100% correct as users could have previously + // added: `annotations: {}` as the value for annotations to get + // them to render correctly. + Labels: helmette.Merge( + FullLabels(dot), + values.Service.Annotations, + ), + }, + Spec: corev1.ServiceSpec{ + IPFamilies: []corev1.IPFamily{ + corev1.IPv4Protocol, + }, + IPFamilyPolicy: ptr.To(corev1.IPFamilyPolicySingleStack), + Ports: ports, + Selector: PodLabels(dot), + SessionAffinity: corev1.ServiceAffinityNone, + Type: corev1.ServiceTypeClusterIP, + }, + } +} diff --git a/charts/redpanda/redpanda/5.9.2/charts/connectors/serviceaccount.go b/charts/redpanda/redpanda/5.9.2/charts/connectors/serviceaccount.go new file mode 100644 index 0000000000..2b689effd6 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/connectors/serviceaccount.go @@ -0,0 +1,44 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You 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. +// +// +gotohelm:filename=_serviceaccount.go.tpl +package connectors + +import ( + "github.com/redpanda-data/helm-charts/pkg/gotohelm/helmette" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func ServiceAccount(dot *helmette.Dot) *corev1.ServiceAccount { + values := helmette.Unwrap[Values](dot.Values) + + if !values.ServiceAccount.Create { + return nil + } + + return &corev1.ServiceAccount{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "v1", + Kind: "ServiceAccount", + }, + ObjectMeta: metav1.ObjectMeta{ + Annotations: values.ServiceAccount.Annotations, + Labels: FullLabels(dot), + Name: ServiceAccountName(dot), + Namespace: dot.Release.Namespace, + }, + } +} diff --git a/charts/redpanda/redpanda/5.9.2/charts/connectors/templates/_deployment.go.tpl b/charts/redpanda/redpanda/5.9.2/charts/connectors/templates/_deployment.go.tpl new file mode 100644 index 0000000000..f785c1ad92 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/connectors/templates/_deployment.go.tpl @@ -0,0 +1,136 @@ +{{- /* Generated from "deployment.go" */ -}} + +{{- define "connectors.Deployment" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (not $values.deployment.create) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $topologySpreadConstraints := (coalesce nil) -}} +{{- range $_, $spread := $values.deployment.topologySpreadConstraints -}} +{{- $topologySpreadConstraints = (concat (default (list ) $topologySpreadConstraints) (list (mustMergeOverwrite (dict "maxSkew" 0 "topologyKey" "" "whenUnsatisfiable" "" ) (dict "labelSelector" (mustMergeOverwrite (dict ) (dict "matchLabels" (get (fromJson (include "connectors.PodLabels" (dict "a" (list $dot) ))) "r") )) "maxSkew" ($spread.maxSkew | int) "topologyKey" $spread.topologyKey "whenUnsatisfiable" $spread.whenUnsatisfiable )))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $ports := (list (mustMergeOverwrite (dict "containerPort" 0 ) (dict "containerPort" ($values.connectors.restPort | int) "name" "rest-api" "protocol" "TCP" ))) -}} +{{- range $_, $port := $values.service.ports -}} +{{- $ports = (concat (default (list ) $ports) (list (mustMergeOverwrite (dict "containerPort" 0 ) (dict "name" $port.name "containerPort" ($port.port | int) "protocol" "TCP" )))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $podAntiAffinity := (coalesce nil) -}} +{{- if (ne $values.deployment.podAntiAffinity (coalesce nil)) -}} +{{- if (eq $values.deployment.podAntiAffinity.type "hard") -}} +{{- $podAntiAffinity = (mustMergeOverwrite (dict ) (dict "requiredDuringSchedulingIgnoredDuringExecution" (list (mustMergeOverwrite (dict "topologyKey" "" ) (dict "topologyKey" $values.deployment.podAntiAffinity.topologyKey "namespaces" (list $dot.Release.Namespace) "labelSelector" (mustMergeOverwrite (dict ) (dict "matchLabels" (get (fromJson (include "connectors.PodLabels" (dict "a" (list $dot) ))) "r") )) ))) )) -}} +{{- else -}}{{- if (eq $values.deployment.podAntiAffinity.type "soft") -}} +{{- $podAntiAffinity = (mustMergeOverwrite (dict ) (dict "preferredDuringSchedulingIgnoredDuringExecution" (list (mustMergeOverwrite (dict "weight" 0 "podAffinityTerm" (dict "topologyKey" "" ) ) (dict "weight" $values.deployment.podAntiAffinity.weight "podAffinityTerm" (mustMergeOverwrite (dict "topologyKey" "" ) (dict "topologyKey" $values.deployment.podAntiAffinity.topologyKey "namespaces" (list $dot.Release.Namespace) "labelSelector" (mustMergeOverwrite (dict ) (dict "matchLabels" (get (fromJson (include "connectors.PodLabels" (dict "a" (list $dot) ))) "r") )) )) ))) )) -}} +{{- else -}}{{- if (eq $values.deployment.podAntiAffinity.type "custom") -}} +{{- $podAntiAffinity = $values.deployment.podAntiAffinity.custom -}} +{{- end -}} +{{- end -}} +{{- end -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "spec" (dict "selector" (coalesce nil) "template" (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "spec" (dict "containers" (coalesce nil) ) ) "strategy" (dict ) ) "status" (dict ) ) (mustMergeOverwrite (dict ) (dict "apiVersion" "apps/v1" "kind" "Deployment" )) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "name" (get (fromJson (include "connectors.Fullname" (dict "a" (list $dot) ))) "r") "labels" (merge (dict ) (get (fromJson (include "connectors.FullLabels" (dict "a" (list $dot) ))) "r") $values.deployment.annotations) )) "spec" (mustMergeOverwrite (dict "selector" (coalesce nil) "template" (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "spec" (dict "containers" (coalesce nil) ) ) "strategy" (dict ) ) (dict "replicas" $values.deployment.replicas "progressDeadlineSeconds" ($values.deployment.progressDeadlineSeconds | int) "revisionHistoryLimit" $values.deployment.revisionHistoryLimit "selector" (mustMergeOverwrite (dict ) (dict "matchLabels" (get (fromJson (include "connectors.PodLabels" (dict "a" (list $dot) ))) "r") )) "strategy" $values.deployment.strategy "template" (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "spec" (dict "containers" (coalesce nil) ) ) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "annotations" $values.deployment.annotations "labels" (get (fromJson (include "connectors.PodLabels" (dict "a" (list $dot) ))) "r") )) "spec" (mustMergeOverwrite (dict "containers" (coalesce nil) ) (dict "terminationGracePeriodSeconds" $values.deployment.terminationGracePeriodSeconds "affinity" (mustMergeOverwrite (dict ) (dict "nodeAffinity" $values.deployment.nodeAffinity "podAffinity" $values.deployment.podAffinity "podAntiAffinity" $podAntiAffinity )) "serviceAccountName" (get (fromJson (include "connectors.ServiceAccountName" (dict "a" (list $dot) ))) "r") "containers" (list (mustMergeOverwrite (dict "name" "" "resources" (dict ) ) (dict "name" "connectors-cluster" "image" (printf "%s:%s" $values.image.repository (get (fromJson (include "connectors.Tag" (dict "a" (list $dot) ))) "r")) "imagePullPolicy" $values.image.pullPolicy "securityContext" $values.container.securityContext "command" $values.deployment.command "env" (get (fromJson (include "connectors.env" (dict "a" (list $values) ))) "r") "envFrom" $values.deployment.extraEnvFrom "livenessProbe" (mustMergeOverwrite (dict ) (mustMergeOverwrite (dict ) (dict "httpGet" (mustMergeOverwrite (dict "port" 0 ) (dict "path" "/" "port" "rest-api" "scheme" "HTTP" )) )) (dict "initialDelaySeconds" ($values.deployment.livenessProbe.initialDelaySeconds | int) "timeoutSeconds" ($values.deployment.livenessProbe.timeoutSeconds | int) "periodSeconds" ($values.deployment.livenessProbe.periodSeconds | int) "successThreshold" ($values.deployment.livenessProbe.successThreshold | int) "failureThreshold" ($values.deployment.livenessProbe.failureThreshold | int) )) "readinessProbe" (mustMergeOverwrite (dict ) (mustMergeOverwrite (dict ) (dict "httpGet" (mustMergeOverwrite (dict "port" 0 ) (dict "path" "/connectors" "port" "rest-api" "scheme" "HTTP" )) )) (dict "initialDelaySeconds" ($values.deployment.readinessProbe.initialDelaySeconds | int) "timeoutSeconds" ($values.deployment.readinessProbe.timeoutSeconds | int) "periodSeconds" ($values.deployment.readinessProbe.periodSeconds | int) "successThreshold" ($values.deployment.readinessProbe.successThreshold | int) "failureThreshold" ($values.deployment.readinessProbe.failureThreshold | int) )) "ports" $ports "resources" (mustMergeOverwrite (dict ) (dict "requests" $values.container.resources.request "limits" $values.container.resources.limits )) "terminationMessagePath" "/dev/termination-log" "terminationMessagePolicy" "File" "volumeMounts" (get (fromJson (include "connectors.volumeMountss" (dict "a" (list $values) ))) "r") ))) "dnsPolicy" "ClusterFirst" "restartPolicy" $values.deployment.restartPolicy "schedulerName" $values.deployment.schedulerName "nodeSelector" $values.deployment.nodeSelector "imagePullSecrets" $values.imagePullSecrets "securityContext" $values.deployment.securityContext "tolerations" $values.deployment.tolerations "topologySpreadConstraints" $topologySpreadConstraints "volumes" (get (fromJson (include "connectors.volumes" (dict "a" (list $values) ))) "r") )) )) )) ))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "connectors.env" -}} +{{- $values := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $env := (list (mustMergeOverwrite (dict "name" "" ) (dict "name" "CONNECT_CONFIGURATION" "value" (get (fromJson (include "connectors.connectorConfiguration" (dict "a" (list $values) ))) "r") )) (mustMergeOverwrite (dict "name" "" ) (dict "name" "CONNECT_ADDITIONAL_CONFIGURATION" "value" $values.connectors.additionalConfiguration )) (mustMergeOverwrite (dict "name" "" ) (dict "name" "CONNECT_BOOTSTRAP_SERVERS" "value" $values.connectors.bootstrapServers ))) -}} +{{- if (not (empty $values.connectors.schemaRegistryURL)) -}} +{{- $env = (concat (default (list ) $env) (list (mustMergeOverwrite (dict "name" "" ) (dict "name" "SCHEMA_REGISTRY_URL" "value" $values.connectors.schemaRegistryURL )))) -}} +{{- end -}} +{{- $env = (concat (default (list ) $env) (list (mustMergeOverwrite (dict "name" "" ) (dict "name" "CONNECT_GC_LOG_ENABLED" "value" $values.container.javaGCLogEnabled )) (mustMergeOverwrite (dict "name" "" ) (dict "name" "CONNECT_HEAP_OPTS" "value" (printf "-Xms256M -Xmx%s" $values.container.resources.javaMaxHeapSize) )) (mustMergeOverwrite (dict "name" "" ) (dict "name" "CONNECT_LOG_LEVEL" "value" $values.logging.level )))) -}} +{{- if (get (fromJson (include "connectors.Auth.SASLEnabled" (dict "a" (list $values.auth) ))) "r") -}} +{{- $env = (concat (default (list ) $env) (list (mustMergeOverwrite (dict "name" "" ) (dict "name" "CONNECT_SASL_USERNAME" "value" $values.auth.sasl.userName )) (mustMergeOverwrite (dict "name" "" ) (dict "name" "CONNECT_SASL_MECHANISM" "value" $values.auth.sasl.mechanism )) (mustMergeOverwrite (dict "name" "" ) (dict "name" "CONNECT_SASL_PASSWORD_FILE" "value" "rc-credentials/password" )))) -}} +{{- end -}} +{{- $env = (concat (default (list ) $env) (list (mustMergeOverwrite (dict "name" "" ) (dict "name" "CONNECT_TLS_ENABLED" "value" (printf "%v" $values.connectors.brokerTLS.enabled) )))) -}} +{{- if (not (empty $values.connectors.brokerTLS.ca.secretRef)) -}} +{{- $ca := (default "ca.crt" $values.connectors.brokerTLS.ca.secretNameOverwrite) -}} +{{- $env = (concat (default (list ) $env) (list (mustMergeOverwrite (dict "name" "" ) (dict "name" "CONNECT_TRUSTED_CERTS" "value" (printf "ca/%s" $ca) )))) -}} +{{- end -}} +{{- if (not (empty $values.connectors.brokerTLS.cert.secretRef)) -}} +{{- $cert := (default "tls.crt" $values.connectors.brokerTLS.cert.secretNameOverwrite) -}} +{{- $env = (concat (default (list ) $env) (list (mustMergeOverwrite (dict "name" "" ) (dict "name" "CONNECT_TLS_AUTH_CERT" "value" (printf "cert/%s" $cert) )))) -}} +{{- end -}} +{{- if (not (empty $values.connectors.brokerTLS.key.secretRef)) -}} +{{- $key := (default "tls.key" $values.connectors.brokerTLS.key.secretNameOverwrite) -}} +{{- $env = (concat (default (list ) $env) (list (mustMergeOverwrite (dict "name" "" ) (dict "name" "CONNECT_TLS_AUTH_KEY" "value" (printf "key/%s" $key) )))) -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (concat (default (list ) $env) (default (list ) $values.deployment.extraEnv))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "connectors.connectorConfiguration" -}} +{{- $values := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $lines := (list (printf "rest.advertised.port=%d" ($values.connectors.restPort | int)) (printf "rest.port=%d" ($values.connectors.restPort | int)) "key.converter=org.apache.kafka.connect.converters.ByteArrayConverter" "value.converter=org.apache.kafka.connect.converters.ByteArrayConverter" (printf "group.id=%s" $values.connectors.groupID) (printf "offset.storage.topic=%s" $values.connectors.storage.topic.offset) (printf "config.storage.topic=%s" $values.connectors.storage.topic.config) (printf "status.storage.topic=%s" $values.connectors.storage.topic.status) (printf "offset.storage.redpanda.remote.read=%t" $values.connectors.storage.remote.read.offset) (printf "offset.storage.redpanda.remote.write=%t" $values.connectors.storage.remote.write.offset) (printf "config.storage.redpanda.remote.read=%t" $values.connectors.storage.remote.read.config) (printf "config.storage.redpanda.remote.write=%t" $values.connectors.storage.remote.write.config) (printf "status.storage.redpanda.remote.read=%t" $values.connectors.storage.remote.read.status) (printf "status.storage.redpanda.remote.write=%t" $values.connectors.storage.remote.write.status) (printf "offset.storage.replication.factor=%d" ($values.connectors.storage.replicationFactor.offset | int)) (printf "config.storage.replication.factor=%d" ($values.connectors.storage.replicationFactor.config | int)) (printf "status.storage.replication.factor=%d" ($values.connectors.storage.replicationFactor.status | int)) (printf "producer.linger.ms=%d" ($values.connectors.producerLingerMS | int)) (printf "producer.batch.size=%d" ($values.connectors.producerBatchSize | int)) "config.providers=file,secretsManager,env" "config.providers.file.class=org.apache.kafka.common.config.provider.FileConfigProvider") -}} +{{- if $values.connectors.secretManager.enabled -}} +{{- $lines = (concat (default (list ) $lines) (list "config.providers.secretsManager.class=com.github.jcustenborder.kafka.config.aws.SecretsManagerConfigProvider" (printf "config.providers.secretsManager.param.secret.prefix=%s%s" $values.connectors.secretManager.consolePrefix $values.connectors.secretManager.connectorsPrefix) (printf "config.providers.secretsManager.param.aws.region=%s" $values.connectors.secretManager.region))) -}} +{{- end -}} +{{- $lines = (concat (default (list ) $lines) (list "config.providers.env.class=org.apache.kafka.common.config.provider.EnvVarConfigProvider")) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (join "\n" $lines)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "connectors.volumes" -}} +{{- $values := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $volumes := (coalesce nil) -}} +{{- if (not (empty $values.connectors.brokerTLS.ca.secretRef)) -}} +{{- $volumes = (concat (default (list ) $volumes) (list (mustMergeOverwrite (dict "name" "" ) (mustMergeOverwrite (dict ) (dict "secret" (mustMergeOverwrite (dict ) (dict "defaultMode" (0o444 | int) "secretName" $values.connectors.brokerTLS.ca.secretRef )) )) (dict "name" "truststore" )))) -}} +{{- end -}} +{{- if (not (empty $values.connectors.brokerTLS.cert.secretRef)) -}} +{{- $volumes = (concat (default (list ) $volumes) (list (mustMergeOverwrite (dict "name" "" ) (mustMergeOverwrite (dict ) (dict "secret" (mustMergeOverwrite (dict ) (dict "defaultMode" (0o444 | int) "secretName" $values.connectors.brokerTLS.cert.secretRef )) )) (dict "name" "cert" )))) -}} +{{- end -}} +{{- if (not (empty $values.connectors.brokerTLS.key.secretRef)) -}} +{{- $volumes = (concat (default (list ) $volumes) (list (mustMergeOverwrite (dict "name" "" ) (mustMergeOverwrite (dict ) (dict "secret" (mustMergeOverwrite (dict ) (dict "defaultMode" (0o444 | int) "secretName" $values.connectors.brokerTLS.key.secretRef )) )) (dict "name" "key" )))) -}} +{{- end -}} +{{- if (get (fromJson (include "connectors.Auth.SASLEnabled" (dict "a" (list $values.auth) ))) "r") -}} +{{- $volumes = (concat (default (list ) $volumes) (list (mustMergeOverwrite (dict "name" "" ) (mustMergeOverwrite (dict ) (dict "secret" (mustMergeOverwrite (dict ) (dict "defaultMode" (0o444 | int) "secretName" $values.auth.sasl.secretRef )) )) (dict "name" "rc-credentials" )))) -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (concat (default (list ) $volumes) (default (list ) $values.storage.volume))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "connectors.volumeMountss" -}} +{{- $values := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $mounts := (coalesce nil) -}} +{{- if (get (fromJson (include "connectors.Auth.SASLEnabled" (dict "a" (list $values.auth) ))) "r") -}} +{{- $mounts = (concat (default (list ) $mounts) (list (mustMergeOverwrite (dict "name" "" "mountPath" "" ) (dict "mountPath" "/opt/kafka/connect-password/rc-credentials" "name" "rc-credentials" )))) -}} +{{- end -}} +{{- if (not (empty $values.connectors.brokerTLS.ca.secretRef)) -}} +{{- $mounts = (concat (default (list ) $mounts) (list (mustMergeOverwrite (dict "name" "" "mountPath" "" ) (dict "name" "truststore" "mountPath" "/opt/kafka/connect-certs/ca" )))) -}} +{{- end -}} +{{- if (not (empty $values.connectors.brokerTLS.cert.secretRef)) -}} +{{- $mounts = (concat (default (list ) $mounts) (list (mustMergeOverwrite (dict "name" "" "mountPath" "" ) (dict "name" "cert" "mountPath" "/opt/kafka/connect-certs/cert" )))) -}} +{{- end -}} +{{- if (not (empty $values.connectors.brokerTLS.key.secretRef)) -}} +{{- $mounts = (concat (default (list ) $mounts) (list (mustMergeOverwrite (dict "name" "" "mountPath" "" ) (dict "name" "key" "mountPath" "/opt/kafka/connect-certs/key" )))) -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (concat (default (list ) $mounts) (default (list ) $values.storage.volumeMounts))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + diff --git a/charts/redpanda/redpanda/5.9.2/charts/connectors/templates/_helpers.go.tpl b/charts/redpanda/redpanda/5.9.2/charts/connectors/templates/_helpers.go.tpl new file mode 100644 index 0000000000..49b7115382 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/connectors/templates/_helpers.go.tpl @@ -0,0 +1,131 @@ +{{- /* Generated from "helpers.go" */ -}} + +{{- define "connectors.Name" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $name := (default $dot.Chart.Name $values.nameOverride) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (get (fromJson (include "connectors.trunc" (dict "a" (list $name) ))) "r")) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "connectors.Fullname" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (not (empty $values.fullnameOverride)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (get (fromJson (include "connectors.trunc" (dict "a" (list $values.fullnameOverride) ))) "r")) | toJson -}} +{{- break -}} +{{- end -}} +{{- $name := (default $dot.Chart.Name $values.nameOverride) -}} +{{- if (contains $name $dot.Release.Name) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (get (fromJson (include "connectors.trunc" (dict "a" (list $dot.Release.Name) ))) "r")) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (get (fromJson (include "connectors.trunc" (dict "a" (list (printf "%s-%s" $dot.Release.Name $name)) ))) "r")) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "connectors.FullLabels" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $_is_returning = true -}} +{{- (dict "r" (merge (dict ) (dict "helm.sh/chart" (get (fromJson (include "connectors.Chart" (dict "a" (list $dot) ))) "r") "app.kubernetes.io/managed-by" $dot.Release.Service ) (get (fromJson (include "connectors.PodLabels" (dict "a" (list $dot) ))) "r"))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "connectors.PodLabels" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $_is_returning = true -}} +{{- (dict "r" (merge (dict ) (dict "app.kubernetes.io/name" (get (fromJson (include "connectors.Name" (dict "a" (list $dot) ))) "r") "app.kubernetes.io/instance" $dot.Release.Name "app.kubernetes.io/component" (get (fromJson (include "connectors.Name" (dict "a" (list $dot) ))) "r") ) $values.commonLabels)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "connectors.Chart" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $chart := (printf "%s-%s" $dot.Chart.Name $dot.Chart.Version) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (get (fromJson (include "connectors.trunc" (dict "a" (list (replace "+" "_" $chart)) ))) "r")) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "connectors.Semver" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $_is_returning = true -}} +{{- (dict "r" (trimPrefix "v" (get (fromJson (include "connectors.Tag" (dict "a" (list $dot) ))) "r"))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "connectors.ServiceAccountName" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if $values.serviceAccount.create -}} +{{- $_is_returning = true -}} +{{- (dict "r" (default (get (fromJson (include "connectors.Fullname" (dict "a" (list $dot) ))) "r") $values.serviceAccount.name)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (default "default" $values.serviceAccount.name)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "connectors.ServiceName" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $_is_returning = true -}} +{{- (dict "r" (default (get (fromJson (include "connectors.Fullname" (dict "a" (list $dot) ))) "r") $values.service.name)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "connectors.Tag" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $tag := (default $dot.Chart.AppVersion $values.image.tag) -}} +{{- $matchString := "^v(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$" -}} +{{- if (not (mustRegexMatch $matchString $tag)) -}} +{{- $_ := (fail "image.tag must start with a 'v' and be a valid semver") -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $tag) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "connectors.trunc" -}} +{{- $s := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $_is_returning = true -}} +{{- (dict "r" (trimSuffix "-" (trunc (63 | int) $s))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + diff --git a/charts/redpanda/redpanda/5.9.2/charts/connectors/templates/_helpers.tpl b/charts/redpanda/redpanda/5.9.2/charts/connectors/templates/_helpers.tpl new file mode 100644 index 0000000000..89c888eeef --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/connectors/templates/_helpers.tpl @@ -0,0 +1,79 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You 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. +*/}} +{{/* +Expand the name of the chart. +*/}} +{{- define "connectors.name" -}} +{{- get ((include "connectors.Name" (dict "a" (list .))) | fromJson) "r" }} +{{- 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 "connectors.fullname" }} +{{- get ((include "connectors.Fullname" (dict "a" (list .))) | fromJson) "r" }} +{{- end }} + +{{/* +full helm labels + common labels +*/}} +{{- define "full.labels" -}} +{{- (get ((include "connectors.FullLabels" (dict "a" (list .))) | fromJson) "r") | toYaml }} +{{- end -}} + +{{/* +pod labels merged with common labels +*/}} +{{- define "connectors-pod-labels" -}} +{{- (get ((include "connectors.PodLabels" (dict "a" (list .))) | fromJson) "r") | toYaml }} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "connectors.chart" -}} +{{- get ((include "connectors.Chart" (dict "a" (list .))) | fromJson) "r" }} +{{- end }} + +{{/* +Get the version of redpanda being used as an image +*/}} +{{- define "connectors.semver" -}} +{{- get ((include "connectors.Tag" (dict "a" (list .))) | fromJson) "r" }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "connectors.serviceAccountName" -}} +{{- get ((include "connectors.ServiceAccountName" (dict "a" (list .))) | fromJson) "r" }} +{{- end }} + +{{/* +Create the name of the service to use +*/}} +{{- define "connectors.serviceName" -}} +{{- get ((include "connectors.ServiceName" (dict "a" (list .))) | fromJson) "r" }} +{{- end }} + +{{/* +Use AppVersion if image.tag is not set +*/}} +{{- define "connectors.tag" -}} +{{- get ((include "connectors.Tag" (dict "a" (list .))) | fromJson) "r" }} +{{- end -}} diff --git a/charts/redpanda/redpanda/5.9.2/charts/connectors/templates/_pod-monitor.go.tpl b/charts/redpanda/redpanda/5.9.2/charts/connectors/templates/_pod-monitor.go.tpl new file mode 100644 index 0000000000..4e12b20084 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/connectors/templates/_pod-monitor.go.tpl @@ -0,0 +1,18 @@ +{{- /* Generated from "podmonitor.go" */ -}} + +{{- define "connectors.PodMonitor" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (not $values.monitoring.enabled) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "spec" (dict "podMetricsEndpoints" (coalesce nil) "selector" (dict ) "namespaceSelector" (dict ) ) ) (mustMergeOverwrite (dict ) (dict "apiVersion" "monitoring.coreos.com/v1" "kind" "PodMonitor" )) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "name" (get (fromJson (include "connectors.Fullname" (dict "a" (list $dot) ))) "r") "labels" $values.monitoring.labels "annotations" $values.monitoring.annotations )) "spec" (mustMergeOverwrite (dict "podMetricsEndpoints" (coalesce nil) "selector" (dict ) "namespaceSelector" (dict ) ) (dict "namespaceSelector" $values.monitoring.namespaceSelector "podMetricsEndpoints" (list (mustMergeOverwrite (dict "bearerTokenSecret" (dict "key" "" ) ) (dict "path" "/" "port" "prometheus" ))) "selector" (mustMergeOverwrite (dict ) (dict "matchLabels" (get (fromJson (include "connectors.PodLabels" (dict "a" (list $dot) ))) "r") )) )) ))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + diff --git a/charts/redpanda/redpanda/5.9.2/charts/connectors/templates/_service.go.tpl b/charts/redpanda/redpanda/5.9.2/charts/connectors/templates/_service.go.tpl new file mode 100644 index 0000000000..54a7ce8a05 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/connectors/templates/_service.go.tpl @@ -0,0 +1,20 @@ +{{- /* Generated from "service.go" */ -}} + +{{- define "connectors.Service" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $ports := (list (mustMergeOverwrite (dict "port" 0 "targetPort" 0 ) (dict "name" "rest-api" "port" ($values.connectors.restPort | int) "targetPort" ($values.connectors.restPort | int) "protocol" "TCP" ))) -}} +{{- range $_, $port := $values.service.ports -}} +{{- $ports = (concat (default (list ) $ports) (list (mustMergeOverwrite (dict "port" 0 "targetPort" 0 ) (dict "name" $port.name "port" ($port.port | int) "targetPort" ($port.port | int) "protocol" "TCP" )))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "spec" (dict ) "status" (dict "loadBalancer" (dict ) ) ) (mustMergeOverwrite (dict ) (dict "apiVersion" "v1" "kind" "Service" )) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "name" (get (fromJson (include "connectors.ServiceName" (dict "a" (list $dot) ))) "r") "labels" (merge (dict ) (get (fromJson (include "connectors.FullLabels" (dict "a" (list $dot) ))) "r") $values.service.annotations) )) "spec" (mustMergeOverwrite (dict ) (dict "ipFamilies" (list "IPv4") "ipFamilyPolicy" "SingleStack" "ports" $ports "selector" (get (fromJson (include "connectors.PodLabels" (dict "a" (list $dot) ))) "r") "sessionAffinity" "None" "type" "ClusterIP" )) ))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + diff --git a/charts/redpanda/redpanda/5.9.2/charts/connectors/templates/_serviceaccount.go.tpl b/charts/redpanda/redpanda/5.9.2/charts/connectors/templates/_serviceaccount.go.tpl new file mode 100644 index 0000000000..31b5ac2acd --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/connectors/templates/_serviceaccount.go.tpl @@ -0,0 +1,18 @@ +{{- /* Generated from "serviceaccount.go" */ -}} + +{{- define "connectors.ServiceAccount" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (not $values.serviceAccount.create) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) ) (mustMergeOverwrite (dict ) (dict "apiVersion" "v1" "kind" "ServiceAccount" )) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "annotations" $values.serviceAccount.annotations "labels" (get (fromJson (include "connectors.FullLabels" (dict "a" (list $dot) ))) "r") "name" (get (fromJson (include "connectors.ServiceAccountName" (dict "a" (list $dot) ))) "r") "namespace" $dot.Release.Namespace )) ))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + diff --git a/charts/redpanda/redpanda/5.9.2/charts/connectors/templates/_shims.tpl b/charts/redpanda/redpanda/5.9.2/charts/connectors/templates/_shims.tpl new file mode 100644 index 0000000000..e3bb40e415 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/connectors/templates/_shims.tpl @@ -0,0 +1,289 @@ +{{- /* Generated from "bootstrap.go" */ -}} + +{{- define "_shims.typetest" -}} +{{- $typ := (index .a 0) -}} +{{- $value := (index .a 1) -}} +{{- $zero := (index .a 2) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (typeIs $typ $value) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list $value true)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list $zero false)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.typeassertion" -}} +{{- $typ := (index .a 0) -}} +{{- $value := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (not (typeIs $typ $value)) -}} +{{- $_ := (fail (printf "expected type of %q got: %T" $typ $value)) -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $value) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.dicttest" -}} +{{- $m := (index .a 0) -}} +{{- $key := (index .a 1) -}} +{{- $zero := (index .a 2) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (hasKey $m $key) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list (index $m $key) true)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list $zero false)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.compact" -}} +{{- $args := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $out := (dict ) -}} +{{- range $i, $e := $args -}} +{{- $_ := (set $out (printf "T%d" ((add (1 | int) $i) | int)) $e) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $out) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.deref" -}} +{{- $ptr := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (eq $ptr (coalesce nil)) -}} +{{- $_ := (fail "nil dereference") -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $ptr) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.len" -}} +{{- $m := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (eq $m (coalesce nil)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (0 | int)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (len $m)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.ptr_Deref" -}} +{{- $ptr := (index .a 0) -}} +{{- $def := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (ne $ptr (coalesce nil)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $ptr) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $def) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.ptr_Equal" -}} +{{- $a := (index .a 0) -}} +{{- $b := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (and (eq $a (coalesce nil)) (eq $b (coalesce nil))) -}} +{{- $_is_returning = true -}} +{{- (dict "r" true) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (eq $a $b)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.lookup" -}} +{{- $apiVersion := (index .a 0) -}} +{{- $kind := (index .a 1) -}} +{{- $namespace := (index .a 2) -}} +{{- $name := (index .a 3) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $result := (lookup $apiVersion $kind $namespace $name) -}} +{{- if (empty $result) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list (coalesce nil) false)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list $result true)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.asnumeric" -}} +{{- $value := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (typeIs "float64" $value) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list $value true)) | toJson -}} +{{- break -}} +{{- end -}} +{{- if (typeIs "int64" $value) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list $value true)) | toJson -}} +{{- break -}} +{{- end -}} +{{- if (typeIs "int" $value) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list $value true)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list (0 | int) false)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.asintegral" -}} +{{- $value := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (or (typeIs "int64" $value) (typeIs "int" $value)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list $value true)) | toJson -}} +{{- break -}} +{{- end -}} +{{- if (and (typeIs "float64" $value) (eq (floor $value) $value)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list $value true)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list (0 | int) false)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.parseResource" -}} +{{- $repr := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (typeIs "float64" $repr) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list (float64 $repr) 1.0)) | toJson -}} +{{- break -}} +{{- end -}} +{{- if (not (typeIs "string" $repr)) -}} +{{- $_ := (fail (printf "invalid Quantity expected string or float64 got: %T (%v)" $repr $repr)) -}} +{{- end -}} +{{- if (not (regexMatch `^[0-9]+(\.[0-9]{0,6})?(k|m|M|G|T|P|Ki|Mi|Gi|Ti|Pi)?$` $repr)) -}} +{{- $_ := (fail (printf "invalid Quantity: %q" $repr)) -}} +{{- end -}} +{{- $reprStr := (toString $repr) -}} +{{- $unit := (regexFind "(k|m|M|G|T|P|Ki|Mi|Gi|Ti|Pi)$" $repr) -}} +{{- $numeric := (float64 (substr (0 | int) ((sub ((get (fromJson (include "_shims.len" (dict "a" (list $reprStr) ))) "r") | int) ((get (fromJson (include "_shims.len" (dict "a" (list $unit) ))) "r") | int)) | int) $reprStr)) -}} +{{- $tmp_tuple_1 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.dicttest" (dict "a" (list (dict "" 1.0 "m" 0.001 "k" (1000 | int) "M" (1000000 | int) "G" (1000000000 | int) "T" (1000000000000 | int) "P" (1000000000000000 | int) "Ki" (1024 | int) "Mi" (1048576 | int) "Gi" (1073741824 | int) "Ti" (1099511627776 | int) "Pi" (1125899906842624 | int) ) $unit (coalesce nil)) ))) "r")) ))) "r") -}} +{{- $ok := $tmp_tuple_1.T2 -}} +{{- $scale := ($tmp_tuple_1.T1 | float64) -}} +{{- if (not $ok) -}} +{{- $_ := (fail (printf "unknown unit: %q" $unit)) -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list $numeric $scale)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.resource_MustParse" -}} +{{- $repr := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $tmp_tuple_2 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.parseResource" (dict "a" (list $repr) ))) "r")) ))) "r") -}} +{{- $scale := ($tmp_tuple_2.T2 | float64) -}} +{{- $numeric := ($tmp_tuple_2.T1 | float64) -}} +{{- $strs := (list "" "m" "k" "M" "G" "T" "P" "Ki" "Mi" "Gi" "Ti" "Pi") -}} +{{- $scales := (list 1.0 0.001 (1000 | int) (1000000 | int) (1000000000 | int) (1000000000000 | int) (1000000000000000 | int) (1024 | int) (1048576 | int) (1073741824 | int) (1099511627776 | int) (1125899906842624 | int)) -}} +{{- $idx := -1 -}} +{{- range $i, $s := $scales -}} +{{- if (eq ($s | float64) ($scale | float64)) -}} +{{- $idx = $i -}} +{{- break -}} +{{- end -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- if (eq $idx -1) -}} +{{- $_ := (fail (printf "unknown scale: %v" $scale)) -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (printf "%s%s" (toString $numeric) (index $strs $idx))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.resource_Value" -}} +{{- $repr := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $tmp_tuple_3 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.parseResource" (dict "a" (list $repr) ))) "r")) ))) "r") -}} +{{- $scale := ($tmp_tuple_3.T2 | float64) -}} +{{- $numeric := ($tmp_tuple_3.T1 | float64) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (int64 (ceil ((mulf $numeric $scale) | float64)))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.resource_MilliValue" -}} +{{- $repr := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $tmp_tuple_4 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.parseResource" (dict "a" (list $repr) ))) "r")) ))) "r") -}} +{{- $scale := ($tmp_tuple_4.T2 | float64) -}} +{{- $numeric := ($tmp_tuple_4.T1 | float64) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (int64 (ceil ((mulf ((mulf $numeric 1000.0) | float64) $scale) | float64)))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.render-manifest" -}} +{{- $tpl := (index . 0) -}} +{{- $dot := (index . 1) -}} +{{- $manifests := (get ((include $tpl (dict "a" (list $dot))) | fromJson) "r") -}} +{{- if not (typeIs "[]interface {}" $manifests) -}} +{{- $manifests = (list $manifests) -}} +{{- end -}} +{{- range $_, $manifest := $manifests -}} +{{- if ne $manifest nil }} +--- +{{toYaml (unset (unset $manifest "status") "creationTimestamp")}} +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/charts/redpanda/redpanda/5.9.2/charts/connectors/templates/_values.go.tpl b/charts/redpanda/redpanda/5.9.2/charts/connectors/templates/_values.go.tpl new file mode 100644 index 0000000000..9b304d4bf6 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/connectors/templates/_values.go.tpl @@ -0,0 +1,15 @@ +{{- /* Generated from "values.go" */ -}} + +{{- define "connectors.Auth.SASLEnabled" -}} +{{- $c := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $saslEnabled := (not (empty $c.sasl.userName)) -}} +{{- $saslEnabled = (and $saslEnabled (not (empty $c.sasl.mechanism))) -}} +{{- $saslEnabled = (and $saslEnabled (not (empty $c.sasl.secretRef))) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $saslEnabled) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + diff --git a/charts/redpanda/redpanda/5.9.2/charts/connectors/templates/deployment.yaml b/charts/redpanda/redpanda/5.9.2/charts/connectors/templates/deployment.yaml new file mode 100644 index 0000000000..ee78b69ebf --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/connectors/templates/deployment.yaml @@ -0,0 +1,17 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You 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. +*/}} +{{- include "_shims.render-manifest" (list "connectors.Deployment" .) -}} diff --git a/charts/redpanda/redpanda/5.9.2/charts/connectors/templates/pod-monitor.yaml b/charts/redpanda/redpanda/5.9.2/charts/connectors/templates/pod-monitor.yaml new file mode 100644 index 0000000000..42c1457546 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/connectors/templates/pod-monitor.yaml @@ -0,0 +1,17 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You 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. +*/}} +{{- include "_shims.render-manifest" (list "connectors.PodMonitor" .) -}} diff --git a/charts/redpanda/redpanda/5.9.2/charts/connectors/templates/service.yaml b/charts/redpanda/redpanda/5.9.2/charts/connectors/templates/service.yaml new file mode 100644 index 0000000000..0b8825befc --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/connectors/templates/service.yaml @@ -0,0 +1,17 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You 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. +*/}} +{{- include "_shims.render-manifest" (list "connectors.Service" .) -}} diff --git a/charts/redpanda/redpanda/5.9.2/charts/connectors/templates/serviceaccount.yaml b/charts/redpanda/redpanda/5.9.2/charts/connectors/templates/serviceaccount.yaml new file mode 100644 index 0000000000..eda755fb14 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/connectors/templates/serviceaccount.yaml @@ -0,0 +1,17 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You 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. +*/}} +{{- include "_shims.render-manifest" (list "connectors.ServiceAccount" .) -}} diff --git a/charts/redpanda/redpanda/5.9.2/charts/connectors/templates/tests/01-mm2-values.yaml b/charts/redpanda/redpanda/5.9.2/charts/connectors/templates/tests/01-mm2-values.yaml new file mode 100644 index 0000000000..f74732def8 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/connectors/templates/tests/01-mm2-values.yaml @@ -0,0 +1,176 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You 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. +*/}} +{{- define "curl-options" -}} +{{- print " -svm3 --fail --retry \"120\" --retry-max-time \"120\" --retry-all-errors -o - -w \"\\nstatus=%{http_code} %{redirect_url} size=%{size_download} time=%{time_total} content-type=\\\"%{content_type}\\\"\\n\" "}} +{{- end -}} +{{- if .Values.test.create -}} +apiVersion: v1 +kind: Pod +metadata: + name: {{ include "connectors.fullname" . }}-mm2-test-{{ randNumeric 3 }} + namespace: {{ .Release.Namespace | quote }} + labels: +{{- with include "full.labels" . }} + {{- . | nindent 4 }} +{{- end }} + annotations: + "helm.sh/hook": test + "helm.sh/hook-delete-policy": before-hook-creation +spec: + restartPolicy: Never + {{- with .Values.imagePullSecrets }} + imagePullSecrets: {{- toYaml . | nindent 4 }} + {{- end }} + containers: + - name: create-mm2 + image: docker.redpanda.com/redpandadata/redpanda:latest + command: + - /bin/bash + - -c + - | + set -xe + + trap connectorsState ERR + + connectorsState () { + echo check connectors expand status + curl {{ template "curl-options" . }} http://{{ include "connectors.serviceName" . }}:{{ .Values.connectors.restPort }}/connectors?expand=status + echo check connectors expand info + curl {{ template "curl-options" . }} http://{{ include "connectors.serviceName" . }}:{{ .Values.connectors.restPort }}/connectors?expand=info + echo check connector configuration + curl {{ template "curl-options" . }} http://{{ include "connectors.serviceName" . }}:{{ .Values.connectors.restPort }}/connectors/$CONNECTOR_NAME + echo check connector topics + curl {{ template "curl-options" . }} http://{{ include "connectors.serviceName" . }}:{{ .Values.connectors.restPort }}/connectors/$CONNECTOR_NAME/topics + } + + curl {{ template "curl-options" . }} http://{{ include "connectors.serviceName" . }}:{{ .Values.connectors.restPort }}/connectors + + SASL_MECHANISM="PLAIN" + {{- if .Values.auth.sasl.enabled }} + set -e + set +x + + IFS=: read -r CONNECT_SASL_USERNAME KAFKA_SASL_PASSWORD CONNECT_SASL_MECHANISM < $(find /mnt/users/* -print) + CONNECT_SASL_MECHANISM=${CONNECT_SASL_MECHANISM:-{{ .Values.auth.sasl.mechanism | upper }}} + if [[ -n "$CONNECT_SASL_USERNAME" && -n "$KAFKA_SASL_PASSWORD" && -n "$CONNECT_SASL_MECHANISM" ]]; then + rpk profile set user=$CONNECT_SASL_USERNAME pass=$KAFKA_SASL_PASSWORD sasl.mechanism=$CONNECT_SASL_MECHANISM + SASL_MECHANISM=$CONNECT_SASL_MECHANISM + JAAS_CONFIG_SOURCE="\"source.cluster.sasl.jaas.config\": \"org.apache.kafka.common.security.scram.ScramLoginModule required username=\\\\"\"${CONNECT_SASL_USERNAME}\\\\"\" password=\\\\"\"${KAFKA_SASL_PASSWORD}\\\\"\";\"," + JAAS_CONFIG_TARGET="\"target.cluster.sasl.jaas.config\": \"org.apache.kafka.common.security.scram.ScramLoginModule required username=\\\\"\"${CONNECT_SASL_USERNAME}\\\\"\" password=\\\\"\"${KAFKA_SASL_PASSWORD}\\\\"\";\"," + fi + + set -x + set +e + {{- end }} + + rpk profile create test + rpk profile set tls.enabled={{.Values.connectors.brokerTLS.enabled}} brokers={{ .Values.connectors.bootstrapServers }} + {{- if .Values.connectors.brokerTLS.ca.secretRef }} + rpk profile set tls.ca={{ printf "/redpanda-certs/%s" (default "ca.crt" .Values.connectors.brokerTLS.ca.secretNameOverwrite) }} + {{- end }} + + {{- if .Values.connectors.brokerTLS.enabled }} + CONNECT_TLS_ENABLED=true + {{- else }} + CONNECT_TLS_ENABLED=false + {{- end }} + SECURITY_PROTOCOL=PLAINTEXT + if [[ -n "$CONNECT_SASL_MECHANISM" && $CONNECT_TLS_ENABLED == "true" ]]; then + SECURITY_PROTOCOL="SASL_SSL" + elif [[ -n "$CONNECT_SASL_MECHANISM" ]]; then + SECURITY_PROTOCOL="SASL_PLAINTEXT" + elif [[ $CONNECT_TLS_ENABLED == "true" ]]; then + SECURITY_PROTOCOL="SSL" + fi + + rpk topic list + rpk topic create test-topic + rpk topic list + echo "Test message!" | rpk topic produce test-topic + + CONNECTOR_NAME=mm2-$RANDOM + cat << 'EOF' > /tmp/mm2-conf.json + { + "name": "CONNECTOR_NAME", + "config": { + "connector.class": "org.apache.kafka.connect.mirror.MirrorSourceConnector", + "topics": "test-topic", + "replication.factor": "1", + "tasks.max": "1", + "source.cluster.bootstrap.servers": {{ .Values.connectors.bootstrapServers | quote }}, + "target.cluster.bootstrap.servers": {{ .Values.connectors.bootstrapServers | quote }}, + "target.cluster.alias": "test-only", + "source.cluster.alias": "source", + "key.converter": "org.apache.kafka.connect.converters.ByteArrayConverter", + "value.converter": "org.apache.kafka.connect.converters.ByteArrayConverter", + "source->target.enabled": "true", + "target->source.enabled": "false", + "sync.topic.configs.interval.seconds": "5", + "sync.topics.configs.enabled": "true", + "source.cluster.ssl.truststore.type": "PEM", + "target.cluster.ssl.truststore.type": "PEM", + "source.cluster.ssl.truststore.location": {{ printf "/opt/kafka/connect-certs/ca/%s" (default "ca.crt" .Values.connectors.brokerTLS.ca.secretNameOverwrite) | quote }}, + "target.cluster.ssl.truststore.location": {{ printf "/opt/kafka/connect-certs/ca/%s" (default "ca.crt" .Values.connectors.brokerTLS.ca.secretNameOverwrite) | quote }}, + JAAS_CONFIG_SOURCE + JAAS_CONFIG_TARGET + "source.cluster.security.protocol": "SECURITY_PROTOCOL", + "target.cluster.security.protocol": "SECURITY_PROTOCOL", + "source.cluster.sasl.mechanism": "SASL_MECHANISM", + "target.cluster.sasl.mechanism": "SASL_MECHANISM", + "offset-syncs.topic.replication.factor": 1 + } + } + EOF + + sed -i "s/CONNECTOR_NAME/$CONNECTOR_NAME/g" /tmp/mm2-conf.json + sed -i "s/SASL_MECHANISM/$SASL_MECHANISM/g" /tmp/mm2-conf.json + sed -i "s/SECURITY_PROTOCOL/$SECURITY_PROTOCOL/g" /tmp/mm2-conf.json + set +x + sed -i "s/JAAS_CONFIG_SOURCE/$JAAS_CONFIG_SOURCE/g" /tmp/mm2-conf.json + sed -i "s/JAAS_CONFIG_TARGET/$JAAS_CONFIG_TARGET/g" /tmp/mm2-conf.json + set -x + + curl {{ template "curl-options" . }} -H 'Content-Type: application/json' http://{{ include "connectors.serviceName" . }}:{{ .Values.connectors.restPort }}/connectors -d @/tmp/mm2-conf.json + + # The rpk topic consume could fail for the first few times as kafka connect needs + # to spawn the task and copy one message from the source topic. To solve this race condition + # the retry should be implemented in bash for rpk topic consume or other mechanism that + # can confirm source connectors started its execution. As a fast fix fixed 30 second fix is added. + sleep 30 + + rpk topic consume source.test-topic -n 1 | grep "Test message!" + + curl {{ template "curl-options" . }} -X DELETE http://{{ include "connectors.serviceName" . }}:{{ .Values.connectors.restPort }}/connectors/$CONNECTOR_NAME + + curl {{ template "curl-options" . }} http://{{ include "connectors.serviceName" . }}:{{ .Values.connectors.restPort }}/connectors + + rpk topic delete test-topic source.test-topic mm2-offset-syncs.test-only.internal + volumeMounts: + {{- if .Values.connectors.brokerTLS.ca.secretRef }} + - mountPath: /redpanda-certs + name: redpanda-ca + {{- end }} + {{- toYaml .Values.storage.volumeMounts | nindent 8 }} + volumes: + {{- if .Values.connectors.brokerTLS.ca.secretRef }} + - name: redpanda-ca + secret: + defaultMode: 0444 + secretName: {{ .Values.connectors.brokerTLS.ca.secretRef }} + {{- end }} + {{- toYaml .Values.storage.volume | nindent 4 }} +{{- end }} diff --git a/charts/redpanda/redpanda/5.9.2/charts/connectors/testdata/template-cases-generated.txtar b/charts/redpanda/redpanda/5.9.2/charts/connectors/testdata/template-cases-generated.txtar new file mode 100644 index 0000000000..575120e324 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/connectors/testdata/template-cases-generated.txtar @@ -0,0 +1,13778 @@ +Generated by TestGenerateCases +-- case-000 -- +fullnameOverride: rpVz +imagePullSecrets: +- name: "Y" +- name: oCy +- name: M +logging: + level: 0rksB2 +monitoring: + enabled: true + labels: + 5Fm2d5: 8GfL + HhgyOa: "1" + L9qHqt6R: LhlwQrUay + namespaceSelector: {} +nameOverride: pO5m +test: {} +tolerations: +- effect: 險CƅN奚4z攷Ȭ懿ǩi + key: ftgtOR + operator: 轧ǎɄHL骮磊胦Ĥ鰭 + value: HNRvd3P +- effect: $駏AF + key: QEX + operator: TŦ + tolerationSeconds: 9130697478155031191 + value: gFhGwGYsZj8 +- effect: Ð(Ƨ4ýZ_体}ʢ + key: Skz0OP3K + operator: oEa@w瑭 + value: 3G +-- case-001 -- +auth: {} +container: + javaGCLogEnabled: t1lDqf0PT8Xy + securityContext: {} +fullnameOverride: WtC +nameOverride: nZ +service: + name: 5wkC +storage: {} +-- case-002 -- +container: + javaGCLogEnabled: YUlcy4 + resources: {} +fullnameOverride: xp6vcIlb +imagePullSecrets: +- name: Tm0bmByz +- name: gSGPB +- name: 58yP +nameOverride: ZZ5 +serviceAccount: + annotations: + gM: gxAdfFrD + create: true + name: AN +storage: + volume: + - name: AhJ + volumeMounts: + - mountPath: hVlmCfXmla + mountPropagation: ÇƭȊ餧鵣鋚蕛ʖ诂瑧)ɍĿ8šȪ轭ʌ倈 + name: 482T + readOnly: true + subPath: Un28M + subPathExpr: weDK9jo + - mountPath: YWN6OS + name: 5ijm8 + subPath: safiSmZ + - mountPath: MBW5 + name: ibiELmf2 + readOnly: true + subPath: E + subPathExpr: piX +test: {} +tolerations: +- effect: 翀ɫŧ(馕Ť B + key: z4CO9NIHr + operator: =ǒ旔Īz尰淅ȜL + tolerationSeconds: -3342574177579699030 + value: 6qB +- effect: f + operator: Jǂ繦緮:Ǥ鄒鉠V}璊澘苚澞邍 + value: eAj9 +- effect: ʥ龦ȏ櫕3ø½ + key: mVGM5 + operator: pȩ纆s;畞"ŀ凓ɿ®ĄǤ_ + tolerationSeconds: 8874959473893236931 + value: S97vJbOM +-- case-003 -- +container: + javaGCLogEnabled: AGZOKrMs + securityContext: {} +fullnameOverride: kNrkCdEuw9V +imagePullSecrets: +- name: QIa +- name: 9QE3ez +- name: np1QDs89l +logging: + level: s2fGu +monitoring: + scrapeInterval: 1275505h31m51.442697795s +nameOverride: Wvpgs +tolerations: +- effect: 蠉ŊWƎ-ɄM@腒z饊4宝芵D + key: ZA +- effect: 桋 + key: 89yJQ + operator: 統nȓ璝,搼匪¨蕂Z酺ŕ賀枴蕧颥 + tolerationSeconds: 404439244630337484 + value: 6CGQZY +-- case-004 -- +fullnameOverride: 74qyne +imagePullSecrets: +- name: lnn +nameOverride: xhLPt0 +test: {} +-- case-005 -- +auth: {} +container: + javaGCLogEnabled: u12AMM +deployment: + nodeSelector: + ppXWIa: yWFoE + priorityClassName: MVCo + readinessProbe: + exec: {} + failureThreshold: -321470157 + grpc: + port: -157736567 + service: lkRxi7xVArBg7 + initialDelaySeconds: 1821796808 + periodSeconds: -469069323 + successThreshold: -1171276641 + terminationGracePeriodSeconds: -6163690760469911235 + timeoutSeconds: 1191785929 + revisionHistoryLimit: -544556764 + schedulerName: Lwp + securityContext: + fsGroupChangePolicy: eĻȊ4愻' + runAsGroup: 7076055353387776300 + runAsUser: 1448978345039473532 + supplementalGroups: + - 6910305894952865149 + strategy: + type: AT9FgtX + terminationGracePeriodSeconds: 1820238753 + topologySpreadConstraints: + - topologyKey: OAvMKg + whenUnsatisfiable: pasNu + - topologyKey: izYRz + whenUnsatisfiable: V2RO2 +fullnameOverride: J +nameOverride: W +serviceAccount: + name: VLlCi +storage: + volumeMounts: + - mountPath: 9hR6GGwna + name: f9h8iHd + subPath: u6UaQTj + subPathExpr: A13AGT +-- case-006 -- +commonLabels: + LvtMtyy: tvfxqD2lry + YC2zBn: OLSkBqQE + m2DRq: cS +fullnameOverride: R93VG +logging: + level: 0aZ +nameOverride: Vlci +service: + name: gkX +serviceAccount: + annotations: + 2oUsUW: r + lx: u6Li342dNU + create: true + name: "7" +test: {} +tolerations: +- effect: ']粢GDž洉鼭i簾Ƹȑȼ裋#' + key: XVr + operator: rȷ,xdk« + value: S7cZC +-- case-007 -- +connectors: + additionalConfiguration: ZQu + bootstrapServers: ue + brokerTLS: {} + groupID: y2 + schemaRegistryURL: kS0A8GucOgn + secretManager: + connectorsPrefix: I072i1u + consolePrefix: ppQ9x2 + region: uohiz + storage: {} +fullnameOverride: NUTO +logging: + level: n3s7 +monitoring: + enabled: false + scrapeInterval: 758193h55m31.821599286s +nameOverride: Gb7J7k +service: + name: 9PY0 +test: + create: true +tolerations: +- key: Mq8z6HgsAvY + tolerationSeconds: 2615803531399402268 + value: hlJeDG2R +- effect: Æ弽ʟʍb³Y庻啱Ŧ頱ɛ隕蜐m鼋焜 + key: h + operator: P涉晣 ľ÷ɇV湣庻/ + value: Q +- effect: k + key: rt + operator: 菔xn + tolerationSeconds: 9166113446651272576 + value: kkW +-- case-008 -- +container: + javaGCLogEnabled: pq3jgGoeY +deployment: + budget: {} + extraEnvFrom: + - prefix: W + - prefix: 6Cgj + - prefix: YV + livenessProbe: + failureThreshold: -1790317528 + httpGet: + host: qAB + path: Eim2yxc + port: qhcH6h + scheme: 5捰¥­鎻藦 + initialDelaySeconds: -853917423 + periodSeconds: 1730314559 + successThreshold: -1047272333 + terminationGracePeriodSeconds: -6159328979217767494 + timeoutSeconds: 478977165 + podAntiAffinity: + custom: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + faNCB: E4juJ + oIG4a9Wa: Fca0z9t + mismatchLabelKeys: + - 5lmh + - zy + namespaces: + - E2xl + topologyKey: 8N3 + - namespaceSelector: {} + topologyKey: hrMRkZSK + topologyKey: 9ZbeCsEgDC + type: jUSv + priorityClassName: T6Ndpl0PL + progressDeadlineSeconds: 467220788 + schedulerName: iVovlD + terminationGracePeriodSeconds: 1520290623 +fullnameOverride: PNw8 +imagePullSecrets: +- name: EzI +- {} +- name: rjR6q +nameOverride: tPhRiQRK +test: {} +-- case-009 -- +auth: + sasl: + enabled: false + mechanism: ECm + secretRef: Udgkf + userName: nhJO6Xj +container: + javaGCLogEnabled: K + resources: + limits: {} + request: {} + securityContext: + allowPrivilegeEscalation: true +deployment: + create: false + livenessProbe: + failureThreshold: -999329257 + grpc: + port: -155863346 + service: bWO + initialDelaySeconds: 1584729597 + periodSeconds: -1715701628 + successThreshold: 729966777 + timeoutSeconds: 696662707 + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: [] + priorityClassName: oEOG + schedulerName: FzFE73 +fullnameOverride: Ygj9B +nameOverride: wCD97n +service: + name: H +serviceAccount: + annotations: + LWQ09i: tiLdCrApld + v2D6hTB: NGlgEEm + create: true + name: eyeD +test: + create: true +tolerations: +- effect: Q笜ƿ]0Ƒ5Ġ瞙镆 + key: JHnNnpNn4wHeL + operator: 羛矖暓(ĵ蕥}撟CťI精Ů + value: 5k0 +- effect: 牭顭Ů"ɇ郿ƛ摒炽?ƗlûǤ眗ɣ@ģb + key: pcwgtTr + operator: ř + value: zs +-- case-010 -- +auth: {} +commonLabels: + cUt: YvDFEsYlU + g3hOh91HKI: CHwTjLYe2XS + h4yNA: fJL +container: + javaGCLogEnabled: "" + resources: {} +fullnameOverride: LsGZn +monitoring: + enabled: true + labels: + wsUYAN3C: BzMz48 + namespaceSelector: + any: true +nameOverride: 9fz +serviceAccount: + create: false + name: bZ1w2 +storage: {} +-- case-011 -- +auth: + sasl: + mechanism: eTh + secretRef: H5TroU8 + userName: 8MR9Bee +commonLabels: + bX: vmmkhH2NHvdt + mO: pT +connectors: + additionalConfiguration: "" + bootstrapServers: vucld + brokerTLS: + enabled: false + key: + secretNameOverwrite: VT + secretRef: lz9QFe + groupID: X + producerBatchSize: 606208011 + producerLingerMS: 1644100599 + schemaRegistryURL: mGj8 + secretManager: + connectorsPrefix: uTTGy6JO572 + consolePrefix: TFKp + enabled: true + region: Zga57aiC +deployment: + budget: + maxUnavailable: -1825328882 + extraEnv: + - name: ogAtm + value: mJfm + - name: 2dTzgfH + value: sNiAP + valueFrom: + configMapKeyRef: + key: gSl56 + name: c + optional: true + resourceFieldRef: + containerName: AXKLF + divisor: "0" + resource: "" + - name: N1yV1 + value: nLSeqDK + extraEnvFrom: + - prefix: 9HB6W4t + secretRef: + name: NYC3bKPQWLc + optional: false + livenessProbe: + exec: {} + failureThreshold: -757710692 + initialDelaySeconds: -949475509 + periodSeconds: 1423942066 + successThreshold: 1080931760 + timeoutSeconds: -1902342435 + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchFields: + - key: qi12DQkzc + operator: 駣>蕐k泌蚮奘5d墥7Ȋ + values: + - Sp + weight: 1587628539 + podAntiAffinity: + topologyKey: rero1 + type: u + weight: 2087428837 + priorityClassName: ulsVLH + revisionHistoryLimit: -1010709730 + schedulerName: g + securityContext: + fsGroupChangePolicy: b + strategy: + type: XhI1Zz + updateStrategy: + type: OwYo +fullnameOverride: etuP +logging: + level: 20R9 +nameOverride: xiBXju +serviceAccount: + annotations: + OZRRPON: npX3 + Y1hvwE727: rZI + i1rZ2cwr: "" + name: dr5NDVhU0W3x +storage: + volumeMounts: + - mountPath: NIVHRdAc + name: BHPad + readOnly: true + subPath: z + subPathExpr: iwiB7uVoG + - mountPath: S6g7 + mountPropagation: $+g"訜駄 + name: 1iwfb + readOnly: true + subPath: 5XRI + subPathExpr: zNyXts +test: + create: false +-- case-012 -- +container: + javaGCLogEnabled: L9Ab4 +deployment: + annotations: + qhL: NwcVhzqvm + wjUv: xruF36CXB6YP + budget: {} + create: false + livenessProbe: + failureThreshold: -2109366246 + grpc: + port: -1015383620 + service: ritV + initialDelaySeconds: 1360388115 + periodSeconds: 768065118 + successThreshold: 1600450204 + terminationGracePeriodSeconds: -7255894925502993587 + timeoutSeconds: -1772311361 + nodeAffinity: {} + nodeSelector: + TPLQj2m: 7U6MPf + podAntiAffinity: + custom: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + "": lEtTbibY + KL: "9" + cRAELbm: o7TNTG + namespaceSelector: {} + topologyKey: 65ytaH + - matchLabelKeys: + - cxFsG + - kfVIsSK1 + - k + namespaceSelector: {} + topologyKey: YL8 + topologyKey: lxPsOox + type: T + weight: -864722068 + priorityClassName: CX + progressDeadlineSeconds: 368835309 + revisionHistoryLimit: 1912936765 + schedulerName: FfXGO1 + strategy: + type: mjPaU + updateStrategy: + type: 0u +fullnameOverride: Tpn +monitoring: + labels: + "0": m4M + VAD3Bq: LIrfcIp + Zc7e: Ixb + namespaceSelector: + matchNames: + - 24w + scrapeInterval: 175243h15m49.218935959s +nameOverride: MexiU +service: + name: Ac +test: {} +tolerations: +- effect: 村ɭȢvɝ>Á阣ǵ«彼Ċȣ庯蕠ń + key: XLicRkmamr + operator: É晱鄼9腁 +- effect: FkËT鋏T碻 + key: DbJOt + operator: 涛ĩ差s坥閵;ĺ%堢醧 1?`脪雯! + value: RKg76fjFC +- effect: ƐlǎÜʛdž壟嚲A厪ļk.BF + key: r + operator: ']縖' + value: 0f +-- case-013 -- +auth: + sasl: + enabled: true + mechanism: SDp7 + secretRef: 4WR + userName: MwyeN8 +deployment: + budget: + maxUnavailable: 24384073 + create: false + livenessProbe: + exec: {} + failureThreshold: 2001873995 + grpc: + port: -570073675 + service: VF + initialDelaySeconds: 1435901271 + periodSeconds: -1827120891 + successThreshold: 543681313 + terminationGracePeriodSeconds: 7623134148266453805 + timeoutSeconds: -602096728 + nodeSelector: + pflZ7G: A0jyH + priorityClassName: zjQ2B + revisionHistoryLimit: -841820257 + schedulerName: h3uqMw4N + tolerations: + - key: 5o5Syu + operator: _ɤʞƏ穆rPNij9ʯP缪Ƈǿw + tolerationSeconds: -1826520063540927425 + value: 1VpdZ + - effect: Ǒ±Ǖ;ʐ覓朊c$迂Ƀȣf + key: "1" + operator: '"轜N_''ğ)Í5Iu:+Ņe嶵薏' + tolerationSeconds: -7530147871827456803 +fullnameOverride: bAtOao +monitoring: + enabled: true + scrapeInterval: 66327h16m50.874180173s +nameOverride: w8tCi3K +service: + name: InI +serviceAccount: + name: 6le +test: + create: true +tolerations: +- effect: ^嚿潷 + key: Xth0FkarCwDhRM + operator: ']ǒŘMpU謵Mɗ缿@篦3qǴ ʝ諜费' + tolerationSeconds: -2483428479265143204 +- effect: 堟Y注ʥ骊țL芮|łfÆ + key: IF9M6x + operator: y;旴XƬ糔剰Ǜ鮡 + value: USzGY +-- case-014 -- +auth: + sasl: + mechanism: ntVNf + secretRef: mQuWoG00Z + userName: "" +connectors: + additionalConfiguration: E + bootstrapServers: cywT8MNAo + groupID: 6AsORVCaYJ + producerBatchSize: -831136974 + schemaRegistryURL: cSf + secretManager: + connectorsPrefix: RnHNJ7bJD0 + consolePrefix: GMeK0dod3 + enabled: false + region: t77zc +fullnameOverride: u7DU +monitoring: + enabled: true + labels: + aVoQ7: vECqlu0Pe + namespaceSelector: + matchNames: + - alQT6bxHho + - jKf + - p +nameOverride: dA1zsc +serviceAccount: + name: HAAJtAWrjJ +-- case-015 -- +auth: {} +commonLabels: + 96Kx: 1DW5QoLP + LY: nDw + etW: "9" +deployment: + budget: + maxUnavailable: -1737560958 + create: false + extraEnv: + - name: Bc + value: pB + valueFrom: + configMapKeyRef: + key: RStSG + name: rpc1FHY + resourceFieldRef: + containerName: sKpIz + divisor: "0" + resource: GM5pHA + secretKeyRef: + key: gM8EqA + name: KmFME + optional: false + - name: "" + value: me8paXgJ + - name: nLU + value: "6" + valueFrom: + fieldRef: + apiVersion: rsTk + fieldPath: Hs + resourceFieldRef: + containerName: TvVr1l + divisor: "0" + resource: HH4x1 + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: null + nodeSelector: + fh9: xbk + jILeDZ3: SJ16 + uzP02S: iZVVMqQ + podAffinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: null + podAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - namespaceSelector: + matchExpressions: + - key: 57Js + operator: "" + values: + - EdjUMt + - key: mJ8aRtIDW2S + operator: Ɨ3綂ȕ0蘗Iɉ8Ȟ怶Ⱥ门ʛC嫾ʑªƛ + values: + - 7eo + - 004AeS + - key: EJ + operator: dP + values: + - IgSuQGAK6gx + - oNFCGVbRN + - C5qeL + matchLabels: + gbheV: 6ZDyWDt + namespaces: + - elkM9HO + - 8C7YR9 + - IYYqJs + topologyKey: "" + podAntiAffinity: {} + priorityClassName: 7M + progressDeadlineSeconds: -660403045 + restartPolicy: zy莃:`KEȈ乭Ş璡o髞ůKė趡ʭ + revisionHistoryLimit: -1404737890 + schedulerName: z6D0iC + terminationGracePeriodSeconds: -194304314 + updateStrategy: + type: xSEGKS +fullnameOverride: 5eY7 +logging: + level: lk9GZiF6 +nameOverride: bpgtWxol +service: + name: x +storage: + volume: + - name: pD + - name: MmiQZ4o + volumeMounts: + - mountPath: Fk9qDh + mountPropagation: OV棴ǝɃ箪 + name: GHi + readOnly: true + subPath: MHNGOL2dBmh + subPathExpr: wZHGIC2B3 + - mountPath: k97wi + mountPropagation: 摪ƝH迒LhĂ + name: A2 + subPath: ij8 + subPathExpr: vMM + - mountPath: 7iD + mountPropagation: Dè轖#KŵÅi轓m癈跔 + name: JOhkrajKTFMI + subPath: krtU + subPathExpr: cxblS +test: {} +-- case-016 -- +container: + javaGCLogEnabled: NSE + resources: + javaMaxHeapSize: "0" + request: + cpu: "0" + securityContext: {} +fullnameOverride: bGMfavR +logging: + level: oj4P +monitoring: + scrapeInterval: 1616184h3m28.108622923s +nameOverride: Cex3v +service: + annotations: + IUeOwNT: T3w1nV + Si: dNUY + name: B5Y + ports: + - name: HzTtdut + port: 741893604 + - name: yT6vYOdszF + port: -1916404761 +serviceAccount: + name: cxOBE +storage: + volume: + - name: X7ZZu + - name: KkkMA7 + - name: Btxy +test: {} +-- case-017 -- +commonLabels: + wR: GAm +connectors: + additionalConfiguration: ro5XOd9Tf + bootstrapServers: RKH + brokerTLS: + cert: + secretNameOverwrite: khTfK + secretRef: qXwTCH + enabled: true + key: + secretNameOverwrite: u0 + secretRef: OCzzkl + groupID: hPUA1m7 + producerBatchSize: 1121174748 + producerLingerMS: -221329759 + schemaRegistryURL: dt2Vd1bTg + secretManager: + connectorsPrefix: Z5Cv + consolePrefix: X1zP + enabled: true + region: LrK6I + storage: + remote: + read: + config: false + offset: false + write: + config: false + offset: false + topic: + config: Uf + offset: "n" + status: kNLwla +container: + javaGCLogEnabled: x3dH + resources: + javaMaxHeapSize: "0" + limits: + cpu: "0" + request: + cpu: "0" + securityContext: + allowPrivilegeEscalation: false +deployment: + annotations: + fet: YGwnq + create: true + extraEnvFrom: + - prefix: Ci6EGf + secretRef: + name: cDwbNN + livenessProbe: + failureThreshold: 1181508047 + grpc: + port: 1103363052 + service: BghH + httpGet: + path: 5Io5 + port: fXmkdb + scheme: ɚ + initialDelaySeconds: -215289091 + periodSeconds: 918675027 + successThreshold: -1707139863 + timeoutSeconds: 1673866844 + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: "2" + operator: 箓Ęȁ銵鷝Ā喳Ăɀ} + - key: j + operator: ɓ + matchFields: + - key: "" + operator: vǃ鞳邪§Ț皾6 + - key: Yi7SzM + operator: Ǎ浹籥岷Ħ + values: + - Czu9d1V + - key: r6y + operator: 牁p认ð_蠡hHiÖq肓ǭʤe)ĉB扝 + - {} + podAntiAffinity: + topologyKey: MECG5Y + type: bTzd + weight: -803515299 + priorityClassName: "N" + progressDeadlineSeconds: 444536561 + readinessProbe: + exec: + command: + - TGFiXP + - Z79QNgs + failureThreshold: -1832996555 + grpc: + port: 431368512 + service: eUPPAkf + httpGet: + host: f + path: KJ + port: NNA + scheme: $ǡH庋Y¶闣ĸǽv蘈 + initialDelaySeconds: 877141221 + periodSeconds: 2102410645 + successThreshold: 1537121792 + terminationGracePeriodSeconds: -8439557874955512884 + timeoutSeconds: -2026548303 + revisionHistoryLimit: 1418020237 + schedulerName: FQjdKmjClI5B + strategy: + type: WVP1Q8 + terminationGracePeriodSeconds: 1127207064 + topologySpreadConstraints: + - maxSkew: -1487816419 + topologyKey: Mw7m + whenUnsatisfiable: "" + - maxSkew: -1469244889 + topologyKey: HuZRY + whenUnsatisfiable: NX + - maxSkew: -346884429 + topologyKey: xVWCd + whenUnsatisfiable: p + updateStrategy: + type: "" +fullnameOverride: u1Dk +nameOverride: DAE +serviceAccount: + annotations: + GPwb: rsHTj2N + c4: HTI5lp + vUnChIysI: ZfUINMh + create: false + name: zF +test: + create: true +tolerations: +- effect: f + key: RDN + operator: 狀番ǵ曻縖=&Ɛʤe佥墺辅x7絼櫓 + tolerationSeconds: 4568597810181054356 + value: 7zNQUA +-- case-018 -- +auth: + sasl: + mechanism: VtLC5 + secretRef: ng2m + userName: 1Iwn7 +connectors: + additionalConfiguration: l3aLVX5 + bootstrapServers: hj4Aab + brokerTLS: + key: + secretNameOverwrite: z4oRSGo + secretRef: Ee + groupID: m + producerBatchSize: 1913291774 + producerLingerMS: -313398730 + restPort: 1476502274 + schemaRegistryURL: nL5qOV + secretManager: + connectorsPrefix: 2KQcX + consolePrefix: NnQ + region: 0P7 +fullnameOverride: hX1VdtP7gp7c +imagePullSecrets: +- name: W1 +monitoring: + annotations: + JZgY7gH: ZeFjP9nhvOjMI + gS26QJ5: cAc + labels: + DORM: tayRzd99 + yc2ti: kI0liqp5YBMr + namespaceSelector: + any: true +nameOverride: C +service: + name: CVJfMb + ports: + - name: DT +serviceAccount: + create: false + name: 3xqtRwRI +storage: + volumeMounts: + - mountPath: 5koRVhJz + mountPropagation: 穠耱誕Ȝ躰灬灺Ķ輔硯dzȦ1e蘄ò.o + name: 5lp + subPath: bEZmgVKO + subPathExpr: 5UCo6 +test: {} +-- case-019 -- +commonLabels: + 1sF: 45XnA + a1rMZK: Jzq +connectors: + additionalConfiguration: "" + bootstrapServers: ezzGY + groupID: CL5YFuVD + producerLingerMS: -936976440 + restPort: 2065008586 + schemaRegistryURL: XTAQJ + secretManager: + connectorsPrefix: Q + consolePrefix: "79" + enabled: true + region: 3EfPcaJPeL +deployment: + budget: {} + create: true + extraEnv: + - name: s + value: q7x401sB3R + - name: p + value: Odn + valueFrom: + fieldRef: + apiVersion: Tmp29KLiQ5 + fieldPath: "2" + secretKeyRef: + key: RRlr0C + name: jx + - name: M + value: dHu2S + valueFrom: + configMapKeyRef: + key: YT + name: x84MM29Kc5u + optional: true + fieldRef: + apiVersion: AKdDlUG8v + fieldPath: wHCWO + extraEnvFrom: + - configMapRef: + name: MF8pnsf + optional: false + prefix: lT + secretRef: + name: W + livenessProbe: + exec: {} + failureThreshold: 832341066 + httpGet: + host: 2YhKEXGGy + path: Er43b4o + port: 523079005 + scheme: '-' + initialDelaySeconds: -493754907 + periodSeconds: -888317874 + successThreshold: -1792385861 + timeoutSeconds: -359586002 + podAntiAffinity: + topologyKey: 4YPfUs + type: 62y + priorityClassName: HXWM5 + readinessProbe: + exec: {} + failureThreshold: -2059548026 + httpGet: + host: z + path: jn + port: k1cVehfSqQ + scheme: 筭洰a恥¾兼ƍV5 + initialDelaySeconds: 438569678 + periodSeconds: 2034323562 + successThreshold: -1007748590 + timeoutSeconds: -1489292970 + revisionHistoryLimit: -656791059 + schedulerName: Wrjb3H + tolerations: + - effect: Ƿ闄 + key: O + operator: 鵉鼌q穋R譼驪妼擕`ƛ駴ň + tolerationSeconds: -8397972967079996177 + value: 1KZwe4 +fullnameOverride: S9NS5c +monitoring: + enabled: false + namespaceSelector: {} + scrapeInterval: 1263504h12m50.743340543s +nameOverride: qQY +service: + name: iPsih4 +storage: {} +test: + create: false +tolerations: +- effect: '}´ƃë\]Ä嗍6u乡嗹v鄭°' + key: E1j + operator: 滲 + value: OA +-- case-020 -- +auth: {} +deployment: + annotations: + hM5Ozaprm: lIZA9 + mT: 0LKs + create: false + extraEnvFrom: + - configMapRef: + name: FLR + optional: false + prefix: eDtm + - configMapRef: + name: t + optional: false + prefix: dlW1 + secretRef: + name: y3pc2pFWSm + livenessProbe: + exec: + command: + - h + failureThreshold: 2104262150 + httpGet: + host: Ah8pO + path: CRw + port: -1437145013 + scheme: y崬lAJ埰u<~ţ馜哶炽nj荻Ȩ淣 @ + initialDelaySeconds: 1024187677 + periodSeconds: 913677726 + successThreshold: 1848348137 + terminationGracePeriodSeconds: 3692284600662469393 + timeoutSeconds: 414675637 + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: bYDy + operator: 5ȺĜƒ靍殌ȌƗǢ4;幄 + values: + - EF9 + - FQ + - key: oxk5s + operator: '}Ū椣Ğn' + values: + - lgx + - NcKuJ + - key: NC4kwCJt + operator: ńƕÅǽȄʛ + values: + - f0 + - 7yXJIG + - W + weight: -806977733 + - preference: {} + weight: -1752665730 + - preference: + matchFields: + - key: BE + operator: +ÐQ斴T"wǶ偌T脍Ş逢 + values: + - zMTwun9 + - CeAjK + - key: TYVhhI1HI + operator: ǚůƍ嬀ĸȮ-(0玖ž[Ǚ炓檓se + weight: -1752262723 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: TmnaP + operator: ´ĵ3QI馉ȿʊ}ƻ + values: + - EcGCXgcAX + - key: k9Y9tmH + operator: ĕÏ呇ǔƘ綹* + - key: "" + operator: 铈ş< ƞ'Sķ筋e7,=冘蚖詞 + matchFields: + - key: zc5PoF + operator: "" + values: + - y7IJrN + - F8X + - PSmazIp + - key: keuZoH + operator: Sy + values: + - 7sXP + - 37w3o9wjEfLo + - "3" + - {} + - matchExpressions: + - key: "" + operator: 賋è霺ghoơz闠Ĉ«ƍq + values: + - rhFXXif7v + - ixPCwn + - O3 + matchFields: + - key: FNmh89toZo + operator: '''勃ʇ夛浵欑"鋫驾{êPǪvÍ襑' + values: + - dV + - vRVfIecf + podAntiAffinity: + topologyKey: DK7g + type: "" + weight: 2116118619 + priorityClassName: Wy3x + progressDeadlineSeconds: -2099104625 + readinessProbe: + failureThreshold: 1384600958 + grpc: + port: -2111497644 + service: U62KFYODDp + httpGet: + host: i3U2 + path: u3nsOY + port: -120629401 + scheme: Ɲ H齧責欖Ğâ柷ɒł + initialDelaySeconds: -1607019514 + periodSeconds: 1117157063 + successThreshold: -2017370070 + terminationGracePeriodSeconds: -6500262321144121445 + timeoutSeconds: -689176139 + schedulerName: MXeR + securityContext: + fsGroupChangePolicy: Ɛ6佒ʕ + runAsGroup: 993874004271065493 + runAsUser: -6188102389190039866 + sysctls: + - name: NnI7Pde1 + value: E8nl + terminationGracePeriodSeconds: 708995785 + updateStrategy: + type: cIAjo4 +fullnameOverride: IAukfjAiE +imagePullSecrets: +- name: Jm0uOuT +logging: + level: g +monitoring: + enabled: false + labels: + IwGT2: U9Mez5Vvz + RTBh: DcL3Cfz3j + Scvr6HhI: TcOJcRH + namespaceSelector: + any: true + scrapeInterval: -90129h16m11.711713376s +nameOverride: kUuRn +storage: + volumeMounts: + - mountPath: TTEa + name: h + subPath: tG52z + subPathExpr: eh4wQ + - mountPath: iY66G4 + mountPropagation: 5ŀÖTcĿƠĎ躵9[Ãw胍 + name: WB3KpIQZ + subPath: hd + subPathExpr: Ekw2NtL7 + - mountPath: hB + mountPropagation: Ɲv抡吾蒩2ʛ + name: r7V + subPath: 4YrJ + subPathExpr: 4bIK9CT +tolerations: +- effect: Ź褦齸稽2舦胢襉`cq~ + key: iusZ5 + operator: LƩîmOv丌Þlɢɮ&żő子ʫƅq + tolerationSeconds: 1567502669304402305 + value: v1rTmQCoOJX +- effect: q#2崫 + key: rn1ih + operator: ă#暻vÔtgiɿ + value: K1 +-- case-021 -- +commonLabels: + 5D3dcbYcmq: bkcA + "y": TxHhxVY2tRx1i +connectors: + additionalConfiguration: jzE + bootstrapServers: as60 + brokerTLS: + ca: + secretNameOverwrite: fifa + secretRef: BmRMpc + cert: + secretNameOverwrite: MY5Ss + secretRef: gy7g + groupID: eOkhi4 + producerBatchSize: -500780400 + producerLingerMS: -1955065214 + schemaRegistryURL: Jrt + storage: + remote: + read: + config: false + offset: false + status: true + write: + config: true + status: true + replicationFactor: + config: -1860412640 + offset: -1901393869 + status: -4761328 + topic: + config: EI + offset: IK4 + status: WIZGj +container: + javaGCLogEnabled: HG + resources: + limits: + cpu: "0" + memory: "0" + request: + memory: "0" + securityContext: + allowPrivilegeEscalation: false +deployment: + annotations: + "8": 6L8d + budget: + maxUnavailable: -1972147103 + extraEnv: + - name: mbyKA5WPoY + value: bhMRx + extraEnvFrom: + - configMapRef: + name: e7KgN9ff + optional: false + prefix: ug4D + secretRef: + name: CzuiueSY + optional: false + - configMapRef: + name: TlIbaiI + optional: true + prefix: I + - configMapRef: + name: IuBuoY8u5xD1D7 + optional: false + prefix: 2xqoZ + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: j3g + operator: ŷǘȵiì渭ʫ抁Ğŋ + values: + - DJoN22 + - 4Kszk + - key: KYKZgrf + operator: 櫮ƣ+Ź藦vď蔸聺3vMʪ + matchFields: + - key: di6 + operator: ɫ0l5璠û介ɗ蟦ǘ厁ɂh磊 + values: + - ct + - 3e + - YICL + weight: 1941396141 + - preference: + matchExpressions: + - key: PRs0G0 + operator: ©MʥȩɅ2ď鏓 + - key: L83 + operator: °¥¶ĕ焲粮剚e喏鑝梋ƃ5~Ìnidž + matchFields: + - key: 78fF + operator: =ŞŽ熧曪ń + weight: 1964511070 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchFields: + - key: AHvs + operator: ɵȝʩm幃 + - key: 0ac + operator: MWæ諒鸠 + - {} + - matchExpressions: + - key: wRdw + operator: VP萺鵷 + - key: "" + operator: x + values: + - Fx + - I1rNR + - key: JZ + operator: 訖 + nodeSelector: + 88m: ofL96viVG + lM: uR4 + podAntiAffinity: + topologyKey: ug + type: dMLFJ2vJ + weight: -1646642412 + priorityClassName: dirA + progressDeadlineSeconds: 741558819 + readinessProbe: + exec: + command: + - Cnn275T + - 90rjZczLp + - Hi + failureThreshold: 137175425 + grpc: + port: -990908140 + service: "n" + initialDelaySeconds: 385463317 + periodSeconds: 1814148060 + successThreshold: -2130595018 + terminationGracePeriodSeconds: 1602275511469638547 + timeoutSeconds: -1983859400 + restartPolicy: 奡ʄ臔ȁ + revisionHistoryLimit: 1560482462 + schedulerName: v + securityContext: + fsGroup: 2775178225296577779 + runAsGroup: -873168801110302232 + runAsNonRoot: true + runAsUser: -8949664932683740838 + sysctls: + - name: u + value: 0mDq + - name: UDLOQRVGXH + value: "" + - name: eakEWdkHQ + value: UWw + strategy: + type: "9" + terminationGracePeriodSeconds: 1135949557 + tolerations: + - effect: ɖ + key: lzvKb + operator: V毣«mpAp餂ĵ$İƊ俊ĺ + tolerationSeconds: 1365476841054063816 + value: HqnJ8gfT + - effect: T鏚裦黂 + key: vgU + operator: 訹gǷ×婚ǀ + tolerationSeconds: -8509532606436755290 + value: KI + - effect: ?遗x + key: 6fxivUhl + operator: KŸȘ绒Nj赤 + value: mK2Hz + updateStrategy: + type: jz1E9Ra +fullnameOverride: "" +imagePullSecrets: +- name: kq1gha8w +- {} +logging: + level: rb +nameOverride: Cg +service: + annotations: + g: Haj2trb + nQCD85u: 7ENE + name: kt3xi + ports: + - name: ZD6QnCdlL + - name: kUQU +serviceAccount: + annotations: + QvndcW2wD: JmD + create: true + name: ABdKo +storage: {} +test: {} +tolerations: +- effect: -ā;CpĔ霬ie + key: S9EFzL6 + operator: ƥǝYǾĶi¢pÔ + tolerationSeconds: -8069168009016427174 + value: KpBi0ZYe +- effect: ɸ怭酟Tɛ;淸ayËz + key: jCr + operator: \qʑVȎ汕qʜźʊ圙$h袪ʅ) + tolerationSeconds: -573606976387196365 + value: sVZZ5RB +- key: cuDMjsSUzeD + operator: 注SʯLV臙?Ⱥ祉萼禝!DŽKɋ中N + tolerationSeconds: -220176424743278478 + value: ZsR4KEl1X +-- case-022 -- +commonLabels: + 3T: w2SpAA6br + I758z7Cf: 6V + JvnbWUk: pPMb +connectors: + additionalConfiguration: faRWi + bootstrapServers: XngcT + brokerTLS: + ca: + secretNameOverwrite: MDvyt3bw + secretRef: b809b + cert: + secretNameOverwrite: LP7Pcx1xGT + secretRef: Gg + enabled: true + groupID: 3SgngS9vl + producerBatchSize: 889009746 + schemaRegistryURL: b4VVbJxS + secretManager: + connectorsPrefix: ALseg + consolePrefix: JoDngQ + region: X +deployment: + create: true + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: Ro3T + operator: aĒĴŪ*3ɀ 币6鳴Ã偯d?A`åȏ + - key: 7XExK + operator: 濻舒^T莄1Â]葉 + values: + - A61yP5MBIRlE + - PvGUE + - 3dEaVo + - key: cLddzEo + operator: 櫜毉FÊi嶙# + matchFields: + - key: 5d + operator: 葜.¼v詝擽Ĉ + - key: WSMmbygG + operator: "" + weight: 1129540323 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kwkzOO8tl + operator: ']勋Į掬+' + matchFields: + - key: CQBwi20 + operator: 餞ǚe%Af埧Q哝窓煰 + - key: 9dTBxx + operator: Ĉ|^ + - matchFields: + - key: "" + operator: Á捛ɬĿ脦ǒĈ闲F秿翕卫Ŷ~?ʞŷȎ + values: + - Lg + - key: "42" + operator: 瞍 + values: + - QQMQ + - matchExpressions: + - key: en + operator: HË熙軯-ȓ簩羗č ʏ栽竬熄s)Ó鸰 + - key: Gc9Ntp + operator: "" + matchFields: + - key: 2ZLK4z1 + operator: 捚n匸竟-6ȐÒƑ|ʁĄEʕȘ + values: + - 0GiQ + - FI + - iXXs3k + - key: uujaIM5Y0Eo + operator: Āũ7 + podAffinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: null + podAffinity: {} + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - matchLabelKeys: + - wx6 + - pZWizn + - YalB + namespaceSelector: {} + namespaces: + - VIJ8 + - "" + - "897" + topologyKey: a3iKu + podAntiAffinity: + topologyKey: E0D + type: VvN + priorityClassName: rs1 + progressDeadlineSeconds: 457348204 + readinessProbe: + exec: + command: + - 9NasaU + - gSgxcK + failureThreshold: 511258221 + httpGet: + host: Mho + path: fy80Va + port: 595852956 + scheme: Ț籦绺č擯夭fÀdcq鬎DŽƬ礛 + initialDelaySeconds: 948711230 + periodSeconds: 19027716 + successThreshold: -1810396970 + terminationGracePeriodSeconds: 1798521938678531879 + timeoutSeconds: 1797719976 + revisionHistoryLimit: -700610054 + schedulerName: 6Fuyr + strategy: + type: IbrqLLHodX + terminationGracePeriodSeconds: 1222617058 + tolerations: + - key: 9v + operator: ƱSjc(ϼ霌ʒ酁2Ɣ8kRâ + tolerationSeconds: 699537150416724653 + value: w8QXL + - effect: 旼`BȞ*ąɦ纇åʝ + key: vj3BwiVyW1t + operator: 鼦詡dƅ + tolerationSeconds: -9093487529989850129 + value: i8Agp + topologySpreadConstraints: + - topologyKey: AFVo + whenUnsatisfiable: M4 + - maxSkew: -1157554939 + topologyKey: oF + whenUnsatisfiable: juzJPaV2L03 + - topologyKey: P6ooy + whenUnsatisfiable: svPI + updateStrategy: + type: "" +fullnameOverride: cZ4G4 +monitoring: + enabled: true + labels: + Eedv: 65ZfBI + namespaceSelector: {} + scrapeInterval: 2515390h35m37.419426312s +nameOverride: 6MJPA +service: + name: x4Vu7vj + ports: + - name: G4 + port: -201865350 +tolerations: +- effect: ' ʫȲ嬮+簻' + key: qIS + operator: 奎唐涵¥ȗ咦壥縌筺 + tolerationSeconds: -7358513382849221288 + value: tiRW0E7sm +-- case-023 -- +auth: {} +container: + javaGCLogEnabled: t7nvcU + resources: + limits: + cpu: "0" + memory: "0" + request: + cpu: "0" + memory: "0" + securityContext: {} +fullnameOverride: 9tds +imagePullSecrets: +- name: t +- name: 9jeO +- name: h +logging: + level: bP +monitoring: + enabled: false + scrapeInterval: 1421023h45m34.121658414s +nameOverride: ZI341xw +serviceAccount: + create: false + name: TIG +storage: + volume: + - name: naPNMJ + volumeMounts: + - mountPath: YeET3weL4N8g + mountPropagation: d/嬈Ñ內q謯ƶ8ɳƓ肵 + name: ssEfPGv8 + readOnly: true + subPath: "7" +-- case-024 -- +connectors: + additionalConfiguration: LWHk + bootstrapServers: jn + brokerTLS: + ca: + secretNameOverwrite: qv + secretRef: LRHozVF + enabled: true + groupID: d + producerBatchSize: 1166879364 + producerLingerMS: 714735160 + restPort: -1930935263 + schemaRegistryURL: sz + secretManager: + connectorsPrefix: xoZinJy1V + consolePrefix: kjqs + enabled: false + region: hsKN +container: + javaGCLogEnabled: XS5 + resources: + javaMaxHeapSize: "0" + limits: + cpu: "0" + memory: "0" + request: + cpu: "0" + memory: "0" + securityContext: + allowPrivilegeEscalation: true +deployment: + annotations: + FU4J: "" + HJZjva: jC8uET + budget: {} + livenessProbe: + exec: + command: + - OG + - YBVu + failureThreshold: -1400952913 + grpc: + port: -2029643906 + service: 0a7ILy + httpGet: + host: Z7sbsKoc + path: RhCEkYS + port: 1662747518 + scheme: 巐ȹƠK + initialDelaySeconds: 1536143416 + periodSeconds: -971919376 + successThreshold: 1841265139 + timeoutSeconds: 1519706329 + nodeSelector: + ZBtz30: MaN + wEyS43Wq6sS: A + podAntiAffinity: + topologyKey: H0cu + type: TCF8Ne + weight: 1443189624 + priorityClassName: xL + progressDeadlineSeconds: 5438195 + readinessProbe: + failureThreshold: 2057031608 + httpGet: + host: nCaW7a + path: KggIsy + port: jP + scheme: ʆçɇ滾镡Lj癲:Ą隸C乑鏀贄e監篍z + initialDelaySeconds: 1457702974 + periodSeconds: -1732886 + successThreshold: -723791053 + terminationGracePeriodSeconds: 7303344607566636133 + timeoutSeconds: -547087401 + revisionHistoryLimit: -2103181148 + schedulerName: tXdQ7X + securityContext: + fsGroup: -1024384248472849622 + runAsNonRoot: false + runAsUser: -2673836885766820786 + sysctls: + - name: z + value: 1Xx7BcpTtc + - name: ik + value: mn7hZ2O + - name: 0tRcSAR + value: s3Fmk + strategy: + type: 7Ma6SKn + terminationGracePeriodSeconds: 1680781404 + tolerations: + - effect: '[Ȝ%1@拌魋?>Q[' + key: CM6To + operator: ȫƤP箴ɉ戮嗯嬑lwĶƼ§ʜ + tolerationSeconds: -4298573611145221598 + value: ERnxlMnsbt + updateStrategy: + type: 9jfYH2 +fullnameOverride: e4W +logging: + level: i1QoQHfki73v +nameOverride: Y47 +serviceAccount: + create: false + name: AepmYU +tolerations: +- effect: ',虔wxÓ[bÁ男ɂʁ.ʋ鎊惡&ŵÓ#' + key: M4W + operator: ¿ȉȇ滻[濱喭噫誘蝝Wť揢奬ƕ畐Ǻ + tolerationSeconds: 5209749606101630382 + value: la6lMRP +-- case-025 -- +auth: + sasl: + enabled: false + mechanism: uxD + secretRef: "" + userName: 8yKwAYM +commonLabels: + VGEccN: 1S6Om +connectors: + additionalConfiguration: "n" + bootstrapServers: JhxRF4 + groupID: 2Fy + restPort: -1355681307 + schemaRegistryURL: 9uSqcQk +container: + javaGCLogEnabled: TmzFHzZvwn + resources: + limits: + memory: "0" +deployment: + annotations: + p7R: EjfLOeG + th6: enWXwqe + extraEnv: + - name: 5j0yE + value: O9bMi + valueFrom: + configMapKeyRef: + key: byf25 + name: RIZv + optional: false + fieldRef: + apiVersion: NrtU + fieldPath: 3LC + resourceFieldRef: + containerName: AjmWfg6HqMgn + divisor: "0" + resource: OV + - name: 6hTC + value: r + valueFrom: + configMapKeyRef: + key: 0u + name: 7xxySBjT + optional: true + resourceFieldRef: + containerName: qAO + divisor: "0" + resource: XP + extraEnvFrom: + - configMapRef: + name: uLvK + optional: false + prefix: 2Ij + secretRef: + name: leDGyXv + optional: true + - configMapRef: + name: GK + prefix: dCB + secretRef: + name: u + optional: false + livenessProbe: + exec: {} + failureThreshold: -94764338 + grpc: + port: 1195513848 + service: "" + httpGet: + host: FeqfL8uSFE + path: "57" + port: -1477884035 + scheme: 彀ǥ篠 + initialDelaySeconds: 407315123 + periodSeconds: 165966784 + successThreshold: 970096625 + terminationGracePeriodSeconds: -292284363880963466 + timeoutSeconds: 2091942472 + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchFields: + - key: 6nwZP6 + operator: 乆`Eɪ妶窓o黥屢! + values: + - cJtx + weight: -559166881 + - preference: + matchExpressions: + - key: eyw69 + operator: 獶ʎ^ȁ耦ǚy蝸殽虄X敉${ + values: + - cLTjur + - Ab + - key: iMnx + operator: ßljƨb委揋ǖyǭɮHɋȱ钵瑴= + values: + - oTbQw + matchFields: + - key: peZc + operator: 韨醤H3擅ĭýǚɃ氤徣»嬞籍* + - key: BwW + operator: "" + values: + - lj0f + - key: RTfBwhMV7h + operator: 愐哣碍clȲ + weight: 1712242968 + podAffinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: null + podAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: 5pRrPC5 + operator: lj莇殎璑cy畟2ƫ啔2蜍揈黻~VNjj + - key: Vx5A + operator: 蔞 + values: + - TuNksgudWu + - "4" + matchLabels: + 9yQx2r0z0VT: wKG3GY + m: D7p + matchLabelKeys: + - A94QEh4T + namespaceSelector: {} + namespaces: + - m2oXksKrIQE + - IbVp + topologyKey: aR1q + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + namespaceSelector: + matchExpressions: + - key: affUCeIp + operator: Ǭ\傁斘8ĝG=W¢xŔV + values: + - cGxdE + - WWR + namespaces: + - 8PQ + - IhAKP + topologyKey: mNEK4 + weight: 1622675667 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: 3mP + operator: ƛ)ʥ湯ǥð鸥蝪侀śv + - key: Yjw + operator: 锖膳Ǣ + values: + - JyH6LD + matchLabels: + "Y": 8Dv8Z09h + kV8iai: kRB + uyro3: N2Hv + namespaceSelector: + matchExpressions: + - key: 0r + operator: 嘏X孷Nj,ƦäMD妸*" + values: + - dl11s14 + - x2zsZLYX2j + - key: Sv + operator: 頇r蜿ǚ/ǷȦG络/脾 + namespaces: + - 5z + - AC + - F2RsWTf + topologyKey: N5mg + weight: -1962604072 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + GNdtPS: wYTu + LNoX7W: Tp6mRq + Sq7: bqR0 + matchLabelKeys: + - hlwJOaAy + - 3md + - X + mismatchLabelKeys: + - 4TLXNX + namespaceSelector: + matchExpressions: + - key: uoR + operator: Ȩd²ʜĽNj + - key: k + operator: 杜|漍á疦菁拙螃ɣjʆʕ瘎 + values: + - DcZ7LTc + matchLabels: + xu: U1A7mo + namespaces: + - B5 + topologyKey: Wdm54UR + podAntiAffinity: + custom: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + matchLabelKeys: + - "3" + - xz82vVz + - vEhkI + mismatchLabelKeys: + - vic9n + - Szo + - 0c + namespaceSelector: + matchLabels: + 3X: TPrUq + r1mxgoL: pg + topologyKey: RsMDTIE + weight: -1153984436 + topologyKey: LZJ6PJ1 + type: NwnuPNXi + weight: -417232056 + priorityClassName: e1exaXYQ + progressDeadlineSeconds: 202187696 + readinessProbe: + failureThreshold: 1857603986 + grpc: + port: 1093232805 + service: DU1FQs + httpGet: + host: Osa + path: CX74t + port: OxeuD39 + scheme: 覠尐_媶粷拝紾Iȡb帶墵Ò + initialDelaySeconds: -1402792412 + periodSeconds: 879643685 + successThreshold: 1435235361 + timeoutSeconds: 1464897550 + restartPolicy: '{悛Qª槟ĈW得蹏淂專驁sēɹƐ軋剭' + revisionHistoryLimit: 1394995435 + schedulerName: aA + tolerations: + - effect: cȩ飙 + key: 4Y9saWpr + operator: 輋ƾ跴Ȫ徐1Aǡ{gm櫩茻 + value: yI4k + topologySpreadConstraints: + - maxSkew: 425976069 + topologyKey: aThb + whenUnsatisfiable: G + updateStrategy: + type: CkmVnc9viBQ +fullnameOverride: uv4tHoO +imagePullSecrets: +- name: wd +- name: O +monitoring: + annotations: + hvh: "" + mDK0: OWEQ0y + zpG: XWCs + enabled: true + labels: + Ie5J5: fYnrHO + YkM4u7v: iTjIow + iP2Di: ptlD2Xuar + namespaceSelector: + matchNames: + - 9LShi + - klNT12U + - 9e + scrapeInterval: 74012h59m47.17763594s +nameOverride: z3C +service: + name: UFYrvO +test: + create: true +tolerations: +- effect: 弱伹ljȓƱ递$h鬾 + key: DK + operator: Ɨ + tolerationSeconds: -5698206097095774785 + value: D13SrG6 +- effect: =J叶步Ö + key: bk + operator: ȗ¦eŢƓ逺 + tolerationSeconds: 6164794697823934570 + value: X3Lat6r +-- case-026 -- +commonLabels: + op: VnL9o7 +connectors: + additionalConfiguration: T9YzRko + bootstrapServers: 6x4 + brokerTLS: + ca: + secretNameOverwrite: g3oj + secretRef: Dw6 + cert: + secretNameOverwrite: wSXlgsek + secretRef: i8CF9ffAM6p + enabled: true + key: + secretNameOverwrite: lyf69Al + secretRef: deo + groupID: uDg + producerLingerMS: -2006060261 + schemaRegistryURL: fT + secretManager: + connectorsPrefix: 3zl + consolePrefix: EnXNUH + enabled: true + region: cyQNlFt + storage: + remote: + read: + config: false + offset: false + status: true +container: + javaGCLogEnabled: uAsH + resources: + javaMaxHeapSize: "0" + limits: + memory: "0" + securityContext: + allowPrivilegeEscalation: false +deployment: + budget: + maxUnavailable: -2138199446 + create: false + extraEnv: + - name: fSlx6jZkW + value: Gidecru6M + valueFrom: + configMapKeyRef: + key: kDgPE80UsJ + name: VokSO + optional: false + fieldRef: + apiVersion: m0pc + fieldPath: TDq6b1g + resourceFieldRef: + containerName: aHY + divisor: "0" + resource: qGyhyCA + secretKeyRef: + key: Lab + name: XS7bBHw + optional: false + extraEnvFrom: + - configMapRef: + name: "94" + optional: true + prefix: cO1J + secretRef: + name: 5g16 + optional: false + nodeSelector: + d: H2kDk + podAffinity: + nodeAffinity: {} + podAffinity: {} + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: Fx6h + operator: ă瑡周n + matchLabels: + 4iB: XqVe + hjWyR: NY + matchLabelKeys: + - 1p + - 3kVC + namespaceSelector: + matchExpressions: + - key: 0miz + operator: K9輰隂ȧlȆ*¼'酞Ŏ + - key: 99O + operator: "" + - key: SP + operator: '`Čɪ!?钾R|櫊È' + values: + - "y" + - kAhysp4 + - GCV1j6 + matchLabels: + YUuE3XZX: X4t + kDqSk7iDzH: fkcnl + vTp: n2nALh + topologyKey: 64PeJ5 + podAntiAffinity: + custom: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: vQ1crSV + operator: 7nujʠ駺鬺|救 + - key: iOIw8g7V + operator: 萸繴裉ɕ~ŕf!ǿı棨 + - key: n6LU + operator: ȓbR筌ǫLJ + matchLabels: + NC0: "" + XGU5qvzYMs: QmNwb + cc: Ks + namespaces: + - 4pVveJZ + topologyKey: 65SB9i + - namespaceSelector: {} + namespaces: + - SDARb + - 0u + - n82TB + topologyKey: l1 + - labelSelector: + matchExpressions: + - key: h8JZN9ndz + operator: 瓇Ȟù + - key: BbnA + operator: 莾ʩ1ǔƇf楘銷Bqzʁ祤Ĉ肙 + values: + - RPGl + - fCF + - key: 7u + operator: 棣m\羨压ć$ + matchLabels: + 82yA8rU: JjJF0yf2o + 184fSrLtK: msSakH + Bq: "" + mismatchLabelKeys: + - P + namespaceSelector: + matchExpressions: + - key: h + operator: "" + values: + - mqn8Yv + - gdHikJUK + - key: 3lPz + operator: BD + - key: 0baPldJBjJn9 + operator: 樢饓4ʂ + values: + - 2AX + - UbR4z8bGYUVr + matchLabels: + DXgZ163y: 80ssC + sxdB: AWv0 + namespaces: + - qUoe + - WE + topologyKey: fZqb + topologyKey: jghLUT + type: YgTAAdKC + weight: 457351545 + priorityClassName: cMPpGa + progressDeadlineSeconds: 592124572 + readinessProbe: + exec: {} + failureThreshold: -581438581 + grpc: + port: 488383519 + service: l7batCCnvJq + httpGet: + host: FQqXfIuR + path: iUAUmylNEAU + port: -881355027 + scheme: Ȗ% + initialDelaySeconds: 1450868933 + periodSeconds: 84140252 + successThreshold: -349726428 + terminationGracePeriodSeconds: 6323959655336028953 + timeoutSeconds: 226228279 + revisionHistoryLimit: -739568709 + schedulerName: 14z62c7xgckN + securityContext: + fsGroupChangePolicy: 诅S~=ɲ*旫ĺ¬d堤Eq篣 + runAsGroup: 4871537600984265230 + runAsNonRoot: true + runAsUser: -7571157018510467782 + supplementalGroups: + - 7137947427600072682 + - -3730781858194361576 + - 6854632843582773166 + sysctls: + - name: r23vPM + value: 5UfknjwXh + strategy: + type: Je + terminationGracePeriodSeconds: 1594904318 + tolerations: + - effect: è埩仆ȅ<ǭɉ毱暏攦3q + operator: 弦ͼH昽E濄ɻ + tolerationSeconds: 3114895080936277785 + value: Y6vPY2uD + - effect: ŏȉ}葘魼A訇ɍOĩ旽ġ遌墚¦颢Ŏ + operator: 蠥ëV祍竛Ƅ-杸孡t + tolerationSeconds: 47406346758114986 + value: z + - effect: '>' + key: qdKVY + operator: 5m + value: kCCZxwF + updateStrategy: + type: apGLWC +fullnameOverride: XfK7 +logging: + level: e +monitoring: + annotations: + Ap4hj4: hGNy + IWIMYW: dOV6M + enabled: false + labels: + LSnRh7: o + OUKIb: "" + hOs: Jeldy + namespaceSelector: + any: true + matchNames: + - csE6iNb + - 0vF3H6v + - rnL + scrapeInterval: 601737h12m36.927932959s +nameOverride: ATJ +serviceAccount: + create: true + name: jmzfCmHq +storage: + volumeMounts: + - mountPath: kTnYVd0 + mountPropagation: )ȡ蟑 + name: LQoqAJrPB + readOnly: true + subPath: eogR7 + subPathExpr: jd + - mountPath: nL4z + mountPropagation: E驻ʄƒ椺Ņ熆伓1 + name: AC6X7664kgZ + readOnly: true +-- case-027 -- +auth: {} +commonLabels: + LuCiH: SWR3zOt +container: + javaGCLogEnabled: Rk2lueKjUZ + resources: + javaMaxHeapSize: "0" + limits: + cpu: "0" + request: + memory: "0" + securityContext: + allowPrivilegeEscalation: false +fullnameOverride: OL1 +nameOverride: ffe2 +service: + annotations: + JXMpPkd: YoI + Z: DVS9WjadC + name: uSz +serviceAccount: + annotations: + N7gZ: ExrpJkw + PD23ZYO: jlj + create: true + name: maeWLc +storage: + volumeMounts: + - mountPath: RDO + mountPropagation: 縖ʯLj觻ĶR腉赙CèS咍Xz + name: NFJO + readOnly: true + subPath: i4tgwgPir + subPathExpr: 8C3d4ln + - mountPath: I + mountPropagation: "" + name: okJHlIlhWWGN + subPath: UQu + subPathExpr: 1D7d +test: + create: false +tolerations: +- effect: 炩CżCX褒ȁŃ詳Ð剘畭@Tj縶 + key: 5GekCX8zF1Cj + operator: aµ + tolerationSeconds: 728571265301214109 + value: 81x9S +-- case-028 -- +auth: {} +container: + javaGCLogEnabled: 3ahn64ZT + resources: + javaMaxHeapSize: "0" + limits: + cpu: "0" + memory: "0" + securityContext: + allowPrivilegeEscalation: true +deployment: + create: true + extraEnv: + - name: DvkYw9Pk + value: USGTgIYZwyPh + valueFrom: + configMapKeyRef: + key: xomkxxc + name: 7a + optional: false + fieldRef: + apiVersion: tnGFZ3 + fieldPath: H + resourceFieldRef: + containerName: UD5gAM615 + divisor: "0" + resource: EplPSqP + - name: "" + valueFrom: + configMapKeyRef: + key: 2n + name: vw5ZWohT + optional: true + fieldRef: + apiVersion: THSyklTdw + fieldPath: KDDja + resourceFieldRef: + containerName: ha2tB3cM0 + divisor: "0" + resource: 467hL5 + secretKeyRef: + key: I + name: vv9hXsUY + optional: false + extraEnvFrom: + - configMapRef: + name: "y" + optional: true + prefix: 8yKCF + secretRef: + name: 7B5wyZ16F + optional: true + - configMapRef: + name: zqz + prefix: iYiSC0Au26P + - prefix: w + secretRef: + name: p4 + podAntiAffinity: + custom: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: 6kZhQ + operator: k赊炈ǽ|e椩骔Ɛȶ猔 + - key: gqK + operator: Ǚ胵$ğ\f35D辕叞Ǐ + values: + - pcEO171jJq + - LY + - GfNUi6qekSD + - key: k7gF + operator: 17鮅Ƒ灝1ʐɢ艹藩軞K.@媎5ɸ[ + values: + - 54w + - FSM + - 3z7CuL + matchLabels: + 9S3kV3el: 7MbZM6 + NlghDpU1T: Cli8O8lnK + OcV: "" + matchLabelKeys: + - mZggvA8 + - rJkWPc + namespaceSelector: + matchExpressions: + - key: ly0G + operator: $ȝQd睬H剹崈ł + values: + - As + - key: 7eyD22 + operator: 贻Ēa介ţ棨ʘ蝭玴 釷 + values: + - RzMGltB4 + - SFV4v + namespaces: + - Va8Nghyl5Xi7e + topologyKey: 1drlL0V + weight: -1531757892 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: "" + operator: ʬy驮蹲ÆʎŘJ + values: + - 4knxh35 + - u + matchLabels: + CJiPPT: SI + rgLMgFHL: xLCR7k9 + matchLabelKeys: + - n2L6 + mismatchLabelKeys: + - Xm + - 8rT + namespaces: + - 1oMw4m + - b + topologyKey: WyZe3ZI + weight: -1225398774 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: TW2 + operator: ʁ¦_bƻýK正¿őȦŭ'Ƭ1 + values: + - OvaLf52 + - KZf + - key: W80 + operator: _CEvNjn集L鲵ōF簠踑TĚƀa肆 + values: + - h1VYlc + - MKbR + - wxafhmYM + - key: d0o1Q5b2 + operator: "" + values: + - SVkBA + matchLabelKeys: + - nIc + - "" + namespaces: + - i + - B0zuARW3Ulvn9Q + - doQcG3 + topologyKey: g4 + weight: 553767105 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: {} + mismatchLabelKeys: + - XRCSn + - udG + namespaceSelector: + matchLabels: + I7Tlp: gcBQUH + ZD: NK + wMdEcQY4E: "" + namespaces: + - Zp + - IEP7 + - R2B8UbaSFe + topologyKey: V + - labelSelector: {} + mismatchLabelKeys: + - cXL65W + - "y" + - apcJBy + namespaceSelector: + matchLabels: + 96JY: wVF0LERIzj6 + namespaces: + - vWBUXL + topologyKey: RqV9B + topologyKey: i8Sj + type: lp + weight: 1933092510 + priorityClassName: j + restartPolicy: my + revisionHistoryLimit: 1716132030 + schedulerName: KL8nKi + securityContext: + fsGroup: 6950905231485893521 + fsGroupChangePolicy: 4駝ɧɍ匑ĿŃjH(ƨ鏝搲³欍荭 + runAsNonRoot: false + runAsUser: -3842777327443310041 + sysctls: + - name: ADfyWTN + value: "" + - name: A2KbAFX + value: vfiwuHLZA3z + strategy: + type: GG3n + terminationGracePeriodSeconds: -1876643927 + tolerations: + - effect: 幉cè禟ɴ + operator: ġ襜莪_ð迾uɈkʫ~鲕Lɻ戦ʡ2ȠǷ + tolerationSeconds: -3325398021525833538 + value: QDDTEv + - effect: hǝ + key: JwoXCcww + operator: ªA[wƸ + value: NvIa14 + - effect: ŐȜŻ-簀Ȟo/.濈s呁ī + key: v + operator: 7幔ÍX靹蟳 + tolerationSeconds: -8856646878602495698 + value: zOvR +fullnameOverride: ZvvoA +imagePullSecrets: +- name: H +- name: HOE +logging: + level: k1wsL2of +monitoring: + enabled: true + namespaceSelector: + any: true + scrapeInterval: -2272665h1m59.977529594s +nameOverride: "3" +service: + annotations: + 3yehn: hb1JTt4bE6 + 8kZ: syTRQDJ + QFMui15S766: gMn5Cet2XRLMo + name: 9VQ +serviceAccount: + annotations: + kTXPsd: S4sMQbj + name: Ms3WxpzY6U +storage: {} +test: + create: false +-- case-029 -- +auth: + sasl: + mechanism: pVvPbLq8PH + secretRef: a8g3R + userName: "206" +connectors: + additionalConfiguration: Mq9r58Wn2 + bootstrapServers: GhGh + brokerTLS: + ca: + secretNameOverwrite: "" + secretRef: u + enabled: false + key: + secretNameOverwrite: kn1yG + secretRef: CE + groupID: F3e + producerBatchSize: -1760140219 + producerLingerMS: -410672871 + restPort: 1337396066 + schemaRegistryURL: eVOEb + secretManager: + connectorsPrefix: emUV + consolePrefix: pC3 + enabled: true + region: l6uFeZtI + storage: + remote: + read: + offset: true + status: true + write: + config: true + offset: false + status: true +container: + javaGCLogEnabled: "" + resources: + request: + cpu: "0" + securityContext: {} +deployment: + budget: + maxUnavailable: -1357187310 + create: true + extraEnv: + - name: "" + value: a + valueFrom: + configMapKeyRef: + key: S + optional: false + fieldRef: + apiVersion: cAFu3Wwm4O + fieldPath: "" + resourceFieldRef: + containerName: K + divisor: "0" + resource: pYz + secretKeyRef: + key: rrusH7t + name: 6hR1vtMek + optional: true + - name: 62b + value: b4k + valueFrom: + resourceFieldRef: + containerName: 9Zuqk + divisor: "0" + resource: wDbwci + secretKeyRef: + key: q + name: a3Go0SITja + optional: false + - name: CAn + value: r + valueFrom: + configMapKeyRef: + key: oBsj + name: f + optional: true + fieldRef: + apiVersion: K + fieldPath: e60DM + resourceFieldRef: + containerName: 9xyY28RraQXtmbHZs9v + divisor: "0" + resource: ddr6SE + secretKeyRef: + key: HIl + name: 6i + extraEnvFrom: + - prefix: J + secretRef: + name: 4niuc27 + optional: false + - configMapRef: + name: dVR + optional: false + prefix: WUotCc + secretRef: + optional: true + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchFields: + - key: Th8xQ0 + operator: '};ƾ:Ơȏ旊苆$ź榘ę[Ş悈ȥ' + values: + - gOPH1k + - KOsql + priorityClassName: 3ogB9tWXV + progressDeadlineSeconds: 533336746 + readinessProbe: + exec: + command: + - 4ndWdZzqE2k + failureThreshold: 2079208961 + grpc: + port: 892171148 + service: CsKUHVZ + httpGet: + host: gYLBe6Cp + path: qmK3f8GwgZ + port: 8pIb + scheme: ʥ>Yj14寧枌A|íF + initialDelaySeconds: 1156905473 + periodSeconds: -1924622812 + successThreshold: -1575566868 + terminationGracePeriodSeconds: 5810637601195744899 + timeoutSeconds: -450997563 + revisionHistoryLimit: -121719569 + schedulerName: Z7Ne6 + securityContext: + fsGroup: -790114255836881973 + runAsGroup: 4623887472960955175 + runAsNonRoot: true + runAsUser: 7622666161830127482 + supplementalGroups: + - -3228001931932573252 + - -7141992959148915907 + - -17407268992027108 + sysctls: + - name: 8qCsQ + value: RwRLG + - name: f2Rn + value: afHwsU + - name: 3jYk9 + value: V + strategy: + type: "" + terminationGracePeriodSeconds: -1948657833 + tolerations: + - effect: 冮味Pf鵸q\)霰¢玲&糦Ŀ怋ɌÁ燹 + key: uTzXciQ + operator: 3IJuʙNj + value: FB0Hu +fullnameOverride: IyM +imagePullSecrets: +- name: 1tlBA +logging: + level: MM8vHtxMK +monitoring: + enabled: false + namespaceSelector: + any: true + scrapeInterval: 1950385h21m49.305979755s +nameOverride: tl2YFI +service: + annotations: + PGxtxZYXR: X5 + name: "" + ports: + - name: 9xn + port: -684513812 + - name: u4xF + port: -391479350 + - name: rDTiR56X + port: 382665278 +test: + create: false +tolerations: +- effect: ĝȈÛ + key: W0K + operator: ɺ$嶩鸦Ę+Ŝ鞬 + tolerationSeconds: -8698254857049033349 + value: AXGq +- effect: Ǜǻ鎃ǥ蹔t處 + key: U6Kwl + operator: 袕ʒ掊蓵 + value: sP +- effect: ɷ蒱Ď脢嚼S劣Ó + key: tXkIQEUaW + operator: 絈:愅ŚŻɵl + tolerationSeconds: 6194136677012499657 + value: G8 +-- case-030 -- +auth: + sasl: + enabled: true + mechanism: rw21b + secretRef: Pmr6Q + userName: VZItSFI +commonLabels: + GCdbeC: cQ4P1cHbv +connectors: + additionalConfiguration: dIZd0USbP + bootstrapServers: znZ + brokerTLS: + ca: + secretNameOverwrite: "" + secretRef: kHUZvj2QDUh4 + cert: + secretNameOverwrite: sskJ + secretRef: l + enabled: true + key: + secretNameOverwrite: iOnKoNxj + secretRef: dRzfIju + groupID: "3" + producerBatchSize: -1998620825 + producerLingerMS: -1373192817 + restPort: -1808248501 + schemaRegistryURL: j7 + secretManager: + connectorsPrefix: 6Bx2Qil2o + consolePrefix: C6KUfZ + enabled: false + region: IkJbzZ + storage: + remote: + read: + config: true + offset: true + status: true + write: + offset: false + status: true + topic: + config: J + offset: b + status: DTmRi +container: + javaGCLogEnabled: hmX8lr55 + resources: + javaMaxHeapSize: "0" + limits: + cpu: "0" + memory: "0" + request: + cpu: "0" + memory: "0" + securityContext: + allowPrivilegeEscalation: true +deployment: + annotations: + co: d + create: false + extraEnv: + - name: U7ZgJptiGP + value: VIyGo + valueFrom: + configMapKeyRef: + key: qxBGDLH + name: RaBlc + optional: false + fieldRef: + apiVersion: ypCq1 + fieldPath: GOf + resourceFieldRef: + containerName: MtGKY + divisor: "0" + resource: I4 + secretKeyRef: + key: qV + name: "9" + optional: false + extraEnvFrom: + - configMapRef: + name: H84ze + optional: false + prefix: VTwW + secretRef: + name: gEsSRAwz + optional: false + - configMapRef: + name: eDeZ0DugXo + optional: true + prefix: SsakeA + secretRef: + name: bG0Sy7 + optional: false + - prefix: ZKPXsAv + secretRef: + name: kxqMF05 + optional: false + livenessProbe: + exec: {} + failureThreshold: 20072615 + grpc: + port: -311576311 + service: cH6 + httpGet: + host: x + path: 2cVqcw + port: 929216339 + scheme: ƇsʯDSĉʍ.RAp鷌噫蕪ʚ + initialDelaySeconds: 1309506491 + periodSeconds: 848313974 + successThreshold: -1895468765 + terminationGracePeriodSeconds: 2309372029983841470 + timeoutSeconds: -1767944726 + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: [] + nodeSelector: + 1ZriYn8T: 6W5ORGSM + "8": tu + Fn2RxRqX: HUwiz + podAffinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: kxw601 + operator: Ǘ裝g彋ɨ戣Ɓ乑侇ƞĉ + values: + - h7 + - "84" + - lskjSC + matchFields: + - key: jX7lO + operator: ȼf糎*¼wA漏捅ǟ#ûç潝Ɖ藪V + values: + - X3sQ + weight: -1964816880 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: null + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + a8p2hiBJSP3TS: yXy733 + matchLabelKeys: + - "" + namespaceSelector: + matchExpressions: + - key: 2YU7Rzi + operator: ō{ʗ劆譄粫 + values: + - LwQ + - KpKr + - iA5gLm + - key: QLh2Y7fPtYq + operator: v掺ÂIA"Ƃ秐ǿ傇ȴOę + matchLabels: + 88xytHI: a + namespaces: + - GkdcO + topologyKey: Gk9 + weight: 1965172043 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: QXrC + operator: ']ƲD檖埙貊' + values: + - sBL + - M + - c + matchLabels: + M5: EqfNjRxqt + matchLabelKeys: + - eDIBN + namespaceSelector: + matchExpressions: + - key: TkA + operator: 乥摟`篿ǫ`鯛d柊朞#=粟ë0"g + values: + - pCd + - tjm1 + - key: L8komgF + operator: 牱鐦騵d公ƅ麭 + values: + - ih77z + namespaces: + - rvCrqx10 + topologyKey: ylag3 + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + matchLabelKeys: + - jJxZ6Rd3 + - "n" + - zUM + namespaceSelector: + matchExpressions: + - key: LgKlZv + operator: 蹉Dǭ乜u3嘴țýȰ¢əfɓ9M + - key: focLN + operator: 峍溌諪ɻɀ鶡凛硓Hʆ&醓y璬P且h晼Ȫ + values: + - 7M + - o + - key: PyRpMu + operator: 軏ƀʪ;ƶ1 + matchLabels: + TLgWRgpL: 6KxhJ8 + topologyKey: R + weight: -2017519918 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: QAEMOx5 + operator: 聚Ē + values: + - ufw1Z3 + - i8Oos + matchLabels: + o6xfK8a: SfPP2rf7Roji + matchLabelKeys: + - le78Yu + - HUTODaS + namespaceSelector: + matchExpressions: + - key: 66vP + operator: u7Ƞ>懝U¤蕃 + values: + - "7" + - GK + - key: J0dXv7ZJJB + operator: 蜸薼野碇甞ĚȤ哕鈁尮"Ǘ枿話Ȕ狏 + values: + - RAX4t + - nPF + - 3ju448C + matchLabels: + M: tVDx2e + jf2: K6SX + xPh3: QQRbks + namespaces: + - "" + - 81J2ER + topologyKey: P0YlKv + weight: 1281715791 + podAntiAffinity: + custom: + requiredDuringSchedulingIgnoredDuringExecution: + - namespaceSelector: + matchExpressions: + - key: xfHcOZ + operator: R ȫ-$<¥;ʗǛ;嶗C臷l + - key: F + operator: '{剽ŢÑ?' + values: + - 4gvxHy + - 8KDxHDtm + - key: dVAZ + operator: ƶG荦鯺x硕=pŮlý:` + values: + - wfeV + - IK + matchLabels: + 31ix: HdDM + S4lHSJCMD2: lu3wExQ2H + namespaces: + - E + - 4tZ + - T + topologyKey: 7sVtS9TK + topologyKey: 7kZ3GBTH + type: ijo + weight: 575486983 + priorityClassName: kVuF7b + progressDeadlineSeconds: 1067800182 + readinessProbe: + failureThreshold: 685579944 + grpc: + port: -2063577057 + service: eR7 + httpGet: + host: EvLo + path: JpKUinL + port: 1426508719 + scheme: ?纙硺ưů溋šwš + initialDelaySeconds: -343905380 + periodSeconds: 1220161608 + successThreshold: -1225720048 + terminationGracePeriodSeconds: 5142513156327389695 + timeoutSeconds: -158246671 + restartPolicy: ȭÕpg琛>盿噸ɸ罀ʊ溠凝ï燘3宓 + revisionHistoryLimit: -867909477 + schedulerName: Cw1 + securityContext: + fsGroup: -1048504685354459048 + fsGroupChangePolicy: 紪兊B©忾iL醒Ɏ}E譮À猃#慆V" + runAsGroup: -5540900310826845836 + runAsNonRoot: true + runAsUser: 1960710021236792309 + supplementalGroups: + - -5069008871988065584 + - 1052747353682433741 + sysctls: + - name: XNC + value: H2sA + strategy: + type: jUn6q9 + terminationGracePeriodSeconds: 1204736887 + topologySpreadConstraints: + - maxSkew: -122908749 + topologyKey: Sx + whenUnsatisfiable: kzg + updateStrategy: + type: "9" +fullnameOverride: IVe +imagePullSecrets: +- name: IDsL67Xzs +- name: j3s2 +- name: rsV +logging: + level: LEXhtAdMw +monitoring: + annotations: + 8UnZf: QuGXzt2iFf + enabled: false + labels: + 5bKl7ZL: OULoJ + rjszo: x + namespaceSelector: + any: true + matchNames: + - SYEcgAmD1 + - pkOAzK + scrapeInterval: 1337119h5m47.177426828s +nameOverride: P7 +serviceAccount: + create: true + name: UQ27oL +storage: + volumeMounts: + - mountPath: T0skfqLM2b + mountPropagation: 訶)5蘳慢墰葭ƓȇkȡʑȆ\&算毳 + name: Xw + subPath: 48LdxME5 + subPathExpr: 3Z +test: + create: false +-- case-031 -- +auth: + sasl: + enabled: false + mechanism: OKrEkY + secretRef: 8nzj + userName: s +connectors: + additionalConfiguration: rJQp + bootstrapServers: 0y2l8XHWK + brokerTLS: + ca: + secretNameOverwrite: "" + secretRef: J + cert: + secretNameOverwrite: copKWn2 + secretRef: DNF6s + enabled: false + key: + secretNameOverwrite: IlMv6 + secretRef: NI3VUhJks3aM + groupID: chzc6 + producerBatchSize: 164004875 + producerLingerMS: -1169688418 + restPort: -1300816856 + schemaRegistryURL: qb + secretManager: + connectorsPrefix: e + consolePrefix: QToud + enabled: false + region: rDADY + storage: + remote: + read: + config: true + offset: true + status: false + write: + config: false + offset: true + status: true + topic: + config: vOa + offset: NoMzWmd + status: UX +container: + javaGCLogEnabled: FZNoDU + resources: + javaMaxHeapSize: "0" + limits: + cpu: "0" + memory: "0" + request: + cpu: "0" + memory: "0" + securityContext: + allowPrivilegeEscalation: true +fullnameOverride: pPZgwOOt +logging: + level: mw +monitoring: + annotations: + 5DX9hu1: TudyZCCNj + A6h88N: VYLm + labels: + bt9lo: o + mnL: cq + namespaceSelector: + any: true + matchNames: + - Oq9en + - SYEqp + - XG13YJtsJ + scrapeInterval: 48406h44m12.186557056s +nameOverride: pLehdV +service: + annotations: + RER: AU + name: MnW8I02 + ports: + - name: 5bgCNjS + - name: gh + port: 792720017 +serviceAccount: + create: false + name: "5" +storage: + volume: + - name: T6INhQ + - name: p0 + - name: EO + volumeMounts: + - mountPath: "" + mountPropagation: Ǜ绕:O+ + name: 4JTdCoLQd + readOnly: true + subPath: RUx + subPathExpr: 0E +test: + create: false +tolerations: +- effect: eǏ=ij醲55 + key: u7vPGy + operator: 欿漎蠶Ðã&¸ŭ垨甕Tàm?Ɣ + tolerationSeconds: -521603474102550743 +- effect: '&縐斮璗ɂĤǤǬŽ56=v謿ȭV囪''' + key: X + value: WYufSN7QfU +-- case-032 -- +auth: + sasl: + enabled: true + mechanism: MJPD + secretRef: SOj + userName: uc7UDCO6UyDA +connectors: + additionalConfiguration: ALs + bootstrapServers: xxQNBWz7 + brokerTLS: + ca: + secretNameOverwrite: tx69jfpT + secretRef: trj6 + cert: + secretNameOverwrite: 5wer + secretRef: zNPqap9 + enabled: false + key: + secretNameOverwrite: 3z6qEC5 + secretRef: "6" + groupID: zqmIj + producerBatchSize: -1704513512 + producerLingerMS: 1028506959 + restPort: 108700971 + schemaRegistryURL: 5EM1GqOCR + secretManager: + connectorsPrefix: CjMvZg3JUj + consolePrefix: zyHuMqq + enabled: false + region: kr + storage: + replicationFactor: + config: -1678993933 + status: -154444750 + topic: + config: lw + offset: QcAJT + status: Cg +container: + javaGCLogEnabled: PB4k + resources: + javaMaxHeapSize: "0" + limits: + memory: "0" + securityContext: + allowPrivilegeEscalation: false +deployment: + budget: + maxUnavailable: -2014617172 + create: false + extraEnvFrom: + - configMapRef: + name: uiS + optional: false + prefix: JBs5bsgvti + secretRef: + name: ctUZi + optional: true + - configMapRef: + optional: false + prefix: tBLmRa + secretRef: + name: 5Y + optional: false + livenessProbe: + exec: + command: + - qSrxe9 + - Ofev8Bf + - nfwKAZufiqv1b + failureThreshold: -1742098812 + grpc: + port: -703296778 + service: JNtb + httpGet: + host: E8hIJ8 + path: Kl96M5dD4rvo + port: 654133412 + scheme: 慌屢癱ž塛F侱鬶7罧鿧P体玿».黾ƺ + initialDelaySeconds: 1821929188 + periodSeconds: -181833766 + successThreshold: 1453387906 + terminationGracePeriodSeconds: -411476157523094884 + timeoutSeconds: -54624232 + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchFields: + - key: LGd + operator: Ʌ + values: + - cBY + - nFQxMQr + - tEAxJ + - key: BVKZ + operator: 觹IJ坌s椉08扸ʥ毄葖0z絓ȍƌII + values: + - 69up + - yC + - HYp + - key: X + operator: ¡Ʋ眭LJqśȚ0ǹ侔T + values: + - UYuQ9O + - matchExpressions: + - key: aH + operator: 倿Ź?Y峬爰R鑾Ȳǜ辇抲縷Ł + - matchFields: + - key: qg + operator: "" + values: + - IDEoPBP + - "" + - 0lyO + - key: aFD + operator: S[橧馐畷蒜ĦţƦxȪ + - key: PPBiwi + operator: Ɖ埓yxȨ崪ǒ圣ǥɳƹ涿跉礃s + values: + - Oim4eTI + - Q + nodeSelector: + PcQX0bVt: 3G + zZB: WG + podAffinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: 8u0nAOFL + operator: 甼 + values: + - tGVYkHw + matchFields: + - key: Fx7oaUO + operator: 辫â8ŸÍc莄ʠʧ + values: + - TbB0SsDhMS + - M9bg + - B + - key: EZlVGKXh5f + operator: d渚竵铃染訧鑩曠辕Sds±Z;œȽ + values: + - CrZH5k2 + - c0oyqS + - key: jiER + operator: b杒嘡ǒ堷©Ƣp髼ö + weight: -1261259648 + - preference: + matchExpressions: + - key: FarFKE + operator: ő%ȫƗ¥+Ŝę恏率偻z髋0BĖ乌 + values: + - LY14XZEILK2 + - d + - key: 70ON9Dm + operator: 1瑚秤¤m½m + values: + - 3gTEM4ST + - key: TKDlMr + operator: ȍ + values: + - L + matchFields: + - key: "" + operator: žE#烊0Ľ曆熥o圉釣XĂ\i螜 + values: + - Qx2kr52zB + - 31Gxk + - cMRkpXPFx + weight: 302435895 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: "" + operator: 浘L# + values: + - LaaH + - 9zM + - Ph29 + - key: B6I + operator: 孞 + values: + - "" + - key: wsS + operator: PȚʀ鑋#栧^ + - matchExpressions: + - key: iflb + operator: MĽ扶C隕ÿ僬í + values: + - o + - kCQif + matchFields: + - key: "1" + operator: 桼ǎsc?ɇ銂 + values: + - rj5 + - wZ8 + - 28Qk + - key: ivMKhM6Ng + operator: Ō/DHT + values: + - gPzgA8 + - Cn + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: s7LHzr + operator: 抧胏$,鵩zǑC©\0vǻɛdz + values: + - rXF + - key: vqysFQX7b + operator: 網Ɉ諌繶ŃbĔj¡ + - key: EUeMa4 + operator: '''鱿pKp馚獮Ú' + values: + - S + - Dz + - wfXfb + matchLabels: + PKUW: Ve + bJOsUOZaJuvc26: XCVIx1 + mismatchLabelKeys: + - OKf + - EzEPAt + namespaceSelector: + matchExpressions: + - key: RKK1 + operator: "" + - key: qDcP4rJ + operator: ƊƣŋsŅ癳鷝3饔¶醐偹 + values: + - s + - "" + - key: 3Np + operator: 揷1Ä[昲ļ莶瀵ƄDŽG~満蒺醟ɟ + matchLabels: + RYJVB: I1y + yc03l: Ifbv6Y + namespaces: + - Z0 + - H80DAh + - 2GH6 + topologyKey: cqxmR1v1 + weight: 885036961 + - podAffinityTerm: + matchLabelKeys: + - OgTFlLP + - W8V + - 2H + mismatchLabelKeys: + - avBvdF + - CTPHay7gi8D + - CUr + namespaceSelector: + matchLabels: + tVu: 6F6BjVP + topologyKey: e + weight: -1410166394 + podAntiAffinity: + topologyKey: 0DOToT + type: 8KfZon1YzpW + priorityClassName: uANVq3U + progressDeadlineSeconds: -1510581315 + restartPolicy: vȺW + revisionHistoryLimit: 2114813392 + schedulerName: CR + securityContext: + fsGroup: -4345780033128932342 + fsGroupChangePolicy: ŧ抱煿ɋM莱皥櫾u$zȉx + runAsGroup: -6541979602773327729 + runAsNonRoot: false + runAsUser: -2014124308289474379 + supplementalGroups: + - -5994021217522109572 + - 3115969151950428485 + - 1514830751691567190 + sysctls: + - name: Is0j + value: JRx4T5 + strategy: + type: g5YzTXRKD + terminationGracePeriodSeconds: 1682090836 + tolerations: + - effect: U褛ɡʇ栂DzǞɴ鲀ǟŻ9 + key: FA2 + operator: 7泏舰ʒ佦ıã}譏'nʣ + value: MyulL3h + - effect: '"dz蜢过7ɏʀ' + key: kOQC0mIA6 + operator: '{僈ʐ' + tolerationSeconds: -9100644779241505077 + value: ROuVy0AbXRg + topologySpreadConstraints: + - maxSkew: -1084227068 + topologyKey: Ux0A3NJk3z6 + whenUnsatisfiable: w + - maxSkew: -1233692580 + topologyKey: oKELv + whenUnsatisfiable: "" + - maxSkew: 1321736372 + topologyKey: FKXPNh + whenUnsatisfiable: CqkZsey + updateStrategy: + type: Ml6hC +fullnameOverride: 8geRNocLQ +imagePullSecrets: +- name: vEXV +logging: + level: 6BNIG1 +monitoring: + annotations: + IPxJONB: hl8rm + iBHXKAAq: hRyn + wPazmhbAf: VofDQ + enabled: false + labels: + 8H: b5A0R8i + AisU: 65Df + oJbv: "" + namespaceSelector: + any: true + matchNames: + - n7CaGZiO + scrapeInterval: 251223h36m21.463919144s +nameOverride: "" +serviceAccount: + annotations: + 3R: vWbEq + 4dl9GK: DwjEF + name: 1Fc +storage: {} +test: + create: true +tolerations: +- effect: B獲鑽RłŠc + key: Zqpy + operator: '`瓋ßW§陆tPǶ' + tolerationSeconds: 6401684450581885663 + value: Vdg8va +- effect: 7婾!彡í萿ǜ暸4*ǝ瀒ɛāɈ琝ɢ + key: NRABB0k8z + operator: ǡ纈g旆Ǿ璈Iôÿ + tolerationSeconds: 1163412628738463513 + value: qkbLHbkA1 +- effect: ɻKpP詮aŁ齱隘' + key: 960b + operator: 諻勵灵ʙƈ3ɋH瓴_ǹĝ屳ݬ8-霖) + tolerationSeconds: -8804703866897420576 +-- case-033 -- +auth: + sasl: + enabled: false + mechanism: eEWwk + secretRef: SH + userName: x +commonLabels: + KZj1Dby: 4SqUXw +connectors: + additionalConfiguration: NbkZ2Rd4mDlY + bootstrapServers: f2 + brokerTLS: + ca: + secretNameOverwrite: tvY + secretRef: L + cert: + secretNameOverwrite: CO + secretRef: f + enabled: false + key: + secretNameOverwrite: 6aXwjPggIiB3 + secretRef: Me + groupID: JyPpZo7 + producerBatchSize: -1287630260 + producerLingerMS: 823182257 + restPort: -1714220122 + schemaRegistryURL: xFi + secretManager: + connectorsPrefix: 6EBYOEL + consolePrefix: Vbhe + enabled: false + region: CuG + storage: + remote: + read: + config: true + status: true + write: + config: false + offset: true + status: true + replicationFactor: + config: -808584898 + offset: -1416545391 + status: 224731880 + topic: + config: XunwY9Z + offset: 6q5 + status: "" +container: + javaGCLogEnabled: LSKF + resources: + javaMaxHeapSize: "0" + limits: + memory: "0" + request: + cpu: "0" + memory: "0" + securityContext: + allowPrivilegeEscalation: false +deployment: + annotations: + EaNQ34T: okvsiPGFK + ZsH7Q: LEUOL + zgKn: 48IBtjSW + budget: + maxUnavailable: 1153958610 + create: false + extraEnv: + - name: Plcb + value: j5YPI + valueFrom: + configMapKeyRef: + key: kD + name: 7v + optional: true + fieldRef: + apiVersion: fb1Ci + fieldPath: P6f4Va + secretKeyRef: + key: 2S40J + name: V + optional: false + - name: YU0bfO + value: jT5 + valueFrom: + configMapKeyRef: + key: "" + name: OBQye + optional: true + fieldRef: + apiVersion: UN3v + fieldPath: N3NnHg + resourceFieldRef: + containerName: TM7dU9JK8Y + divisor: "0" + resource: T + secretKeyRef: + key: drFdfsyL + name: Wn2 + optional: true + extraEnvFrom: + - prefix: glV + secretRef: + optional: false + - configMapRef: + name: F2 + optional: true + prefix: sYg3PgmtONE + secretRef: + name: 4jj + optional: false + livenessProbe: + exec: {} + failureThreshold: 573208914 + grpc: + port: -638612534 + service: wnmWj + initialDelaySeconds: -1420646333 + periodSeconds: -1027365231 + successThreshold: 1837320543 + timeoutSeconds: -508996840 + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchFields: + - key: HDmW + operator: ;ȶR啗xǐy焇灠黰&TɟĬ&啛ɀǕĬ + values: + - dLkZmcXwkLs + - key: bSlNFm + operator: "" + values: + - 3b + - k + - "" + weight: 1914081742 + - preference: + matchFields: + - key: xHLN5 + operator: Eõ虾¤ + values: + - PU + - F4 + - key: REzxn + operator: 唺fµȾHſ劫藦92ţ5刀īȓĥ + values: + - X2vhuqGtb + - 1R + - key: r + operator: )勢ƞʚTćĬ:湭Ǽ焿0\Dzl[邉缝髶 + values: + - PVMaw + - GUlDync + weight: 742714062 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: [] + podAffinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: qtAZ + operator: ən翪洤 + values: + - SD4d + matchFields: + - key: 7NKbhI + operator: 絀^Ŕɛ¢Șl磹Ĺ(ȊO转z菙 + - key: ENUX + operator: Z鞏ƞ慧榷ǐéĕeʫ + values: + - NsTlbi6Hmxvy3 + - "6" + - "" + - key: 0Yz + operator: R£tsb蜗壤筧=鳪e侳V3ƻœ鏮ʖ + values: + - drirgX8L + weight: -1974323169 + - preference: + matchFields: + - key: OulPYnl + operator: ʑȆ&v爆 + values: + - QAbG + - "5" + - vThiAm4DKnR + weight: 1744834253 + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: RZ0 + operator: ƘɁÏą穼ß箮skhƗ + - key: 5yUXaY + operator: 澊 + matchLabels: + EO: wphVPH + Kl28xmWooSwuDBr: nRALc + bOnK6: 8h3Kg0kj3h + matchLabelKeys: + - ntr + - X + namespaceSelector: + matchExpressions: + - key: JYy4u + operator: +ʭkV閁ʏʜ + values: + - jkE8rylM + - wh5eUaC + matchLabels: + "": Hjs7g + QD3Y: EidIPZjSBG9K + namespaces: + - j4WhLEEpQb + topologyKey: 7HX2euiB + weight: -1553649478 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: 93LTmJdbA + operator: 釨鼟峷°DX砛熏Ʋ + - key: Qk + operator: G·ck玫昿圜Ŝ#ʢohȉ$( + values: + - LmlJeSGYq9n + - C9Z73 + matchLabels: + PVQO0E: 3jKFJCwD + p8om: GjoV + matchLabelKeys: + - UrJ + - doKW + mismatchLabelKeys: + - uW4b1SK + - u + - RL + namespaceSelector: + matchExpressions: + - key: KDCwy + operator: ']ȏ jë众膱wɯ.I<¿Ú' + values: + - XYHrwjquv + - Hyk4Lj + - key: wAwVtJ + operator: '''Qxť\ț(f簛ȩ:@&庈Ť橁覡ů帳' + matchLabels: + Axf: NWQcZ + MCs: i4TQ2Fe8F + vL0h88SLvP7: E6 + topologyKey: s + - labelSelector: + matchLabels: + "": eTRlnmbOW + 9RkO: jLG + ZDom: GB + matchLabelKeys: + - Lkfq9 + - NugOS + mismatchLabelKeys: + - rI + - BLa6OVk + namespaceSelector: {} + namespaces: + - qNM17 + topologyKey: FWQOV7 + - labelSelector: + matchLabels: + 99oIA: 7kSmhXyDAZ + UFkHemc59: lgVte + poY7Q: cWSM + matchLabelKeys: + - jVKy + - Fi4Zzb0QUZ + mismatchLabelKeys: + - nYl + - oIFzB + topologyKey: wc4Xr + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: 2WfHC + operator: cĚ任纽a嘟ü庙孋ā槣. + values: + - hZ5fwO + - "Y" + - RD + - key: Joz0bWO + operator: 燎Dkʆ)湽ƫd逯[榄TȽǍ + matchLabels: + RdfPjfak: D + nXYCGG0nf: v7uex1KBj + matchLabelKeys: + - Mmq2 + namespaces: + - VWlNF + - 8RCQE + topologyKey: SAT9 + weight: -812925678 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: "" + operator: ŇɈPĉɳ芏({#'蒛腟敐ų狂釽ƇǴh + values: + - e + - SsHkkcDn + - key: m + operator: śC芲c佟m + - key: ycN + operator: ȭ + matchLabelKeys: + - C + - EUsKF + namespaceSelector: + matchExpressions: + - key: 08sB7HIXW + operator: '{' + values: + - g498LM + - JTB + - key: sLymAyu + operator: 卤{蓍.蕕[纄( + values: + - 0jdLbJ + - "" + - RCaa + matchLabels: + 7M54ahTjl7: NUmm3 + Uw2: t + n9UP: q2uq5Q + topologyKey: Xx329oG + - labelSelector: {} + mismatchLabelKeys: + - jL + - uGU2PnM + - c3qyD + topologyKey: oD9hq + podAntiAffinity: + custom: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: WoYoJXLV0TP + operator: ' ǵeMsɌÆ' + - key: MSdKGV36l83Ke + operator: Ǩj檨ȭ囨氀R钣吏祦ǘR鴛鿾fA + values: + - bEiF39wz + - EWyj4AH + matchLabels: + blQ: brhb + matchLabelKeys: + - 5J81 + - pc + namespaceSelector: {} + namespaces: + - zbPsR + - "" + - Im2BK + topologyKey: uaWl + weight: -1926616342 + - podAffinityTerm: + labelSelector: + matchLabels: + Ye: GUeM + bVTC: "" + matchLabelKeys: + - If + - J9b4 + mismatchLabelKeys: + - "2" + - 9WhJ + namespaces: + - ySEUgx + - R + - M + topologyKey: K + weight: 1801940585 + requiredDuringSchedulingIgnoredDuringExecution: + - mismatchLabelKeys: + - s70p + - xK2tPDm9 + namespaceSelector: + matchLabels: + 3kt5: 95iXhN + miVTQ: Wwsg + namespaces: + - "2" + - U9S1v0ZrRM + topologyKey: xbCfBpsr + - labelSelector: + matchExpressions: + - key: 5sbyp + operator: ÓKzɑĐ®w 辪,厑bʏ佢 + values: + - HBC5IGEufvb + - RJeM + - e8DsOIb + matchLabels: + 0x: ei2F + matchLabelKeys: + - CVu + mismatchLabelKeys: + - Y1y0LR5js + - AdDsZLbi + namespaceSelector: + matchExpressions: + - key: "" + operator: ɮ囧ʪy纽Ŀl騦糭9ɼ騏鋂@_Dï + name: 1NfYEa + readOnly: true + subPath: LtO +test: + create: true +-- case-035 -- +auth: + sasl: + enabled: true + mechanism: 9y9We1zI + secretRef: "" + userName: hK +commonLabels: + co: MffSo + fdioW3StBvzyh: z + wle: mprjb +connectors: + additionalConfiguration: xCn + bootstrapServers: lueYFRx + brokerTLS: + ca: + secretNameOverwrite: "N" + secretRef: lIHvSGq + cert: + secretNameOverwrite: 8ke7H + secretRef: 7EnI0fI + enabled: false + key: + secretNameOverwrite: gUW + secretRef: en9C + groupID: Ue8y5CIOm1s9 + producerBatchSize: 1967229260 + producerLingerMS: -2029655136 + restPort: -559590357 + schemaRegistryURL: BkE6kE + secretManager: + connectorsPrefix: jMsIX + consolePrefix: CI19 + enabled: false + region: xbUhDB40j + storage: + remote: + read: + config: false + offset: false + status: false + write: + config: false + offset: true + status: true + replicationFactor: + config: 1605214820 + offset: 707115192 + status: 233180346 + topic: + config: "" + offset: F + status: JwDpg0NW +container: + javaGCLogEnabled: ciu04f65 + resources: + javaMaxHeapSize: "0" + limits: + cpu: "0" + memory: "0" + request: + cpu: "0" + memory: "0" + securityContext: + allowPrivilegeEscalation: false +deployment: + annotations: + 1XmrLdtzO: x6 + 6ZEV8g: jYUmAT7zj + ziKge: "" + budget: + maxUnavailable: -628496383 + create: false + extraEnvFrom: + - configMapRef: + name: Qi + optional: true + prefix: rvhE + secretRef: + name: iOK + optional: true + - configMapRef: + name: D7eYG4k + optional: false + prefix: mrA + secretRef: + name: q0wiP + optional: true + - configMapRef: + name: dGrcQT + optional: false + prefix: H01JO9 + secretRef: + name: AzjE + optional: true + livenessProbe: + exec: + command: + - teEwkHR + failureThreshold: 822446899 + grpc: + port: 1454930159 + service: Eiw + httpGet: + host: OL + path: YZ5Z0 + port: 1894574353 + scheme: 9Wƾ + initialDelaySeconds: 689975920 + periodSeconds: -1584300544 + successThreshold: -1437519051 + terminationGracePeriodSeconds: -3687935972297794657 + timeoutSeconds: -1664535334 + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - {} + nodeSelector: + yTNxFo: PwiZc65 + podAffinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: hua3lxe + operator: ȅ覝nȔl癋薳ǭ鳳e楉輴ʛ膧Ɵ + - key: JhcL + operator: 趸ƺ胀½+? + values: + - mP + - key: S1hp5 + operator: ï蹃S"KO蔨ʬV虴ķçȁ + matchFields: + - key: xNvhdu0t + operator: ʉ菋3į6娡褛Ǿ襚蛶髳sxZƯ铴 + values: + - zOLf + weight: -62270409 + - preference: + matchFields: + - key: BL + operator: ƓťĿ誁W'鬂ƫqʚ姸轈晾H>至Ƒ欌5 + - key: nS + operator: 塘ijʬ¢| + values: + - CeKuW + - lSaF + - "" + - key: "" + operator: c;锢%Â簰 + values: + - RProQwMwq + weight: 29536709 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: 1Ejbb9t + operator: \9ɫǡ¥ȇ賗 + - key: XlWI4o + operator: '`ȍ泆ɮȴ湨齀Nn2衅' + matchFields: + - key: ZfkSvnt + operator: oơq斡K + values: + - m5k + - A + - "7" + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: tSj + operator: 亁Dž{裧箼e褰ʟ¿Ěv.劮-Col + matchLabels: + xT: 5w6 + mismatchLabelKeys: + - sFVA7a + - rQptjq + namespaceSelector: + matchExpressions: + - key: a8z5P + operator: N戡fȤȴ/栎承\ƽʧs + values: + - vQO1HBT + - key: nuT4ryYMW + operator: ȐƑ蕙.R<偳ř + values: + - g + - IsCtuvE + - 1e + matchLabels: + 6i2L: ffkUfVgqn5 + topologyKey: DFMnWiQikvU3OC + weight: 270744476 + - podAffinityTerm: + labelSelector: + matchLabels: + aKLo8qtH5FR: ZM4Ko + pVf1B: 08llv + pxd: D1 + matchLabelKeys: + - "Y" + - LnTPn + - dD6f + mismatchLabelKeys: + - DKe + namespaceSelector: + matchExpressions: + - key: K4Jk0qV + operator: 蔴桲mȴ + matchLabels: + 842orL5dk0V: i328gg + WUC2Th8PnM: nsm8 + topologyKey: stQ + weight: -2095359713 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: y4 + operator: "" + - key: Jmz + operator: G#ɽ¤伖;ƶ迸,øn阽w + values: + - h1qfybGhqVz + - wzaLoKm + - key: mkmqLc + operator: "" + values: + - fV0Lk + matchLabels: + W: UNez + matchLabelKeys: + - MsmG7dsI + - 18RDxZo3 + - GtxTNKicmIW3H + mismatchLabelKeys: + - i83G + namespaceSelector: + matchLabels: + DsA: dEEI + l6KxKO: K + nf1q: 8t0TDWCLm + topologyKey: 0Bnjw + weight: -2070111635 + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: Go7711 + operator: 皞蹾t蝧)ď巧M迢ɍ`ɸ垕Ĩ瑟J拣實 + - key: iSBfvzSgq + operator: Ȕ:奧焸N_鵪疉ǂF>Ėƿ颛Ǩ)UÝ + values: + - "" + - mOh + - h + matchLabels: + Ei3jdSr8rf: T0VF + KpOUQNu: LVu + matchLabelKeys: + - 3R9wM + - jYR + mismatchLabelKeys: + - OYdNi + - FFUZW + - gL + namespaceSelector: + matchExpressions: + - key: ne81Y49o + operator: 且逼÷A橼­U鐀 + - key: MPlYsS + operator: 馇漹2懛ɒȡ + - key: kz59leD + operator: ȓ3șGzäǧ畬ź*S遯ɱö + values: + - "" + matchLabels: + DnxHc: IIMKKTh7 + jytoiQ: CVq + wJ: B2fd06 + namespaces: + - Gc6fCxz1v + - PzUKSWVR + topologyKey: xQdglfgw + weight: 52691844 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: XXROV5RgOi + operator: '* 鄠hɨ乛ɝĞ#.瓏R蹎倮IJ:嚾' + values: + - e2js0jjV + matchLabels: + BtjCwBEeW5: 2c5wlpNtqI + matchLabelKeys: + - A + - J1Q + namespaceSelector: + matchExpressions: + - key: fHsfsI + operator: 工轹檏嚮ɁǤlňȋ + values: + - LKuQ + - t9Ik + - key: q6a2D3dkj2IO + operator: Ĕ时KɯU抃oʐ董5ŀ + values: + - XP + matchLabels: + 8FEMj: "" + lQqA5yzol27: r + namespaces: + - YIB8e78c + - NBpb4zKSXKv + - yrQw3s + topologyKey: OM7 + weight: 227615315 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + ditk2i184: 1H + fYAoB1dq: u + mismatchLabelKeys: + - 40o7Pt2t + - 6M8vIjdH + namespaceSelector: + matchExpressions: + - key: k0CLLWJ + operator: "" + values: + - PKnQ + - lk5fQk + - ZsVT + - key: 9xJA + operator: 売綺脕cƍʆ + values: + - wzppcOCF1 + - 8vNtmtdYsi + matchLabels: + K4NQB: GbVVmB + Tp: locia + topologyKey: "" + - labelSelector: + matchExpressions: + - key: GNUe + operator: ȳ魴饑揁´ƷLj敧 + values: + - 7cPl9 + - Ku1R6PGe9 + - 0GN2ik0 + - key: OKhwX1 + operator: 'ǒgǝǓ<鋓ʞ墝y浧þ:' + values: + - fJu93tqNe + - PI1Mfnnd + matchLabels: + 5P: o1Q7aT6 + CN8OViOmJe: 58saw + LQa: beDgm + matchLabelKeys: + - TUwrwr + mismatchLabelKeys: + - axK7kBkv + - BiYeKoe + namespaceSelector: + matchLabels: + TNPCe: "0" + Xr: 8j1rURg + c: o9r3qP0D957 + namespaces: + - rtD + - ZemRs0 + - xQ + topologyKey: YB8SGwhpwV + - labelSelector: + matchLabels: + A: 7q2fmfhX + Glg6E: MED4T + sixl1: H33xj + matchLabelKeys: + - BPsroSH0 + - 6z + - CRCc1 + namespaceSelector: + matchExpressions: + - key: KjSwLS6aQ + operator: 8B + values: + - BWWAR + - yVGIt + - poDVRjb + matchLabels: + 7cdkrUS: 5BC + D2Wtwzg: etyr + QIrgRhA: LrxtNTzNr + namespaces: + - DxkXW + - NR4 + topologyKey: 28GQ5Xo + podAntiAffinity: + custom: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: f + operator: ʇŨ礤Z<ǴjyG|wƦ + values: + - ejvRuuwpt1 + - gLMIfr + matchLabels: + 78L: e + Ohko: iVVK + U: I9 + matchLabelKeys: + - IC + namespaceSelector: + matchExpressions: + - key: yuDaghaX7MsB + operator: q蔧ƙÇ¿ƣ鷒啈? + values: + - 8j4L6QsQ + - Uth + - key: Na + operator: "" + values: + - UGpe7wJGcv + - gOerw7DKX + - key: Aibu + operator: tĶʉĺA8p撪ȟ骁)5ĩ碦Ƴ + matchLabels: + pUncJd: pIfYj + namespaces: + - z6PvXvcdOJ + topologyKey: "" + weight: -369728494 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: VqyjJ1pe6s + operator: ɗ嵓 + values: + - 3I + - 3UKCu + - key: XguC + operator: 紂2(ɦ-ɒ煭5U + - key: JDe77b + operator: '*糆忮.ʊ认t昢Õ3' + values: + - H8WZa + matchLabels: + iPqYx: DhnnZ4xOm + matchLabelKeys: + - Js + - ouXfTI + namespaceSelector: {} + namespaces: + - 2OLQUB2p + - 3mETX8a + - lR3 + topologyKey: Jrv + weight: 514367026 + - podAffinityTerm: + labelSelector: + matchLabels: + 1mp6: 99m + 4Efw2wZ: bkoOfCrTsAtp1I + K7eVPls: FPhVHNRC + matchLabelKeys: + - e + - k8c29C + mismatchLabelKeys: + - 8jFnMm + - ajCfcK + namespaceSelector: + matchExpressions: + - key: SD + operator: 騔遲榌 + - key: seFza + operator: ʨĶ躾 + values: + - lWQMf + - key: aKMU + operator: łĩǼƬ\ɲÛ + values: + - 9O + - "" + matchLabels: + fWl: rvQ + topologyKey: vK45 + weight: 780671227 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: YPiAewyLf7 + operator: ǿHżǕ|厪载ț菖Rŧ緽甀4懅Ŭǘ泛 + values: + - "4" + - k + matchLabels: + 6m44: Px5C0 + mismatchLabelKeys: + - SW + - "" + namespaceSelector: + matchExpressions: + - key: bia9 + operator: "" + values: + - uEN + - i + - RneeyW + matchLabels: + 2z4sJnMZ0zanj: XsE9K9qNs3R9d + FE3xnQiMzs: pH + "y": AuxHvFSO5 + topologyKey: Ahkr + - labelSelector: + matchLabels: + 1BI9O: TK + mismatchLabelKeys: + - ADboVaek + namespaceSelector: + matchExpressions: + - key: "" + operator: 挭ɴ + values: + - mN + - "5" + - key: "4" + operator: 庘 + values: + - SNA + - X4aO + - key: "3" + operator: ȲmǪǯy`H腂Ǭɚė;a豮塃ŨB墻 + values: + - rFKRGJSh7izi + namespaces: + - Eu + - ukjSfz + topologyKey: 5p9 + topologyKey: B4OXuwDjfXhpv + type: 3k8SY + weight: -646418769 + priorityClassName: PgbnRKfoNZ9 + progressDeadlineSeconds: 896415388 + readinessProbe: + exec: + command: + - NOohSUxF4B + failureThreshold: 1326051879 + grpc: + port: 167069356 + service: KOkYxO + httpGet: + host: iod + path: cv + port: -1874700217 + initialDelaySeconds: -286116672 + periodSeconds: 215270432 + successThreshold: -1666168294 + terminationGracePeriodSeconds: -4429146824329263796 + timeoutSeconds: 1016008226 + restartPolicy: ʘ鿕1 + revisionHistoryLimit: -756285031 + schedulerName: wkog + securityContext: + fsGroup: -7875411171408920752 + fsGroupChangePolicy: 8^ʝȽ袈gǖ陘&X + runAsGroup: -6294097412272475416 + runAsNonRoot: true + runAsUser: -5578668191823418258 + supplementalGroups: + - -8360179017668391912 + - -5953270946476852863 + sysctls: + - name: QCC + value: 6BUk + - name: OblhYC + value: 69u + - name: 6wi2Dp7MdE + value: wk + strategy: + type: ovF4f + terminationGracePeriodSeconds: 1666535039 + tolerations: + - effect: 賥蟽 + key: Ib7 + tolerationSeconds: -5135177309592069822 + value: sbwrIR + topologySpreadConstraints: + - maxSkew: 1411650727 + topologyKey: ajVI22c + whenUnsatisfiable: GTjhhGH + - maxSkew: -1481674415 + topologyKey: Ed + whenUnsatisfiable: 3Y59WCet0 + - maxSkew: 2066507739 + topologyKey: EVEZo + whenUnsatisfiable: dGL6aGB + updateStrategy: + type: IxL7 +fullnameOverride: 6fr +logging: + level: je +monitoring: + annotations: + "4": kTkxkO + enabled: true + namespaceSelector: + any: true + matchNames: + - FKCzSYm7gaXuLQ + scrapeInterval: 1559435h40m40.991511561s +nameOverride: PeueQ +service: + annotations: + YaiOBiXa: rQx + ofToM: "n" + name: mC3vFeP +serviceAccount: + annotations: + "": 9hOutlF7d + PgHx: nJWqenXs4B + create: false + name: WnDtqu +storage: + volume: + - name: 4W + volumeMounts: + - mountPath: "" + mountPropagation: 泽{9ǸSĝy鯘匉ʩ顎 + name: K + readOnly: true + subPath: ZYmQ0MFTxpFIcfQ + subPathExpr: 6Eof +test: + create: false +tolerations: +- effect: 珧卣硁 + key: q + operator: f甗垈ɰ喸ɋʍLi邦痔昝 + tolerationSeconds: -3369346527291309714 + value: 8CRfBsQ +-- case-036 -- +auth: + sasl: + enabled: true + mechanism: 4pr3gf + secretRef: Na4b + userName: ZTak1O6cR +commonLabels: + 1qqW32x: "" +connectors: + additionalConfiguration: LhQU + bootstrapServers: PJXgS + brokerTLS: + ca: + secretNameOverwrite: pMccWpS50Tt + secretRef: MyH + cert: + secretNameOverwrite: c4sa0FA + secretRef: Iv + enabled: false + key: + secretNameOverwrite: EOAKr + secretRef: no0Ke + groupID: XuGw0bAvU4mCl29 + producerBatchSize: 1402635005 + producerLingerMS: 1479365932 + restPort: -1153123375 + schemaRegistryURL: owIrcBoHKcGy + secretManager: + connectorsPrefix: FtgUV7wBq + consolePrefix: wUj + enabled: false + region: 3d60 + storage: + remote: + read: + config: true + offset: false + status: true + write: + config: false + offset: true + status: false + replicationFactor: + config: 935026050 + offset: 1816899175 + status: 1556885434 + topic: + config: BKIQd85 + offset: AqMgsp + status: cB +container: + javaGCLogEnabled: 92CKlhkT1dY + resources: + javaMaxHeapSize: "0" + limits: + cpu: "0" + memory: "0" + request: + cpu: "0" + memory: "0" + securityContext: + allowPrivilegeEscalation: false +deployment: + budget: + maxUnavailable: 867420096 + create: true + livenessProbe: + exec: {} + failureThreshold: -1589865511 + grpc: + port: 397887456 + service: aC + httpGet: + host: RIACQ5bT + path: ubCDRTj0 + port: G6dz + scheme: v怑撴碥dz/Ȱĩ褔ć咫眜 + initialDelaySeconds: -621095822 + periodSeconds: 280342995 + successThreshold: -167276282 + terminationGracePeriodSeconds: -787336059945079524 + timeoutSeconds: -1535167124 + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchFields: + - key: 3bTiSjGL + operator: Pʡdz饿n抈Ʊt嬩癘Ƈ + values: + - AGfqyUGQXxyY + - FVcNDfkQ + - v3hp7MN8nVKE + - key: L3S + operator: -殊 + values: + - 97iUcu + - dXmY + - KUxQvBTJu + - key: YNi + operator: ijS泉ľ;ŒvS阸多嵠{ + values: + - xf0B + weight: -207219009 + - preference: + matchExpressions: + - key: EAkVkI70 + operator: 钚寽蛺izȭ7_掅桘 + values: + - aAWkk + - ze + - 3wGu + - key: 3RyfQc6N + operator: 5ɔ螗śLƆ扒\ƃ"氧ɉ + values: + - Vv + - key: 1vVqYpX + operator: Yto%Iƈ?暊I)琣?Ć痕猖ȕ + values: + - 9yyhe2i + weight: 2145655584 + - preference: + matchExpressions: + - key: vYGC + operator: 缈饜代u灧Ȼ + matchFields: + - key: Xbz + operator: ż苡訖ɑʟĨı齻@IJ騮削ƽ蹄濁榷鰠 + values: + - qFq5zh0O + - yG0 + - nT + - key: P3 + operator: ǧ唾潣PNJ掉ơ\庱吳.,OLX + - key: 3ATe + operator: ʦ恀^ + values: + - LUm4b + weight: 351084922 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: XLalOY + operator: 挝R凗ŵ莁5E7?Ȓʍm篫l{Č蒄 + values: + - YrzbvR + - 5awUoV + - a + - key: bhAd + operator: 鴵鈌ąt烿æy伸?^đĔʎ{Ç柧 + values: + - GqRb + - key: 8WgrpCvg + operator: bAMƺ惸鹖ŏ垇ɔǁI庫û*ɔ嶢ɚ菑 + values: + - BRd8A5 + - "9" + - K9hDIBU + matchFields: + - key: FntInb + operator: '{@əɃðŗ8''4' + - key: cPqf3 + operator: Ƌ娔殺慑 + - key: o + operator: ɧlǬ量GJ恉əŏ滸IōĈwǝ栢Jȡ + nodeSelector: + gQqg: rQO1 + podAffinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: zOF + operator: 朜褜虳忈笊=^ŦĀæ珆.ļǥ禼%鄍u坳 + - matchExpressions: + - key: 1c49YQG + operator: 鉃) + matchFields: + - key: 8VgAhL + operator: 鲼緊+靠侠婎SiǛ + values: + - xRTpCX4 + - key: nMJRs5gZCA + operator: j¯4x篭竪嗎餀箈aƦğt勤 + values: + - bJ + - matchExpressions: + - key: w2ZrgZZ + operator: 枓2ǘI1~MCʮ毳鲠紱$ + values: + - 2m4u9O + - key: V21P + operator: GɫȎt铊ʍ + values: + - LMhd + - "1" + - key: M4HbYG + operator: pƘá褊ŋɃ縷Ř4#r珩伌 + values: + - 2J0tPZtjgGXw + matchFields: + - key: ZIVyS8kWnnfkYw + operator: c耑 + values: + - Us3BB9T8ZiR + - key: Qhnd7 + operator: 醻墽Pʚ'pQĘ咒|庋Atǯ + podAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: IBWHBnu + operator: 陡陂ȗÍ + values: + - KiVSuBwz + - EKMAH2 + - KltN4D + matchLabels: + Uy: ndCtZ + matchLabelKeys: + - aH + - Jm1CJxCAOFTsTH + namespaceSelector: + matchLabels: + gNqMg: 4uZV + namespaces: + - IRrBPIF + topologyKey: gH + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: W7CLLYL + operator: p + values: + - wBg43v + - jjBoD + - key: mQi + operator: '鏷ï®Ɉʗ:' + - key: zZDCy + operator: ķËʢŖźg6 + matchLabels: + 16OpXu: Jv7c6Z + b: l7o9GuH6 + vHrx7Q7: AJ9NoDNx + matchLabelKeys: + - kuQP + mismatchLabelKeys: + - EOOVnE5 + - JATz6Dw + namespaceSelector: + matchExpressions: + - key: P82eyO3 + operator: .@薉敤 + matchLabels: + 9vDs: Q6Zs + topologyKey: sfoIVZS + weight: -135173201 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + jdVqK: 6uhB + matchLabelKeys: + - Pm + mismatchLabelKeys: + - Hn + namespaceSelector: + matchLabels: + n3Y: Z1 + namespaces: + - TCw + topologyKey: 7K8KHn + podAntiAffinity: + custom: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: EinF5FXZ + operator: bȓ1勳ɭ佽 + values: + - wqg6r + - 779ys6y76nH + - x0ataGm + - key: B25ck + operator: )罎ʟ²倮?.iÃw恷曇 + values: + - lAr5 + - key: tG5hyCt + operator: 葚鍍{ + values: + - VkGpC + - PTmNKiFT + matchLabels: + JcqEAka: 4bOR7 + PPatn0wk: 4tEsp0P7yU + vy1Z: MKK1V + mismatchLabelKeys: + - QRybRT + namespaceSelector: + matchExpressions: + - key: 45Q9A + operator: ũǁɩ + values: + - KlwquGdC + - 3vG + - YOsj4 + - key: uV + operator: Ȗ卑 + values: + - PDpyaQk + - 36Yc + - key: jiY1 + operator: "" + values: + - e4G2 + - QA0U + matchLabels: + zam9TqK: tw8 + topologyKey: Cm + weight: 1308300246 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: oZ + operator: 峜Ɂ墶Ă廮 + - key: 4hL + operator: Ǡ侩歹 + values: + - "" + - 26I2B2P + - 3d + - key: qG + operator: č 榢ĘJŔ + values: + - 6pCF + matchLabels: + QAJb6: zB + namespaceSelector: {} + topologyKey: oR + - labelSelector: + matchExpressions: + - key: aFlMv8 + operator: Ɖa獝^kÖįȆǶnjo愋Ɵ + values: + - pvg + - key: 1A9MoKhHv + operator: ĥ6t+飔鋹ɦ¨怙p|ɽ飏Ɗ軖ʎ沌 + values: + - zHCQw + - "" + - qmFwLPdm + - key: 91HCIQfS + operator: ɿĐ唁 + values: + - IFd + - A8I2KrfF7y + matchLabels: + 9CL: QuOz + RQ4ARy: ynSUOh2CV + matchLabelKeys: + - q + mismatchLabelKeys: + - WKzkVK + - "" + - Sx1Rq8OW2G + namespaceSelector: + matchExpressions: + - key: nZr2S + operator: šp釹%0Lj呱Ʌ + values: + - Ke1J + - key: xSGJ + operator: "" + - key: ZQqukWS + operator: 犨·UaíƄ(ɸ + values: + - tv8GH9 + - RG9n + matchLabels: + 2eHPmc: tu41f + namespaces: + - Q5fw + - GJCz + topologyKey: 6gB + - labelSelector: + matchExpressions: + - key: NL47lV + operator: ǽʼnõ颷 攬 + values: + - QbM1FbtaaCmsyj + - key: Jp0SssgWqj + operator: 糕]ÖXȨ佫 A澡 + values: + - fd + - XmxC3TWsEmq9 + - y0 + matchLabelKeys: + - n3UP0A + - W + - jr3hc + mismatchLabelKeys: + - bvXXaN6hJq + - nEpSV + - "5" + namespaceSelector: + matchExpressions: + - key: CNfZvS4 + operator: ʕ氼呟燌ƴ偻ʧ + values: + - vGHTqK + matchLabels: + "": QYu + 5sSOpIp: ojU2Q + aF4: 7so + namespaces: + - m0TP87i + - Dbr1WY4S6 + - Ddl9oOUe5 + topologyKey: k0qv0ARQ + topologyKey: PK + type: n8LqK + weight: 1862848677 + priorityClassName: xotT7T5AcOs + progressDeadlineSeconds: -1260879447 + readinessProbe: + exec: {} + failureThreshold: 1985429634 + grpc: + port: 1193887492 + service: Nqfbjui + httpGet: + host: W + path: cMG + port: BNN + scheme: ƅÉ鐴ƠÙ + initialDelaySeconds: 520999520 + periodSeconds: 1834416895 + successThreshold: -2144235192 + terminationGracePeriodSeconds: 5498268243526196931 + timeoutSeconds: -1654928979 + restartPolicy: '>Ȏ縂ɴ垍ū*' + revisionHistoryLimit: -1294473838 + schedulerName: mlm5OhgsGh + securityContext: + fsGroup: -24635125662907280 + fsGroupChangePolicy: Ŏ痿1>a茫ȡ跦 þ + runAsGroup: -3967780041970194819 + runAsNonRoot: true + runAsUser: 8970781034706956029 + supplementalGroups: + - -8270543106812796306 + sysctls: + - name: KljKqWpUKsb3 + value: 9Zv + - name: z8scvHARn + value: sk + strategy: + type: 5cn + terminationGracePeriodSeconds: 446877207 + tolerations: + - effect: ɟ + key: J906H + operator: Ȇ:龳虹$鿲Ȥ.t齹Ń5 + tolerationSeconds: 6789201977316389154 + value: vV1 + - effect: ©Ǯ膗Ǖ盉浝Ŝɟ + key: ju6amcMPM8UK + operator: 衭蛩ņý + tolerationSeconds: -8177010640192863674 + value: S + - effect: cÑ + operator: L晚G& + tolerationSeconds: 8159638238997450391 + value: OyDyWZoaY + topologySpreadConstraints: + - maxSkew: 1646710512 + topologyKey: MbS + whenUnsatisfiable: Ia0hRF8y + updateStrategy: + type: v85FBu8J +fullnameOverride: VW0lF +imagePullSecrets: +- name: zaKvtKNIW0 +- name: "9" +- name: fG +logging: + level: PAOVCu +monitoring: + annotations: + FZ: Lz + Hn: kspXbct2sc + enabled: false + namespaceSelector: {} + scrapeInterval: 2385507h10m25.926950118s +nameOverride: taotfWzUIl +service: + annotations: + lp92O: 1QnD84Dhxl + name: GxFDpR9IkU +serviceAccount: + annotations: + 3Of: dCI + qQF2N: p + qRJTCP06eO4: st9XdjpkUTE + create: false + name: srWYjAnpR +storage: + volume: + - name: qx + - name: XeUJ + volumeMounts: + - mountPath: MMqGiv5CN + mountPropagation: 鳮耐uíȪr + name: jHofb9BQ3 + readOnly: true + subPath: aDzkmP + subPathExpr: 4sgTWM4H + - mountPath: KhsFs + mountPropagation: Ǎ繟ƣʜ + name: V02ibh + readOnly: true + subPath: LF + subPathExpr: mi +test: + create: false +tolerations: +- key: Hsie1qK + operator: 7禝Řm蟷8š\ăɴń! + tolerationSeconds: -4804202694445470283 + value: UcY +- effect: 0þ嵡壱ʄ{祗Ů< + key: 7NdQZ + operator: '{#遲TƯ|薚嫛oQ¢龀êƶȈ肯A]Ħ' + tolerationSeconds: 4179143239755402759 + value: VzOAMkU +-- case-037 -- +auth: + sasl: + enabled: false + mechanism: 4jrWn + secretRef: "" + userName: 2sGSSni +commonLabels: + HSu1: FRG692y + QExXAto3Ub2T: etTOY4y8iSmyDOe +connectors: + additionalConfiguration: FTlQkC + bootstrapServers: LeVg + brokerTLS: + ca: + secretNameOverwrite: 49XwYgsyn + secretRef: 28O + cert: + secretNameOverwrite: Wf + secretRef: EDOE + enabled: false + key: + secretNameOverwrite: 7rwbl + secretRef: TaD + groupID: q + producerBatchSize: -1100237413 + producerLingerMS: 982363719 + restPort: 1885084612 + schemaRegistryURL: N8 + secretManager: + connectorsPrefix: zyFCC0ac + consolePrefix: VGoEYwVGt + enabled: false + region: gsEq + storage: + remote: + read: + config: true + offset: true + status: true + write: + config: true + offset: false + status: false + replicationFactor: + config: 575483838 + offset: -1765361377 + status: -1294780557 + topic: + config: fiLg3L + offset: WDtxRL37SvNV + status: Guofk9 +container: + javaGCLogEnabled: mn + resources: + javaMaxHeapSize: "0" + limits: + cpu: "0" + memory: "0" + request: + cpu: "0" + memory: "0" + securityContext: + allowPrivilegeEscalation: false +deployment: + annotations: + PsITu: LgrI + budget: + maxUnavailable: 527993762 + create: true + extraEnv: + - name: 7PtPut9 + value: 4Uo + valueFrom: + configMapKeyRef: + key: H6 + name: JEPQ + optional: true + fieldRef: + apiVersion: yCSfB + fieldPath: HD + resourceFieldRef: + containerName: v0wW + divisor: "0" + resource: BliOlDq + secretKeyRef: + key: AOod + name: Ljqm + optional: false + - name: FItx + value: cZIyVQPdqZ + valueFrom: + configMapKeyRef: + key: O3 + name: KlO + optional: true + fieldRef: + apiVersion: BnfYTBc + fieldPath: xw + resourceFieldRef: + containerName: qzV549 + divisor: "0" + resource: sctpzNUt + secretKeyRef: + key: Ff4vJm + name: hoEa + optional: false + livenessProbe: + exec: + command: + - aAxGQ + - sdk0 + failureThreshold: 1572051601 + grpc: + port: -2511945 + service: mqDAn69OdiR + httpGet: + host: Cw + path: l2JEc34o3Oe + port: -1821016511 + scheme: E嫺S崕襅@卢莩ŹÍ + initialDelaySeconds: -455418157 + periodSeconds: 31037144 + successThreshold: 1836675270 + terminationGracePeriodSeconds: 3628590034628485216 + timeoutSeconds: -722680942 + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: tmEGf + operator: "" + values: + - yCcLCb + - O1NTsHk78miTJ + - key: KuvLpSp4X + operator: 獴ĝB违写õʕĠEɊ繎ª + values: + - oqAB + - "y" + - cLExkHCRfD + - key: tMxc + operator: 1Ņ鸩瀚羨鱬c)0ƶ音êA{ǷZŁȃ + values: + - W2 + - rXnf + matchFields: + - key: dvXtkKrlxr + operator: m駠祸¯獒ɌƗ'Ñnj嗰蒩,幔Ǣ + values: + - vDUy + - vzx4 + - key: UU6d + operator: 惂PqbKɕ`ǃȒCʉ鞊Ĩ% + - key: qm03jaCk + operator: a靔Pƴy%(AĔð勶乀ĥČI#ɃǙ蘨 + weight: -1872535291 + - preference: + matchExpressions: + - key: GjG + operator: űŌ + - key: UQ + operator: d欻Ɲ + values: + - zpBqznM + matchFields: + - key: gKn2 + operator: ÁŠ9玫Ʌ + values: + - Iij79g + weight: 1456486091 + - preference: + matchExpressions: + - key: 1Ef + operator: G飔8`ɒ蕸祹&匪璳拖嶴6s['%邗 + values: + - iBr + - "" + - key: RXMgUipZ + operator: Qāȃ鋘ǖ0iNɭȂuŦ褌7Èȝ鹊淋廽 + values: + - NB + - key: nb6 + operator: 杘ɯ#`慐 + weight: -1381009180 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: [] + podAffinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchFields: + - key: YGfExP + operator: I喝ƀıjXĴǞư + values: + - gMwxOyRC964 + weight: 670180912 + - preference: + matchExpressions: + - key: PG + operator: 軋 + values: + - "" + - key: UG + operator: '#驇qeʩǏ¿貽帇2ʒ士眯隋ƋǨ' + values: + - QegWF3oN + - oatkrd + matchFields: + - key: 3eS + operator: ¼漒2踦{KǗ薵俧©2汻EÁ涼Nz珹瀝 + - key: X6L + operator: '|' + values: + - sEK2 + - qEPmyB + - VYZ + - key: 7RelIlVvL + operator: 幓賵ɱÞ + values: + - pDayYj + - z5Hu + - 4m + weight: -2031437615 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: [] + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: 2FJDM9 + operator: Ŋ>剫嫝"Ą樴娽Gɚ苊绬髻F + values: + - oHS + matchLabelKeys: + - "" + mismatchLabelKeys: + - p + - YjU + - 2odlypNfA95k + namespaceSelector: + matchExpressions: + - key: BT + operator: j^Ƹʥɩ缲摭沕 + values: + - dowWlQ + - bgMn + matchLabels: + X7j: En8zXY + namespaces: + - y2KQMu + - "9" + - zzZnV + topologyKey: tL + weight: 1287421908 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: o + operator: ſo{t柇壚乜狸羧{Xǽ桨嗂 + - key: xwmYvKHx + operator: oDžȫ涳ùY劣²ȩl,s槿ğ壽 + values: + - aWhHkHzjX + - UD9vL + - 0RGjdmKAyBU + matchLabelKeys: + - 1H + - JcEmqhN + mismatchLabelKeys: + - "" + - PDJ5Ju + - dXck + namespaceSelector: + matchExpressions: + - key: f + operator: C喅ŞiŒÔY屜槅*l$SXǙ + values: + - 9x + - key: 3W + operator: ȴ + - key: k + operator: c1ȝ鿋-灯G¸匱矝©YS)3 + values: + - iAgdu918eA + - Vh + - Ay + matchLabels: + 73TP8W: pyVmznhs + qk4vn9ey: Zo338 + r15l: msN3 + namespaces: + - yd6ggcat + topologyKey: 6ASZY + weight: 897890087 + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: yVR + operator: e + matchLabels: + 0JR7: "" + 7h: tsaIv + zJUMBFb: 73VNvB2hGIG + matchLabelKeys: + - "" + - F6e + mismatchLabelKeys: + - pQx3050 + - 48sjiLtK1OX + namespaceSelector: + matchExpressions: + - key: G0S2x + operator: 舥$Ƴ諺襔`Č詊Ù佱i^ + matchLabels: + KiIaV: 9VV + namespaces: + - "" + - wqDGw + - X8fMvo + topologyKey: PQ + weight: -234450005 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: y95Eu + operator: 鎲鼳C羝 + values: + - rVqdBdT + - VS + - key: hcv + operator: lɏɘ顷k§4uĭ_Ǩ + values: + - oOC + - GcSQ7eMK + matchLabels: + bhI1zyBLWzjf: zMQO + iEDKDYY: "1" + matchLabelKeys: + - wc + - CQ + namespaceSelector: + matchExpressions: + - key: dXMvM0 + operator: '#欚@Khú4腠?炼DC' + values: + - "" + - P7LAsv + - key: T3JJIOe0 + operator: wƞ鱽用 + matchLabels: + WR1yFB: 1p8kbHuc + hvXw: Q + namespaces: + - r + - G83y0Rb + topologyKey: MG + weight: -1355438616 + - podAffinityTerm: + labelSelector: + matchLabels: + ng: k4 + y07PoU: lAmDC + matchLabelKeys: + - vXtdl9TKf + - w + - 5ne5 + namespaceSelector: + matchExpressions: + - key: S + operator: ȥśĭ醝U + values: + - E4 + - key: uAocj4wN + operator: żǞŃȢDǩ彇馥或 + values: + - QT + namespaces: + - vDbd + - bBdeHkb + - 2qHmj6f8r20 + topologyKey: "" + weight: 1121806715 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: Q + operator: ĶÖ}鏀襹*貳ɇɱ + values: + - IhHh9y + - Twz + - "" + - key: wA + operator: ǘ焓緉ķĐƞ橝许椕NŬ + values: + - zH + - key: kNVTA5c5 + operator: 磰À弰¥ + matchLabels: + 3HCFedhUu: m3REU6b5 + matchLabelKeys: + - MAmo + - QMqy5uJI + - "" + mismatchLabelKeys: + - s0qo8x + namespaceSelector: + matchExpressions: + - key: wI1MBZM + operator: '&3帐箮WƑ擙Ǜƻ{®ǩ靡Ý羷觕ʛ' + values: + - 74aJ + - PJyXLgY + - XHNS8s4 + - key: aA0AN3t + operator: 旓樮ʉs鬞ǵù + values: + - SgO7 + - key: 4R + operator: p3尐\ + values: + - IB + namespaces: + - 0lYJ + - 2D + - zoo + topologyKey: qeuhMV5b + podAntiAffinity: + custom: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: 20PY3f + operator: 茟踹 + - key: ASopYP + operator: Ȭ + - key: 3ABJJ + operator: ʀ嵜瑎WR裛寋嚊韍Ȉ瑷谾ʇXɂƵ掸踷 + values: + - vN9Qn + - KTrN + matchLabels: + FEtqF1P: da9Y6HCr + TaC8ul: lKZj7JT + nKtu: 0dAf + matchLabelKeys: + - jWp + mismatchLabelKeys: + - 8ghGuz0Zts + - 2W + namespaceSelector: + matchExpressions: + - key: uQ + operator: Fȭ0 + values: + - EZNyEqasw + - nh + - 7mUbUIiNekjf + - key: 8m0i9Gw + operator: 誠öT%=%专O螆挪uv敁 + values: + - "" + - chJrkkoa9 + - XpOAIuKt1 + namespaces: + - 11BBEfT + - B9Yw + - mMPq + topologyKey: gUcmhv4Wymn + - labelSelector: + matchExpressions: + - key: jr + operator: 萺L(Š鼁嶵謝鿹犈=ŗB粦ú纑 + values: + - qV9 + - N3wxU + - gGa + matchLabels: + 5LE6Fz: ihjmXy + 8O: WL9 + matchLabelKeys: + - LF4 + - Iw5KCY + mismatchLabelKeys: + - Yj + namespaceSelector: + matchLabels: + 4g: CWx + RpPK4ak3: 5APfgG0 + namespaces: + - zlH1Ayq + - iN5A0H + - gHs0AD6 + topologyKey: ROQ5F + topologyKey: pxtZlO5o + type: yt + weight: -1822679559 + priorityClassName: E6rwXY + progressDeadlineSeconds: -1761307563 + readinessProbe: + exec: + command: + - F1Ji + failureThreshold: 1393918041 + grpc: + port: -402186756 + service: weWQs7z + httpGet: + host: W7 + path: "1" + port: -2008006258 + scheme: ƗǺƑȹƱ哮黰"bZ + initialDelaySeconds: -1529972341 + periodSeconds: 1791885136 + successThreshold: -1003238871 + terminationGracePeriodSeconds: -6904279593611975807 + timeoutSeconds: 516179111 + restartPolicy: tAȍ_祴珗ƨŐ飔矜ƧŸȺ8Ù凿吱 + revisionHistoryLimit: -1377004535 + schedulerName: k + securityContext: + fsGroup: -8943063634632832728 + fsGroupChangePolicy: 樜3g罡Sɺ:礁j + runAsGroup: -8183677367766309518 + runAsNonRoot: false + runAsUser: 6257019186377025309 + supplementalGroups: + - 6349796974429449397 + - -6495960424240767705 + sysctls: + - name: tNzNhbs + value: Li + - name: xw + value: wQYd + - name: rijilGaE1rE + value: O1VB + strategy: + type: qVm + terminationGracePeriodSeconds: -340872360 + tolerations: + - effect: 旽ǷȬƱĬɔH辂W'ʩ菽懝 + key: NRzfhGYG1Y + operator: 皏棵FɁÈ棿X + tolerationSeconds: 4658882017834992565 + value: Lu + - effect: "~" + key: k + operator: 垫 + tolerationSeconds: -950306177981439209 + value: j2wtF4uhca + topologySpreadConstraints: + - maxSkew: -1481065440 + topologyKey: SER + whenUnsatisfiable: 5L7rrGecd + updateStrategy: + type: 9C8ybQ +fullnameOverride: vRXgQsUzl3 +imagePullSecrets: +- name: d18 +logging: + level: Y0gfv +monitoring: + annotations: + Hr: 7uW + gZeic8h0Pp: C9ox + ggG9V: 0HgD + enabled: false + namespaceSelector: + matchNames: + - twAaqe5jt + scrapeInterval: -2278442h2m26.413746462s +nameOverride: 03U7 +service: + annotations: + 5bK2xe: ZRy + name: "87" + ports: + - name: yMA8tJxHo + port: -582141187 + - name: "9" + port: 830415771 +serviceAccount: + annotations: + 4XITA7: dwhbdLpr + G6zvz: "" + create: false + name: 1J +storage: + volume: + - name: QbE11Wi + - name: 5p + volumeMounts: + - mountPath: FMieal + mountPropagation: q睢1Êb2y"ğJĢ + name: GRAaf7 + readOnly: true + subPath: Wvz + subPathExpr: K4St + - mountPath: E6 + mountPropagation: 2`| + name: yu + subPath: 1Qyv + subPathExpr: lq + - mountPath: "9" + mountPropagation: J仅<Ⱦù觏牨¼Ǐ蒜,J偛l挨 + name: CkWy + subPath: 1YtfYCwcHU3 + subPathExpr: xUIPjXS +test: + create: true +tolerations: +- effect: 鮻 + key: TnWM + operator: 6yĢ置ǟȶų(ʌ寵Ůu诀. + tolerationSeconds: -4327555826581044156 + value: zsh6p +-- case-038 -- +auth: + sasl: + enabled: false + mechanism: r6Ew + secretRef: feyz + userName: p3MeX +connectors: + additionalConfiguration: eFqd + bootstrapServers: vF9T9o1K + brokerTLS: + ca: + secretNameOverwrite: nvP + secretRef: 4cOI2 + cert: + secretNameOverwrite: ZAZH + secretRef: pa6XYq09 + enabled: true + key: + secretNameOverwrite: JTIF7f + secretRef: wFZhDXH + groupID: NgUalZU70 + producerBatchSize: -1494749189 + producerLingerMS: 1372991769 + restPort: 436787525 + schemaRegistryURL: c + secretManager: + connectorsPrefix: Ed + consolePrefix: 8bUfufKV + enabled: false + region: GdY5AF + storage: + remote: + read: + config: true + offset: true + status: true + write: + config: true + offset: true + status: false + replicationFactor: + config: -1726135850 + offset: -1194630723 + status: 1047213359 + topic: + config: 5ipmMylSvvfF + offset: UVjBc + status: 5plTTvTKV +container: + javaGCLogEnabled: jIw1 + resources: + javaMaxHeapSize: "0" + limits: + cpu: "0" + memory: "0" + request: + cpu: "0" + memory: "0" + securityContext: + allowPrivilegeEscalation: false +deployment: + annotations: + Wk: JaAXs + ku: f3BwiPJdI9MX + budget: + maxUnavailable: -683730360 + create: false + extraEnvFrom: + - configMapRef: + name: xM0JJY + optional: true + prefix: MdrcdYg + secretRef: + name: md9h + optional: false + livenessProbe: + exec: + command: + - wskd + - qt9q0 + failureThreshold: -2043749481 + grpc: + port: -1703450062 + service: TBMlp + httpGet: + host: RHQg3u + path: bi2McNI + port: 2127214512 + scheme: D4¿@駉也òV雕7徑篍衾 + initialDelaySeconds: 1969882690 + periodSeconds: 412101592 + successThreshold: 1426526420 + terminationGracePeriodSeconds: 2990769791924451128 + timeoutSeconds: -65595943 + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: KmRBa + operator: ʯ惱ȷQ墨閙榈Ř欋觗 + - key: A9jxPVS + operator: ux$ + values: + - dxNjKzWbRnUM + - eXHweVWL2Pz2OY + - WV2g + - key: HNX + operator: 檯嫋R躞ĝ螩 + values: + - Rn8TX3 + matchFields: + - key: 5T5Xer2S + operator: 帯斢桁įē=搞 + values: + - J1c4aNW + - kBL + - key: kWlWYP + operator: 砱鸾ʦrO³ʬǬÒ銘`陶V + values: + - 8rj + - tRn1g + - JNMw + - key: FcK + operator: ÐDŨDř术ÛÅ謮¿錔qʃƾ + values: + - yX + - x8Y + - matchExpressions: + - key: 8H + operator: Ȥ肌 + values: + - p0ggz + - piU + - key: puh + operator: ',鑍' + values: + - iDpZ6XA1 + - FUhQ0R + - oT1raqx + - key: qevYLhMPR + operator: Wx鏅L;Ɏ擔qƑ鐿.Xʩ鍌檓ř1(柌 + values: + - RpnGZEk + - "" + nodeSelector: + "": "y" + 6Dk: 2fxwA + podAffinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: teMRu2T + operator: Ɲʪ·8çƋǴ肊N|蒚Ɲ啉yìɧ扶I + values: + - Bd + - "" + - key: qrADH + operator: 讉eĚ翫ÜU郂g乖ljơ絣謧帮:$棎m + matchFields: + - key: "3" + operator: 簆L叅nǜ欕巅 + weight: -1648909491 + - preference: + matchExpressions: + - key: 2Q6H + operator: 棞犺櫗dž媇僤Ȝ橴$荌 + values: + - n2zWd + - key: iv + operator: gƦ甗ì + values: + - "Y" + - HkyZzJUQa + weight: 1775867956 + - preference: + matchFields: + - key: 3Km + operator: Ƥ + values: + - HdpB + - FFce4C + - key: DDfe3Br + operator: ǣ@澳轒 + weight: -1363992583 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: nOZtJ6 + operator: 臭ƞ亁ǃzzŘGc`ţ憝魃軠÷柆踗dz+ + values: + - 1lsA + - key: NitAsm + operator: ʛ凃ď + values: + - qXRXHjOFv + - gKZECIIQ3 + - key: i + operator: '[蹦ɑ邺絡6y罝ȘƋȆ皼殸pȲDz' + values: + - 8JPcGR + - XX + - UjJ + matchFields: + - key: evL + operator: 籬愡 + values: + - a + - key: "6" + operator: ZƾPȢu实ƯƊ讅 + - matchExpressions: + - key: "1" + operator: 2苺Œzʀ)%ŭ姀FĢȿ蹨İÎ锨lj螙 + values: + - zmAKL + - YwUOGPS + - key: SH + operator: 饓緔箈* + - matchFields: + - key: B0p + operator: 榫!Ż«rE弬摢 + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: OcA0Nz + operator: ƒ卺ɞ塼{ťD4櫡ĆGɐåÑHK + values: + - oGEU4xtS + - jIQQO + - "" + - key: vgsCex + operator: cü鏚.Ʀ)ǿcʕ賏狔D{ + values: + - XX13 + - key: KJfwWv9 + operator: ëe + matchLabels: + ntGxX7: se + sE2: Tm9 + matchLabelKeys: + - gHCbAaW + namespaceSelector: + matchExpressions: + - key: m24 + operator: '>Ⱥɴ燝ǭ蹞ƥ捅ƾ' + values: + - ThKy + matchLabels: + 1C: K6xD + mmCBd9: "" + namespaces: + - EiJj + topologyKey: MB7Ffl17s + weight: 849538477 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: 7swY + operator: A鉅圁ƫŊq羹m簷 + - key: d6SeWSh + operator: 5rʮǦƎ + values: + - dm1R + - key: d + operator: '}u§kɒ改滘ɹ磆' + values: + - 41yZvs7 + - cfQ + matchLabels: + "Y": SHn4 + k: v04 + qdVWBKTq: D8 + matchLabelKeys: + - xdJ1 + - Efbwu + - GoWrIvE + namespaceSelector: + matchExpressions: + - key: RBmbA0 + operator: Wɋ痒Ɣ诖×濹綕ŠA湹8ŭ9&Ȱ镤糣E + - key: 3AYh0S4PFUGFT1Q4 + operator: 俾粶e喎鷗bFŹ + values: + - BXmjN + - "" + - X + - key: Rw + operator: 赖鏰 + values: + - lsr9z45 + namespaces: + - Le + - QR0YVKV7 + topologyKey: Pdl + weight: -1148243505 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: IXPMNZa + operator: 杆Ų奧 + values: + - 46KgE6 + matchLabels: + KiDaIrgAdj2i6: WUooNk + S1BO: aC32zkEY + ggqE: "" + matchLabelKeys: + - nmwrQ + - l0EMEawrM + - yIo3pm + namespaceSelector: + matchExpressions: + - key: pp + operator: 襊Țj槟瓼帪ȴʨĈ¶ijH + values: + - hW + matchLabels: + y6: D4hcq4 + namespaces: + - "" + - fe + - 6mdE + topologyKey: MO8Zrjss + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: K4dO7 + operator: XgƔ6 + values: + - dedFsXyHQrV6 + - "" + - qIv + namespaceSelector: + matchExpressions: + - key: Ok + operator: ȝ.fƛ審 + values: + - IltM + - VM + - IQ + namespaces: + - XQ3u + - Z + topologyKey: 8EBdM6LA + weight: 619790919 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: ZM + operator: To圄K岫崐ɳ紩舀氦 + values: + - ef + - 5NXS + - wHs + - key: Wz7hwea + operator: Už4Yg柹蘫ȏ凂;3u- + values: + - S8CKq + - IELC + - 4LfAe9mU21nt3m + - key: nDk7 + operator: Wy仏蚐uĨƞ + values: + - 9pI + mismatchLabelKeys: + - NWO5gU2td + - EWcIg6zintP5M + - Cylo0 + namespaceSelector: + matchLabels: + qTAJ0Ku: Kl0 + namespaces: + - 5JQb + topologyKey: rf4Nr + weight: 425635824 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: vUAgkTO + operator: ^y醷 + values: + - Zkmn + - ALk + - key: ny + operator: 鞨[į郞Ƞʩʓ雈ßŧ嗹^Ċʌʋ烫Ơ + values: + - QI0nu16ho17 + - IHyQuhB9gR + - key: Ztr4LMZo1hL6 + operator: ô籞bü歃ɃGǡ監麧ɈFŌ- + values: + - 2UpYa + - CScTi6 + matchLabels: + TTB0NFAm0: Txb5 + sb7CDUXLD9ga: JHh565 + zAWL: xg9JgA0 + matchLabelKeys: + - "" + - kzCaeoA + mismatchLabelKeys: + - RBz + - uIX + namespaceSelector: + matchLabels: + 7bE: BVKqBxuluopC + namespaces: + - Oj9 + topologyKey: ZX4zl + weight: 160846374 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: HH7 + operator: 緳{ƚ盧âĭ湻3÷:频:7 + values: + - gy + - Vsq + - HSl + - key: sy + operator: ƭǂʉ篸ē穯;ū戋茮酖 + values: + - qCr + - key: 5RI + operator: 涓ɨƚ攁ʋ + values: + - fIJ9 + - znCw + - ew + matchLabels: + 8wxwIB8: 5dR44Q + i6JV: nwXAFeaqSfd91 + mismatchLabelKeys: + - vxwL + - nG9S9I + - pODo + namespaceSelector: + matchExpressions: + - key: mRWuukKFvy + operator: 蛴!:Ć"ɀm¯es獞ĜŚ + values: + - hm3mu5Yy0VB + - 2f0GpZ + matchLabels: + YTpqtey0x: ktPRo + ilti14: wvhcYqTCtrQ + namespaces: + - wLUE + topologyKey: FQ + - labelSelector: + matchExpressions: + - key: Hkoj6F95em + operator: 亿懿0ʙ5Ǣ譨ŷQ + values: + - K + - k4 + - key: "n" + operator: ș郏 + values: + - AU + - 1n0T1IC + matchLabels: + XmZ: 7x + matchLabelKeys: + - ObyO + - "" + mismatchLabelKeys: + - Z1ZPMR1Zt5 + namespaceSelector: + matchExpressions: + - key: ry + operator: ~水ē鎙tj¤禬萃fÒà + values: + - l0Kd3 + matchLabels: + 5j: m8Pm + h1kue6nt: M56ZcLx + xq: "" + topologyKey: 8u1rls3h + - labelSelector: + matchExpressions: + - key: G3 + operator: 櫛Ƞ,=畾 + values: + - U3q4 + - kmv4 + - G1psh + - key: "" + operator: F宗3溜0ȺL + values: + - ZA0 + - 9qmizMS + - fTsusd7wkK0msJD + matchLabels: + N7Ngf: ya + mismatchLabelKeys: + - cgHDLS + - pZfnA + namespaceSelector: + matchExpressions: + - key: Lj3nK + operator: 墜踮vXǡMʉ1ďž熍琾竽Þ醇Ąũ + values: + - Itf + - TI6n + matchLabels: + O2XhtOAcnc: 6PW1x + matchLabelKeys: + - 59yp76ky6 + - S0trr + - G57 + namespaceSelector: + matchExpressions: + - key: oMZ + operator: 蜤 + matchLabels: + MZXascOLD: S + namespaces: + - IIhvh + - 8U + topologyKey: TQy8B4r8b + topologyKey: xuo5iwF + type: xMymP + weight: -1034622956 + priorityClassName: mUbO1P2 + progressDeadlineSeconds: -1221802348 + readinessProbe: + exec: {} + failureThreshold: 316564184 + grpc: + port: -28967743 + service: RteTOOJppyrxjp + httpGet: + host: KoK + path: i + port: 1238653747 + scheme: 蜛Ϥ餕 + initialDelaySeconds: -678114858 + periodSeconds: -1932943963 + successThreshold: -1295008485 + terminationGracePeriodSeconds: -3458096367496475490 + timeoutSeconds: 1251310237 + restartPolicy: 刊ǵ椉Ž5荭¶@Ǻ + revisionHistoryLimit: 1248617462 + schedulerName: NtMcVkr + securityContext: + fsGroup: -7790002735836358939 + fsGroupChangePolicy: '猰tą3圇épțU串ɭ惟璼ʜ ' + runAsGroup: 7078321909676639038 + runAsNonRoot: true + runAsUser: -3795473018051875448 + sysctls: + - name: 4bbbOThlM9 + value: OeQ + - name: KzYDmoPm + value: RQkJ4 + - name: gSEB + value: fCw + strategy: + type: qsB + terminationGracePeriodSeconds: 1536232091 + tolerations: + - key: Kme1g + operator: 鸋傚脨ʌȰę,缶 + tolerationSeconds: 9185074187324502073 + value: HP1mcWeehE + updateStrategy: + type: EMvj5gD +fullnameOverride: jio8f +logging: + level: A9j +monitoring: + annotations: + B4Q2a: VlA + WnWMB0U1lR9: ZFtiwVrCZ + gukX6: JE + enabled: false + labels: + HK92: SBAJug3 + namespaceSelector: + any: true + matchNames: + - knSJx6Z + - L0F + - zfWi9TED7ybZ5 + scrapeInterval: 2546609h10m30.192081859s +nameOverride: mn +service: + name: El70 +serviceAccount: + annotations: + UCvD: zlN0tsbA + create: true + name: ZkHM +storage: + volume: + - name: PQgVp5UAKMh + - name: m + - name: "" +test: + create: true +tolerations: +- effect: egɕ=1粊憎Ț$òɎ噸庤ɯ + key: do9aqZLTZ6HKm + operator: ÚǘDz姦éy便 + tolerationSeconds: -8194188728085215250 + value: kaktY +- effect: Ŷ)営雲 + key: LUyN34n + operator: ȲxȖÊǢʓȦ孻 + tolerationSeconds: 8850115598563487459 + value: au +- effect: ʄę媚醌1酙1驏ȴʦXœć + key: I9iCfca + operator: ~贙k閷Ɉ_蜦硺楚Ir廜匳&ğ-5Ō + tolerationSeconds: 5427922333042530071 + value: 2KaG3k +-- case-040 -- +auth: + sasl: + enabled: false + mechanism: eXWm9 + secretRef: M4pqhD32D + userName: KF7Nnx +commonLabels: + 4bQpba: iVh + "n": "" +connectors: + additionalConfiguration: qvMttAMx + bootstrapServers: LRTyIJY + brokerTLS: + ca: + secretNameOverwrite: rRP + secretRef: E + cert: + secretNameOverwrite: peG + secretRef: P5mPIj + enabled: false + key: + secretNameOverwrite: Tbz + secretRef: mBxPtYNUs + groupID: br + producerBatchSize: -2033745427 + producerLingerMS: -1500250091 + restPort: -1022927047 + schemaRegistryURL: cL1M + secretManager: + connectorsPrefix: cS + consolePrefix: J4nFaA + enabled: false + region: REh2 + storage: + remote: + read: + config: false + offset: false + status: true + write: + config: true + offset: true + status: false + replicationFactor: + config: -1386973481 + offset: -1418511808 + status: -748221252 + topic: + config: 9Qtxti + offset: H + status: BP +container: + javaGCLogEnabled: QXA6zua + resources: + javaMaxHeapSize: "0" + limits: + cpu: "0" + memory: "0" + request: + cpu: "0" + memory: "0" + securityContext: + allowPrivilegeEscalation: false +deployment: + annotations: + 6WNO: UvMxPC + ItkfXr: HoRGq + OqfY9eu: U + budget: + maxUnavailable: 175031450 + create: true + extraEnv: + - name: pwJ0I3ZEUK7 + value: aaFCEfM + valueFrom: + configMapKeyRef: + key: DXmjvM9 + name: JYBPb + optional: false + fieldRef: + apiVersion: 9fI + fieldPath: 90keHRVll + resourceFieldRef: + containerName: rBYEwmI + divisor: "0" + resource: Sn9Gkn + secretKeyRef: + key: T3YsImGDrshtv + name: w + optional: false + livenessProbe: + exec: + command: + - f + failureThreshold: 285554662 + grpc: + port: -2014863639 + service: vhVVIzVohs + httpGet: + path: vvG1 + port: "9" + scheme: 阖ŅxĦ鍾?翽 + initialDelaySeconds: 620513520 + periodSeconds: -983699293 + successThreshold: 537883135 + terminationGracePeriodSeconds: -6388371474898008574 + timeoutSeconds: 843588973 + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: 19IV1NC + operator: ȃ}CĚ蟡ɨvǢȺ + values: + - "" + matchFields: + - key: xl + operator: VĦɓ洽Ă滕煂 + values: + - jreFryn + weight: 1586123299 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: [] + nodeSelector: + ne: QT3mjpm7B + podAffinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchFields: + - key: lCaMS + operator: 膳ƶHʭ暍鮊ŏŕǶp9繒Ȍ鐦M~ŲT + values: + - vWH + - i9bXTrq + - key: 9i + operator: ħ}楆$滚 + - key: 7Cy + operator: 曀螱ʞp茟{骺嘅共鞥x逈¢ƣ' + weight: -116851189 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: [] + podAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + Z1tWVGm: e7EmPW + Z3d: 5iGMNPlYG + matchLabelKeys: + - xbzQW + - xgW + - cQ2cTvDEvI + mismatchLabelKeys: + - yLsV + - 3ywbXylVu + - WUm9vGoqT1xY + namespaceSelector: + matchExpressions: + - key: "6" + operator: Q晦ŅǒƂȇ + values: + - ka1gnhq + - 7F + - DeX0 + - key: YoH7Cwsbl + operator: 恴j$'%P嘇 + values: + - "" + - FgHmtv7Dv + matchLabels: + E: q3RqGm + VFHD: l5 + namespaces: + - JDVu + - Jp + - sgN + topologyKey: 0Y30wF + - labelSelector: + matchExpressions: + - key: jMaH + operator: 侢ǻ蹒-Vmɓɛ廏潂譈ƤR + - key: 9B9oc51 + operator: 靏Q|g&ʂ覂 + - key: r + operator: "" + values: + - Pi + matchLabels: + RWbEj: G + matchLabelKeys: + - GQ6u + - DoezHg + - VucamL + mismatchLabelKeys: + - DZV8i + - Q5w4 + - GIR + namespaceSelector: + matchExpressions: + - key: pH + operator: Q袼ʆµ禔q + values: + - "" + - key: q47oWCI + operator: ǖ櫗ã諚框郓ǧy(M橠Ⱥȗ紶Ġ?镏{Ĺ + matchLabels: + XC9g: X9vW + ay7: HDfiZS + hk: oZm0oN + namespaces: + - 099SbHnMR + - D83JPVR + topologyKey: egq2DL + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: DiR + operator: Ɠ;苖,ɳȓ麛H[qʗcȟ.&齧į_Ȥ + matchLabelKeys: + - A35AJ5Fx + mismatchLabelKeys: + - jq4 + namespaceSelector: + matchExpressions: + - key: 618BPJ + operator: 揇õ亏暍WƳ`繥zjĞ已ǧɤ + values: + - Sd + namespaces: + - w3CMzZV + - 4YrTjo + topologyKey: RQOw + weight: -2037086478 + - podAffinityTerm: + labelSelector: {} + matchLabelKeys: + - z4roLehGIu + mismatchLabelKeys: + - iPnBzD + - we5NI + namespaceSelector: + matchExpressions: + - key: QNrHklC + operator: 鬫崤駂懄鐻君x8ʇ潩ɥžTE¬*Sɹ + values: + - MJ + matchLabels: + M8: T + namespaces: + - msRwtqnkMck + topologyKey: rCJ1sQw + weight: -1311337064 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: Yh25gQp + operator: "" + matchLabels: + MH9S: W39vSzna + U7ph0fJ: U + Wfisq: tp + matchLabelKeys: + - hUEM + - bwGbM3B + - 7qA3sIzD + namespaceSelector: + matchExpressions: + - key: Y6zd + operator: IWţ>ɖǮ嵑Q姝銄嶅躣ĸTʡ煛妪)ǻ + values: + - RYq + - key: XE6b + operator: 獘琬DGí麮煙U8ɴ揅懌À圪y齁Z. + values: + - tg5RzsV33R + - njO + - gwxHfV + - key: kUf + operator: z`牸,尿圗薷ɱ暞Üɫ驛Ɯ + values: + - N3 + - "" + matchLabels: + UPANoyszO3: DqKx + namespaces: + - q + - T + - RntZN + topologyKey: A6n8rjlMHwlgliat + podAntiAffinity: + custom: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: aSxOcR + operator: _齯嫉Ħ + - key: AZePAX + operator: wɦ 蓋ʏ炚ȚǐĂfzŵ嫊Ǵǡe釕 + values: + - llnNm + - mksz + - rhSgv + - key: jmu0L6njnJ + operator: Àčťt§ƚʎ莽5謹W胱V嫻ŠMİ啫7 + values: + - MA6 + - xyGSDP + - wykiW + matchLabels: + "": geXhh7JgW + BPr4JUbf: T + c: P2G + matchLabelKeys: + - bIlVRSd + - LxbTkE1 + mismatchLabelKeys: + - 5CJ + - Q1 + namespaceSelector: + matchExpressions: + - key: MHL + operator: O败 + values: + - 6HK + - key: TlK + operator: «V念VáƂ>糸猠-滜 + values: + - aAqd + - DU2IY + - 8TmjiCQPB + - key: J + operator: 泛İɉGȜȻ豦岫ƎŚd檯Ɏq + values: + - JWMWurN + - ist + matchLabels: + IyOEuM9iLPf0m: 2M3Oz + topologyKey: 5FMo + weight: -1885128402 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: cx + operator: KȵG[呖ǸbřǾ:5Z峕鱒 + values: + - cb1gAuU + - 5SR + - key: VhMrp + operator: 枇ā癣#u兂ʘ°ï]ł鋃Ȁ÷|锕+UɎ + matchLabels: + 1w: GVqua + VTVC: "N" + zJs2: 8J0rkyK + matchLabelKeys: + - eD8nG + mismatchLabelKeys: + - VBc + - Ps61 + namespaceSelector: + matchExpressions: + - key: c + operator: WVQ殰ȃ邵ʧ壤Ȃ餝HW稙癑0婝/苤ʝ + values: + - Wo9PeYtzAH4 + - Pd6 + - key: LKb + operator: iwU籇Ǜ螜撉ɦ緓 + values: + - hfFaR + - SYO + - key: jaWpOQ + operator: 葅輴ʤuş馀ťUpƟƨB頎b軖+ + values: + - S + matchLabels: + 0rs2: 6U624Rs + Jm9: qw5 + UXkt0l: Nnny + namespaces: + - pp6 + - PpD43UPH + - yGyzDnb + topologyKey: dOQt + weight: 2027685501 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: FQ + operator: Ě$唵ljs忼ƍ崛ǦA羣捌偾粳Hu銐狣 + values: + - cjD + - key: p4ovi + operator: 厌`(茮ǰ厅ì瞐Za髭幟 + values: + - N9uzrid + matchLabels: + Aj: SkF5 + WSdwL: "70" + namespaceSelector: + matchExpressions: + - key: VnuF + operator: WXç缅紷&goc忷ĕ瀸 + values: + - o + - key: 6blyAM + operator: 菹ƚ摎枵NJ + - key: Pk8z6pc5 + operator: mǁŦ歃Ǽ + values: + - 1YIsb + - fOGtzStos4e + matchLabels: + cNN: k + tH7VC: "" + namespaces: + - hWILh + - "" + topologyKey: 6dn + weight: -670386716 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: ffMQ7m2 + operator: 鴮爫ƞP{j伮浸軠ɭ[PȖQɓ尼M + - key: RTdpF + operator: ; + - key: IHf + operator: "" + matchLabels: + EVhEM: ni9keKo + mismatchLabelKeys: + - 4MUn + namespaceSelector: + matchExpressions: + - key: EkFrl5BBSn8NItyWV + operator: ./c + values: + - "" + - XHbe + - bn0Ln0gKL + - key: Uah + operator: Ʈ6枪伛泿VMĪƍTƤæL櫾ț酞 + values: + - OUjy + - QBmPfr + - mA1eXp8C + matchLabels: + tJ: dZ6 + topologyKey: KpySEIcfuNz + - labelSelector: + matchExpressions: + - key: wA5FZmh + operator: ?V謳抑鼺挑ǥ冺刎 + values: + - 3LYczXN9xVC + - key: S1 + operator: 7nc埊獳ŌR椾&?sʙß(ú + values: + - Tz2Vt + - "Y" + - kpC + - key: Jw + operator: .|?ȏǣv{M沪/ + values: + - AGyJ + - c1CKs5 + - "" + matchLabels: + Rp: iHT + matchLabelKeys: + - o4R + - JIi9IrD + - 7pRw + mismatchLabelKeys: + - Nnk + - 951ew + - DP + namespaceSelector: + matchExpressions: + - key: 7BmzMWwSRU + operator: 儰秘# + values: + - "" + matchLabels: + G5mmHJKQ: H5MG + namespaces: + - ACoFip + topologyKey: HuYKSfDqKssl + topologyKey: e0F8oLDkCTd + type: WlI + weight: -2036050375 + priorityClassName: gSQWfwbf + progressDeadlineSeconds: 570610379 + readinessProbe: + exec: + command: + - jSxwiEDOrw + - 0Dcuuj + - H + failureThreshold: -473671565 + grpc: + port: 2072344414 + service: Tb + httpGet: + host: OSJEX + path: C + port: n136psopLQ + scheme: ɢ糺sªǟ驲gɶUʩč02跡Ť苚2 + initialDelaySeconds: -2130499066 + periodSeconds: -39801992 + successThreshold: -1693089511 + terminationGracePeriodSeconds: 289625866324453619 + timeoutSeconds: -1707372527 + restartPolicy: °č + revisionHistoryLimit: 1380150017 + schedulerName: O26H + securityContext: + fsGroup: 7015643872446876 + fsGroupChangePolicy: 烳=~沽侣X + runAsGroup: -3630702614293936724 + runAsNonRoot: true + runAsUser: 4388805261963142582 + supplementalGroups: + - -7755253763247302204 + - -3310400039802531810 + - 2051254341870837963 + sysctls: + - name: 7UwNr + value: tkn + - name: nGm + value: V + - name: KhS + value: jbpUUVGjT + strategy: + type: 7Mz64 + terminationGracePeriodSeconds: -1194184480 + tolerations: + - effect: 曶ámɶ役ōœE顾坳4Ńɟ蒷Ǚó + key: 3u + operator: 卭ƺ?o + tolerationSeconds: 701640152884990149 + value: N1ekj + - effect: '[ȝ伨]鸲Z;ʞ9阏' + key: 6jmY + operator: n骯Ǩ + tolerationSeconds: 6874204552685767957 + value: saUOHQxkY9 + topologySpreadConstraints: + - maxSkew: 1898212660 + topologyKey: Ovevl + whenUnsatisfiable: PFGhR + updateStrategy: + type: KdJp +fullnameOverride: NCw6T6UcQY +imagePullSecrets: +- name: u +- name: 13J +- name: q9t1lU0k +logging: + level: Tb +monitoring: + annotations: + eZHJsIIV4Rky: Pk + enabled: true + labels: + n5El: sDg0twGSFjIgP + namespaceSelector: + any: true + scrapeInterval: 239636h9m22.788738258s +nameOverride: 4iNcef5 +service: + annotations: + LG: ZJQw2J8u + g: 0z9gQt4Yj + name: KxK + ports: + - name: 61dR + port: 9129423 + - name: p0D + port: 1391241101 + - name: 0MZ6s8 + port: 708219631 +serviceAccount: + annotations: + "": s + 6aAoyzS: BVK + SV0dnqH: Rk + create: true + name: FKhGHe3aO +storage: + volume: + - name: kXFFnM +test: + create: false +tolerations: +- effect: 錨 + key: MlBJ + operator: 菛垜 + tolerationSeconds: 8052990160895509636 + value: DUs0Wq9 +- effect: 鸯¨ŭ.6罘逢YĊCK蕛ʭ姪 + key: Iz26 + operator: ',F鐖烁喷' + tolerationSeconds: -4458555514794455537 + value: 32m +-- case-041 -- +auth: + sasl: + enabled: true + mechanism: I9OZ + secretRef: 2h + userName: BxNfJ +commonLabels: + AwT: yIHdj1wxg + Lr: zYUtd + eP0gw: ZlmzgOXE +connectors: + additionalConfiguration: "9" + bootstrapServers: jts02PD + brokerTLS: + ca: + secretNameOverwrite: i + secretRef: zmW + cert: + secretNameOverwrite: TU4R4tW0Nd + secretRef: G485 + enabled: false + key: + secretNameOverwrite: hDX + secretRef: dQ5 + groupID: KfcZtgISe + producerBatchSize: 1953552561 + producerLingerMS: 540861319 + restPort: -1621274024 + schemaRegistryURL: Esqu + secretManager: + connectorsPrefix: FwZ + consolePrefix: "" + enabled: false + region: e + storage: + remote: + read: + config: true + offset: true + status: true + write: + config: false + offset: false + status: true + replicationFactor: + config: 1120929712 + offset: -1861439076 + status: -1718786575 + topic: + config: n4 + offset: V + status: fLR +container: + javaGCLogEnabled: cjZh + resources: + javaMaxHeapSize: "0" + limits: + cpu: "0" + memory: "0" + request: + cpu: "0" + memory: "0" + securityContext: + allowPrivilegeEscalation: false +deployment: + budget: + maxUnavailable: 440511891 + create: true + extraEnv: + - name: WRSeLSQyxsq + value: 0xespo + valueFrom: + configMapKeyRef: + key: gsjkH + name: hjYCF8i3u + optional: false + fieldRef: + apiVersion: ilis2lH + fieldPath: slhYb + resourceFieldRef: + containerName: ufey2VJTCmS + divisor: "0" + resource: "" + secretKeyRef: + key: nR + name: GKz3 + optional: false + - name: ic + value: N8MdK + valueFrom: + configMapKeyRef: + key: 1QJrX + name: LxK + optional: false + fieldRef: + apiVersion: 0z + fieldPath: UgaSLG1n + resourceFieldRef: + containerName: i + divisor: "0" + resource: "4" + secretKeyRef: + key: "2" + name: ZCqRHp + optional: true + - name: 2TZr + value: P1UUXZH9 + valueFrom: + configMapKeyRef: + key: wgHcFon6xI + name: 6aZcc + optional: false + fieldRef: + apiVersion: dt8 + fieldPath: THGVGMQc + resourceFieldRef: + containerName: Ml + divisor: "0" + resource: tSc + secretKeyRef: + key: L2StNK + name: Qhiy + optional: false + extraEnvFrom: + - configMapRef: + name: "8" + optional: false + prefix: Z3pv + secretRef: + name: c + optional: false + - configMapRef: + name: O3v + optional: false + prefix: eXtX5G3zTnAr + secretRef: + name: FU1b + optional: true + - configMapRef: + name: cLEurajaTv1 + optional: false + prefix: YX + secretRef: + optional: false + livenessProbe: + exec: + command: + - 9lV + failureThreshold: 724202040 + grpc: + port: -1896907397 + service: 1WWZMqI + httpGet: + host: 44PUVI + path: b6Qps + port: 0Hvh0 + scheme: 陙+霒ȁ + initialDelaySeconds: 1171548340 + periodSeconds: 1136904972 + successThreshold: 1663228806 + terminationGracePeriodSeconds: 1596899246031282013 + timeoutSeconds: 1255816268 + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: poCuXUDdP + operator: 3m脄Lj伭ĸ_ȢV!fĩ聿粵昫Ȼ_Ȁ + values: + - bGZy + - key: mxZi7 + operator: 噴姷ʃƸUl>" 噸Lj#ǖHǑv + values: + - vBoyb + - 2VHyI + - key: T + operator: 汜!NJ + podAffinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: nLpF + operator: pʭ:DkƚȗP´紽= + weight: -2090871760 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: [] + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + P: cLp + R11HacB3: 9RqZ + a58: An2 + matchLabelKeys: + - 0O + - gUHbxc0r + - oVpvDVeeBt + mismatchLabelKeys: + - Wv9b + - ZMrNSw + namespaceSelector: + matchExpressions: + - key: TxV + operator: 暌枀R櫇杭 + matchLabels: + "": 1zdSdekKNMM + Cvc9SWB: ayTsVhL + R3BCuM: D2nQvdp + namespaces: + - 86sX + - mS0MBJIxjuB + - uz + topologyKey: a3E + weight: 1708458023 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: QyM + operator: ñ謵g鄜Ǫ莀ś震帑X + values: + - HfAl + matchLabels: + P: TC3 + fThGsVJlo: "" + p6OA8NR: YqzS + mismatchLabelKeys: + - i8o + - SjkWvAG + namespaceSelector: + matchExpressions: + - key: LNn0eU + operator: ƻěµ揁ȟɤ桢Ɛ>绿M\»?Ʉ烐= + values: + - aNRS + - L1NpnUi92 + - key: A + operator: ȀE俫囇Ð鑒Ŕɕj揿J4 ƜƕȔ顠Z + - key: Lol + operator: 鋑祏¤m{\w'潐揥 + matchLabels: + "": eWRv + wRe: 9IuckN + topologyKey: 0D4 + weight: 2119475842 + - podAffinityTerm: + labelSelector: {} + namespaceSelector: + matchExpressions: + - key: AjGs + operator: (R瀳拊ǥit豁菻粸 + - key: b3nRH + operator: ćȹK圎盎I鼆呫痼 + values: + - Dom + - RQMg52 + - BcBODCwowaWn + matchLabels: + NMMTJCj: UsPDH + ip: baDNC39iM + rDr: p + namespaces: + - Byn5KSoK71 + - vF + topologyKey: Yw + weight: 1950258213 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: 3qpdG + operator: c4-ÖS杺束1d煵ȩ簂嶎倖骄Ɍ$#Z + values: + - "3" + - key: L + operator: 耦V@­繙ť烗荝Dž @顕>Ĺm葍(B + values: + - ADR + matchLabels: + Ks6: 4H + crEfPdZ: M5mH + wWc0: w + matchLabelKeys: + - y0gl0w + - nuOpg5 + - Ro1eMA + mismatchLabelKeys: + - ohqF + namespaceSelector: + matchExpressions: + - key: "" + operator: 乻ũ鳅ǸƹņƜ茀ǹm歸ǃǧ殯WqW + values: + - c6wHwn4V + - bnabZlF + matchLabels: + CNJ9it: Pdp + namespaces: + - 6P + topologyKey: mws + - labelSelector: + matchExpressions: + - key: FM + operator: '{欲齜L!ƅnji!T菞ɜc珡坹|' + values: + - 5hjp + - key: OXfaexE + operator: H桄鲩§ſ/cUKG廾cLǾ瘃崚 + values: + - X9rSbDb + - key: Po94eM + operator: ®餑鑱崾歀驽 + values: + - ZaHXvJdaV + - JUq1 + - eR6 + matchLabels: + 9AR: ImAe77 + mismatchLabelKeys: + - DB2GXoYzO + namespaceSelector: + matchExpressions: + - key: scq + operator: 樰mǼ + - key: XPlg + operator: 抷½鉞H膑愭 ē + values: + - Zcqeo + - "" + - RrYuQZzQ + - key: X8GK + operator: ǧŷ + values: + - Oo2Rf + matchLabels: + anEo53b: yblBZcNB + ymCkjK6fCfH: 5k5uIkVNy + namespaces: + - dThUvgS + - p2ts + - eS56TMUxGp + topologyKey: TEvh + topologyKey: cW + type: "" + weight: 1923787359 + priorityClassName: AO + progressDeadlineSeconds: 1079618075 + readinessProbe: + exec: + command: + - Rb + - RI + - "" + failureThreshold: -1131780392 + grpc: + port: -599447137 + service: cq7 + httpGet: + host: SsaWorg + path: UpplF + port: 516047544 + scheme: 牋Ƙ榊 + initialDelaySeconds: 1799248585 + periodSeconds: 373984687 + successThreshold: -1503317917 + terminationGracePeriodSeconds: -7669958782954712463 + timeoutSeconds: 266568456 + restartPolicy: Õ験蘺Sg怰S²蜵-Ǿ笭ī庩X圂蓦5< + revisionHistoryLimit: 485115195 + schedulerName: MF3RwzBCk + securityContext: + fsGroup: -3871220937207142458 + fsGroupChangePolicy: Y蹐\¢倅J趚i転 + runAsGroup: -8140185145867863431 + runAsNonRoot: true + runAsUser: 1443110212215096345 + supplementalGroups: + - 4202411183995629949 + - 9074875661218953213 + - 3682145535007526084 + sysctls: + - name: a9wm1 + value: V48LpVsGVpu + strategy: + type: z1MRV5BXaS20 + terminationGracePeriodSeconds: 1526850382 + tolerations: + - effect: k積Lj + key: YsgfsWrB + operator: Žʚ8鋤縅÷ʪ镲 + tolerationSeconds: 8712200771279582343 + value: 0BC0Sc1 + - effect: a + key: pWUIfI + operator: ā5NƑ鬜牣^,儕髬ǖ藍 ŠɯǦ + tolerationSeconds: 7946113276490164519 + value: lsKkYhoC + - effect: 燀芜/ƶ@犩ɫƭ紱刃飚dēW帠 + key: VQfdy + operator: 腼ʮǬĴǠɬ + tolerationSeconds: -8924157374760987206 + value: UlBiper + topologySpreadConstraints: + - maxSkew: -623096425 + topologyKey: fFI6B + whenUnsatisfiable: PdDm + updateStrategy: + type: Hm36839yLnm +fullnameOverride: AqjekuF +imagePullSecrets: +- name: JeYmHo +logging: + level: fhSGoGeOVO +monitoring: + annotations: + 7gh5s: YcQQPJlU + W2IS: vZNG + bcuaxtS8Sj: F8QJd4 + enabled: false + labels: + CHV: zTXw0 + f: xv + i7b: 5Icwid + namespaceSelector: + any: true + matchNames: + - yTNHdgcpfYS + - 7ezGBhn1FJ + scrapeInterval: 1305701h8m48.166311732s +nameOverride: Ur +service: + annotations: + Z2dqRWb: FmF + name: bjGFkzr + ports: + - name: PoEHOjF + port: -510390395 + - name: DH7c + port: 369451694 +serviceAccount: + annotations: + j5DbR: "" + create: false + name: 1LIGRd6z +storage: + volume: + - name: JoBYh + - name: 4s31 +test: + create: false +-- case-042 -- +auth: + sasl: + enabled: true + mechanism: N6 + secretRef: zV + userName: ksTD03R +commonLabels: + 0F3sU: SaJRcWm + GUF2flpqQUL: KKAcWWY5 + NIiGBL37: eCFaXQGs +connectors: + additionalConfiguration: VHWNn7cM + bootstrapServers: Cufj + brokerTLS: + ca: + secretNameOverwrite: 6CC2 + secretRef: ahw + cert: + secretNameOverwrite: pCPJclf + secretRef: XynCs + enabled: false + key: + secretNameOverwrite: c2jX1p + secretRef: 4JoKw + groupID: 3QzOolf5 + producerBatchSize: -227006427 + producerLingerMS: 282669617 + restPort: -1489153770 + schemaRegistryURL: 0NFMF6Sql + secretManager: + connectorsPrefix: XkmA + consolePrefix: uOHBYjCeV + enabled: true + region: HAnfg7IX + storage: + remote: + read: + config: false + offset: false + status: false + write: + config: true + offset: false + status: true + replicationFactor: + config: -948402977 + offset: -529217276 + status: -1552614518 + topic: + config: P + offset: It + status: wF +container: + javaGCLogEnabled: "" + resources: + javaMaxHeapSize: "0" + limits: + cpu: "0" + memory: "0" + request: + cpu: "0" + memory: "0" + securityContext: + allowPrivilegeEscalation: false +deployment: + budget: + maxUnavailable: 1629881483 + create: false + extraEnv: + - name: Fif + value: 3tSkpD + valueFrom: + configMapKeyRef: + key: REro1Fq + name: L9wKUwjKABNYV + optional: false + fieldRef: + apiVersion: Jpb2 + fieldPath: 8UAa6RrFC + resourceFieldRef: + divisor: "0" + resource: 54CvEvHC + secretKeyRef: + key: F + name: cByAdOH + optional: false + extraEnvFrom: + - configMapRef: + name: YcRcIU + optional: false + prefix: kBHfd8qG + secretRef: + name: qYDGh8F + optional: true + - configMapRef: + name: RqArRvKcx + optional: false + prefix: Nk + secretRef: + name: o66DF3e + optional: false + - configMapRef: + name: FAcAyd6s + optional: true + prefix: 6MjNWd + secretRef: + name: 8B + optional: false + livenessProbe: + exec: + command: + - RyaDt95rbS + - xB48 + failureThreshold: 784891686 + grpc: + port: 390551496 + service: fVkZ + httpGet: + host: rIuzFin + path: NGsJoEcvH + port: BMI + scheme: '{銧澅ŗ妪ɑ鱄Xŋɘ@癳:­g' + initialDelaySeconds: -1933904380 + periodSeconds: 276259650 + successThreshold: 2046548753 + terminationGracePeriodSeconds: -6638478800684614739 + timeoutSeconds: 1573691516 + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: WdCi3K + operator: K愉獝8ʊ_-DŽ + values: + - z + - a8fo2i + - jFI + matchFields: + - key: A + operator: ǪŊe>?啚竈鹿蜩-¿ʒ + values: + - LO1mpxYfL + - key: Izo + operator: -Ù=粆貘ʼnɟph + values: + - HXsf + - i8G + - key: VTyRD + operator: ɸ + values: + - WPVh + - 0tmIEB4c + - matchFields: + - key: oohVNIkSc + operator: ǎ8鸗襋ãƋ[ + values: + - k5ac + - Rqt1Oi + - ccc + - key: Jb9lgJhH + operator: Vjʁy笊# + values: + - Kkpi + - jTlWbv5UPrD + - matchFields: + - key: Rg + operator: 洂{Ŋ秗AƵė蕸ʚʨT³遫< + values: + - zZDzBsm + podAffinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: 0PWrKZSAA8EIc + operator: Hʯ匎)1G蹩Ð趦Ȃ禽Ų{ǘÒƶżn\ + values: + - fXOr + - 7U1Ics + - "" + - key: STfde + operator: 銲 + values: + - 29Vn + - wNjqS + weight: 741986916 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: [] + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + NhiZwhBuO: h5IvAFqx + matchLabelKeys: + - hSkqAMLm + - PQ3KCpn + mismatchLabelKeys: + - Vyc + - 57y + - LdH + namespaceSelector: + matchExpressions: + - key: I8 + operator: 猊ɑÒ昍ő游 + - key: LD0xPi + operator: 掯6Ȓ骁 + - key: sqVE6U + operator: ɧǓR麐H`&驯苨镪覕ɚWʁ繊5 + values: + - UC + - p + matchLabels: + 7XjD: kIxut + F2tD: m6 + Z: 9fj + namespaces: + - Epk + topologyKey: K2kmRJbaS + weight: -1127986578 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: HAxkB + operator: 'w ' + values: + - Rbl + matchLabels: + hlZgiLqv: "" + mbw: qzC2I + mismatchLabelKeys: + - h9W + namespaceSelector: + matchExpressions: + - key: RsAXrqlW7 + operator: f+医屨Ȫfƣʥõ巻隒ȱ繗镗}琸ƪ + values: + - xpQj + namespaces: + - Z + - fL86 + - yjWwvzz3HL + topologyKey: ReSGOlVKW + weight: 1976075077 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: PVC + operator: '}霬变滑铒;ȝPõ割ņɥ' + values: + - hH + - SyoM + - key: wEUm4 + operator: O>垽Xk*Ȟ + values: + - LP7TxsN + - yA0qMiZhntz + - key: z5ej + operator: 叶濯šŀ瞺Dj撂Ü$鬉 + values: + - "3" + - SayBRwXjLss + matchLabels: + kryupfr: "N" + mismatchLabelKeys: + - 7v58Aijbbzr + - 5Td + - "" + namespaceSelector: + matchExpressions: + - key: NPR + operator: ĆŽPǶǣǜ,t鍋特,簬 + values: + - Echt + - S2zBVD + matchLabels: + b5m: JCUgN4 + namespaces: + - 5tFo + - ROQBeEaCa + topologyKey: "" + - labelSelector: + matchExpressions: + - key: H0 + operator: GƇbǼuȌx舺®茳Ǣ憻°r鯗 + values: + - 2pWjFL + - Pd + - key: iF395JQy + operator: 翭薯³e觙窒_e{kĘ + values: + - ElB9TE + matchLabels: + arlQ1: 5Ji3V + cfD527SUZXN: B95nY + npPKK3n: jQ2Nk + matchLabelKeys: + - fZh6WLiv + mismatchLabelKeys: + - jmBW33O + - vczPF99 + namespaceSelector: + matchExpressions: + - key: "" + operator: $^.鼖顧誑>:×兾 + values: + - 33sh + - MkhT + - aceo88Nxvo + matchLabels: + IMizQHA: m + fbOw: Et79k + t: 4BlF + namespaces: + - "" + topologyKey: j + - labelSelector: + matchExpressions: + - key: DBm + operator: 6<Ɠƍ柵ƹK鷨Žů胞朱 + - key: EW + operator: Ȼȇ϶綎渗DzȜȕC庮辞ɔ + values: + - bkmB + - lH + matchLabels: + "8": vrm + F: 9LRR + G: Qknw + matchLabelKeys: + - XDBVVJD + mismatchLabelKeys: + - k1vdw + - JHcKRmh + - YBaCax + namespaceSelector: + matchExpressions: + - key: hRX + operator: ɡÐbïſ佖蘑播譽h3`Ƀ騅\尲- + values: + - 9xi4 + - QwOFfbmV + - key: bcA + operator: _%ó=©~ÈƦ>Ä礜 + values: + - typiPHsA2 + - tR52 + matchLabels: + "": Jtgef4L + topologyKey: sKnzsZj + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + Ng12: "0" + QyudSu: tsRA5y + VN9G: l + matchLabelKeys: + - K + mismatchLabelKeys: + - KRP2 + - eII2WRDSD + - irPHaS + namespaceSelector: + matchExpressions: + - key: TKoBwC + operator: ʧʋ騊鸦)ĮeUðVXI鍵Ǵ + values: + - mLxI0Wg + - Mzb0A1w + - tvF + matchLabels: + OkqFT: fweHH + Z9p: ubKfGhvxM + xNNR: ZJOxMl + topologyKey: uooEh1P + weight: 1385222265 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: 02mz3TF + operator: Uë帴Ƙºb顛Î< + matchLabels: + 6GGA: pc6WNhW + nApBYzP: DYF4RQ + w: d + matchLabelKeys: + - pHV + - QHr + mismatchLabelKeys: + - vyygwe + - x + - yjf + namespaceSelector: + matchExpressions: + - key: CVbZ4UXGJU + operator: d虌|芈 + values: + - X + - CQOoQv4J + - baPs + - key: 9CRLLSg + operator: 灈选/塄Jª佨5漍Ĩ鑐+婨$斕«圪Ɯ + values: + - TOZk6JD + - key: R9NR + operator: ú-ZƗ餦ĵ跇:ō擱饍 + values: + - NCPg + matchLabels: + "": I3WuOi1b2 + oo: jY0oqR + namespaces: + - Tqrc6Ze2N + - cwqJG8fEZ + - Enix + topologyKey: G + weight: -1520224775 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: Ycp3KvRGz + operator: ɪ惐ʕ漲竹虣pȤ= + values: + - 2UO + - 6M + - HxThxOi2V + - key: o592O0 + operator: Į~Ȩɇ煢贯嗼 + values: + - DoHIEpQDxot + - CHQTeD + - key: 2u8kQT + operator: ʃ + matchLabels: + 1yzAgQmi: ksb6DdF + matchLabelKeys: + - cHo96 + - kuHW + namespaceSelector: + matchExpressions: + - key: u4 + operator: 懌V炠劭迈țġ + values: + - k9FIUOj + - J + - key: uwMyy2qYx6hy + operator: h/ÆƴɆ腿F聈 + values: + - uei + - key: sswBKfF4e + operator: 牍Ǖ啳ɸ碟l鞢=叠喜ī=Ų齣墛靰Ô + values: + - R9KxFV + - Voq6Z + namespaces: + - qywMPFgqR + topologyKey: 4bTD + weight: 607381810 + podAntiAffinity: + custom: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: SFS4n + operator: \喆Zơ穿蹇膣憮 + values: + - 7XfjCE9 + - key: 1qwRrI + operator: Ǹ8\棧係 + values: + - EftX4 + - key: GJO + operator: ɮ件ǚ謮Ǿ佄 + values: + - ZPiBXBh + matchLabelKeys: + - U + - NYI + mismatchLabelKeys: + - RPvU + - tsP + - UTI + namespaceSelector: + matchExpressions: + - key: ZAM + operator: 3¿ťM彅 + values: + - DMm3F4GI + matchLabels: + KS6no: xRO + Ljsiegm: JJhji + tpre: EKt + namespaces: + - KceYF6pL + - "" + - I3c9p9ndODqy5 + topologyKey: x + weight: -453783752 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: "" + operator: 柨2½vq舀髼齔Í蠔 + values: + - "" + - 89A2 + - vu + mismatchLabelKeys: + - uj + - 9DS4IruvqS + - 5hiI + namespaceSelector: + matchLabels: + a: 5oM + kfAKrh: i + o3XC: Lmn + namespaces: + - O + - wzhuV + topologyKey: bJsgWL + weight: 811646551 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: Ks + operator: 钷ǀʝ + - key: GA + operator: :ĕū温槑蹥Ʃ + values: + - x5h0N + - xs + matchLabels: + 2R: 0uO + 6lkH: 9mu + k4L4vQRyl: bER4lJ + matchLabelKeys: + - cPXNS + - U6 + mismatchLabelKeys: + - xUdn + - HmU + - tnS2Jk + namespaceSelector: + matchExpressions: + - key: HmYpl + operator: p恾TȽCú瀺i4LĎƀɎƉ7A{Ț + - key: CwHHd + operator: 讥磖厒槡c7\ɞ晧懊 + key: b + operator: ĸ傜郠Ĩ沲INJ5ȴW离Úǣ' + tolerationSeconds: -4016572537968724845 + value: wLj4YcHC7E + updateStrategy: + type: 6P2B5DOkpdaY +fullnameOverride: GhHS +imagePullSecrets: +- name: KKI2K +- name: t5qixoHm +logging: + level: MkT53E +monitoring: + annotations: + kSsMHYkP: hdg + enabled: false + labels: + "": rbJDO + 3qrEiU: On6nePI + c: aQavQj9 + namespaceSelector: + matchNames: + - Pp + scrapeInterval: -1405670h6m56.58808485s +nameOverride: s9WyH2Y +service: + annotations: + fzz: CLoaDJm9w + rryVp: TZ + name: 8Tb8k + ports: + - name: GYfGwLr + port: -1114107001 +serviceAccount: + create: true + name: w +storage: + volume: + - name: aWdnfP53 + - name: 88Qdn0Y +test: + create: true +tolerations: +- effect: y寫ÃY=ÿ勓霌猆7訚篹 + operator: 秹yƂj + tolerationSeconds: -808124645233925629 + value: MEkdJx +- effect: 阔ɛHĠP灃oN伎Dz遽ų + key: KSBOWC + tolerationSeconds: -2431873710746455413 + value: A1eQM +-- case-043 -- +auth: + sasl: + enabled: false + mechanism: gsR + secretRef: PIWVDNSJ5h2 + userName: Nb +commonLabels: + Mv: hvvf9ur + aWpK: fy05 + xYCcuP: zC +connectors: + additionalConfiguration: d9YXDim9 + bootstrapServers: r + brokerTLS: + ca: + secretNameOverwrite: 3ULc + secretRef: db + cert: + secretNameOverwrite: xB + secretRef: u + enabled: true + key: + secretNameOverwrite: Lof + secretRef: Nm + groupID: tAHp058 + producerBatchSize: 326061542 + producerLingerMS: -812360105 + restPort: 2118887935 + schemaRegistryURL: QoRmKviP + secretManager: + connectorsPrefix: CrfpXnLE + consolePrefix: O5i8fAPb + enabled: true + region: HMVvAZ + storage: + remote: + read: + config: true + offset: true + status: true + write: + config: false + offset: true + status: true + replicationFactor: + config: 814601878 + offset: -486723389 + status: -28524957 + topic: + config: 5fJu + offset: TD4L69vOIK + status: O4GNLUy0b +container: + javaGCLogEnabled: JgX + resources: + javaMaxHeapSize: "0" + limits: + cpu: "0" + memory: "0" + request: + cpu: "0" + memory: "0" + securityContext: + allowPrivilegeEscalation: true +deployment: + budget: + maxUnavailable: 275053237 + create: false + extraEnv: + - name: Kf3T + value: A + valueFrom: + configMapKeyRef: + key: y58L3y2j + name: 935KHbGnvvRU + optional: false + fieldRef: + apiVersion: d3KFOU + fieldPath: 7L6 + resourceFieldRef: + containerName: t2Zr + divisor: "0" + resource: 6Vma1 + secretKeyRef: + key: "4" + name: wRw9G65Ia + optional: false + - name: x5pHL7nk + value: BqVjA6 + valueFrom: + configMapKeyRef: + key: Qz + name: Tv5Yk + optional: false + fieldRef: + apiVersion: Cwp2TnKc + fieldPath: phqwy + resourceFieldRef: + containerName: IRPmIS + divisor: "0" + resource: T2b4IkoE + secretKeyRef: + key: 49QU9 + name: VJexY9PvmE + optional: true + extraEnvFrom: + - configMapRef: + optional: false + prefix: ZX0G + secretRef: + name: 7d8 + optional: true + livenessProbe: + exec: + command: + - JTuvS30g + failureThreshold: -1640702378 + grpc: + port: 967836932 + service: DHJo2M + httpGet: + host: tSNAs + path: oumIal + port: 1497455731 + scheme: 敜毑穏羋4Ć徸塍灶广 + initialDelaySeconds: 580277422 + periodSeconds: 1352858518 + successThreshold: -288162847 + terminationGracePeriodSeconds: -3550736034833886440 + timeoutSeconds: 1134857368 + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: 9l + operator: /脀夻粀ǁT繐窲ɋ譎Yʫ蓶¶ɐ­ + values: + - ilYoM + - KRlxfBr + - pkOnwv + - key: JPeTO00 + operator: EƱ遂øɗHi檁襡Ǥ姾踖VyǤǃ錂枴 + values: + - EKHBGGOr + - key: 97Edg + operator: Ȫ + values: + - S1s7J7oI + - Vxj7AJSI + matchFields: + - key: DDK41B9 + operator: 崦 + values: + - YI1ISW + weight: 684587648 + - preference: + matchExpressions: + - key: DJA7gLPH + operator: Əuya¬Dz鸓-毗 + values: + - Q61pLQH + matchFields: + - key: sjT + operator: 璠ɩ髓ƺ + values: + - Y7p + - S09Ii5EB + - "" + - key: b + operator: '*ŃƤÒ軿觳DŽż蠪' + weight: 346231665 + - preference: + matchExpressions: + - key: Nr3PF + operator: 劶ǽ + values: + - 5cD + - 3nxp5qH + matchFields: + - key: xEJEaTIM0JIYQ + operator: '@熹`)k殣 ' + values: + - K + weight: 1016822803 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: "" + operator: ɐ裔x艥滦Hł¯軋Ǚǰ!荦Ŭƫ踼)肩朦 + values: + - VTc + - key: nuazd + operator: 檋魋ç厸m/ʜ + values: + - FgRAHGQAPP + - key: Qmku + operator: 遢ǪůLJ鷳莵瞸永荅Rɤ悌 + - matchExpressions: + - key: EkoeuAS9eFK + operator: "" + values: + - SZW + - 5G5EtcG + - key: lIcNlSIO6YTW + operator: B駽qçǐ鵊`w鏬鐜^釵c#î嚩Èa + - key: 9I0A + operator: 'h駨瞾蠪檾ʌ2Ǔ細Ɲe ' + values: + - 2zd + - GigtgQi + matchFields: + - key: QpMXTyA + operator: 昐 + - matchExpressions: + - key: tb84 + operator: :ëKȂ鐛顟÷!) + values: + - Fv + - AGwpAxy2 + - key: 2JS2BTg + operator: ɝư_ļX溢嵦ʞɥȢ橲ƅ(ç3Ȟƭ徔 + - key: 2dM + operator: 儗羇d肜ɢ鲵ɑ\毊ɤ嫱邁珧Ș + values: + - hcjpSwjiNZb2he + - i7r + matchFields: + - key: Z4 + operator: 2'§ + values: + - pipyk5ygBGjgjjb + nodeSelector: + 1ckyXyf: Cif + podAffinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: 72I + operator: .O厪> + values: + - qy + - key: qDkN + operator: 腽R雀Ȓ镚ȋŦ彼仵ƨ碦Q挪iń兟Ƨɷ + values: + - IFT + - FB + - ZV + - key: Hik4 + operator: 烳=氂ť珈臼帑淬nwȻHÖ鮑7 + values: + - 5qz + weight: -1431971269 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: Q + operator: ɦĐƠì>Z2Ɂ-撅 + values: + - Hggu8 + - wfTW27ko + - gdO + - key: PgRx5hRr + operator: "" + matchFields: + - key: 91PYj0Wim + operator: p紃x岜|鄊ǖ眜殼"Ü洹過eY尺 + - matchExpressions: + - key: jvmYjph + operator: ǘH)2ǧŀɸU# + values: + - HkV7 + - o + - key: kbIqE7D + operator: '"Eât`ʃ進癹''0皭Ģ鶰' + - key: CXgvWZ0 + operator: Ċ舞°u箸g ƀ姲Ƹ= + values: + - 4e1oZk + - 0N3m9UO + - r2Nc2 + matchFields: + - key: kUSBT + operator: Ȧ弒祩冕毾聒Ăwv譧势H + values: + - Mtfk + - ThywTd + - pTxY9Z + - key: ty + operator: .ɐN鎁ɜ=ɯ憎2Y!}% + values: + - a4o + - O20 + - gfU + podAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: gTv61 + operator: '[徵<»ȕDZŖȿ钶蘐潿ɠ菙鈣ƦO' + matchLabels: + GNi1: XTv3 + agO1: rNYRcx + matchLabelKeys: + - q + - "" + - 4u + mismatchLabelKeys: + - E28Dz + namespaceSelector: + matchExpressions: + - key: 0j + operator: 凵TU啜Ŋ螢馹ʍſ + values: + - rRA51 + - igqVL3dl + - cMQsgEymY + - key: 2gObxnA9 + operator: .埑9±Ľ + values: + - 7xXJ3 + - b5YaQ6 + - WISJEcAF + - key: bwy + operator: ȼ殦ʬR颥Ǭʌa鴸&ąFjɚ` + values: + - w6clsK + - bjYH + matchLabels: + TY0: bhwBS + u9trttO: lGYO8h + namespaces: + - qn + - BYd2 + - kmeXHHG + topologyKey: 1Ft72IT + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: Yi + operator: '"' + values: + - k3wctb + matchLabels: + IUEo7: Wvj4K + VZH: s1lVwq7 + matchLabelKeys: + - pVo0yd + - tH2 + namespaceSelector: + matchLabels: + TW0C: fKUjlPkN5 + cpGUpaXo: xC3 + giVV: oOcx4 + namespaces: + - kaYiZrU + - Mx5F + - ty + topologyKey: 7cL + weight: -796426395 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: 4IQ + operator: ~炷ŀ邛嵪ó5F墪ȍ驇揷A§ƚf{>ȹ + values: + - "" + - GpsIXxXhAo9 + - qs + - key: La + operator: n;憂莰 囒GȋhȆ熨e鑜Jƫ + - key: 8BkIi + operator: '}ȴ藆¨ʄk鵢ʡm' + values: + - U + - FDzLXdzU + mismatchLabelKeys: + - A2CjGC8H + - c + - IYWbM + namespaceSelector: + matchLabels: + LnrpS9obyu: 1n + wKRnL: "" + topologyKey: njqm3p7G + - labelSelector: + matchExpressions: + - key: CG + operator: §顲º + values: + - "" + - 41vsmSfIvpw + - yyVdBOWqYG3JK + - key: imA + operator: µ欤!k;壁ƶ + values: + - D2tGL + - "N" + - IzBvfEz + matchLabels: + L1: Y5MT6 + mismatchLabelKeys: + - gP42KfEC + - ON2I7o + - hYr40 + namespaceSelector: {} + namespaces: + - "6" + - uO2 + - yLgyfiR + topologyKey: zjRcu + - labelSelector: + matchExpressions: + - key: luBI + operator: ʃ>ȲºPũɹ霄F6ʣ­鴙 + values: + - cBmF8 + matchLabels: + 0vH: 9N + 2lClMO: iDGDJsP + Rbm: SV4R0ij0kv + matchLabelKeys: + - tbbRcpcmE + namespaceSelector: + matchExpressions: + - key: elN6 + operator: MȧJǐt + values: + - cfxfv + - W + - "" + matchLabels: + CZ7: KJ1 + hh6xT9iBgnx: 680J7Ww3 + topologyKey: I + podAntiAffinity: + custom: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: "8" + operator: "" + values: + - KM + - lAT + - NN6ch + - key: an9V9F7e + operator: 蒖瞗ƕ3É伿)ƒ売c+HɑHŀ礽{¿K + - key: SbRvHE + operator: ~ú+銃刅ȱ + values: + - S6tzqFt + - zKss3W + - R3XXZp + matchLabelKeys: + - N5 + mismatchLabelKeys: + - Rt8aa + - "" + - NWv + namespaceSelector: + matchLabels: + EX: HZGSzbFGX + QYppQ: jVvw0V + topologyKey: g7HL + topologyKey: FhZosc + type: smnyiuV + weight: -589206663 + priorityClassName: xuvUg + progressDeadlineSeconds: 625787929 + readinessProbe: + exec: + command: + - D6pWcMRx + - f + - WJoWsx + failureThreshold: -1732496585 + grpc: + port: 2008777 + service: EH9aue + httpGet: + host: 27wRHd + path: z5 + port: gBHMh6 + scheme: ŇZ罡î孷Ď凯IJ穮臈g嚄=榓ʄ + initialDelaySeconds: 41316909 + periodSeconds: -1536340211 + successThreshold: -872033350 + terminationGracePeriodSeconds: 755864549545305461 + timeoutSeconds: 641817532 + restartPolicy: 莺N + revisionHistoryLimit: -1523772697 + schedulerName: pAjniqNhZyOs + securityContext: + fsGroup: 4315889566768146013 + fsGroupChangePolicy: 4ŋu攠Įȯʟ%闓諗ɸDž= + runAsGroup: -2570730350940379829 + runAsNonRoot: false + runAsUser: 8876786175168037156 + supplementalGroups: + - 8106893607739023128 + - -3191337886248958794 + - -9161390975044730852 + strategy: + type: t19cLk + terminationGracePeriodSeconds: 955744914 + tolerations: + - effect: 洪 + key: RsZkLxkjJ + operator: N鱕 + tolerationSeconds: -7968213159538961006 + value: x + - effect: 送孺糯{\ȸ!¦d + key: XS + operator: Łʼn抂ôƨQ敊ȈǤ|f揻渪ʫô!iȔ + tolerationSeconds: -6845197254618999245 + value: Lw1e + topologySpreadConstraints: + - maxSkew: -1978515794 + topologyKey: g + whenUnsatisfiable: iC + - maxSkew: -755886947 + topologyKey: AMp0C4H + whenUnsatisfiable: NNjCNE + updateStrategy: + type: jtzm3 +fullnameOverride: DPRe +imagePullSecrets: +- name: iNrm +- name: tXVc4 +- name: 2FI6svfYzUT +logging: + level: xYn +monitoring: + annotations: + k8EzKZ: oXYkaOnH + enabled: true + labels: + 07sPUbsx7a: "4" + namespaceSelector: + any: true + scrapeInterval: -1922855h59m11.982156464s +nameOverride: WdYlcGB +service: + annotations: + 25swrT: LyMk + AgV: 2ZT + LR7E9YY7J: rc + name: L + ports: + - name: "0" + port: 1958832246 +serviceAccount: + annotations: + tUrOJRs: sa + u5pe: o5HFd6E + create: false + name: 2QWHyV8 +storage: + volume: + - name: 6mgHY + - name: aPVxgB + - name: ml + volumeMounts: + - mountPath: YuAZg + mountPropagation: Ŭ鷾/1p[睘6nƴ攝ŝ'Xǯ鍻市 + name: uA5mP95UbWz2DU + readOnly: true + subPath: Rd + subPathExpr: HjiP + - mountPath: I8PeS4vph6 + mountPropagation: ȁ8ǁ + name: "" + subPath: KXRi25s3l + subPathExpr: J2VIP0O + - mountPath: kMp9FbjBpDZFC + mountPropagation: Ƿ + name: h + subPath: D0waN + subPathExpr: uBJAJhe1iu +test: + create: false +tolerations: +- effect: Ȳɯ廝T憎Ľ摛lN&ƫ'ɸwc¢Vh + key: IDKt + operator: 趉 + tolerationSeconds: -769067857200268382 + value: gRii1 +-- case-044 -- +auth: + sasl: + enabled: false + mechanism: LO + secretRef: mhOAME + userName: "n" +connectors: + additionalConfiguration: xypAC + bootstrapServers: AJo + brokerTLS: + ca: + secretNameOverwrite: LZ8 + secretRef: Qd + cert: + secretNameOverwrite: "N" + secretRef: 4Hwd2 + enabled: true + key: + secretNameOverwrite: NGmzeL6Y + secretRef: ak + groupID: S7uyvF + producerBatchSize: 577860685 + producerLingerMS: -1432617314 + restPort: 871084350 + schemaRegistryURL: BMfK + secretManager: + connectorsPrefix: MIv88J + consolePrefix: 5dJ + enabled: true + region: ToqBft85 + storage: + remote: + read: + config: true + offset: true + status: true + write: + config: true + offset: false + status: false + replicationFactor: + config: 1110431616 + offset: -1272331222 + status: 342664574 + topic: + config: MSUfKAm + offset: 1EER + status: d6yOc +container: + javaGCLogEnabled: "2" + resources: + javaMaxHeapSize: "0" + limits: + cpu: "0" + memory: "0" + request: + cpu: "0" + memory: "0" + securityContext: + allowPrivilegeEscalation: true +deployment: + annotations: + e1: EPUL4 + budget: + maxUnavailable: -853711840 + create: true + extraEnv: + - name: Hn + value: RLmuTFKt + valueFrom: + configMapKeyRef: + key: u8iVw + name: l8S7wk + optional: true + fieldRef: + apiVersion: 5q4Wkck9Yhn + fieldPath: e56i1D + resourceFieldRef: + containerName: MP6 + divisor: "0" + resource: W + secretKeyRef: + key: Sow4h93xH + name: tK6mZbO + optional: true + extraEnvFrom: + - configMapRef: + name: 6a + optional: true + prefix: wqO + secretRef: + name: eZxNk + optional: false + livenessProbe: + exec: + command: + - 6AVfWWiU + - gjBVfhPqm87 + failureThreshold: -179099947 + grpc: + port: 2055240519 + service: 85th + httpGet: + host: aY98zm4 + path: qhNVygpz + port: D5cj4qxJ + scheme: 训珙仾ɠ/a]"蒟ɩ蓫nµ@- + initialDelaySeconds: -741511239 + periodSeconds: -301254020 + successThreshold: -1795354231 + terminationGracePeriodSeconds: -1555270337534101901 + timeoutSeconds: 17970381 + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: ggOgs + operator: ʆ=Ǭ + values: + - 6xOHO + weight: 1438312308 + - preference: + matchExpressions: + - key: sVT + operator: Nj溚K$P" + - key: 3i + operator: 状w¿鄏荤džöǹĄ + values: + - hl9dZyPnxN + - C87 + - key: Pt + operator: ʬƴXw/8綷 + values: + - S9I6Qrsfz + matchFields: + - key: Gvnxn3 + operator: â氠喬 + values: + - d + weight: -886172272 + - preference: + matchExpressions: + - key: oy973i + operator: 圅¢璸'ɆʥʚvǴMĴ + values: + - OBP + - "1" + - YNoey99 + - key: Zy0iQotc + operator: +g + values: + - FO1apzD9 + - epCNQ66B + matchFields: + - key: 8nakITBFg + operator: '|ȍ' + values: + - 9z + - RX + - key: "" + operator: Mȃ"ô薱黭夃< + values: + - "" + - C + - YE3 + - key: iZFE5e + operator: nǮ + values: + - LHp7ijJ + weight: 567068826 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: we + operator: ɜP苞崉汊S + values: + - 1zCAp + - DVu + - key: piI + operator: Ǔɽ觩-鸭諣0ʙɮ鈿莳CyJ2 + values: + - 8oy + - HijL4M2 + - key: Xjq + operator: d遢豾9藌NJəBǔ,ɿǸ5Ƶº'芎婑( + values: + - kGBJo + - MpcP0e2Tga + matchFields: + - key: JhC5vQ1U8 + operator: "" + values: + - t + nodeSelector: + m8ypcZn: yD + podAffinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: QqHIF + operator: SČA窚R顒e涜efʩCá盻ɭ峄觘1 + - key: lOM35 + operator: Ljw盫励饇脧 + matchFields: + - key: Xvd + operator: 俍郖=璻Ęb錽Ȫ碄尫ɋ硣!)桂寥 + values: + - qt + - y3U08eS + weight: 2109206004 + - preference: + matchExpressions: + - key: S + operator: ɃƗA尯DɮǪȽʎƥ銐Ǧ + values: + - "46" + - p0eIl + matchFields: + - key: Ih + operator: "" + values: + - tf3 + - yiPSH6Zx + - C + - key: uZ70o + operator: "" + values: + - 4UJb + - oH8P43gtksh + weight: -709859925 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: QTE13xnu + operator: ŝ + values: + - VHR0qG + - MOvO + - tb1sLuv + matchFields: + - key: g + operator: Yʝz_GBDŽ糎腄Z:*秡*kƗ + values: + - tLOJ + podAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: pwXEKFjBU + operator: "" + - key: feqEDUfP + operator: 慐;姁ƣ憙c蚖J + values: + - TJyZpGt + matchLabels: + B1R: sAy6clnGGjf + mismatchLabelKeys: + - G56 + - 3U + namespaceSelector: + matchExpressions: + - key: Irk + operator: 朩š­ȅ擋fħʎ;脕擿 + values: + - fR + - HI6qMSx + - kKz + namespaces: + - 2Gjzz + - p1ZzhD4REnP + topologyKey: 6Qb + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: yCd1 + operator: "" + values: + - w + - RGxbGQ + - F01lOE + - key: gFNsh + operator: ɢ渖ŕň詌& + values: + - Qf2 + - U9ebth375LF + - key: Eym8DG + operator: 軩榺骧F鑣槙ƹ=懸 + values: + - "" + matchLabelKeys: + - e + - I + - a1moWz + mismatchLabelKeys: + - GB + namespaceSelector: + matchExpressions: + - key: br8ud4ME + operator: _粡垵Ȁu|Ňɾǡ + values: + - IRAa3b + - mJaeH + matchLabels: + QzUL: lBDdFKkr + YCq8PhpxP: pFQirOBS + topologyKey: 9fEh + weight: -1030104992 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: HGoREM + operator: /咹ȱ駧裀 + values: + - afgtBu + - 62p2cohE + - LcvApZ + matchLabelKeys: + - Q + mismatchLabelKeys: + - a6cO + namespaceSelector: + matchExpressions: + - key: n6x6j + operator: ô萿Ɍ昙ʉĄ髪ƭ囯ğĠʏxC萓ɝzjZ + values: + - pFL5xvt + - key: s + operator: Ö祻Ř + values: + - bTZ7C33 + - 7rM4m + matchLabels: + DgZsb: m6XWnS + namespaces: + - yJgfZk + - Yf7For + - XF2ycSW + topologyKey: "4" + weight: -2000314685 + - podAffinityTerm: + labelSelector: {} + mismatchLabelKeys: + - pfRhN + - dtRA + - iTYieI78 + namespaceSelector: + matchLabels: + IF7T: rAjc + mCuB: rL0bjM3 + namespaces: + - b + topologyKey: qb + weight: 507067570 + podAntiAffinity: + custom: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: "1" + operator: rʒ±&Bc'慈棊r9ş噱ȅ + values: + - hTfTJGI + - hCkH6FF2Si + - AZSo18hB + - key: Z6aBXlU + operator: P-ŋLǃGȐ + values: + - UnrL + - 8SKSgIl + - XyUUHq + - key: mX + operator: ȂcǍ*饻蜵yȔ7 + values: + - wZkqm + - 6fK + - bLHwoiWtxS + matchLabels: + wqj3bNcE3: 7PXUv + mismatchLabelKeys: + - 95VHWEv + - oc + - XvcBqP + namespaceSelector: + matchExpressions: + - key: T2L + operator: 悪ȵǠȸR&>S%%­ + values: + - T51z8Xf + namespaces: + - 2akt + - 97MqCK + topologyKey: q + weight: 1571306470 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: AdbAjo + operator: ɠ¡苋H籲Ž蛏LjKHw銮梀 + values: + - UFW + - RzRYQce8u + - iL + matchLabels: + JiS2: 1H8Jf + namespaceSelector: {} + namespaces: + - C8 + - ghqER + topologyKey: utHH + weight: -696696597 + - podAffinityTerm: + labelSelector: + matchLabels: + "": Bbi + eYzf2x: "2" + matchLabelKeys: + - dCIk + - 3Vwvq + - vJu + mismatchLabelKeys: + - a7 + namespaceSelector: + matchExpressions: + - key: drG3i8uijLu + operator: +ȟk崓ȆGƥ + values: + - flTafhZKt + namespaces: + - KXcRu9Rvr + - bf0AY + topologyKey: 6Hp + weight: -1330375242 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: rlde + operator: ŗ嚩魟ʂ洁ʌº騛匱ũ閳Ŵ蕄禱0銜_犢 + values: + - 6J + - key: bI + operator: 哱{謶HKƜ滞彟 錃 + values: + - 2XcglJ8jt + - h6dh + matchLabels: + "": DJ + QbwFkC: rtU + matchLabelKeys: + - Ywe5PNR6 + mismatchLabelKeys: + - oyq + - j + namespaceSelector: + matchExpressions: + - key: AM9Vlx + operator: ɚ瀣 + values: + - YDBHwbSJx11 + matchLabels: + J: aFw + oqgO2J: EQq9cWAp + namespaces: + - fmF1dGO9 + - f2pZ93 + - IUUP + topologyKey: "" + topologyKey: YFCQ + type: Tuxria5udfO0g6l + weight: -612629711 + priorityClassName: u + progressDeadlineSeconds: -1210754760 + readinessProbe: + exec: {} + failureThreshold: 1162556666 + grpc: + port: 1033949401 + service: 0xDhM + httpGet: + host: FFe6 + path: jXYC + port: -1764755290 + scheme: 姕鯼ñ赇邬N[ƥ + initialDelaySeconds: -1796420049 + periodSeconds: 940741811 + successThreshold: 1628971624 + terminationGracePeriodSeconds: 906647697820167459 + timeoutSeconds: -1878581735 + restartPolicy: OL恟´跒ɴ珛姌Ŋ + revisionHistoryLimit: 400792738 + schedulerName: FfnrLnAtn3 + securityContext: + fsGroup: 5186362895627063604 + fsGroupChangePolicy: E甗dbƾ潸 + runAsGroup: 4738220116750422009 + runAsNonRoot: true + runAsUser: 4123601200118601914 + supplementalGroups: + - 5067618254965113558 + - 2922991898118782560 + sysctls: + - name: 1idwf + value: RtGFIRLv + - name: toxsb + value: "" + - name: bC + value: IcMTnt + strategy: + type: AQc + terminationGracePeriodSeconds: 1834992377 + tolerations: + - effect: r"ǘ + key: 7FvMPWDDP + operator: 杍Ɍ + tolerationSeconds: -4685795240412632399 + value: G9czii + topologySpreadConstraints: + - maxSkew: -1990808403 + topologyKey: y1s + whenUnsatisfiable: bxCWoMA + updateStrategy: + type: S6j +fullnameOverride: ZNfeDYT +imagePullSecrets: +- name: HaLjyQ02L +- name: yjimP +- name: 5KCFV6 +logging: + level: p +monitoring: + annotations: + SF8: t7jzDFP + enabled: true + labels: + "3": P + GGM8HrAa: AroHM7WrsoM + namespaceSelector: {} + scrapeInterval: -947976h35m5.865272977s +nameOverride: R64C +service: + annotations: + t7u5eHUdpR: nq6injR + name: L + ports: + - name: 2Pm + port: -597719959 + - name: z + port: -1354836854 +serviceAccount: + create: true + name: c +storage: + volume: + - name: RXJ + - name: JJ +test: + create: false +tolerations: +- effect: /褫ţ\軳銑Ü雷倮Ų婏$ŮƩĚ + key: 5HSJSb6w + operator: 煬3獽渷VUȁM喎_鎼崞PA1廫Á + tolerationSeconds: 5989052173653210891 + value: 02lqbv +- effect: 笶雟襠¼Ⱥc芽"鵙ȓ矎Ş赈Ɓzŭ帆弯 + key: q + tolerationSeconds: -3826318230045492347 + value: 9hOSh +- effect: ă庡泣dƤÇ漰-Čɺ阂垑 + key: Uj + operator: 蓐}à]@ƚʀ0#Ĵ.Ɓ> + tolerationSeconds: -603362735954808522 + value: ONkOq +-- case-045 -- +auth: + sasl: + enabled: true + mechanism: xG0RkV + secretRef: BIwqKvbDzty + userName: QhJxq +commonLabels: + MbBpaa: UzKZX + h52qwPFCCL1xE: q +connectors: + additionalConfiguration: zhdlWU + bootstrapServers: r1Qjuz + brokerTLS: + ca: + secretNameOverwrite: vu5uhRVRV + secretRef: sv4 + cert: + secretNameOverwrite: c + secretRef: NXfOTPmR0 + enabled: false + key: + secretNameOverwrite: xHLx8Dd + secretRef: j674MI8jFC + groupID: "1" + producerBatchSize: -816839187 + producerLingerMS: -182038831 + restPort: 1110004877 + schemaRegistryURL: lpElMB + secretManager: + connectorsPrefix: sN + consolePrefix: a0o9mHxTvK + enabled: true + region: zhGJZW + storage: + remote: + read: + config: true + offset: false + status: true + write: + config: true + offset: false + status: false + replicationFactor: + config: 1812077740 + offset: 1243553126 + status: -829555769 + topic: + config: jwiijthRuB + offset: C53fN + status: JY +container: + javaGCLogEnabled: E + resources: + javaMaxHeapSize: "0" + limits: + cpu: "0" + memory: "0" + request: + cpu: "0" + memory: "0" + securityContext: + allowPrivilegeEscalation: true +deployment: + annotations: + 51a3: g2ULKf + 91y: DbHu4ZZ + E42Z4BCZaV: rYnLAo4y + budget: + maxUnavailable: -1040325689 + create: false + extraEnv: + - name: UPHAx9 + value: QbO4m + valueFrom: + configMapKeyRef: + key: 5Z + name: fIO1tsT4L + optional: true + fieldRef: + apiVersion: k6XVQx1bizA + fieldPath: aDTDwvyQ2EkZlp + resourceFieldRef: + containerName: gARZ4U + divisor: "0" + resource: LnJW0S3driTR + secretKeyRef: + key: t4ZmT + name: fOXC9P + optional: true + extraEnvFrom: + - configMapRef: + name: aNWPY + optional: true + prefix: MuH8ACn + secretRef: + name: JkiHQd + optional: true + - configMapRef: + name: s + optional: true + prefix: v + secretRef: + name: jWW04 + optional: true + livenessProbe: + exec: + command: + - "" + - "" + failureThreshold: -1532177375 + grpc: + port: 130895075 + service: DEDl0lcO + httpGet: + host: men + path: VPV + port: VOrs + scheme: 7id{=崂妐"蘆償ʙ^v疷k` + initialDelaySeconds: -1596982922 + periodSeconds: 56768361 + successThreshold: 592299817 + terminationGracePeriodSeconds: -3570152852783991929 + timeoutSeconds: 841818051 + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: HT + operator: 笔ư -汯糵O, + values: + - W + - wa4yZu8SI + - key: bGRL28 + operator: "" + - matchExpressions: + - key: aczzo + operator: 瞦Ɖ¸ + values: + - NSkH0Tn + - key: BcZ + operator: ȗʪb蒘Ơ + values: + - YPr6 + - irqBr + - c5yp13P + - key: mJl + operator: 穚Z踿> + matchFields: + - key: p2Za + operator: "" + values: + - 2qA + - hUhp4Y + - key: sP5fxY + operator: đʜi芻u(喏eƠ=扑腧ń虮损磎 + values: + - O4 + - key: Ic4jA + operator: '"Ě钄蝼Ş' + values: + - Z + - matchExpressions: + - key: AnlK + operator: 顷媵z貢嵟v埾Ɗzv学ʑ別¼ɷ齕穁漕 + values: + - f + - ggWBzmm + - MhgW + - key: cC + operator: "" + values: + - "y" + - tPa8q + - ZQfr6 + - key: YsiT0s + operator: æ脣ǻ熛&PK$Ė.£'sVq + values: + - 86vjg + - WJVZECB + - Ois6M + matchFields: + - key: 0cMl8NXDE + operator: 8¡尗;鍼WN睧>MȼÙ斴}Xx + values: + - LjHKAAyI + - MBJl + - "" + - key: DLPymz + operator: 僔ʯ煎Q礔 + values: + - k + - dpS5fQi8cuuj + matchLabels: + O71m8d1PjMco: z + RnzP: moJ2 + b8S6njSwAa: u3InH7A + namespaces: + - 5Uf0lBWUp + topologyKey: eVQ4ec + topologyKey: tm + type: "" + weight: -887302512 + priorityClassName: O1Kw + progressDeadlineSeconds: 346316441 + readinessProbe: + exec: + command: + - C1rtCjV + - xVJ + failureThreshold: 264449477 + grpc: + port: -691797345 + service: lcF + httpGet: + host: u + path: O7iQge0AMQ + port: j3 + scheme: 猡9ȹǵ + initialDelaySeconds: -1669763451 + periodSeconds: 977763135 + successThreshold: 1558580703 + terminationGracePeriodSeconds: -6309681110777439769 + timeoutSeconds: -1984487220 + restartPolicy: 鏄纽潘翙i宫ǃŬZI摌嚶S媏§Ŵ + revisionHistoryLimit: -1788607261 + schedulerName: F8EoeT + securityContext: + fsGroup: 6765195282399752912 + fsGroupChangePolicy: ɹ緟/xZ}纨SŖ奝杆ü詁Sij徖 + runAsGroup: -5644369168799206336 + runAsNonRoot: true + runAsUser: 7294021627851308883 + supplementalGroups: + - 8068234294449949843 + sysctls: + - name: mf + value: r9jQF6Qmf + - name: lTWR1RE8VW + value: qgy + strategy: + type: rtCVvHc + terminationGracePeriodSeconds: -1972969881 + topologySpreadConstraints: + - maxSkew: -532646137 + topologyKey: jF + whenUnsatisfiable: MyH6gO2 + - maxSkew: -1392634033 + topologyKey: tu7J2 + whenUnsatisfiable: QyTBF + updateStrategy: + type: A5hk +fullnameOverride: uLr8eH +imagePullSecrets: +- name: 4E +- name: 4lLe +- name: OsAOb +logging: + level: kR +monitoring: + annotations: + ADPu3ozSd: q + IirIQ: nU4N + z1: CMu8InAI + enabled: true + namespaceSelector: + any: true + matchNames: + - UCZpu + scrapeInterval: -2400738h41m36.27693474s +nameOverride: 8UJFy +service: + annotations: + H8XRE: XmuXsN + name: 58KMN + ports: + - name: 7oEiI3 + port: -1730203461 + - name: pxPCPLymcj + port: 1857328046 +serviceAccount: + create: true + name: Vk +storage: + volume: + - name: wYHcQRdOs + - name: "" + - name: ttvGMzWGLl + volumeMounts: + - mountPath: dIJTWQIJ + mountPropagation: 摢闟2喟搩 + name: uTG + readOnly: true + subPath: L + subPathExpr: tp +test: + create: true +tolerations: +- effect: 齼/r3ȕ顉ÏveŌ脜ȹ鋕忼癲h%Ə嚼 + key: 5ik + operator: Ȳ穖ș汥ë¦ʋ/ + tolerationSeconds: -588635388335609407 + value: Nf +- effect: ɠ+ů.ʓr敡¾蔠Õ9琕Ș0ŀũ + key: Rx + operator: v氒>妉Ȇ鼏,ə$Ȑƈ + tolerationSeconds: -4656106895121584518 + value: dYSELiW +-- case-046 -- +auth: + sasl: + enabled: true + mechanism: Q1Z + secretRef: thcka + userName: fnI +connectors: + additionalConfiguration: m2GNF8s7jf + bootstrapServers: D + brokerTLS: + ca: + secretNameOverwrite: SYFFF + secretRef: cz + cert: + secretNameOverwrite: 3XIvjsWLN6 + secretRef: 6sd3d + enabled: true + key: + secretNameOverwrite: T + secretRef: 9JF + groupID: elUuL + producerBatchSize: -1573191506 + producerLingerMS: -770515576 + restPort: -1606573822 + schemaRegistryURL: 7RGVLKX7Aw + secretManager: + connectorsPrefix: gZ + consolePrefix: JVMm3xRzC6L + enabled: true + region: w3xB + storage: + remote: + read: + config: false + offset: true + status: false + write: + config: true + offset: false + status: true + replicationFactor: + config: -258960528 + offset: -2024950872 + status: 861394883 + topic: + config: atuSRuNrckHcf + offset: 1RcFXt + status: 8LlPa +container: + javaGCLogEnabled: lI + resources: + javaMaxHeapSize: "0" + limits: + cpu: "0" + memory: "0" + request: + cpu: "0" + memory: "0" + securityContext: + allowPrivilegeEscalation: false +deployment: + budget: + maxUnavailable: -149051994 + create: false + extraEnv: + - name: WU + value: peR0Ss + valueFrom: + configMapKeyRef: + key: xoj + name: LFu + optional: true + fieldRef: + apiVersion: fu + fieldPath: "" + resourceFieldRef: + containerName: a1O7Y + divisor: "0" + resource: "0" + secretKeyRef: + key: 93J1 + name: 9nuLdu6 + optional: false + - name: Mvin4FAU5 + value: 9a + valueFrom: + configMapKeyRef: + key: LweOD + name: fvKkyzS + optional: true + fieldRef: + apiVersion: epGY + fieldPath: q + resourceFieldRef: + containerName: 6c7Gx + divisor: "0" + resource: Owy + secretKeyRef: + key: E0Zk + name: KZlUt + optional: true + extraEnvFrom: + - configMapRef: + name: mLUxg + optional: true + prefix: g97qu + secretRef: + name: 4QxnP + optional: false + - configMapRef: + name: b0w + optional: true + prefix: J + secretRef: + name: sI801BdyQH + optional: false + - configMapRef: + name: NprLkY + optional: false + prefix: jezpH6a5kO + secretRef: + name: R7Ho + optional: false + livenessProbe: + exec: {} + failureThreshold: 105969409 + grpc: + port: -654227233 + service: BVatgTUI + httpGet: + host: SvQfS9AXrg + path: LfSm + port: -937311468 + scheme: Ųd;踇嗞ȅ¼3纊襶贼Ɔ郼ý渶ƁüȮ + initialDelaySeconds: -638210685 + periodSeconds: 825763830 + successThreshold: 285294064 + terminationGracePeriodSeconds: -6200311383477120435 + timeoutSeconds: 1016755696 + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchFields: + - key: "" + operator: Ƚ|]缴ŋĄƽQ晫喹蘉 + values: + - 1LZaJjl + weight: 2108667665 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: Nv1N + operator: D朵ƁRč + values: + - vmxJB + matchFields: + - key: VQWv + operator: 臋NʤŇ矤ɘęłê'ß²ÝIȸe + values: + - VRLGHJ + - b9wx + - OWO + - key: kwjnJ + operator: '`>ʮ:' + - key: I1 + operator: ß躺^î歾 + - matchExpressions: + - key: 3sC + operator: ɥ飽璫誾 + values: + - "" + - FTiwF + - TZcoXdUX + - key: nXHo + operator: Dĕ风哢 ȫ晎灬c^P堓r]Ñh> + values: + - DJA5PjIE + - key: B6a + operator: ÿF[ gǝ竈霙46蹤ȩt鐱防粽磱ɞ + matchFields: + - key: B0 + operator: 6撙早ƽ"籩O+ÿ±9V瀨谐 + - key: "1" + operator: ĊÔʗ掏芊p裏k癭.ɹ擶bɡ凥 + values: + - yD9RzH1 + - nfvbXbaS + - key: rp4R + operator: c弙ú + values: + - T30OE17 + - cNJe1Vb0y + - matchFields: + - key: 0bnhPvmYY + operator: ā + values: + - ogK1 + - "" + - aC8YOr + - key: ya + operator: 洯 + values: + - o + - NJh + - Dfx9Y + - key: UjdX + operator: mă漚洰綗eɞ噢A:dɱ + values: + - OGzFB1je + - 9v + - eA + nodeSelector: + VX: MKV5ljOmB + qPiO: "" + podAffinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: F + operator: 鰩礄ʗOtĎFdƣÍƅf濆炝史飘 + - key: "" + operator: R8話Ů¾ɻʝÞɻ0Ǝ蕗 + values: + - HA0N0 + - key: o + operator: Ƞʁ蝟峵陭ń搏莨嶐 + matchFields: + - key: 2DQC + operator: ǥ + values: + - oncBIr + - gG + - leEScS + - key: tueth + operator: Aɰ邸ƑeŰ + weight: -2084006794 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: [] + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: B5t9 + operator: jWuŅ.鵀ĕd眶mw\塠kȒ觤Ȗɯ著 + values: + - YX + matchLabelKeys: + - As + namespaceSelector: + matchLabels: + 9YGQMUgrqH: 5rQRCucN + N2djrnHv: Kt4eVwh + kUhn3: 0hb + namespaces: + - ipRMD8PjRE + - TyGdLq51qHtCTp + topologyKey: Qb + weight: 1218556128 + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: {} + matchLabelKeys: + - UEXU0jm + - 3DvGK + - q7ZgoFKzY + mismatchLabelKeys: + - 8rS + - Zhmgc + namespaceSelector: + matchExpressions: + - key: Ahp7S + operator: 垄^ȕɝi + matchLabels: + j: Z + zn: 5N1spN + namespaces: + - 5U55 + topologyKey: El4O + weight: -1441269991 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: JeAkeb + operator: 齁.瀵倖Q{鑵À{ôk凔wȅ穝蠴礰 + values: + - NLDkgX + matchLabels: + Nb6NP: U + matchLabelKeys: + - 0xUxIZ5yra + mismatchLabelKeys: + - PO + - 0lMaP + - wjTYW4v + namespaceSelector: + matchLabels: + dfk: 2CoJF65 + l: EO55 + rSCM: 7ax + namespaces: + - LA8zh + topologyKey: ME + weight: -1429618030 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: fSvZx + operator: 簬¥彖馜@鰭ʛSŘʪw罗羐 + values: + - WBKgoDO + - IHFoQPa6I + - 7EBoFbh7 + matchLabels: + bDJ: uVvI + mismatchLabelKeys: + - v4GMLNjOI + namespaceSelector: + matchLabels: + pIeQi8D: hs4uHTom + namespaces: + - ik + - Lt + topologyKey: QP + - labelSelector: + matchExpressions: + - key: 5s2dAmoyzPuH + operator: 鼣WŲ痹 + values: + - SjWekZOshkn + - K8vFvMOrtwkd + - vYvUI0 + matchLabels: + fr69Sg2H: VRYdncoQ + mismatchLabelKeys: + - S + - "6" + namespaceSelector: {} + namespaces: + - LUd218j + - w9 + - VqcJK3hxUk1 + topologyKey: ajmyRnnxd2R + podAntiAffinity: + custom: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: "2" + operator: 詗邼}遱方ƶVIǖ*$ȗ}弇 + - key: g + operator: ƐÑS吁ɹĹ{濍 + values: + - UrWNgdSYW + - SYsweJvP1r + matchLabels: + TzMQ8: F4coq + b3vIQZ: sUq + xcd5: MP6g + matchLabelKeys: + - t + - uMrJ + - F9jZ + namespaceSelector: + matchExpressions: + - key: b + operator: ǻǴ溤Ɂ璝4ƥ砬Ä.汃ÌQc% + namespaces: + - "6" + - Qipxt + topologyKey: WtKz + weight: -1783246152 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: sCMVaOSO + operator: Ǽ歏Ģ`蓱g:ļ熹笡珁Ú0嘳*ʖ鱣 + values: + - kCylM + - "" + - Kpn13h4g + - key: GchDvxjZ + operator: ¿狘 + matchLabels: + BaG8QJGx: "" + dW2Wn: kBm + kulZty4hr: zdkw + matchLabelKeys: + - 29OT95 + - qW7mvgum + mismatchLabelKeys: + - "" + - keMPa + namespaceSelector: + matchExpressions: + - key: 8wu + operator: 嫧諟Ô·$rœc啢栭 + - key: "8" + operator: M2瓥3鮺Ś;絔@f%奱ʚ坔澡7ƅ戻 + values: + - 6QGU + - GL + - key: qtzYmH3 + operator: 验ǔƃ岶綇ŦE鶁蜊芨 + values: + - TSIjp + - ojx57bK + matchLabels: + 7sUo: "" + DHkjnVf: DNPHWQ + n0Rp: 4dK + namespaces: + - eD2 + topologyKey: iW + weight: -1851545717 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: jd1N + operator: "" + values: + - 8QC + - vPFgOl + - F3qBo + - key: VS7EG1R + operator: ~衙ƛ媧 + values: + - Nx87ge + matchLabels: + tWq1XyYw: KerD + mismatchLabelKeys: + - WEbxlcBJK + - "" + - cFI + namespaceSelector: {} + topologyKey: i0Hj + - labelSelector: + matchExpressions: + - key: SZpuMyf + operator: 妮ě + values: + - x + matchLabels: + 0zhQ2: 4K9P + c: Job + lSKbx3: jzjsb + mismatchLabelKeys: + - g8jh + - 9Qbf7h8 + - PbmM + namespaceSelector: + matchExpressions: + - key: dSc1 + operator: ùǡ幘Ŋ墮臕聍sǵ=Ltɝ蘧d愗E掦 + values: + - 77h6NZ + matchLabels: + "4": cBXu0N + ed: Jd2ob9IYLON + mwzs: JYg + topologyKey: 5um1 + topologyKey: MApo + type: G3a + weight: -522398208 + priorityClassName: 8Ypa1TecZ + progressDeadlineSeconds: -197240712 + readinessProbe: + exec: + command: + - VeG + - ZpYkBZjWQp + failureThreshold: -946013108 + grpc: + port: 1733046252 + service: TE9gSM + httpGet: + host: r5F + path: cEjpG + port: UQUR + scheme: ĺFŪč<,龆ɶƹDƿ孄 + initialDelaySeconds: -1609629919 + periodSeconds: -158429668 + successThreshold: 414657348 + terminationGracePeriodSeconds: 2365381410449413752 + timeoutSeconds: 677541953 + restartPolicy: X\B4錻}ȅ浸(I惽襪葷^Ĥ%ȶ^揬 + revisionHistoryLimit: -640963372 + schedulerName: tcrF + securityContext: + fsGroup: 1542597599134889862 + fsGroupChangePolicy: d坹ɷŰ翖Ȯ笺創y8礗岉 + runAsGroup: 4178156742717272546 + runAsNonRoot: false + runAsUser: -2177916685244537831 + supplementalGroups: + - -5773129745234681762 + - 7956710079209489615 + - 8047946510130583628 + sysctls: + - name: q8BvtyH + value: 32PC + strategy: + type: Ht + terminationGracePeriodSeconds: 2099000264 + tolerations: + - effect: '{梪篤龄Ȃ溺ʓ蚙Hw塨朣手ʛMČ' + key: Q1aKV + operator: '@' + tolerationSeconds: -4086789290485374625 + value: jamSz + - effect: '3ǂ鈫嶈ȯď¥芠ĸÇȻĉ閜PɓFpē ' + key: HmRvIg + operator: '#NO%#:Wù嶴:äʚí}' + tolerationSeconds: 3271010049130049050 + value: vFFxX + topologySpreadConstraints: + - maxSkew: -1728964191 + topologyKey: uwdTzniKw + whenUnsatisfiable: V5KLT + - maxSkew: -1160977379 + topologyKey: Ey5 + whenUnsatisfiable: jJ0E + - maxSkew: -594009032 + topologyKey: Ia5x1fvG2 + whenUnsatisfiable: g47TB + updateStrategy: + type: Zn9 +fullnameOverride: tYC5CG +imagePullSecrets: +- name: KzX +- name: NR1aEs4c2 +logging: + level: TI1KLHr8o +monitoring: + annotations: + "N": "" + b: p + enabled: true + labels: + O: CY3sdu + UddrJ: zlyJcM + klftu: OSDi + namespaceSelector: {} + scrapeInterval: 2140586h7m44.853020521s +nameOverride: fa1XvkvO +service: + annotations: + H: "0" + name: UrU9Bs +serviceAccount: + create: true + name: cl +storage: + volume: + - name: b7Yo6m + - name: cHS + volumeMounts: + - mountPath: 18po2m + mountPropagation: Ś宵 + name: aWWUxCrc6 + readOnly: true + subPath: 84zs + subPathExpr: fXC +test: + create: true +tolerations: +- key: mQ0 + operator: :罀倸三Ș儁岥őď;ȃ仂ȏwɂ定t + tolerationSeconds: -3767873578200433942 + value: OgC1 +- effect: \Į镌M9ʤ馑NdĹ孳ũ¨ + key: gpqxy + operator: ǻƸ瀥 + tolerationSeconds: -5203216359238986826 + value: TyP9PwIp +-- case-047 -- +auth: + sasl: + enabled: true + mechanism: EL + secretRef: 8qA + userName: "" +commonLabels: + YQJWn90y: CaduGS6 + ytV2tl: icxW +connectors: + additionalConfiguration: s + bootstrapServers: "" + brokerTLS: + ca: + secretNameOverwrite: REGD0a + secretRef: ZFEDD + cert: + secretNameOverwrite: aG9QIiXqg + secretRef: zrc5V + enabled: true + key: + secretNameOverwrite: D + secretRef: dtIKjx4fd0k + groupID: "" + producerBatchSize: 221474765 + producerLingerMS: -999496889 + restPort: 660248664 + schemaRegistryURL: W9TUtY + secretManager: + connectorsPrefix: "0" + consolePrefix: VMaz + enabled: false + region: T9 + storage: + remote: + read: + config: true + offset: false + status: true + write: + config: false + offset: false + status: true + replicationFactor: + config: 181733785 + offset: -551216099 + status: 894783312 + topic: + config: zpj + offset: s0 + status: e3Caq +container: + javaGCLogEnabled: zIkzV8Ox + resources: + javaMaxHeapSize: "0" + limits: + cpu: "0" + memory: "0" + request: + cpu: "0" + memory: "0" + securityContext: + allowPrivilegeEscalation: true +deployment: + annotations: + 1taGex8O: RBXE4 + A: uiKIoNCT + NtMz: b7Zk1GQ7 + budget: + maxUnavailable: -1503513883 + create: true + extraEnvFrom: + - configMapRef: + name: dx + optional: true + prefix: OgoO8WCa + secretRef: + optional: true + - configMapRef: + name: Kk + optional: false + prefix: 6Rdx + secretRef: + name: nM5Hn4S + optional: false + - configMapRef: + name: nQ + optional: true + prefix: z70 + secretRef: + name: C + optional: true + livenessProbe: + exec: {} + failureThreshold: -2044419963 + grpc: + port: 1294112857 + service: T3du6tMf + httpGet: + host: y3 + path: GnHrZ + port: glSjqG9 + scheme: 0軫頟似. + initialDelaySeconds: 888211900 + periodSeconds: -42722218 + successThreshold: 337318108 + terminationGracePeriodSeconds: -1562611613414558057 + timeoutSeconds: 1870975781 + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: ajGWX3E + operator: Ǫ囍 + values: + - HbIL2OUP + - q + matchFields: + - key: 453h + operator: DZƮìX莁Ǜ詍^屶K}豫ţoJ櫉 + values: + - h + - a4s + - key: Y1AE + operator: 4噸đƪǶS绲aģ序e$襫枠ÿ攒 + values: + - uVsu + weight: -280128439 + - preference: {} + weight: 46457932 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: [] + nodeSelector: + SFPTn: eN2 + podAffinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: L7t6 + operator: ʆa[穳w迂v + - key: "" + operator: 频弰t剼< + - key: T7uv4GBBUzUbG6 + operator: S鯉¸ń + weight: -1468638122 + - preference: + matchExpressions: + - key: h5w7 + operator: 癸āÞ + matchFields: + - key: uv + operator: º癲癇ɇ許ɠ/ȗ捪Ƭ#ʘ堅Ŧ + values: + - Cw0B + - BqrHb6 + weight: 907696087 + - preference: + matchExpressions: + - key: hojak + operator: 1坥矸挍嘧^ʗȆ箂ƅɯƴpȵ + weight: 1364801782 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: [] + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: pd8S + operator: uɝ?ɻZYƎ1Ǯʦ郬Dz + - key: DUO7i + operator: 谦`í + values: + - 6FwSwcs + - GN + matchLabels: + n6f8z: zXtgC + matchLabelKeys: + - Fnubc + - LA8QDbda + mismatchLabelKeys: + - qVxsEJ + - qE1yBoG + namespaceSelector: + matchExpressions: + - key: MrEWOI + operator: lZ7¹ɣkņl + values: + - U1nS9j70 + - yszBN8o + - neNbj2gZ + matchLabels: + 0hps: O + UgKJX: y1 + topologyKey: PMw0c + weight: -952955605 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: b5kCbI0z + operator: "" + values: + - tXLI + - key: KnIWiUw + operator: ǂ + values: + - kQ1Z + - 0QODSv + - MQSRMGsLu9 + matchLabelKeys: + - PA + - iYvDj + mismatchLabelKeys: + - o + - FrWVnE2CYwqd + - rT1 + namespaceSelector: {} + namespaces: + - rQgxNt + - pvhrsnC + topologyKey: GEeifY + weight: 1975729679 + - podAffinityTerm: + labelSelector: + matchLabels: + EVfT8M0: o + PxD: 79PJExTR + yA: TZecIw + matchLabelKeys: + - hdY1YQQRr + mismatchLabelKeys: + - cCPWUZy + namespaceSelector: + matchExpressions: + - key: "" + operator: 嬡媏9o茺SȥƗɯkQ蘓#邯ɑ叧ɵǁ + values: + - ou2ng + - AZY8 + - d6bB + - key: pgpk + operator: n:`ʂ + matchLabels: + ojwxs: 6GFt + namespaces: + - 88ER7b + - T + - SZ3 + topologyKey: MjN + weight: 540230312 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: Op + operator: Ň訹ʮXaG9酣敺ʞƪDŽ訯ɤ + - key: MHiaw0pSV + operator: ƋL(>Np賖ʙ + values: + - fj4sKVJws + - 4Iv + - key: O7pKHAO3pzP + operator: '%' + matchLabelKeys: + - eh93u + - gRYCx + mismatchLabelKeys: + - yy683S + namespaceSelector: + matchExpressions: + - key: 9h + operator: ıȖ飊蹯ƹ箰 + values: + - KNEG + - XdPWA + - mMvRH + - key: KTtr + operator: 觯hɪ + values: + - BcMH9NnOk + - h8ObHDc9P + matchLabels: + hT4lkum: En + sU73ic: NcW + namespaces: + - 4uQ4TMGRLt + topologyKey: 8vXEv + - labelSelector: + matchExpressions: + - key: "Y" + operator: ȅ鍼鿿$FƆnjǭ)ÿ + values: + - V2V + - key: Iz + operator: '>鱼狷趟`jCɨ*儚zkǀ柍ōÌ崉!ʥ' + matchLabels: + IM1GdEa: K3Ew + dCIEnPl73: bavvaL9ErI + s1b: ThqLOi4 + namespaceSelector: + matchExpressions: + - key: 8EKqCm + operator: ǝdz÷Ťʦ^創炲穡箃ťQ + values: + - ML + matchLabels: + PnWmWZ: odki1Yo + namespaces: + - k5I + - ncPcE + topologyKey: w4kt + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: Yj3M8wFy + operator: $<ȉ<ý暍Ě鰎3^ + values: + - eUG + - "y" + - x7 + - key: w9T3ut1T + operator: 販鳓ŕ莴傢Á礗Įǔ騦, + values: + - p6PWo + - 9j + - D5RQxUdU7 + - key: nCy5c + operator: ^-Yǫ4伴陜nk鋻歱峓sɡɂ + values: + - gB68BjwnCV + - L + - qBx3B + matchLabels: + vPL: i8KO + matchLabelKeys: + - wMm + - usVVmD + mismatchLabelKeys: + - u3k5X + - VUT71fj + namespaceSelector: + matchExpressions: + - key: V0iWHNZi + operator: "" + values: + - nUqA + - OZu9Dz + - key: x + operator: 屩lʞ敹 + matchLabels: + Rd: P8QK1 + cgd: YlfL4 + topologyKey: TBXmu4 + weight: 710078611 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: ymyCCU + operator: Q葿暩葆ɿÇ\ė3ʔ + values: + - SLrkpqf + matchLabels: + A5Y7aa: 2hDLZ + klIJgF: LOi6 + lO4xDpk6kTs: nSmQZErq + matchLabelKeys: + - ulCY + - V + - GZw7g + mismatchLabelKeys: + - zAmZ + - ko + namespaceSelector: {} + topologyKey: "" + - labelSelector: + matchExpressions: + - key: Z5F + operator: +寺厸|珑/ĸ) + values: + - LpjJqgfBG5F + - 2Cb3Y3c + - t2UCr + matchLabels: + 6FO: "" + mismatchLabelKeys: + - TQA1xK + - t8pbUmQd + - 8wO778bgDXR + namespaceSelector: + matchExpressions: + - key: oVEoNom + operator: ʊ椴審(@Ă.綂Ȱʔ3ǯʅ + - key: K7 + operator: 暎棽阽ɥ + - key: HWJwxOp + operator: 髋}Ƿɐ耷ì鄶#ǟu|Ť貘+6莠墙荜$ÿē裬葤 + - key: 4qGD7ZW + operator: y餟ƵÁɑǡ + values: + - I + - 8ihw + - "0" + matchLabels: + "": W7oExjz5 + Gc6: we5g + kwnNTF6H: AavRqArX + mismatchLabelKeys: + - bOwb + - bK + - ghihlm2Lhp + namespaceSelector: + matchExpressions: + - key: 6BDJ + operator: "" + - key: U9EAdB + operator: 鶜}C-[j丱螜Ȳ旕dƽɿ鞨ĠK+飵 + topologyKey: 6eQggF + podAntiAffinity: + custom: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + 7i: TbE + JXB5: J2fg + lLpX: 9AiEG4e + matchLabelKeys: + - Behe + - 1dGT2Z + - mZgjixI + mismatchLabelKeys: + - jIIXs + - Zl8X + namespaceSelector: + matchExpressions: + - key: Vlif1O + operator: ħ洱3;膲a + values: + - QalaoxQ06 + - 2lsIfdVFk + - WTKxi + - key: 6I + operator: RǨz + values: + - 7dOQ + - 9F00G + topologyKey: v0BKMpg + - labelSelector: + matchExpressions: + - key: Cxkv + operator: ɱƔ(I + values: + - JsYrlrlk + - "3" + - xCrG + - key: 0w + operator: xw + values: + - neE3 + - key: wdni + operator: )攁捙笶陯 + values: + - BTSUHf + - LRA + matchLabelKeys: + - 2Wmpf0XJ + namespaceSelector: + matchExpressions: + - key: cyu + operator: 潦c%f)v + values: + - ZmNo9Hc + - 4ec + - 8ptw + namespaces: + - M5GjE + - "" + topologyKey: V + topologyKey: "2" + type: JFBH9 + weight: 1888684498 + priorityClassName: Wg8Wu + progressDeadlineSeconds: -1524384619 + readinessProbe: + exec: + command: + - ogUapD + - JNor0OH + failureThreshold: -2099739674 + grpc: + port: 2056719693 + service: Nk8deyFml + httpGet: + host: qS + path: S6Cj2 + port: EeKCZ + scheme: ʅ鹒p + initialDelaySeconds: -359104350 + periodSeconds: 1897832932 + successThreshold: -962367820 + terminationGracePeriodSeconds: -5091110669039213167 + timeoutSeconds: -677019415 + restartPolicy: 爃ɥ90İĔ + revisionHistoryLimit: 1994939456 + schedulerName: i57b + securityContext: + fsGroup: 1520694499640274668 + fsGroupChangePolicy: 嫽Ǭ + runAsGroup: 3728458047896784619 + runAsNonRoot: false + runAsUser: -8957070032009944858 + sysctls: + - name: NBH + value: bXsgSc + - name: WTZnja + value: p4Du + strategy: + type: RDNEX8T + terminationGracePeriodSeconds: 1122010486 + topologySpreadConstraints: + - maxSkew: 2113683386 + topologyKey: H1AWsSn + whenUnsatisfiable: VEpgY + updateStrategy: + type: 6b7BSE +fullnameOverride: Bl0rL2 +imagePullSecrets: +- name: LGwi +logging: + level: b +monitoring: + annotations: + "": O + AFH4V: ga95qmjNhc + enabled: true + labels: + 9HWO7MGwhk: vGHnz6 + NNg3k: hbR + RXL: VxSIXgS + namespaceSelector: + any: true + matchNames: + - WZxK8iNK2gdU + scrapeInterval: -1823238h3m59.524888469s +nameOverride: wN +service: + annotations: + "": pZ + name: xW + ports: + - name: V + port: -1924603054 +serviceAccount: + annotations: + "": mNGwfCN + create: true + name: 3m +storage: + volume: + - name: Cm + - name: eHp5 + - name: r1T + volumeMounts: + - mountPath: 5aM + mountPropagation: Ěɲ'再ʖ|皑F9ĺOĆ|Oô + name: 2HGf2z + subPath: vuF7gt + subPathExpr: y6zTs2 + - mountPath: QU6 + mountPropagation: QǢx槱Sɼ湙Ȥ恑ñ鹒 + name: PbVBK + subPath: foAWHAo + subPathExpr: I8f + - mountPath: "" + mountPropagation: ƇNʆ¹¯檷AvdŜ踆ÿDȂ + name: cA + readOnly: true + subPath: y6Kasn + subPathExpr: DIUY0V +test: + create: true +tolerations: +- effect: 涏Ř + key: i6DqmjDv2K + operator: 钨{Õ\ʭQIɘʯIŸ + tolerationSeconds: -8713064626657727741 + value: fLHW9 +-- case-048 -- +auth: + sasl: + enabled: false + mechanism: Xr + secretRef: i5 + userName: aXR +commonLabels: + x3: e1lz +connectors: + additionalConfiguration: stdaxfP + bootstrapServers: fOZsu37vN + brokerTLS: + ca: + secretNameOverwrite: hln + secretRef: k5U1 + cert: + secretNameOverwrite: s47Hy + secretRef: ljqjD + enabled: true + key: + secretNameOverwrite: Wxw + secretRef: icjt + groupID: piupb6 + producerBatchSize: -1479166006 + producerLingerMS: -1816218257 + restPort: -2097692565 + schemaRegistryURL: xg4Cxakw + secretManager: + connectorsPrefix: KeHoy + consolePrefix: 1HcDE + enabled: false + region: snd + storage: + remote: + read: + config: false + offset: false + status: false + write: + config: true + offset: false + status: false + replicationFactor: + config: -103098671 + offset: 864522858 + status: -1797067435 + topic: + config: FBdy5 + offset: ytzBE0 + status: FHVut +container: + javaGCLogEnabled: Fu + resources: + javaMaxHeapSize: "0" + limits: + cpu: "0" + memory: "0" + request: + cpu: "0" + memory: "0" + securityContext: + allowPrivilegeEscalation: true +deployment: + budget: + maxUnavailable: 896500401 + create: true + extraEnvFrom: + - configMapRef: + name: w9vIEs + optional: true + prefix: oFWtF + secretRef: + name: Z1 + optional: true + - configMapRef: + name: 9wMxsz + optional: false + secretRef: + name: zLL2kR + optional: false + livenessProbe: + exec: {} + failureThreshold: 1532121771 + grpc: + port: 908100480 + service: P2AKgA6 + httpGet: + host: G1t + path: dTC5Sa + port: "" + scheme: 鷫w八ǤɩT÷3蔉ǰ*贝弔琎Î + initialDelaySeconds: -893256878 + periodSeconds: -674475842 + successThreshold: -1740698110 + terminationGracePeriodSeconds: 1865038295935824451 + timeoutSeconds: 326371790 + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: b + operator: 鷘泝, + values: + - 0N3rqLJ + - "4" + - 1L + matchFields: + - key: gnmK + operator: '@D煡摡o昪ɼ柤斕ɲı58,tț>' + values: + - i1 + - 5PqjZCTW + weight: -1104761106 + - preference: + matchExpressions: + - key: dT + operator: 犘ijň鉻ĴɳǁȨD + values: + - XdGct + - key: 2BYB + operator: '}閂譗輸礯Ʊx' + values: + - MU2j1Vu + - "17" + - key: ypgFjkuHHfzj + operator: '`4ʫfƗ8鲙華ė' + values: + - "y" + - LHvKvSZf2 + matchFields: + - key: GImX3 + operator: "" + values: + - xQPC + - R4R + - 3Y0mxG + weight: -521155604 + - preference: + matchExpressions: + - key: ft5L + operator: ȗ垁屹3瞬铵烱#祟渥 + matchFields: + - key: Fx + operator: ǷɂZ + values: + - WT + weight: 677594922 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: AwTQm2 + operator: 展ɏǀ襋k(ȴSǮ讶ʁ + values: + - 8i1 + - key: gQ1DB + operator: 汴F见Doĵw?Pc|昋階ʇ亸d灀麕ʞ + values: + - uqEzQKDpVw + - Q2 + - icCcpbp8 + - key: d9Z + operator: Ǽ船薲ɲĊbJĘƑƮOȄ鄹 + values: + - flK9jMt + - jt4 + - TSJ + - matchExpressions: + - key: Cf40pEWF + operator: ŌZ雯瘍 + values: + - "0" + - cSCIGvcwc + - Izvo0 + - key: mB4jp + operator: Í淙篝Hƨ_u误Ý + values: + - OTJJx + - KgWLC + - key: TxkO + operator: ȠȰsa'ʫƲ鑠 + values: + - 3gqlT + matchFields: + - key: l + operator: é糁v抯 + - key: QZFxqZ + operator: / + values: + - q0DJ + - M0 + - 6XMtos + - {} + nodeSelector: + DdMU: TvKI + cxzoe: "41" + i6KwA0A6qU1g: E6j + podAffinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: [] + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: 27Ay + operator: 効P禶Ƃ淑×_髉沎1g雺+ + values: + - rgEa + - d + - HhpA + - key: 1dPtPjTbh + operator: Ƿă麺 + values: + - b + matchLabelKeys: + - iEi952afuE + mismatchLabelKeys: + - O2Hto + namespaceSelector: + matchExpressions: + - key: kum0cz + operator: ɚ釣腅庆@\Ɂ檄6!G闎)īæʀŇ]璯 + values: + - "" + - 9FZmV7q + - vPK3 + - key: "" + operator: 堁əC峎&ŕDʣM'雐Ɉŗx + - key: G + operator: 'QjŌ:' + matchLabels: + BFPI4M: uzYC + MJLqR: z + namespaces: + - UX3IA3h5 + - 3Bds + - AKT9H + topologyKey: b3TODHaa + weight: -1228882596 + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: mc + operator: -V:7pƧʖò跪x©砚砰`ƨ茩钪Z敓 + values: + - wSITrxHTS9HZC3 + - CuIo6L6CDmUgu + - key: "" + operator: 媉跈铄堕Ŀ/{jň + values: + - jF3HYWqWEr7TR + matchLabels: + 4F5Kv: G00k + ctjZYe4x1uNh: gtkkPK + nTjG: pwyKCyJEv + matchLabelKeys: + - "" + - "4" + - "N" + namespaceSelector: + matchExpressions: + - key: LUJp + operator: Ū咄unjʢPXǘ憱朤Ű尙űb[灘勈Yȱ + values: + - 5Z3rbs2EdAE + - ZuP + - key: yiWkttM + operator: '`樞髨đķ姞XƃHɏ材ȝ:yĎ窘' + values: + - F + - Twn69 + - ji + - key: 4hLx + operator: bȷ + values: + - Ki + - kjWG9 + - c847VrQVN + matchLabels: + GhZu: 9T1Ai5 + namespaces: + - trsp + - eYMhJsX + topologyKey: d7QkCGS + weight: 579883095 + - podAffinityTerm: + labelSelector: + matchLabels: + "": BkvZx + 5Cl51conQ: "" + JIK0XU5wF: QpRIa + matchLabelKeys: + - rB + mismatchLabelKeys: + - 8FzxAzJeIit + - ZOQj0d + namespaceSelector: + matchLabels: + nP2HZf2eH: aUzmR3uuKY + namespaces: + - mF3O + topologyKey: QCmkc + weight: -1703667772 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: krwcqI + operator: '#:' + values: + - ibt + - t + - i9469 + matchLabels: + HT64Ybn3: KGLr3jpQ + LpfpVnOJf: 0rLjo + erYb3: 9lRqTXj4m + matchLabelKeys: + - 9p4 + mismatchLabelKeys: + - hzEmU + namespaceSelector: + matchExpressions: + - key: VL0 + operator: JX0ɅE拮Lsʚ茲]ʢ + values: + - Uymjw + - YCn + - ethVoHhJL + matchLabels: + "": t + topologyKey: ZFbEWa + podAntiAffinity: + custom: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + FkdFP8S: l47McZdSiw + matchLabelKeys: + - LVSg8I + - ZIbzqVPIrjF + - YWwSaAw87 + namespaceSelector: + matchExpressions: + - key: tlsDj + operator: 6Ȇ`3Ze伢qDȖ槑ȟł + - key: p + operator: 鈃'豕VĐ斆ȱ!ȃ?wqɇƬ + values: + - F + - key: RfCxe + operator: 轫Ê98叀疓}漢[D偆幕繋<Ò=峕ɀ + values: + - HDyJ9 + - 03Uzj4m + namespaces: + - Y6Ay + - 5rDS + topologyKey: sU + weight: -1397412749 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: qQcAm + operator: ç脣Èðɇ鄅ɯrʐǷœo4刋冉菣ʠ鰼 + values: + - LdQOKui + - key: oSZdMcc + operator: "0" + values: + - TX + - UZ5iQ + - JBYSo2 + matchLabels: + WArJvOMSNO: rgBzJ + iaBvi1H: B8up7I + x: i4F + matchLabelKeys: + - k7ML + - VR + - qtQ0dTf + mismatchLabelKeys: + - s7 + namespaceSelector: + matchExpressions: + - key: c7 + operator: ʋ\ɸ|ǖ炡utɜŦ"Kxh + - key: cpqDs + operator: ɽ鈶Ʈ¡ƽǨļɤ儧Ÿn}Ǝʞƛ史 + values: + - rCrj5wg + - SXZzoY + - key: ZNVtqG + operator: Ơ瑊ȼ+櫓'ɻýʯX´cƈkĺk6 + values: + - Gsw + namespaces: + - quffgHoEKxxO + topologyKey: iHNr + weight: -284270585 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: 4C + operator: 7zF脥Q:2僝jǑ + values: + - Uk + - key: 721gY + operator: C悺鹼岶狫ń±敛P煺\nŨ泞ǵ,ȣC菹 + values: + - r1k + - "1" + matchLabelKeys: + - g + - vDoU0BjC + mismatchLabelKeys: + - IrO + namespaceSelector: + matchLabels: + ONSj: 3Xh3NX + ONgggfk8t: DQxXyxu + wba4o3ae: Nl85N5 + topologyKey: mjD + weight: 960522068 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: 1su + operator: Ƕ + values: + - jxhj8g4 + matchLabels: + KTyQMh: sByLd + mismatchLabelKeys: + - "" + - 4jOv0EhQW + namespaceSelector: + matchExpressions: + - key: Wm + operator: BC螝Ħ耡±湡/宥趋ɑ瘖乶:汁彌 + values: + - n56fpGxrnr + - m + - 24OqIm + - key: wfDuGoF + operator: 瑺冐¥凖摶蝾b蚽嵷銱 + values: + - ooNGd + - 6G0GF + namespaces: + - ElrXceeDN + - EAtS23 + topologyKey: NLu0gTOn8p + - labelSelector: + matchExpressions: + - key: Eq8n + operator: "" + values: + - ZdBbrGxG + - ozepn + - p + matchLabels: + a: 5Nrk3 + matchLabelKeys: + - Z + - "4" + - 4W + mismatchLabelKeys: + - hBR76gl + - ZI8T + namespaceSelector: + matchExpressions: + - key: YfWOe + operator: "" + - key: F + operator: ;起ǣlʄ川Ɖýß歙懥瘵 + matchLabels: + kbHRw: "n" + topologyKey: Qk8l + topologyKey: rXnckz + type: d04GWjGpDQOK4K + weight: 2110708875 + priorityClassName: IKSxf + progressDeadlineSeconds: -1933689162 + readinessProbe: + exec: + command: + - 0XHj27GU + failureThreshold: -2100702858 + grpc: + port: -426293371 + service: JTK0kP + httpGet: + host: QPoQbZ9 + path: PxIHuC3 + port: dY + scheme: ʏÞ荻a鎘ʇ塜H唽×ʃ刉 + initialDelaySeconds: 1930411693 + periodSeconds: 1985310483 + successThreshold: 769125679 + terminationGracePeriodSeconds: -4123472799765155241 + timeoutSeconds: -1364329005 + restartPolicy: À潌貛ă貈懍Eŵɀȩ + revisionHistoryLimit: -1768466640 + schedulerName: RMki + securityContext: + fsGroup: -3162007349665636938 + fsGroupChangePolicy: F@AǶvĭȟū琐噌黣坩Ǚɮŀ + runAsGroup: 164107928150233301 + runAsNonRoot: false + runAsUser: -6374867922909642928 + strategy: + type: OMXfGqbFsWh + terminationGracePeriodSeconds: 1025063088 + tolerations: + - effect: ƸL諟Hv餣A嶌ɣYƵ轝脡sT酉 + key: rvPW78A + tolerationSeconds: 2277475321707653696 + value: zmQU7sY + - effect: 瘅1Ʉ夆 + key: 0p + operator: 冂÷s廥肚Zj陎1aÚkĤɀǟR + tolerationSeconds: 1191004605682561615 + value: sZcoDHahsR79 + topologySpreadConstraints: + - maxSkew: -1723926017 + topologyKey: KnB17 + whenUnsatisfiable: WpP6r0 + updateStrategy: + type: 56m +fullnameOverride: xPmln +imagePullSecrets: +- name: P0 +- name: AoBx4D0STGS8Z +logging: + level: QSl3 +monitoring: + annotations: + Ph: jqBcTVUZf6Q + bphXvWC: RZuPl1 + wrQkm: whQu3 + enabled: false + labels: + WGbtca: qquyS56V2v5 + dBJC: qNJ + hO: Mv5VfzUC + namespaceSelector: {} + scrapeInterval: 856582h27m40.130242944s +nameOverride: r7G +service: + name: w4DG +serviceAccount: + annotations: + 6tv5saOxoc: 6xq4 + EMXt4yV: 6g0eIa7vAQ3 + Nv: 2r + create: false + name: YIo +storage: + volume: + - name: I0 + volumeMounts: + - mountPath: FgUy2D + mountPropagation: ül幯wȅƑʀ,姅 + name: kUw2 + subPath: D0Qb + subPathExpr: EemIo6uDnv0 + - mountPath: r + mountPropagation: 剐ƥ<¶抿菋ɯ粦梘ȡ( + name: 15LL4 + readOnly: true + subPath: tcGS + subPathExpr: pwB + - mountPath: aC8MZYmVC + mountPropagation: ʢǮZ薽R擽ē1Xȭ硡衕卣A礖XÚY2 + name: "9" + subPath: qg + subPathExpr: cPz1rA +test: + create: false +tolerations: +- effect: S爨5p皳衷ƖE + key: htSQi8X + operator: 枦悬Ɵ洌?峎 + tolerationSeconds: -3814415431062878896 + value: Rbg +-- case-049 -- +auth: + sasl: + enabled: true + mechanism: lZOXaE + secretRef: YOdINi + userName: BXFWsRQboaO4 +commonLabels: + AxgO: ie + a: xGJKP + wy9DijfF9: pY +connectors: + additionalConfiguration: q9c + bootstrapServers: IgVAbq38dU + brokerTLS: + ca: + secretNameOverwrite: kYnXvq + secretRef: IvgqIPUbzG + cert: + secretNameOverwrite: 7JbcQ + secretRef: buOno + enabled: true + key: + secretNameOverwrite: 20O + secretRef: 6hz5McyLWN + groupID: Wk7p7aNJ + producerBatchSize: 2121357080 + producerLingerMS: 2074731749 + restPort: -447671166 + schemaRegistryURL: 6N0Bmg4 + secretManager: + connectorsPrefix: x7I5NRn + consolePrefix: eDG + enabled: false + region: SkMqmYBpLtPJj + storage: + remote: + read: + config: false + offset: false + status: true + write: + config: true + offset: true + status: true + replicationFactor: + config: 1354970349 + offset: -471311251 + status: 1502440377 + topic: + config: D1lY + offset: O1OSNfw8U87 + status: GPw +container: + javaGCLogEnabled: s4ggDHmuiTC + resources: + javaMaxHeapSize: "0" + limits: + cpu: "0" + memory: "0" + request: + cpu: "0" + memory: "0" + securityContext: + allowPrivilegeEscalation: false +deployment: + budget: + maxUnavailable: -372928360 + create: false + extraEnv: + - name: FW + value: 5RU04xp + valueFrom: + configMapKeyRef: + key: 7nxdup + name: tnQpS3Y01 + optional: false + fieldRef: + apiVersion: eNiNGSSDL + fieldPath: 5119g + resourceFieldRef: + containerName: 4D + divisor: "0" + resource: 7O + secretKeyRef: + key: RERK + name: jtlhC8sfN + optional: true + - name: K3Z5 + value: v + valueFrom: + configMapKeyRef: + key: 5yl + name: J9LMEohiq + optional: false + fieldRef: + apiVersion: wbFQyoK4 + fieldPath: GL6kNJ + resourceFieldRef: + containerName: Xy2OPZ2 + divisor: "0" + resource: w + secretKeyRef: + key: 70As + name: PIR8cXF + optional: false + - name: TvqBj3M9 + value: n5DeWNx + valueFrom: + configMapKeyRef: + key: A3J + name: HC + optional: false + fieldRef: + apiVersion: 7vcn + fieldPath: NVb + resourceFieldRef: + containerName: Kw5PS + divisor: "0" + resource: M + secretKeyRef: + key: exITv + name: 6BCCh + optional: false + extraEnvFrom: + - configMapRef: + name: mKhZU + optional: false + prefix: 7r + secretRef: + name: 4dK + optional: false + - configMapRef: + name: N7 + optional: true + prefix: v8lf + secretRef: + name: Rmh + optional: true + livenessProbe: + exec: + command: + - Cx + - J87G2o + failureThreshold: 781863739 + grpc: + port: -1245485251 + service: Rea6qLZtf + httpGet: + host: m + path: 81qOdO8W + port: 2000006026 + scheme: 0觇瓄ȗ-狐´Ǝ酤ƆjĴȘ梟 + initialDelaySeconds: -845959215 + periodSeconds: 968971981 + successThreshold: -1102843833 + terminationGracePeriodSeconds: -9135098607736928416 + timeoutSeconds: -1624177358 + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: M2 + operator: ?ʪv椾ɛŵR{昂 + values: + - VijxsIC + - Z + - ccgUy6X4 + - key: Hyr7Bi + operator: 糪鄖藸*ɭ + values: + - qX9fMe + - key: SGTnNAR9 + operator: tđ鑨aɰ@Gȧ匈瑴駳ʨ譄ř顲IJ蓡"餛 + values: + - XGZRPQ + - HvYW + - SJm + matchFields: + - key: OeW + operator: z顡àP賤曑^ȴQ@蝂ź斁棈玔ʯ% + values: + - ml + - 4O7U + - wQ4YJ36 + - matchExpressions: + - key: Lya + operator: 潲pƏ黇稖4 + values: + - jC9 + - F + matchFields: + - key: Ynazf + operator: 6u閄甚 + values: + - 4qKPH + - key: hqS6 + operator: ¤W瑨ǀ螛觴囻 + values: + - ZFA3 + - O5sJmCwV + - key: Qf8jOwRnP + operator: ~I鳥撢禽殪yȿ嗍-芠ǒY`唞 + values: + - Jx4jV5qM + - PDQTY + nodeSelector: + dduQyGRf: 7nwg + podAffinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: A + operator: qnjü熂¤}ðÅŧ@蕑 + values: + - 6vy + - rl4UI + - FFXR + matchFields: + - key: YHp0vUR + operator: Ggɱ棁 + - key: UgkXI + operator: mn<#ɠ铑k趴ǟ韝 + values: + - 5JJK + - key: oTJ8B + operator: ȡ拳řɒW阾u掠鄗懓j9[唊ȱ + values: + - yb3 + - 2YZE2W0 + - L + weight: -1083324198 + - preference: + matchExpressions: + - key: OTNrwf + operator: ö议昇ŁüC + values: + - WLOo + - vs0cZ0R + - Khhase + weight: -711215427 + - preference: {} + weight: -1613072214 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: [] + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: gVZf + operator: _逋 + values: + - JzYY + - ywDxP1 + matchLabels: + Xegma69PO3houPR: Rmbc + d: MlcH4i7 + matchLabelKeys: + - K + - f + - rhU2t + mismatchLabelKeys: + - van87 + - 0ZYdEF5 + namespaceSelector: {} + namespaces: + - P8O + topologyKey: 1NGe + weight: 569962286 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: BeFIzF + operator: Ĝɿē + - key: Rvo6WB + operator: ʊ候ɥÂ漦靿Nj搘溦恱徒,ɴɜĿ怀Õ8貐 + values: + - PBaiU + - key: knGp2I + operator: Ǩ鄧^&膽s硢üf厵¸Ŧ錨譖梑*屟 + values: + - Nbn6I + matchLabels: + 0fc: HuJvN + 9tYU: 88OR4d2 + WR5Fy: lfBGVZo + matchLabelKeys: + - WukVD + mismatchLabelKeys: + - Vx + - BtHH + - dajjlO + namespaceSelector: + matchExpressions: + - key: t + operator: ']XFȁ窔示ʛ' + matchLabels: + 4Qh1x8JGl: Ex + 4hLpox: VP1 + gV0AjuaYC: aUwAN + namespaces: + - p + topologyKey: CM + weight: -1434839877 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: {} + matchLabelKeys: + - 3Ss + mismatchLabelKeys: + - fobV + namespaceSelector: + matchExpressions: + - key: X0rcjmbG + operator: 聹璴ɒ轢ąG箽Ɗş + values: + - 8ghV9wL + matchLabels: + 03NYmC8: "N" + H0mvdY: iy8ac + namespaces: + - C6sd7 + - F6FE + - 9W4PbMcZ + topologyKey: G4eB + - labelSelector: + matchExpressions: + - key: sNU + operator: dYC + values: + - YQaiV + - key: Pua + operator: ɸnŔ摔岖nǏȚȂ昗 + values: + - YpXB37PnW + - f2 + - MM + - key: DxVCz6I2x + operator: 埸爻 + values: + - Hm2CX + matchLabels: + sD0FFW: DLDqfI + matchLabelKeys: + - 1ZijjM + - bMD + - wKDup + namespaceSelector: + matchExpressions: + - key: h + operator: 蠺¾l拏|GȎ俴|~嶻屶À 9攑mʏC + values: + - lt1f + - Rx6 + - z + namespaces: + - vXafQDN + topologyKey: "" + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + R: xf6sJsIR2 + XRGK: HU40WMP2tH + matchLabelKeys: + - kZ9w2o + - C9lRMoB80Kf + mismatchLabelKeys: + - 5Q + namespaceSelector: + matchLabels: + lBX7: deB6Qg + namespaces: + - EZQJcE + - agIqApffRAjm + - hNChs7M + topologyKey: y6 + weight: 310831703 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: LG + operator: 寭Z踸賟ð蔄lǦÏ徫*柝RŒĕă都 + values: + - Ia3H + - pGJa9 + - key: PLHavnryhJ + operator: čʬȰ呰vʤ涜Â擁隨鄡u評ƚ鼷Ō"ǩ¦ + values: + - VurUeIEAI + matchLabelKeys: + - "" + - fKBu + mismatchLabelKeys: + - L1 + - eG155Q + namespaceSelector: + matchLabels: + RYjDmg9L: S08IW6cHa + topologyKey: bIA8oKUvNZ + weight: -980786377 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: Vdtt + operator: ƃ摰Ǹc茜颭ƅ{ɘ侼ȅ.ġ + values: + - GY + - IL + - e82zQBv8 + matchLabels: + LCyGc: 7onELXh4E + r3: 3jFJ + s: 2JH8 + matchLabelKeys: + - ett + - e + - CBNjUaCu + mismatchLabelKeys: + - gOfT + - H8q + namespaceSelector: + matchLabels: + "": wpC + oKw8pdan7Q0: dLiDRyH + namespaces: + - qw + - Rm1a1x + - kjfaf + topologyKey: guuynpKQ9lV8 + weight: -1608829726 + podAntiAffinity: + custom: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: s + operator: ɠ襱Ȣʅ鶌脸ĕŎ鋃澣'Ɵɡ舩V÷ë4 + values: + - "" + - RdE4 + - IwoP349d + - key: K8OuT + operator: Wʼn + namespaceSelector: + matchExpressions: + - key: F + operator: ɆƂr嗫nÈÚ7{ƴ视ƺ覵ʋŬƛ + values: + - CKicU4 + - QtnR1mf + namespaces: + - JZ + - 9j60y + - VdjQ + topologyKey: V79Fc + weight: 1058838095 + - podAffinityTerm: + labelSelector: + matchLabels: + IhQLO3: k0ZI08 + phsC: hrahrRruQ + matchLabelKeys: + - rCSflQW + namespaceSelector: + matchExpressions: + - key: kcxL + operator: Į + values: + - NCGT + matchLabels: + 3tPhW: yFH6u + 4PB1z: cjQ28Es3I + topologyKey: s50 + weight: 2003899640 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: t + operator: 菠_Ɩ-ĉ垝ʮ + values: + - 2yD6SK7sQNyQ + - key: s1 + operator: 衙鵇ȔºɢG枬涕L$k賽Ö + values: + - xR + - ItozQOJu + matchLabels: + 8rP96Bm: gRg8miP + Gop: LnoRl + matchLabelKeys: + - asNzX03 + - UQz + namespaceSelector: + matchExpressions: + - key: tlFJgp + operator: 翺$ȵ硽dzXȷ鿁aȐG + values: + - yCG5CU + - key: ezfpbDKj36Qk + operator: ?盉剴痐èěȆ倒f^ + namespaces: + - C + - BWSk + topologyKey: NRyT + weight: -1887589 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: VqAEfS9 + operator: 'š勐§2äƇ镧 ' + values: + - zAiR + - MAdfP + - u + namespaceSelector: + matchExpressions: + - key: bss + operator: 龌ɒRuĖXʃĹę琴 + values: + - fYA3 + - 3nOKAD + - CIt5uEowlBLQ1 + matchLabels: + 8ZPfixhDT2u: NhaXnN + 9m0: A1gs2 + GXhMHUyy: KmKI + namespaces: + - W + - BrU0P3 + - "" + topologyKey: PxOw + topologyKey: B + type: 0ZYR + weight: -1306525291 + priorityClassName: m3Ex + progressDeadlineSeconds: -1434788483 + readinessProbe: + exec: + command: + - MNs0Ba + failureThreshold: 584818346 + grpc: + port: 321294336 + service: "" + httpGet: + host: 7VJXwz + path: 1ygxm + port: Dcl8Z8 + scheme: 慲ė鼔ƀ + initialDelaySeconds: 1026532597 + periodSeconds: 1489595355 + successThreshold: 1696560908 + terminationGracePeriodSeconds: -4249833353592859621 + timeoutSeconds: -147660350 + restartPolicy: Y2dɪ赥ȡěȫ + revisionHistoryLimit: 529570324 + schedulerName: mzo86Jb + securityContext: + fsGroup: -2777096360811827600 + fsGroupChangePolicy: ǑȽ劐2$t剭赖' + runAsGroup: -8516502997065582904 + runAsNonRoot: true + runAsUser: 4444001915347831322 + supplementalGroups: + - -713783482271938969 + - -1237716613088890768 + - -3929371009074647393 + sysctls: + - name: xlxKwO + value: mVa0Vk + - name: Pe + value: ggm6uD4s5 + strategy: + type: 1Y + terminationGracePeriodSeconds: -1036531185 + tolerations: + - effect: ƨU;È性ǯ9ƝZ軷ĖĀ<猀Ħ瑍ş + key: hrn + operator: 駾G + tolerationSeconds: -5689841415932882459 + value: 7wGF139wPxrS + topologySpreadConstraints: + - maxSkew: 2056579760 + topologyKey: 3Vxn0PFD + whenUnsatisfiable: Zd + - maxSkew: -1862577769 + topologyKey: 0ifTRZ + whenUnsatisfiable: ovqoS + updateStrategy: + type: nlatLA +fullnameOverride: fubwSl +logging: + level: 4GjwwD +monitoring: + annotations: + dn7: Ed1FfDz + uj8: fVksEAUZ + enabled: false + labels: + OuMMzK: U + u67Epbv: bs83 + namespaceSelector: + matchNames: + - YfURCd + - pjn + scrapeInterval: -1243725h11m11.812387569s +nameOverride: pyCdF +service: + annotations: + uH: o + name: 37ihe +serviceAccount: + annotations: + "": 0h6QKRWo + ayiUDPgwgG9: Wh + create: true + name: zr1OY +storage: + volume: + - name: VzP + - name: B2c9ZE + volumeMounts: + - mountPath: H + mountPropagation: 繹Ó!矃oǷ;ŞV佬bĨ`惽鬾 + name: Pv + readOnly: true + subPath: ayluKt + subPathExpr: WSAQj + - mountPath: aJ + mountPropagation: '*灡毑Ŭĩ凭xʂ閪' + name: WOCY + readOnly: true + subPath: U3AsYVGQTA + subPathExpr: oS2EoO7q5 +test: + create: true +tolerations: +- effect: 灊ƌň + key: m4LJ7 + operator: ȁ溥洡Âƴ蘐ǎĽ懋冝幼埍Ré + tolerationSeconds: -5062975468014163162 + value: zvAp +- effect: 渊M璄劮椆 + key: AhabI + operator: ʀǏ3亚O + tolerationSeconds: -4592469483950966275 + value: "07" +- effect: 嶝¹総| + key: CAi + operator: s咴 + tolerationSeconds: -3369184239394783815 + value: n5 diff --git a/charts/redpanda/redpanda/5.9.2/charts/connectors/testdata/template-cases.golden.txtar b/charts/redpanda/redpanda/5.9.2/charts/connectors/testdata/template-cases.golden.txtar new file mode 100644 index 0000000000..d483171c80 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/connectors/testdata/template-cases.golden.txtar @@ -0,0 +1,10301 @@ +-- testdata/case-000.yaml.golden -- +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: pO5m + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: pO5m + helm.sh/chart: connectors-0.1.12 + name: rpVz +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: 8083 + protocol: TCP + targetPort: 8083 + - name: prometheus + port: 9404 + protocol: TCP + targetPort: 9404 + selector: + app.kubernetes.io/component: pO5m + app.kubernetes.io/instance: console + app.kubernetes.io/name: pO5m + sessionAffinity: None + type: ClusterIP +--- +# Source: connectors/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: pO5m + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: pO5m + helm.sh/chart: connectors-0.1.12 + name: rpVz +spec: + progressDeadlineSeconds: 600 + replicas: null + revisionHistoryLimit: 10 + selector: + matchLabels: + app.kubernetes.io/component: pO5m + app.kubernetes.io/instance: console + app.kubernetes.io/name: pO5m + strategy: + type: RollingUpdate + template: + metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/component: pO5m + app.kubernetes.io/instance: console + app.kubernetes.io/name: pO5m + spec: + affinity: + nodeAffinity: {} + podAffinity: {} + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: pO5m + app.kubernetes.io/instance: console + app.kubernetes.io/name: pO5m + namespaces: + - default + topologyKey: kubernetes.io/hostname + containers: + - command: null + env: + - name: CONNECT_CONFIGURATION + value: |- + rest.advertised.port=8083 + rest.port=8083 + key.converter=org.apache.kafka.connect.converters.ByteArrayConverter + value.converter=org.apache.kafka.connect.converters.ByteArrayConverter + group.id=connectors-cluster + offset.storage.topic=_internal_connectors_offsets + config.storage.topic=_internal_connectors_configs + status.storage.topic=_internal_connectors_status + offset.storage.redpanda.remote.read=false + offset.storage.redpanda.remote.write=false + config.storage.redpanda.remote.read=false + config.storage.redpanda.remote.write=false + status.storage.redpanda.remote.read=false + status.storage.redpanda.remote.write=false + offset.storage.replication.factor=-1 + config.storage.replication.factor=-1 + status.storage.replication.factor=-1 + producer.linger.ms=1 + producer.batch.size=131072 + config.providers=file,secretsManager,env + config.providers.file.class=org.apache.kafka.common.config.provider.FileConfigProvider + config.providers.env.class=org.apache.kafka.common.config.provider.EnvVarConfigProvider + - name: CONNECT_ADDITIONAL_CONFIGURATION + value: "" + - name: CONNECT_BOOTSTRAP_SERVERS + value: "" + - name: CONNECT_GC_LOG_ENABLED + value: "false" + - name: CONNECT_HEAP_OPTS + value: -Xms256M -Xmx2G + - name: CONNECT_LOG_LEVEL + value: 0rksB2 + - name: CONNECT_TLS_ENABLED + value: "false" + envFrom: [] + image: docker.redpanda.com/redpandadata/connectors:v1.0.29 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: rest-api + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: connectors-cluster + ports: + - containerPort: 8083 + name: rest-api + protocol: TCP + - containerPort: 9404 + name: prometheus + protocol: TCP + readinessProbe: + failureThreshold: 2 + httpGet: + path: /connectors + port: rest-api + scheme: HTTP + initialDelaySeconds: 60 + periodSeconds: 10 + successThreshold: 3 + timeoutSeconds: 5 + resources: + limits: + cpu: "1" + memory: 2350Mi + requests: + cpu: "1" + memory: 2350Mi + securityContext: + allowPrivilegeEscalation: false + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /tmp + name: rp-connect-tmp + dnsPolicy: ClusterFirst + imagePullSecrets: + - name: "Y" + - name: oCy + - name: M + nodeSelector: {} + restartPolicy: Always + schedulerName: "" + securityContext: + fsGroup: 101 + fsGroupChangePolicy: OnRootMismatch + runAsUser: 101 + serviceAccountName: default + terminationGracePeriodSeconds: 30 + tolerations: [] + topologySpreadConstraints: + - labelSelector: + matchLabels: + app.kubernetes.io/component: pO5m + app.kubernetes.io/instance: console + app.kubernetes.io/name: pO5m + maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: ScheduleAnyway + volumes: + - emptyDir: + medium: Memory + sizeLimit: 5Mi + name: rp-connect-tmp +--- +# Source: connectors/templates/pod-monitor.yaml +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + annotations: {} + creationTimestamp: null + labels: + 5Fm2d5: 8GfL + HhgyOa: "1" + L9qHqt6R: LhlwQrUay + name: rpVz +spec: + namespaceSelector: + any: true + podMetricsEndpoints: + - bearerTokenSecret: + key: "" + path: / + port: prometheus + selector: + matchLabels: + app.kubernetes.io/component: pO5m + app.kubernetes.io/instance: console + app.kubernetes.io/name: pO5m +-- testdata/case-001.yaml.golden -- +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: nZ + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: nZ + helm.sh/chart: connectors-0.1.12 + name: 5wkC +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: 8083 + protocol: TCP + targetPort: 8083 + - name: prometheus + port: 9404 + protocol: TCP + targetPort: 9404 + selector: + app.kubernetes.io/component: nZ + app.kubernetes.io/instance: console + app.kubernetes.io/name: nZ + sessionAffinity: None + type: ClusterIP +--- +# Source: connectors/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: nZ + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: nZ + helm.sh/chart: connectors-0.1.12 + name: WtC +spec: + progressDeadlineSeconds: 600 + replicas: null + revisionHistoryLimit: 10 + selector: + matchLabels: + app.kubernetes.io/component: nZ + app.kubernetes.io/instance: console + app.kubernetes.io/name: nZ + strategy: + type: RollingUpdate + template: + metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/component: nZ + app.kubernetes.io/instance: console + app.kubernetes.io/name: nZ + spec: + affinity: + nodeAffinity: {} + podAffinity: {} + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: nZ + app.kubernetes.io/instance: console + app.kubernetes.io/name: nZ + namespaces: + - default + topologyKey: kubernetes.io/hostname + containers: + - command: null + env: + - name: CONNECT_CONFIGURATION + value: |- + rest.advertised.port=8083 + rest.port=8083 + key.converter=org.apache.kafka.connect.converters.ByteArrayConverter + value.converter=org.apache.kafka.connect.converters.ByteArrayConverter + group.id=connectors-cluster + offset.storage.topic=_internal_connectors_offsets + config.storage.topic=_internal_connectors_configs + status.storage.topic=_internal_connectors_status + offset.storage.redpanda.remote.read=false + offset.storage.redpanda.remote.write=false + config.storage.redpanda.remote.read=false + config.storage.redpanda.remote.write=false + status.storage.redpanda.remote.read=false + status.storage.redpanda.remote.write=false + offset.storage.replication.factor=-1 + config.storage.replication.factor=-1 + status.storage.replication.factor=-1 + producer.linger.ms=1 + producer.batch.size=131072 + config.providers=file,secretsManager,env + config.providers.file.class=org.apache.kafka.common.config.provider.FileConfigProvider + config.providers.env.class=org.apache.kafka.common.config.provider.EnvVarConfigProvider + - name: CONNECT_ADDITIONAL_CONFIGURATION + value: "" + - name: CONNECT_BOOTSTRAP_SERVERS + value: "" + - name: CONNECT_GC_LOG_ENABLED + value: t1lDqf0PT8Xy + - name: CONNECT_HEAP_OPTS + value: -Xms256M -Xmx2G + - name: CONNECT_LOG_LEVEL + value: warn + - name: CONNECT_TLS_ENABLED + value: "false" + envFrom: [] + image: docker.redpanda.com/redpandadata/connectors:v1.0.29 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: rest-api + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: connectors-cluster + ports: + - containerPort: 8083 + name: rest-api + protocol: TCP + - containerPort: 9404 + name: prometheus + protocol: TCP + readinessProbe: + failureThreshold: 2 + httpGet: + path: /connectors + port: rest-api + scheme: HTTP + initialDelaySeconds: 60 + periodSeconds: 10 + successThreshold: 3 + timeoutSeconds: 5 + resources: + limits: + cpu: "1" + memory: 2350Mi + requests: + cpu: "1" + memory: 2350Mi + securityContext: + allowPrivilegeEscalation: false + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /tmp + name: rp-connect-tmp + dnsPolicy: ClusterFirst + imagePullSecrets: [] + nodeSelector: {} + restartPolicy: Always + schedulerName: "" + securityContext: + fsGroup: 101 + fsGroupChangePolicy: OnRootMismatch + runAsUser: 101 + serviceAccountName: default + terminationGracePeriodSeconds: 30 + tolerations: [] + topologySpreadConstraints: + - labelSelector: + matchLabels: + app.kubernetes.io/component: nZ + app.kubernetes.io/instance: console + app.kubernetes.io/name: nZ + maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: ScheduleAnyway + volumes: + - emptyDir: + medium: Memory + sizeLimit: 5Mi + name: rp-connect-tmp +-- testdata/case-002.yaml.golden -- +--- +# Source: connectors/templates/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + annotations: + gM: gxAdfFrD + creationTimestamp: null + labels: + app.kubernetes.io/component: ZZ5 + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: ZZ5 + helm.sh/chart: connectors-0.1.12 + name: AN + namespace: default +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: ZZ5 + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: ZZ5 + helm.sh/chart: connectors-0.1.12 + name: xp6vcIlb +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: 8083 + protocol: TCP + targetPort: 8083 + - name: prometheus + port: 9404 + protocol: TCP + targetPort: 9404 + selector: + app.kubernetes.io/component: ZZ5 + app.kubernetes.io/instance: console + app.kubernetes.io/name: ZZ5 + sessionAffinity: None + type: ClusterIP +--- +# Source: connectors/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: ZZ5 + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: ZZ5 + helm.sh/chart: connectors-0.1.12 + name: xp6vcIlb +spec: + progressDeadlineSeconds: 600 + replicas: null + revisionHistoryLimit: 10 + selector: + matchLabels: + app.kubernetes.io/component: ZZ5 + app.kubernetes.io/instance: console + app.kubernetes.io/name: ZZ5 + strategy: + type: RollingUpdate + template: + metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/component: ZZ5 + app.kubernetes.io/instance: console + app.kubernetes.io/name: ZZ5 + spec: + affinity: + nodeAffinity: {} + podAffinity: {} + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: ZZ5 + app.kubernetes.io/instance: console + app.kubernetes.io/name: ZZ5 + namespaces: + - default + topologyKey: kubernetes.io/hostname + containers: + - command: null + env: + - name: CONNECT_CONFIGURATION + value: |- + rest.advertised.port=8083 + rest.port=8083 + key.converter=org.apache.kafka.connect.converters.ByteArrayConverter + value.converter=org.apache.kafka.connect.converters.ByteArrayConverter + group.id=connectors-cluster + offset.storage.topic=_internal_connectors_offsets + config.storage.topic=_internal_connectors_configs + status.storage.topic=_internal_connectors_status + offset.storage.redpanda.remote.read=false + offset.storage.redpanda.remote.write=false + config.storage.redpanda.remote.read=false + config.storage.redpanda.remote.write=false + status.storage.redpanda.remote.read=false + status.storage.redpanda.remote.write=false + offset.storage.replication.factor=-1 + config.storage.replication.factor=-1 + status.storage.replication.factor=-1 + producer.linger.ms=1 + producer.batch.size=131072 + config.providers=file,secretsManager,env + config.providers.file.class=org.apache.kafka.common.config.provider.FileConfigProvider + config.providers.env.class=org.apache.kafka.common.config.provider.EnvVarConfigProvider + - name: CONNECT_ADDITIONAL_CONFIGURATION + value: "" + - name: CONNECT_BOOTSTRAP_SERVERS + value: "" + - name: CONNECT_GC_LOG_ENABLED + value: YUlcy4 + - name: CONNECT_HEAP_OPTS + value: -Xms256M -Xmx2G + - name: CONNECT_LOG_LEVEL + value: warn + - name: CONNECT_TLS_ENABLED + value: "false" + envFrom: [] + image: docker.redpanda.com/redpandadata/connectors:v1.0.29 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: rest-api + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: connectors-cluster + ports: + - containerPort: 8083 + name: rest-api + protocol: TCP + - containerPort: 9404 + name: prometheus + protocol: TCP + readinessProbe: + failureThreshold: 2 + httpGet: + path: /connectors + port: rest-api + scheme: HTTP + initialDelaySeconds: 60 + periodSeconds: 10 + successThreshold: 3 + timeoutSeconds: 5 + resources: + limits: + cpu: "1" + memory: 2350Mi + requests: + cpu: "1" + memory: 2350Mi + securityContext: + allowPrivilegeEscalation: false + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: hVlmCfXmla + mountPropagation: ÇƭȊ餧鵣鋚蕛ʖ诂瑧)ɍĿ8šȪ轭ʌ倈 + name: 482T + readOnly: true + subPath: Un28M + subPathExpr: weDK9jo + - mountPath: YWN6OS + name: 5ijm8 + subPath: safiSmZ + - mountPath: MBW5 + name: ibiELmf2 + readOnly: true + subPath: E + subPathExpr: piX + dnsPolicy: ClusterFirst + imagePullSecrets: + - name: Tm0bmByz + - name: gSGPB + - name: 58yP + nodeSelector: {} + restartPolicy: Always + schedulerName: "" + securityContext: + fsGroup: 101 + fsGroupChangePolicy: OnRootMismatch + runAsUser: 101 + serviceAccountName: AN + terminationGracePeriodSeconds: 30 + tolerations: [] + topologySpreadConstraints: + - labelSelector: + matchLabels: + app.kubernetes.io/component: ZZ5 + app.kubernetes.io/instance: console + app.kubernetes.io/name: ZZ5 + maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: ScheduleAnyway + volumes: + - name: AhJ +-- testdata/case-003.yaml.golden -- +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: Wvpgs + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: Wvpgs + helm.sh/chart: connectors-0.1.12 + name: kNrkCdEuw9V +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: 8083 + protocol: TCP + targetPort: 8083 + - name: prometheus + port: 9404 + protocol: TCP + targetPort: 9404 + selector: + app.kubernetes.io/component: Wvpgs + app.kubernetes.io/instance: console + app.kubernetes.io/name: Wvpgs + sessionAffinity: None + type: ClusterIP +--- +# Source: connectors/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: Wvpgs + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: Wvpgs + helm.sh/chart: connectors-0.1.12 + name: kNrkCdEuw9V +spec: + progressDeadlineSeconds: 600 + replicas: null + revisionHistoryLimit: 10 + selector: + matchLabels: + app.kubernetes.io/component: Wvpgs + app.kubernetes.io/instance: console + app.kubernetes.io/name: Wvpgs + strategy: + type: RollingUpdate + template: + metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/component: Wvpgs + app.kubernetes.io/instance: console + app.kubernetes.io/name: Wvpgs + spec: + affinity: + nodeAffinity: {} + podAffinity: {} + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: Wvpgs + app.kubernetes.io/instance: console + app.kubernetes.io/name: Wvpgs + namespaces: + - default + topologyKey: kubernetes.io/hostname + containers: + - command: null + env: + - name: CONNECT_CONFIGURATION + value: |- + rest.advertised.port=8083 + rest.port=8083 + key.converter=org.apache.kafka.connect.converters.ByteArrayConverter + value.converter=org.apache.kafka.connect.converters.ByteArrayConverter + group.id=connectors-cluster + offset.storage.topic=_internal_connectors_offsets + config.storage.topic=_internal_connectors_configs + status.storage.topic=_internal_connectors_status + offset.storage.redpanda.remote.read=false + offset.storage.redpanda.remote.write=false + config.storage.redpanda.remote.read=false + config.storage.redpanda.remote.write=false + status.storage.redpanda.remote.read=false + status.storage.redpanda.remote.write=false + offset.storage.replication.factor=-1 + config.storage.replication.factor=-1 + status.storage.replication.factor=-1 + producer.linger.ms=1 + producer.batch.size=131072 + config.providers=file,secretsManager,env + config.providers.file.class=org.apache.kafka.common.config.provider.FileConfigProvider + config.providers.env.class=org.apache.kafka.common.config.provider.EnvVarConfigProvider + - name: CONNECT_ADDITIONAL_CONFIGURATION + value: "" + - name: CONNECT_BOOTSTRAP_SERVERS + value: "" + - name: CONNECT_GC_LOG_ENABLED + value: AGZOKrMs + - name: CONNECT_HEAP_OPTS + value: -Xms256M -Xmx2G + - name: CONNECT_LOG_LEVEL + value: s2fGu + - name: CONNECT_TLS_ENABLED + value: "false" + envFrom: [] + image: docker.redpanda.com/redpandadata/connectors:v1.0.29 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: rest-api + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: connectors-cluster + ports: + - containerPort: 8083 + name: rest-api + protocol: TCP + - containerPort: 9404 + name: prometheus + protocol: TCP + readinessProbe: + failureThreshold: 2 + httpGet: + path: /connectors + port: rest-api + scheme: HTTP + initialDelaySeconds: 60 + periodSeconds: 10 + successThreshold: 3 + timeoutSeconds: 5 + resources: + limits: + cpu: "1" + memory: 2350Mi + requests: + cpu: "1" + memory: 2350Mi + securityContext: + allowPrivilegeEscalation: false + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /tmp + name: rp-connect-tmp + dnsPolicy: ClusterFirst + imagePullSecrets: + - name: QIa + - name: 9QE3ez + - name: np1QDs89l + nodeSelector: {} + restartPolicy: Always + schedulerName: "" + securityContext: + fsGroup: 101 + fsGroupChangePolicy: OnRootMismatch + runAsUser: 101 + serviceAccountName: default + terminationGracePeriodSeconds: 30 + tolerations: [] + topologySpreadConstraints: + - labelSelector: + matchLabels: + app.kubernetes.io/component: Wvpgs + app.kubernetes.io/instance: console + app.kubernetes.io/name: Wvpgs + maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: ScheduleAnyway + volumes: + - emptyDir: + medium: Memory + sizeLimit: 5Mi + name: rp-connect-tmp +-- testdata/case-004.yaml.golden -- +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: xhLPt0 + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: xhLPt0 + helm.sh/chart: connectors-0.1.12 + name: 74qyne +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: 8083 + protocol: TCP + targetPort: 8083 + - name: prometheus + port: 9404 + protocol: TCP + targetPort: 9404 + selector: + app.kubernetes.io/component: xhLPt0 + app.kubernetes.io/instance: console + app.kubernetes.io/name: xhLPt0 + sessionAffinity: None + type: ClusterIP +--- +# Source: connectors/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: xhLPt0 + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: xhLPt0 + helm.sh/chart: connectors-0.1.12 + name: 74qyne +spec: + progressDeadlineSeconds: 600 + replicas: null + revisionHistoryLimit: 10 + selector: + matchLabels: + app.kubernetes.io/component: xhLPt0 + app.kubernetes.io/instance: console + app.kubernetes.io/name: xhLPt0 + strategy: + type: RollingUpdate + template: + metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/component: xhLPt0 + app.kubernetes.io/instance: console + app.kubernetes.io/name: xhLPt0 + spec: + affinity: + nodeAffinity: {} + podAffinity: {} + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: xhLPt0 + app.kubernetes.io/instance: console + app.kubernetes.io/name: xhLPt0 + namespaces: + - default + topologyKey: kubernetes.io/hostname + containers: + - command: null + env: + - name: CONNECT_CONFIGURATION + value: |- + rest.advertised.port=8083 + rest.port=8083 + key.converter=org.apache.kafka.connect.converters.ByteArrayConverter + value.converter=org.apache.kafka.connect.converters.ByteArrayConverter + group.id=connectors-cluster + offset.storage.topic=_internal_connectors_offsets + config.storage.topic=_internal_connectors_configs + status.storage.topic=_internal_connectors_status + offset.storage.redpanda.remote.read=false + offset.storage.redpanda.remote.write=false + config.storage.redpanda.remote.read=false + config.storage.redpanda.remote.write=false + status.storage.redpanda.remote.read=false + status.storage.redpanda.remote.write=false + offset.storage.replication.factor=-1 + config.storage.replication.factor=-1 + status.storage.replication.factor=-1 + producer.linger.ms=1 + producer.batch.size=131072 + config.providers=file,secretsManager,env + config.providers.file.class=org.apache.kafka.common.config.provider.FileConfigProvider + config.providers.env.class=org.apache.kafka.common.config.provider.EnvVarConfigProvider + - name: CONNECT_ADDITIONAL_CONFIGURATION + value: "" + - name: CONNECT_BOOTSTRAP_SERVERS + value: "" + - name: CONNECT_GC_LOG_ENABLED + value: "false" + - name: CONNECT_HEAP_OPTS + value: -Xms256M -Xmx2G + - name: CONNECT_LOG_LEVEL + value: warn + - name: CONNECT_TLS_ENABLED + value: "false" + envFrom: [] + image: docker.redpanda.com/redpandadata/connectors:v1.0.29 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: rest-api + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: connectors-cluster + ports: + - containerPort: 8083 + name: rest-api + protocol: TCP + - containerPort: 9404 + name: prometheus + protocol: TCP + readinessProbe: + failureThreshold: 2 + httpGet: + path: /connectors + port: rest-api + scheme: HTTP + initialDelaySeconds: 60 + periodSeconds: 10 + successThreshold: 3 + timeoutSeconds: 5 + resources: + limits: + cpu: "1" + memory: 2350Mi + requests: + cpu: "1" + memory: 2350Mi + securityContext: + allowPrivilegeEscalation: false + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /tmp + name: rp-connect-tmp + dnsPolicy: ClusterFirst + imagePullSecrets: + - name: lnn + nodeSelector: {} + restartPolicy: Always + schedulerName: "" + securityContext: + fsGroup: 101 + fsGroupChangePolicy: OnRootMismatch + runAsUser: 101 + serviceAccountName: default + terminationGracePeriodSeconds: 30 + tolerations: [] + topologySpreadConstraints: + - labelSelector: + matchLabels: + app.kubernetes.io/component: xhLPt0 + app.kubernetes.io/instance: console + app.kubernetes.io/name: xhLPt0 + maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: ScheduleAnyway + volumes: + - emptyDir: + medium: Memory + sizeLimit: 5Mi + name: rp-connect-tmp +-- testdata/case-005.yaml.golden -- +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: W + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: W + helm.sh/chart: connectors-0.1.12 + name: J +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: 8083 + protocol: TCP + targetPort: 8083 + - name: prometheus + port: 9404 + protocol: TCP + targetPort: 9404 + selector: + app.kubernetes.io/component: W + app.kubernetes.io/instance: console + app.kubernetes.io/name: W + sessionAffinity: None + type: ClusterIP +--- +# Source: connectors/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: W + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: W + helm.sh/chart: connectors-0.1.12 + name: J +spec: + progressDeadlineSeconds: 600 + replicas: null + revisionHistoryLimit: -544556764 + selector: + matchLabels: + app.kubernetes.io/component: W + app.kubernetes.io/instance: console + app.kubernetes.io/name: W + strategy: + type: AT9FgtX + template: + metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/component: W + app.kubernetes.io/instance: console + app.kubernetes.io/name: W + spec: + affinity: + nodeAffinity: {} + podAffinity: {} + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: W + app.kubernetes.io/instance: console + app.kubernetes.io/name: W + namespaces: + - default + topologyKey: kubernetes.io/hostname + containers: + - command: null + env: + - name: CONNECT_CONFIGURATION + value: |- + rest.advertised.port=8083 + rest.port=8083 + key.converter=org.apache.kafka.connect.converters.ByteArrayConverter + value.converter=org.apache.kafka.connect.converters.ByteArrayConverter + group.id=connectors-cluster + offset.storage.topic=_internal_connectors_offsets + config.storage.topic=_internal_connectors_configs + status.storage.topic=_internal_connectors_status + offset.storage.redpanda.remote.read=false + offset.storage.redpanda.remote.write=false + config.storage.redpanda.remote.read=false + config.storage.redpanda.remote.write=false + status.storage.redpanda.remote.read=false + status.storage.redpanda.remote.write=false + offset.storage.replication.factor=-1 + config.storage.replication.factor=-1 + status.storage.replication.factor=-1 + producer.linger.ms=1 + producer.batch.size=131072 + config.providers=file,secretsManager,env + config.providers.file.class=org.apache.kafka.common.config.provider.FileConfigProvider + config.providers.env.class=org.apache.kafka.common.config.provider.EnvVarConfigProvider + - name: CONNECT_ADDITIONAL_CONFIGURATION + value: "" + - name: CONNECT_BOOTSTRAP_SERVERS + value: "" + - name: CONNECT_GC_LOG_ENABLED + value: u12AMM + - name: CONNECT_HEAP_OPTS + value: -Xms256M -Xmx2G + - name: CONNECT_LOG_LEVEL + value: warn + - name: CONNECT_TLS_ENABLED + value: "false" + envFrom: [] + image: docker.redpanda.com/redpandadata/connectors:v1.0.29 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: rest-api + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: connectors-cluster + ports: + - containerPort: 8083 + name: rest-api + protocol: TCP + - containerPort: 9404 + name: prometheus + protocol: TCP + readinessProbe: + failureThreshold: -321470157 + httpGet: + path: /connectors + port: rest-api + scheme: HTTP + initialDelaySeconds: 1821796808 + periodSeconds: -469069323 + successThreshold: -1171276641 + timeoutSeconds: 1191785929 + resources: + limits: + cpu: "1" + memory: 2350Mi + requests: + cpu: "1" + memory: 2350Mi + securityContext: + allowPrivilegeEscalation: false + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: 9hR6GGwna + name: f9h8iHd + subPath: u6UaQTj + subPathExpr: A13AGT + dnsPolicy: ClusterFirst + imagePullSecrets: [] + nodeSelector: + ppXWIa: yWFoE + restartPolicy: Always + schedulerName: Lwp + securityContext: + fsGroup: 101 + fsGroupChangePolicy: eĻȊ4愻' + runAsGroup: 7076055353387776000 + runAsUser: 1448978345039473400 + supplementalGroups: + - 6910305894952865000 + serviceAccountName: VLlCi + terminationGracePeriodSeconds: 1820238753 + tolerations: [] + topologySpreadConstraints: + - labelSelector: + matchLabels: + app.kubernetes.io/component: W + app.kubernetes.io/instance: console + app.kubernetes.io/name: W + maxSkew: 0 + topologyKey: OAvMKg + whenUnsatisfiable: pasNu + - labelSelector: + matchLabels: + app.kubernetes.io/component: W + app.kubernetes.io/instance: console + app.kubernetes.io/name: W + maxSkew: 0 + topologyKey: izYRz + whenUnsatisfiable: V2RO2 + volumes: + - emptyDir: + medium: Memory + sizeLimit: 5Mi + name: rp-connect-tmp +-- testdata/case-006.yaml.golden -- +--- +# Source: connectors/templates/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + annotations: + 2oUsUW: r + lx: u6Li342dNU + creationTimestamp: null + labels: + LvtMtyy: tvfxqD2lry + YC2zBn: OLSkBqQE + app.kubernetes.io/component: Vlci + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: Vlci + helm.sh/chart: connectors-0.1.12 + m2DRq: cS + name: "7" + namespace: default +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + LvtMtyy: tvfxqD2lry + YC2zBn: OLSkBqQE + app.kubernetes.io/component: Vlci + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: Vlci + helm.sh/chart: connectors-0.1.12 + m2DRq: cS + name: gkX +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: 8083 + protocol: TCP + targetPort: 8083 + - name: prometheus + port: 9404 + protocol: TCP + targetPort: 9404 + selector: + LvtMtyy: tvfxqD2lry + YC2zBn: OLSkBqQE + app.kubernetes.io/component: Vlci + app.kubernetes.io/instance: console + app.kubernetes.io/name: Vlci + m2DRq: cS + sessionAffinity: None + type: ClusterIP +--- +# Source: connectors/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + LvtMtyy: tvfxqD2lry + YC2zBn: OLSkBqQE + app.kubernetes.io/component: Vlci + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: Vlci + helm.sh/chart: connectors-0.1.12 + m2DRq: cS + name: R93VG +spec: + progressDeadlineSeconds: 600 + replicas: null + revisionHistoryLimit: 10 + selector: + matchLabels: + LvtMtyy: tvfxqD2lry + YC2zBn: OLSkBqQE + app.kubernetes.io/component: Vlci + app.kubernetes.io/instance: console + app.kubernetes.io/name: Vlci + m2DRq: cS + strategy: + type: RollingUpdate + template: + metadata: + annotations: {} + creationTimestamp: null + labels: + LvtMtyy: tvfxqD2lry + YC2zBn: OLSkBqQE + app.kubernetes.io/component: Vlci + app.kubernetes.io/instance: console + app.kubernetes.io/name: Vlci + m2DRq: cS + spec: + affinity: + nodeAffinity: {} + podAffinity: {} + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + LvtMtyy: tvfxqD2lry + YC2zBn: OLSkBqQE + app.kubernetes.io/component: Vlci + app.kubernetes.io/instance: console + app.kubernetes.io/name: Vlci + m2DRq: cS + namespaces: + - default + topologyKey: kubernetes.io/hostname + containers: + - command: null + env: + - name: CONNECT_CONFIGURATION + value: |- + rest.advertised.port=8083 + rest.port=8083 + key.converter=org.apache.kafka.connect.converters.ByteArrayConverter + value.converter=org.apache.kafka.connect.converters.ByteArrayConverter + group.id=connectors-cluster + offset.storage.topic=_internal_connectors_offsets + config.storage.topic=_internal_connectors_configs + status.storage.topic=_internal_connectors_status + offset.storage.redpanda.remote.read=false + offset.storage.redpanda.remote.write=false + config.storage.redpanda.remote.read=false + config.storage.redpanda.remote.write=false + status.storage.redpanda.remote.read=false + status.storage.redpanda.remote.write=false + offset.storage.replication.factor=-1 + config.storage.replication.factor=-1 + status.storage.replication.factor=-1 + producer.linger.ms=1 + producer.batch.size=131072 + config.providers=file,secretsManager,env + config.providers.file.class=org.apache.kafka.common.config.provider.FileConfigProvider + config.providers.env.class=org.apache.kafka.common.config.provider.EnvVarConfigProvider + - name: CONNECT_ADDITIONAL_CONFIGURATION + value: "" + - name: CONNECT_BOOTSTRAP_SERVERS + value: "" + - name: CONNECT_GC_LOG_ENABLED + value: "false" + - name: CONNECT_HEAP_OPTS + value: -Xms256M -Xmx2G + - name: CONNECT_LOG_LEVEL + value: 0aZ + - name: CONNECT_TLS_ENABLED + value: "false" + envFrom: [] + image: docker.redpanda.com/redpandadata/connectors:v1.0.29 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: rest-api + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: connectors-cluster + ports: + - containerPort: 8083 + name: rest-api + protocol: TCP + - containerPort: 9404 + name: prometheus + protocol: TCP + readinessProbe: + failureThreshold: 2 + httpGet: + path: /connectors + port: rest-api + scheme: HTTP + initialDelaySeconds: 60 + periodSeconds: 10 + successThreshold: 3 + timeoutSeconds: 5 + resources: + limits: + cpu: "1" + memory: 2350Mi + requests: + cpu: "1" + memory: 2350Mi + securityContext: + allowPrivilegeEscalation: false + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /tmp + name: rp-connect-tmp + dnsPolicy: ClusterFirst + imagePullSecrets: [] + nodeSelector: {} + restartPolicy: Always + schedulerName: "" + securityContext: + fsGroup: 101 + fsGroupChangePolicy: OnRootMismatch + runAsUser: 101 + serviceAccountName: "7" + terminationGracePeriodSeconds: 30 + tolerations: [] + topologySpreadConstraints: + - labelSelector: + matchLabels: + LvtMtyy: tvfxqD2lry + YC2zBn: OLSkBqQE + app.kubernetes.io/component: Vlci + app.kubernetes.io/instance: console + app.kubernetes.io/name: Vlci + m2DRq: cS + maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: ScheduleAnyway + volumes: + - emptyDir: + medium: Memory + sizeLimit: 5Mi + name: rp-connect-tmp +-- testdata/case-007.yaml.golden -- +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: Gb7J7k + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: Gb7J7k + helm.sh/chart: connectors-0.1.12 + name: 9PY0 +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: 8083 + protocol: TCP + targetPort: 8083 + - name: prometheus + port: 9404 + protocol: TCP + targetPort: 9404 + selector: + app.kubernetes.io/component: Gb7J7k + app.kubernetes.io/instance: console + app.kubernetes.io/name: Gb7J7k + sessionAffinity: None + type: ClusterIP +--- +# Source: connectors/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: Gb7J7k + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: Gb7J7k + helm.sh/chart: connectors-0.1.12 + name: NUTO +spec: + progressDeadlineSeconds: 600 + replicas: null + revisionHistoryLimit: 10 + selector: + matchLabels: + app.kubernetes.io/component: Gb7J7k + app.kubernetes.io/instance: console + app.kubernetes.io/name: Gb7J7k + strategy: + type: RollingUpdate + template: + metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/component: Gb7J7k + app.kubernetes.io/instance: console + app.kubernetes.io/name: Gb7J7k + spec: + affinity: + nodeAffinity: {} + podAffinity: {} + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: Gb7J7k + app.kubernetes.io/instance: console + app.kubernetes.io/name: Gb7J7k + namespaces: + - default + topologyKey: kubernetes.io/hostname + containers: + - command: null + env: + - name: CONNECT_CONFIGURATION + value: |- + rest.advertised.port=8083 + rest.port=8083 + key.converter=org.apache.kafka.connect.converters.ByteArrayConverter + value.converter=org.apache.kafka.connect.converters.ByteArrayConverter + group.id=y2 + offset.storage.topic=_internal_connectors_offsets + config.storage.topic=_internal_connectors_configs + status.storage.topic=_internal_connectors_status + offset.storage.redpanda.remote.read=false + offset.storage.redpanda.remote.write=false + config.storage.redpanda.remote.read=false + config.storage.redpanda.remote.write=false + status.storage.redpanda.remote.read=false + status.storage.redpanda.remote.write=false + offset.storage.replication.factor=-1 + config.storage.replication.factor=-1 + status.storage.replication.factor=-1 + producer.linger.ms=1 + producer.batch.size=131072 + config.providers=file,secretsManager,env + config.providers.file.class=org.apache.kafka.common.config.provider.FileConfigProvider + config.providers.env.class=org.apache.kafka.common.config.provider.EnvVarConfigProvider + - name: CONNECT_ADDITIONAL_CONFIGURATION + value: ZQu + - name: CONNECT_BOOTSTRAP_SERVERS + value: ue + - name: SCHEMA_REGISTRY_URL + value: kS0A8GucOgn + - name: CONNECT_GC_LOG_ENABLED + value: "false" + - name: CONNECT_HEAP_OPTS + value: -Xms256M -Xmx2G + - name: CONNECT_LOG_LEVEL + value: n3s7 + - name: CONNECT_TLS_ENABLED + value: "false" + envFrom: [] + image: docker.redpanda.com/redpandadata/connectors:v1.0.29 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: rest-api + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: connectors-cluster + ports: + - containerPort: 8083 + name: rest-api + protocol: TCP + - containerPort: 9404 + name: prometheus + protocol: TCP + readinessProbe: + failureThreshold: 2 + httpGet: + path: /connectors + port: rest-api + scheme: HTTP + initialDelaySeconds: 60 + periodSeconds: 10 + successThreshold: 3 + timeoutSeconds: 5 + resources: + limits: + cpu: "1" + memory: 2350Mi + requests: + cpu: "1" + memory: 2350Mi + securityContext: + allowPrivilegeEscalation: false + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /tmp + name: rp-connect-tmp + dnsPolicy: ClusterFirst + imagePullSecrets: [] + nodeSelector: {} + restartPolicy: Always + schedulerName: "" + securityContext: + fsGroup: 101 + fsGroupChangePolicy: OnRootMismatch + runAsUser: 101 + serviceAccountName: default + terminationGracePeriodSeconds: 30 + tolerations: [] + topologySpreadConstraints: + - labelSelector: + matchLabels: + app.kubernetes.io/component: Gb7J7k + app.kubernetes.io/instance: console + app.kubernetes.io/name: Gb7J7k + maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: ScheduleAnyway + volumes: + - emptyDir: + medium: Memory + sizeLimit: 5Mi + name: rp-connect-tmp +-- testdata/case-008.yaml.golden -- +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: tPhRiQRK + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: tPhRiQRK + helm.sh/chart: connectors-0.1.12 + name: PNw8 +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: 8083 + protocol: TCP + targetPort: 8083 + - name: prometheus + port: 9404 + protocol: TCP + targetPort: 9404 + selector: + app.kubernetes.io/component: tPhRiQRK + app.kubernetes.io/instance: console + app.kubernetes.io/name: tPhRiQRK + sessionAffinity: None + type: ClusterIP +--- +# Source: connectors/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: tPhRiQRK + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: tPhRiQRK + helm.sh/chart: connectors-0.1.12 + name: PNw8 +spec: + progressDeadlineSeconds: 467220788 + replicas: null + revisionHistoryLimit: 10 + selector: + matchLabels: + app.kubernetes.io/component: tPhRiQRK + app.kubernetes.io/instance: console + app.kubernetes.io/name: tPhRiQRK + strategy: + type: RollingUpdate + template: + metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/component: tPhRiQRK + app.kubernetes.io/instance: console + app.kubernetes.io/name: tPhRiQRK + spec: + affinity: + nodeAffinity: {} + podAffinity: {} + podAntiAffinity: null + containers: + - command: null + env: + - name: CONNECT_CONFIGURATION + value: |- + rest.advertised.port=8083 + rest.port=8083 + key.converter=org.apache.kafka.connect.converters.ByteArrayConverter + value.converter=org.apache.kafka.connect.converters.ByteArrayConverter + group.id=connectors-cluster + offset.storage.topic=_internal_connectors_offsets + config.storage.topic=_internal_connectors_configs + status.storage.topic=_internal_connectors_status + offset.storage.redpanda.remote.read=false + offset.storage.redpanda.remote.write=false + config.storage.redpanda.remote.read=false + config.storage.redpanda.remote.write=false + status.storage.redpanda.remote.read=false + status.storage.redpanda.remote.write=false + offset.storage.replication.factor=-1 + config.storage.replication.factor=-1 + status.storage.replication.factor=-1 + producer.linger.ms=1 + producer.batch.size=131072 + config.providers=file,secretsManager,env + config.providers.file.class=org.apache.kafka.common.config.provider.FileConfigProvider + config.providers.env.class=org.apache.kafka.common.config.provider.EnvVarConfigProvider + - name: CONNECT_ADDITIONAL_CONFIGURATION + value: "" + - name: CONNECT_BOOTSTRAP_SERVERS + value: "" + - name: CONNECT_GC_LOG_ENABLED + value: pq3jgGoeY + - name: CONNECT_HEAP_OPTS + value: -Xms256M -Xmx2G + - name: CONNECT_LOG_LEVEL + value: warn + - name: CONNECT_TLS_ENABLED + value: "false" + envFrom: + - prefix: W + - prefix: 6Cgj + - prefix: YV + image: docker.redpanda.com/redpandadata/connectors:v1.0.29 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: -1790317528 + httpGet: + path: / + port: rest-api + scheme: HTTP + initialDelaySeconds: -853917423 + periodSeconds: 1730314559 + successThreshold: -1047272333 + timeoutSeconds: 478977165 + name: connectors-cluster + ports: + - containerPort: 8083 + name: rest-api + protocol: TCP + - containerPort: 9404 + name: prometheus + protocol: TCP + readinessProbe: + failureThreshold: 2 + httpGet: + path: /connectors + port: rest-api + scheme: HTTP + initialDelaySeconds: 60 + periodSeconds: 10 + successThreshold: 3 + timeoutSeconds: 5 + resources: + limits: + cpu: "1" + memory: 2350Mi + requests: + cpu: "1" + memory: 2350Mi + securityContext: + allowPrivilegeEscalation: false + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /tmp + name: rp-connect-tmp + dnsPolicy: ClusterFirst + imagePullSecrets: + - name: EzI + - {} + - name: rjR6q + nodeSelector: {} + restartPolicy: Always + schedulerName: iVovlD + securityContext: + fsGroup: 101 + fsGroupChangePolicy: OnRootMismatch + runAsUser: 101 + serviceAccountName: default + terminationGracePeriodSeconds: 1520290623 + tolerations: [] + topologySpreadConstraints: + - labelSelector: + matchLabels: + app.kubernetes.io/component: tPhRiQRK + app.kubernetes.io/instance: console + app.kubernetes.io/name: tPhRiQRK + maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: ScheduleAnyway + volumes: + - emptyDir: + medium: Memory + sizeLimit: 5Mi + name: rp-connect-tmp +-- testdata/case-009.yaml.golden -- +--- +# Source: connectors/templates/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + annotations: + LWQ09i: tiLdCrApld + v2D6hTB: NGlgEEm + creationTimestamp: null + labels: + app.kubernetes.io/component: wCD97n + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: wCD97n + helm.sh/chart: connectors-0.1.12 + name: eyeD + namespace: default +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: wCD97n + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: wCD97n + helm.sh/chart: connectors-0.1.12 + name: H +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: 8083 + protocol: TCP + targetPort: 8083 + - name: prometheus + port: 9404 + protocol: TCP + targetPort: 9404 + selector: + app.kubernetes.io/component: wCD97n + app.kubernetes.io/instance: console + app.kubernetes.io/name: wCD97n + sessionAffinity: None + type: ClusterIP +-- testdata/case-010.yaml.golden -- +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: 9fz + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 9fz + cUt: YvDFEsYlU + g3hOh91HKI: CHwTjLYe2XS + h4yNA: fJL + helm.sh/chart: connectors-0.1.12 + name: LsGZn +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: 8083 + protocol: TCP + targetPort: 8083 + - name: prometheus + port: 9404 + protocol: TCP + targetPort: 9404 + selector: + app.kubernetes.io/component: 9fz + app.kubernetes.io/instance: console + app.kubernetes.io/name: 9fz + cUt: YvDFEsYlU + g3hOh91HKI: CHwTjLYe2XS + h4yNA: fJL + sessionAffinity: None + type: ClusterIP +--- +# Source: connectors/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: 9fz + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 9fz + cUt: YvDFEsYlU + g3hOh91HKI: CHwTjLYe2XS + h4yNA: fJL + helm.sh/chart: connectors-0.1.12 + name: LsGZn +spec: + progressDeadlineSeconds: 600 + replicas: null + revisionHistoryLimit: 10 + selector: + matchLabels: + app.kubernetes.io/component: 9fz + app.kubernetes.io/instance: console + app.kubernetes.io/name: 9fz + cUt: YvDFEsYlU + g3hOh91HKI: CHwTjLYe2XS + h4yNA: fJL + strategy: + type: RollingUpdate + template: + metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/component: 9fz + app.kubernetes.io/instance: console + app.kubernetes.io/name: 9fz + cUt: YvDFEsYlU + g3hOh91HKI: CHwTjLYe2XS + h4yNA: fJL + spec: + affinity: + nodeAffinity: {} + podAffinity: {} + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: 9fz + app.kubernetes.io/instance: console + app.kubernetes.io/name: 9fz + cUt: YvDFEsYlU + g3hOh91HKI: CHwTjLYe2XS + h4yNA: fJL + namespaces: + - default + topologyKey: kubernetes.io/hostname + containers: + - command: null + env: + - name: CONNECT_CONFIGURATION + value: |- + rest.advertised.port=8083 + rest.port=8083 + key.converter=org.apache.kafka.connect.converters.ByteArrayConverter + value.converter=org.apache.kafka.connect.converters.ByteArrayConverter + group.id=connectors-cluster + offset.storage.topic=_internal_connectors_offsets + config.storage.topic=_internal_connectors_configs + status.storage.topic=_internal_connectors_status + offset.storage.redpanda.remote.read=false + offset.storage.redpanda.remote.write=false + config.storage.redpanda.remote.read=false + config.storage.redpanda.remote.write=false + status.storage.redpanda.remote.read=false + status.storage.redpanda.remote.write=false + offset.storage.replication.factor=-1 + config.storage.replication.factor=-1 + status.storage.replication.factor=-1 + producer.linger.ms=1 + producer.batch.size=131072 + config.providers=file,secretsManager,env + config.providers.file.class=org.apache.kafka.common.config.provider.FileConfigProvider + config.providers.env.class=org.apache.kafka.common.config.provider.EnvVarConfigProvider + - name: CONNECT_ADDITIONAL_CONFIGURATION + value: "" + - name: CONNECT_BOOTSTRAP_SERVERS + value: "" + - name: CONNECT_GC_LOG_ENABLED + value: "" + - name: CONNECT_HEAP_OPTS + value: -Xms256M -Xmx2G + - name: CONNECT_LOG_LEVEL + value: warn + - name: CONNECT_TLS_ENABLED + value: "false" + envFrom: [] + image: docker.redpanda.com/redpandadata/connectors:v1.0.29 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: rest-api + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: connectors-cluster + ports: + - containerPort: 8083 + name: rest-api + protocol: TCP + - containerPort: 9404 + name: prometheus + protocol: TCP + readinessProbe: + failureThreshold: 2 + httpGet: + path: /connectors + port: rest-api + scheme: HTTP + initialDelaySeconds: 60 + periodSeconds: 10 + successThreshold: 3 + timeoutSeconds: 5 + resources: + limits: + cpu: "1" + memory: 2350Mi + requests: + cpu: "1" + memory: 2350Mi + securityContext: + allowPrivilegeEscalation: false + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /tmp + name: rp-connect-tmp + dnsPolicy: ClusterFirst + imagePullSecrets: [] + nodeSelector: {} + restartPolicy: Always + schedulerName: "" + securityContext: + fsGroup: 101 + fsGroupChangePolicy: OnRootMismatch + runAsUser: 101 + serviceAccountName: bZ1w2 + terminationGracePeriodSeconds: 30 + tolerations: [] + topologySpreadConstraints: + - labelSelector: + matchLabels: + app.kubernetes.io/component: 9fz + app.kubernetes.io/instance: console + app.kubernetes.io/name: 9fz + cUt: YvDFEsYlU + g3hOh91HKI: CHwTjLYe2XS + h4yNA: fJL + maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: ScheduleAnyway + volumes: + - emptyDir: + medium: Memory + sizeLimit: 5Mi + name: rp-connect-tmp +--- +# Source: connectors/templates/pod-monitor.yaml +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + annotations: {} + creationTimestamp: null + labels: + wsUYAN3C: BzMz48 + name: LsGZn +spec: + namespaceSelector: + any: true + podMetricsEndpoints: + - bearerTokenSecret: + key: "" + path: / + port: prometheus + selector: + matchLabels: + app.kubernetes.io/component: 9fz + app.kubernetes.io/instance: console + app.kubernetes.io/name: 9fz + cUt: YvDFEsYlU + g3hOh91HKI: CHwTjLYe2XS + h4yNA: fJL +-- testdata/case-011.yaml.golden -- +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: xiBXju + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: xiBXju + bX: vmmkhH2NHvdt + helm.sh/chart: connectors-0.1.12 + mO: pT + name: etuP +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: 8083 + protocol: TCP + targetPort: 8083 + - name: prometheus + port: 9404 + protocol: TCP + targetPort: 9404 + selector: + app.kubernetes.io/component: xiBXju + app.kubernetes.io/instance: console + app.kubernetes.io/name: xiBXju + bX: vmmkhH2NHvdt + mO: pT + sessionAffinity: None + type: ClusterIP +--- +# Source: connectors/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: xiBXju + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: xiBXju + bX: vmmkhH2NHvdt + helm.sh/chart: connectors-0.1.12 + mO: pT + name: etuP +spec: + progressDeadlineSeconds: 600 + replicas: null + revisionHistoryLimit: -1010709730 + selector: + matchLabels: + app.kubernetes.io/component: xiBXju + app.kubernetes.io/instance: console + app.kubernetes.io/name: xiBXju + bX: vmmkhH2NHvdt + mO: pT + strategy: + type: XhI1Zz + template: + metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/component: xiBXju + app.kubernetes.io/instance: console + app.kubernetes.io/name: xiBXju + bX: vmmkhH2NHvdt + mO: pT + spec: + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchFields: + - key: qi12DQkzc + operator: 駣>蕐k泌蚮奘5d墥7Ȋ + values: + - Sp + weight: 1587628539 + podAffinity: {} + podAntiAffinity: null + containers: + - command: null + env: + - name: CONNECT_CONFIGURATION + value: |- + rest.advertised.port=8083 + rest.port=8083 + key.converter=org.apache.kafka.connect.converters.ByteArrayConverter + value.converter=org.apache.kafka.connect.converters.ByteArrayConverter + group.id=X + offset.storage.topic=_internal_connectors_offsets + config.storage.topic=_internal_connectors_configs + status.storage.topic=_internal_connectors_status + offset.storage.redpanda.remote.read=false + offset.storage.redpanda.remote.write=false + config.storage.redpanda.remote.read=false + config.storage.redpanda.remote.write=false + status.storage.redpanda.remote.read=false + status.storage.redpanda.remote.write=false + offset.storage.replication.factor=-1 + config.storage.replication.factor=-1 + status.storage.replication.factor=-1 + producer.linger.ms=1644100599 + producer.batch.size=606208011 + config.providers=file,secretsManager,env + config.providers.file.class=org.apache.kafka.common.config.provider.FileConfigProvider + config.providers.secretsManager.class=com.github.jcustenborder.kafka.config.aws.SecretsManagerConfigProvider + config.providers.secretsManager.param.secret.prefix=TFKpuTTGy6JO572 + config.providers.secretsManager.param.aws.region=Zga57aiC + config.providers.env.class=org.apache.kafka.common.config.provider.EnvVarConfigProvider + - name: CONNECT_ADDITIONAL_CONFIGURATION + value: "" + - name: CONNECT_BOOTSTRAP_SERVERS + value: vucld + - name: SCHEMA_REGISTRY_URL + value: mGj8 + - name: CONNECT_GC_LOG_ENABLED + value: "false" + - name: CONNECT_HEAP_OPTS + value: -Xms256M -Xmx2G + - name: CONNECT_LOG_LEVEL + value: 20R9 + - name: CONNECT_SASL_USERNAME + value: 8MR9Bee + - name: CONNECT_SASL_MECHANISM + value: eTh + - name: CONNECT_SASL_PASSWORD_FILE + value: rc-credentials/password + - name: CONNECT_TLS_ENABLED + value: "false" + - name: CONNECT_TLS_AUTH_KEY + value: key/VT + - name: ogAtm + value: mJfm + - name: 2dTzgfH + value: sNiAP + valueFrom: + configMapKeyRef: + key: gSl56 + name: c + optional: true + resourceFieldRef: + containerName: AXKLF + divisor: "0" + resource: "" + - name: N1yV1 + value: nLSeqDK + envFrom: + - prefix: 9HB6W4t + secretRef: + name: NYC3bKPQWLc + optional: false + image: docker.redpanda.com/redpandadata/connectors:v1.0.29 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: -757710692 + httpGet: + path: / + port: rest-api + scheme: HTTP + initialDelaySeconds: -949475509 + periodSeconds: 1423942066 + successThreshold: 1080931760 + timeoutSeconds: -1902342435 + name: connectors-cluster + ports: + - containerPort: 8083 + name: rest-api + protocol: TCP + - containerPort: 9404 + name: prometheus + protocol: TCP + readinessProbe: + failureThreshold: 2 + httpGet: + path: /connectors + port: rest-api + scheme: HTTP + initialDelaySeconds: 60 + periodSeconds: 10 + successThreshold: 3 + timeoutSeconds: 5 + resources: + limits: + cpu: "1" + memory: 2350Mi + requests: + cpu: "1" + memory: 2350Mi + securityContext: + allowPrivilegeEscalation: false + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /opt/kafka/connect-password/rc-credentials + name: rc-credentials + - mountPath: /opt/kafka/connect-certs/key + name: key + - mountPath: NIVHRdAc + name: BHPad + readOnly: true + subPath: z + subPathExpr: iwiB7uVoG + - mountPath: S6g7 + mountPropagation: $+g"訜駄 + name: 1iwfb + readOnly: true + subPath: 5XRI + subPathExpr: zNyXts + dnsPolicy: ClusterFirst + imagePullSecrets: [] + nodeSelector: {} + restartPolicy: Always + schedulerName: g + securityContext: + fsGroup: 101 + fsGroupChangePolicy: b + runAsUser: 101 + serviceAccountName: dr5NDVhU0W3x + terminationGracePeriodSeconds: 30 + tolerations: [] + topologySpreadConstraints: + - labelSelector: + matchLabels: + app.kubernetes.io/component: xiBXju + app.kubernetes.io/instance: console + app.kubernetes.io/name: xiBXju + bX: vmmkhH2NHvdt + mO: pT + maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: ScheduleAnyway + volumes: + - name: key + secret: + defaultMode: 292 + secretName: lz9QFe + - name: rc-credentials + secret: + defaultMode: 292 + secretName: H5TroU8 + - emptyDir: + medium: Memory + sizeLimit: 5Mi + name: rp-connect-tmp +-- testdata/case-012.yaml.golden -- +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: MexiU + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: MexiU + helm.sh/chart: connectors-0.1.12 + name: Ac +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: 8083 + protocol: TCP + targetPort: 8083 + - name: prometheus + port: 9404 + protocol: TCP + targetPort: 9404 + selector: + app.kubernetes.io/component: MexiU + app.kubernetes.io/instance: console + app.kubernetes.io/name: MexiU + sessionAffinity: None + type: ClusterIP +-- testdata/case-013.yaml.golden -- +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: w8tCi3K + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: w8tCi3K + helm.sh/chart: connectors-0.1.12 + name: InI +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: 8083 + protocol: TCP + targetPort: 8083 + - name: prometheus + port: 9404 + protocol: TCP + targetPort: 9404 + selector: + app.kubernetes.io/component: w8tCi3K + app.kubernetes.io/instance: console + app.kubernetes.io/name: w8tCi3K + sessionAffinity: None + type: ClusterIP +--- +# Source: connectors/templates/pod-monitor.yaml +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + annotations: {} + creationTimestamp: null + labels: {} + name: bAtOao +spec: + namespaceSelector: + any: true + podMetricsEndpoints: + - bearerTokenSecret: + key: "" + path: / + port: prometheus + selector: + matchLabels: + app.kubernetes.io/component: w8tCi3K + app.kubernetes.io/instance: console + app.kubernetes.io/name: w8tCi3K +-- testdata/case-014.yaml.golden -- +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: dA1zsc + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: dA1zsc + helm.sh/chart: connectors-0.1.12 + name: u7DU +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: 8083 + protocol: TCP + targetPort: 8083 + - name: prometheus + port: 9404 + protocol: TCP + targetPort: 9404 + selector: + app.kubernetes.io/component: dA1zsc + app.kubernetes.io/instance: console + app.kubernetes.io/name: dA1zsc + sessionAffinity: None + type: ClusterIP +--- +# Source: connectors/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: dA1zsc + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: dA1zsc + helm.sh/chart: connectors-0.1.12 + name: u7DU +spec: + progressDeadlineSeconds: 600 + replicas: null + revisionHistoryLimit: 10 + selector: + matchLabels: + app.kubernetes.io/component: dA1zsc + app.kubernetes.io/instance: console + app.kubernetes.io/name: dA1zsc + strategy: + type: RollingUpdate + template: + metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/component: dA1zsc + app.kubernetes.io/instance: console + app.kubernetes.io/name: dA1zsc + spec: + affinity: + nodeAffinity: {} + podAffinity: {} + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: dA1zsc + app.kubernetes.io/instance: console + app.kubernetes.io/name: dA1zsc + namespaces: + - default + topologyKey: kubernetes.io/hostname + containers: + - command: null + env: + - name: CONNECT_CONFIGURATION + value: |- + rest.advertised.port=8083 + rest.port=8083 + key.converter=org.apache.kafka.connect.converters.ByteArrayConverter + value.converter=org.apache.kafka.connect.converters.ByteArrayConverter + group.id=6AsORVCaYJ + offset.storage.topic=_internal_connectors_offsets + config.storage.topic=_internal_connectors_configs + status.storage.topic=_internal_connectors_status + offset.storage.redpanda.remote.read=false + offset.storage.redpanda.remote.write=false + config.storage.redpanda.remote.read=false + config.storage.redpanda.remote.write=false + status.storage.redpanda.remote.read=false + status.storage.redpanda.remote.write=false + offset.storage.replication.factor=-1 + config.storage.replication.factor=-1 + status.storage.replication.factor=-1 + producer.linger.ms=1 + producer.batch.size=-831136974 + config.providers=file,secretsManager,env + config.providers.file.class=org.apache.kafka.common.config.provider.FileConfigProvider + config.providers.env.class=org.apache.kafka.common.config.provider.EnvVarConfigProvider + - name: CONNECT_ADDITIONAL_CONFIGURATION + value: E + - name: CONNECT_BOOTSTRAP_SERVERS + value: cywT8MNAo + - name: SCHEMA_REGISTRY_URL + value: cSf + - name: CONNECT_GC_LOG_ENABLED + value: "false" + - name: CONNECT_HEAP_OPTS + value: -Xms256M -Xmx2G + - name: CONNECT_LOG_LEVEL + value: warn + - name: CONNECT_TLS_ENABLED + value: "false" + envFrom: [] + image: docker.redpanda.com/redpandadata/connectors:v1.0.29 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: rest-api + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: connectors-cluster + ports: + - containerPort: 8083 + name: rest-api + protocol: TCP + - containerPort: 9404 + name: prometheus + protocol: TCP + readinessProbe: + failureThreshold: 2 + httpGet: + path: /connectors + port: rest-api + scheme: HTTP + initialDelaySeconds: 60 + periodSeconds: 10 + successThreshold: 3 + timeoutSeconds: 5 + resources: + limits: + cpu: "1" + memory: 2350Mi + requests: + cpu: "1" + memory: 2350Mi + securityContext: + allowPrivilegeEscalation: false + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /tmp + name: rp-connect-tmp + dnsPolicy: ClusterFirst + imagePullSecrets: [] + nodeSelector: {} + restartPolicy: Always + schedulerName: "" + securityContext: + fsGroup: 101 + fsGroupChangePolicy: OnRootMismatch + runAsUser: 101 + serviceAccountName: HAAJtAWrjJ + terminationGracePeriodSeconds: 30 + tolerations: [] + topologySpreadConstraints: + - labelSelector: + matchLabels: + app.kubernetes.io/component: dA1zsc + app.kubernetes.io/instance: console + app.kubernetes.io/name: dA1zsc + maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: ScheduleAnyway + volumes: + - emptyDir: + medium: Memory + sizeLimit: 5Mi + name: rp-connect-tmp +--- +# Source: connectors/templates/pod-monitor.yaml +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + annotations: {} + creationTimestamp: null + labels: + aVoQ7: vECqlu0Pe + name: u7DU +spec: + namespaceSelector: + any: true + matchNames: + - alQT6bxHho + - jKf + - p + podMetricsEndpoints: + - bearerTokenSecret: + key: "" + path: / + port: prometheus + selector: + matchLabels: + app.kubernetes.io/component: dA1zsc + app.kubernetes.io/instance: console + app.kubernetes.io/name: dA1zsc +-- testdata/case-015.yaml.golden -- +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + 96Kx: 1DW5QoLP + LY: nDw + app.kubernetes.io/component: bpgtWxol + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: bpgtWxol + etW: "9" + helm.sh/chart: connectors-0.1.12 + name: x +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: 8083 + protocol: TCP + targetPort: 8083 + - name: prometheus + port: 9404 + protocol: TCP + targetPort: 9404 + selector: + 96Kx: 1DW5QoLP + LY: nDw + app.kubernetes.io/component: bpgtWxol + app.kubernetes.io/instance: console + app.kubernetes.io/name: bpgtWxol + etW: "9" + sessionAffinity: None + type: ClusterIP +-- testdata/case-016.yaml.golden -- +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + IUeOwNT: T3w1nV + Si: dNUY + app.kubernetes.io/component: Cex3v + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: Cex3v + helm.sh/chart: connectors-0.1.12 + name: B5Y +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: 8083 + protocol: TCP + targetPort: 8083 + - name: HzTtdut + port: 741893604 + protocol: TCP + targetPort: 741893604 + - name: yT6vYOdszF + port: -1916404761 + protocol: TCP + targetPort: -1916404761 + selector: + app.kubernetes.io/component: Cex3v + app.kubernetes.io/instance: console + app.kubernetes.io/name: Cex3v + sessionAffinity: None + type: ClusterIP +--- +# Source: connectors/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: Cex3v + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: Cex3v + helm.sh/chart: connectors-0.1.12 + name: bGMfavR +spec: + progressDeadlineSeconds: 600 + replicas: null + revisionHistoryLimit: 10 + selector: + matchLabels: + app.kubernetes.io/component: Cex3v + app.kubernetes.io/instance: console + app.kubernetes.io/name: Cex3v + strategy: + type: RollingUpdate + template: + metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/component: Cex3v + app.kubernetes.io/instance: console + app.kubernetes.io/name: Cex3v + spec: + affinity: + nodeAffinity: {} + podAffinity: {} + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: Cex3v + app.kubernetes.io/instance: console + app.kubernetes.io/name: Cex3v + namespaces: + - default + topologyKey: kubernetes.io/hostname + containers: + - command: null + env: + - name: CONNECT_CONFIGURATION + value: |- + rest.advertised.port=8083 + rest.port=8083 + key.converter=org.apache.kafka.connect.converters.ByteArrayConverter + value.converter=org.apache.kafka.connect.converters.ByteArrayConverter + group.id=connectors-cluster + offset.storage.topic=_internal_connectors_offsets + config.storage.topic=_internal_connectors_configs + status.storage.topic=_internal_connectors_status + offset.storage.redpanda.remote.read=false + offset.storage.redpanda.remote.write=false + config.storage.redpanda.remote.read=false + config.storage.redpanda.remote.write=false + status.storage.redpanda.remote.read=false + status.storage.redpanda.remote.write=false + offset.storage.replication.factor=-1 + config.storage.replication.factor=-1 + status.storage.replication.factor=-1 + producer.linger.ms=1 + producer.batch.size=131072 + config.providers=file,secretsManager,env + config.providers.file.class=org.apache.kafka.common.config.provider.FileConfigProvider + config.providers.env.class=org.apache.kafka.common.config.provider.EnvVarConfigProvider + - name: CONNECT_ADDITIONAL_CONFIGURATION + value: "" + - name: CONNECT_BOOTSTRAP_SERVERS + value: "" + - name: CONNECT_GC_LOG_ENABLED + value: NSE + - name: CONNECT_HEAP_OPTS + value: -Xms256M -Xmx0 + - name: CONNECT_LOG_LEVEL + value: oj4P + - name: CONNECT_TLS_ENABLED + value: "false" + envFrom: [] + image: docker.redpanda.com/redpandadata/connectors:v1.0.29 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: rest-api + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: connectors-cluster + ports: + - containerPort: 8083 + name: rest-api + protocol: TCP + - containerPort: 741893604 + name: HzTtdut + protocol: TCP + - containerPort: -1916404761 + name: yT6vYOdszF + protocol: TCP + readinessProbe: + failureThreshold: 2 + httpGet: + path: /connectors + port: rest-api + scheme: HTTP + initialDelaySeconds: 60 + periodSeconds: 10 + successThreshold: 3 + timeoutSeconds: 5 + resources: + limits: + cpu: "1" + memory: 2350Mi + requests: + cpu: "0" + memory: 2350Mi + securityContext: + allowPrivilegeEscalation: false + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /tmp + name: rp-connect-tmp + dnsPolicy: ClusterFirst + imagePullSecrets: [] + nodeSelector: {} + restartPolicy: Always + schedulerName: "" + securityContext: + fsGroup: 101 + fsGroupChangePolicy: OnRootMismatch + runAsUser: 101 + serviceAccountName: cxOBE + terminationGracePeriodSeconds: 30 + tolerations: [] + topologySpreadConstraints: + - labelSelector: + matchLabels: + app.kubernetes.io/component: Cex3v + app.kubernetes.io/instance: console + app.kubernetes.io/name: Cex3v + maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: ScheduleAnyway + volumes: + - name: X7ZZu + - name: KkkMA7 + - name: Btxy +-- testdata/case-017.yaml.golden -- +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: DAE + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: DAE + helm.sh/chart: connectors-0.1.12 + wR: GAm + name: u1Dk +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: 8083 + protocol: TCP + targetPort: 8083 + - name: prometheus + port: 9404 + protocol: TCP + targetPort: 9404 + selector: + app.kubernetes.io/component: DAE + app.kubernetes.io/instance: console + app.kubernetes.io/name: DAE + wR: GAm + sessionAffinity: None + type: ClusterIP +--- +# Source: connectors/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: DAE + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: DAE + fet: YGwnq + helm.sh/chart: connectors-0.1.12 + wR: GAm + name: u1Dk +spec: + progressDeadlineSeconds: 444536561 + replicas: null + revisionHistoryLimit: 1418020237 + selector: + matchLabels: + app.kubernetes.io/component: DAE + app.kubernetes.io/instance: console + app.kubernetes.io/name: DAE + wR: GAm + strategy: + type: WVP1Q8 + template: + metadata: + annotations: + fet: YGwnq + creationTimestamp: null + labels: + app.kubernetes.io/component: DAE + app.kubernetes.io/instance: console + app.kubernetes.io/name: DAE + wR: GAm + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: "2" + operator: 箓Ęȁ銵鷝Ā喳Ăɀ} + - key: j + operator: ɓ + matchFields: + - key: "" + operator: vǃ鞳邪§Ț皾6 + - key: Yi7SzM + operator: Ǎ浹籥岷Ħ + values: + - Czu9d1V + - key: r6y + operator: 牁p认ð_蠡hHiÖq肓ǭʤe)ĉB扝 + - {} + podAffinity: {} + podAntiAffinity: null + containers: + - command: null + env: + - name: CONNECT_CONFIGURATION + value: |- + rest.advertised.port=8083 + rest.port=8083 + key.converter=org.apache.kafka.connect.converters.ByteArrayConverter + value.converter=org.apache.kafka.connect.converters.ByteArrayConverter + group.id=hPUA1m7 + offset.storage.topic=n + config.storage.topic=Uf + status.storage.topic=kNLwla + offset.storage.redpanda.remote.read=false + offset.storage.redpanda.remote.write=false + config.storage.redpanda.remote.read=false + config.storage.redpanda.remote.write=false + status.storage.redpanda.remote.read=false + status.storage.redpanda.remote.write=false + offset.storage.replication.factor=-1 + config.storage.replication.factor=-1 + status.storage.replication.factor=-1 + producer.linger.ms=-221329759 + producer.batch.size=1121174748 + config.providers=file,secretsManager,env + config.providers.file.class=org.apache.kafka.common.config.provider.FileConfigProvider + config.providers.secretsManager.class=com.github.jcustenborder.kafka.config.aws.SecretsManagerConfigProvider + config.providers.secretsManager.param.secret.prefix=X1zPZ5Cv + config.providers.secretsManager.param.aws.region=LrK6I + config.providers.env.class=org.apache.kafka.common.config.provider.EnvVarConfigProvider + - name: CONNECT_ADDITIONAL_CONFIGURATION + value: ro5XOd9Tf + - name: CONNECT_BOOTSTRAP_SERVERS + value: RKH + - name: SCHEMA_REGISTRY_URL + value: dt2Vd1bTg + - name: CONNECT_GC_LOG_ENABLED + value: x3dH + - name: CONNECT_HEAP_OPTS + value: -Xms256M -Xmx0 + - name: CONNECT_LOG_LEVEL + value: warn + - name: CONNECT_TLS_ENABLED + value: "true" + - name: CONNECT_TLS_AUTH_CERT + value: cert/khTfK + - name: CONNECT_TLS_AUTH_KEY + value: key/u0 + envFrom: + - prefix: Ci6EGf + secretRef: + name: cDwbNN + image: docker.redpanda.com/redpandadata/connectors:v1.0.29 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 1181508047 + httpGet: + path: / + port: rest-api + scheme: HTTP + initialDelaySeconds: -215289091 + periodSeconds: 918675027 + successThreshold: -1707139863 + timeoutSeconds: 1673866844 + name: connectors-cluster + ports: + - containerPort: 8083 + name: rest-api + protocol: TCP + - containerPort: 9404 + name: prometheus + protocol: TCP + readinessProbe: + failureThreshold: -1832996555 + httpGet: + path: /connectors + port: rest-api + scheme: HTTP + initialDelaySeconds: 877141221 + periodSeconds: 2102410645 + successThreshold: 1537121792 + timeoutSeconds: -2026548303 + resources: + limits: + cpu: "0" + memory: 2350Mi + requests: + cpu: "0" + memory: 2350Mi + securityContext: + allowPrivilegeEscalation: false + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /opt/kafka/connect-certs/cert + name: cert + - mountPath: /opt/kafka/connect-certs/key + name: key + - mountPath: /tmp + name: rp-connect-tmp + dnsPolicy: ClusterFirst + imagePullSecrets: [] + nodeSelector: {} + restartPolicy: Always + schedulerName: FQjdKmjClI5B + securityContext: + fsGroup: 101 + fsGroupChangePolicy: OnRootMismatch + runAsUser: 101 + serviceAccountName: zF + terminationGracePeriodSeconds: 1127207064 + tolerations: [] + topologySpreadConstraints: + - labelSelector: + matchLabels: + app.kubernetes.io/component: DAE + app.kubernetes.io/instance: console + app.kubernetes.io/name: DAE + wR: GAm + maxSkew: -1487816419 + topologyKey: Mw7m + whenUnsatisfiable: "" + - labelSelector: + matchLabels: + app.kubernetes.io/component: DAE + app.kubernetes.io/instance: console + app.kubernetes.io/name: DAE + wR: GAm + maxSkew: -1469244889 + topologyKey: HuZRY + whenUnsatisfiable: NX + - labelSelector: + matchLabels: + app.kubernetes.io/component: DAE + app.kubernetes.io/instance: console + app.kubernetes.io/name: DAE + wR: GAm + maxSkew: -346884429 + topologyKey: xVWCd + whenUnsatisfiable: p + volumes: + - name: cert + secret: + defaultMode: 292 + secretName: qXwTCH + - name: key + secret: + defaultMode: 292 + secretName: OCzzkl + - emptyDir: + medium: Memory + sizeLimit: 5Mi + name: rp-connect-tmp +-- testdata/case-018.yaml.golden -- +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: C + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: C + helm.sh/chart: connectors-0.1.12 + name: CVJfMb +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: 1476502274 + protocol: TCP + targetPort: 1476502274 + - name: DT + port: 0 + protocol: TCP + targetPort: 0 + selector: + app.kubernetes.io/component: C + app.kubernetes.io/instance: console + app.kubernetes.io/name: C + sessionAffinity: None + type: ClusterIP +--- +# Source: connectors/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: C + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: C + helm.sh/chart: connectors-0.1.12 + name: hX1VdtP7gp7c +spec: + progressDeadlineSeconds: 600 + replicas: null + revisionHistoryLimit: 10 + selector: + matchLabels: + app.kubernetes.io/component: C + app.kubernetes.io/instance: console + app.kubernetes.io/name: C + strategy: + type: RollingUpdate + template: + metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/component: C + app.kubernetes.io/instance: console + app.kubernetes.io/name: C + spec: + affinity: + nodeAffinity: {} + podAffinity: {} + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: C + app.kubernetes.io/instance: console + app.kubernetes.io/name: C + namespaces: + - default + topologyKey: kubernetes.io/hostname + containers: + - command: null + env: + - name: CONNECT_CONFIGURATION + value: |- + rest.advertised.port=1476502274 + rest.port=1476502274 + key.converter=org.apache.kafka.connect.converters.ByteArrayConverter + value.converter=org.apache.kafka.connect.converters.ByteArrayConverter + group.id=m + offset.storage.topic=_internal_connectors_offsets + config.storage.topic=_internal_connectors_configs + status.storage.topic=_internal_connectors_status + offset.storage.redpanda.remote.read=false + offset.storage.redpanda.remote.write=false + config.storage.redpanda.remote.read=false + config.storage.redpanda.remote.write=false + status.storage.redpanda.remote.read=false + status.storage.redpanda.remote.write=false + offset.storage.replication.factor=-1 + config.storage.replication.factor=-1 + status.storage.replication.factor=-1 + producer.linger.ms=-313398730 + producer.batch.size=1913291774 + config.providers=file,secretsManager,env + config.providers.file.class=org.apache.kafka.common.config.provider.FileConfigProvider + config.providers.env.class=org.apache.kafka.common.config.provider.EnvVarConfigProvider + - name: CONNECT_ADDITIONAL_CONFIGURATION + value: l3aLVX5 + - name: CONNECT_BOOTSTRAP_SERVERS + value: hj4Aab + - name: SCHEMA_REGISTRY_URL + value: nL5qOV + - name: CONNECT_GC_LOG_ENABLED + value: "false" + - name: CONNECT_HEAP_OPTS + value: -Xms256M -Xmx2G + - name: CONNECT_LOG_LEVEL + value: warn + - name: CONNECT_SASL_USERNAME + value: 1Iwn7 + - name: CONNECT_SASL_MECHANISM + value: VtLC5 + - name: CONNECT_SASL_PASSWORD_FILE + value: rc-credentials/password + - name: CONNECT_TLS_ENABLED + value: "false" + - name: CONNECT_TLS_AUTH_KEY + value: key/z4oRSGo + envFrom: [] + image: docker.redpanda.com/redpandadata/connectors:v1.0.29 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: rest-api + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: connectors-cluster + ports: + - containerPort: 1476502274 + name: rest-api + protocol: TCP + - containerPort: 0 + name: DT + protocol: TCP + readinessProbe: + failureThreshold: 2 + httpGet: + path: /connectors + port: rest-api + scheme: HTTP + initialDelaySeconds: 60 + periodSeconds: 10 + successThreshold: 3 + timeoutSeconds: 5 + resources: + limits: + cpu: "1" + memory: 2350Mi + requests: + cpu: "1" + memory: 2350Mi + securityContext: + allowPrivilegeEscalation: false + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /opt/kafka/connect-password/rc-credentials + name: rc-credentials + - mountPath: /opt/kafka/connect-certs/key + name: key + - mountPath: 5koRVhJz + mountPropagation: 穠耱誕Ȝ躰灬灺Ķ輔硯dzȦ1e蘄ò.o + name: 5lp + subPath: bEZmgVKO + subPathExpr: 5UCo6 + dnsPolicy: ClusterFirst + imagePullSecrets: + - name: W1 + nodeSelector: {} + restartPolicy: Always + schedulerName: "" + securityContext: + fsGroup: 101 + fsGroupChangePolicy: OnRootMismatch + runAsUser: 101 + serviceAccountName: 3xqtRwRI + terminationGracePeriodSeconds: 30 + tolerations: [] + topologySpreadConstraints: + - labelSelector: + matchLabels: + app.kubernetes.io/component: C + app.kubernetes.io/instance: console + app.kubernetes.io/name: C + maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: ScheduleAnyway + volumes: + - name: key + secret: + defaultMode: 292 + secretName: Ee + - name: rc-credentials + secret: + defaultMode: 292 + secretName: ng2m + - emptyDir: + medium: Memory + sizeLimit: 5Mi + name: rp-connect-tmp +-- testdata/case-019.yaml.golden -- +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + 1sF: 45XnA + a1rMZK: Jzq + app.kubernetes.io/component: qQY + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: qQY + helm.sh/chart: connectors-0.1.12 + name: iPsih4 +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: 2065008586 + protocol: TCP + targetPort: 2065008586 + - name: prometheus + port: 9404 + protocol: TCP + targetPort: 9404 + selector: + 1sF: 45XnA + a1rMZK: Jzq + app.kubernetes.io/component: qQY + app.kubernetes.io/instance: console + app.kubernetes.io/name: qQY + sessionAffinity: None + type: ClusterIP +--- +# Source: connectors/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + 1sF: 45XnA + a1rMZK: Jzq + app.kubernetes.io/component: qQY + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: qQY + helm.sh/chart: connectors-0.1.12 + name: S9NS5c +spec: + progressDeadlineSeconds: 600 + replicas: null + revisionHistoryLimit: -656791059 + selector: + matchLabels: + 1sF: 45XnA + a1rMZK: Jzq + app.kubernetes.io/component: qQY + app.kubernetes.io/instance: console + app.kubernetes.io/name: qQY + strategy: + type: RollingUpdate + template: + metadata: + annotations: {} + creationTimestamp: null + labels: + 1sF: 45XnA + a1rMZK: Jzq + app.kubernetes.io/component: qQY + app.kubernetes.io/instance: console + app.kubernetes.io/name: qQY + spec: + affinity: + nodeAffinity: {} + podAffinity: {} + podAntiAffinity: null + containers: + - command: null + env: + - name: CONNECT_CONFIGURATION + value: |- + rest.advertised.port=2065008586 + rest.port=2065008586 + key.converter=org.apache.kafka.connect.converters.ByteArrayConverter + value.converter=org.apache.kafka.connect.converters.ByteArrayConverter + group.id=CL5YFuVD + offset.storage.topic=_internal_connectors_offsets + config.storage.topic=_internal_connectors_configs + status.storage.topic=_internal_connectors_status + offset.storage.redpanda.remote.read=false + offset.storage.redpanda.remote.write=false + config.storage.redpanda.remote.read=false + config.storage.redpanda.remote.write=false + status.storage.redpanda.remote.read=false + status.storage.redpanda.remote.write=false + offset.storage.replication.factor=-1 + config.storage.replication.factor=-1 + status.storage.replication.factor=-1 + producer.linger.ms=-936976440 + producer.batch.size=131072 + config.providers=file,secretsManager,env + config.providers.file.class=org.apache.kafka.common.config.provider.FileConfigProvider + config.providers.secretsManager.class=com.github.jcustenborder.kafka.config.aws.SecretsManagerConfigProvider + config.providers.secretsManager.param.secret.prefix=79Q + config.providers.secretsManager.param.aws.region=3EfPcaJPeL + config.providers.env.class=org.apache.kafka.common.config.provider.EnvVarConfigProvider + - name: CONNECT_ADDITIONAL_CONFIGURATION + value: "" + - name: CONNECT_BOOTSTRAP_SERVERS + value: ezzGY + - name: SCHEMA_REGISTRY_URL + value: XTAQJ + - name: CONNECT_GC_LOG_ENABLED + value: "false" + - name: CONNECT_HEAP_OPTS + value: -Xms256M -Xmx2G + - name: CONNECT_LOG_LEVEL + value: warn + - name: CONNECT_TLS_ENABLED + value: "false" + - name: s + value: q7x401sB3R + - name: p + value: Odn + valueFrom: + fieldRef: + apiVersion: Tmp29KLiQ5 + fieldPath: "2" + secretKeyRef: + key: RRlr0C + name: jx + - name: M + value: dHu2S + valueFrom: + configMapKeyRef: + key: YT + name: x84MM29Kc5u + optional: true + fieldRef: + apiVersion: AKdDlUG8v + fieldPath: wHCWO + envFrom: + - configMapRef: + name: MF8pnsf + optional: false + prefix: lT + secretRef: + name: W + image: docker.redpanda.com/redpandadata/connectors:v1.0.29 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 832341066 + httpGet: + path: / + port: rest-api + scheme: HTTP + initialDelaySeconds: -493754907 + periodSeconds: -888317874 + successThreshold: -1792385861 + timeoutSeconds: -359586002 + name: connectors-cluster + ports: + - containerPort: 2065008586 + name: rest-api + protocol: TCP + - containerPort: 9404 + name: prometheus + protocol: TCP + readinessProbe: + failureThreshold: -2059548026 + httpGet: + path: /connectors + port: rest-api + scheme: HTTP + initialDelaySeconds: 438569678 + periodSeconds: 2034323562 + successThreshold: -1007748590 + timeoutSeconds: -1489292970 + resources: + limits: + cpu: "1" + memory: 2350Mi + requests: + cpu: "1" + memory: 2350Mi + securityContext: + allowPrivilegeEscalation: false + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /tmp + name: rp-connect-tmp + dnsPolicy: ClusterFirst + imagePullSecrets: [] + nodeSelector: {} + restartPolicy: Always + schedulerName: Wrjb3H + securityContext: + fsGroup: 101 + fsGroupChangePolicy: OnRootMismatch + runAsUser: 101 + serviceAccountName: default + terminationGracePeriodSeconds: 30 + tolerations: + - effect: Ƿ闄 + key: O + operator: 鵉鼌q穋R譼驪妼擕`ƛ駴ň + tolerationSeconds: -8397972967079996000 + value: 1KZwe4 + topologySpreadConstraints: + - labelSelector: + matchLabels: + 1sF: 45XnA + a1rMZK: Jzq + app.kubernetes.io/component: qQY + app.kubernetes.io/instance: console + app.kubernetes.io/name: qQY + maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: ScheduleAnyway + volumes: + - emptyDir: + medium: Memory + sizeLimit: 5Mi + name: rp-connect-tmp +-- testdata/case-020.yaml.golden -- +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: kUuRn + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: kUuRn + helm.sh/chart: connectors-0.1.12 + name: IAukfjAiE +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: 8083 + protocol: TCP + targetPort: 8083 + - name: prometheus + port: 9404 + protocol: TCP + targetPort: 9404 + selector: + app.kubernetes.io/component: kUuRn + app.kubernetes.io/instance: console + app.kubernetes.io/name: kUuRn + sessionAffinity: None + type: ClusterIP +-- testdata/case-021.yaml.golden -- +--- +# Source: connectors/templates/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + annotations: + QvndcW2wD: JmD + creationTimestamp: null + labels: + 5D3dcbYcmq: bkcA + app.kubernetes.io/component: Cg + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: Cg + helm.sh/chart: connectors-0.1.12 + "y": TxHhxVY2tRx1i + name: ABdKo + namespace: default +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + 5D3dcbYcmq: bkcA + app.kubernetes.io/component: Cg + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: Cg + g: Haj2trb + helm.sh/chart: connectors-0.1.12 + nQCD85u: 7ENE + "y": TxHhxVY2tRx1i + name: kt3xi +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: 8083 + protocol: TCP + targetPort: 8083 + - name: ZD6QnCdlL + port: 0 + protocol: TCP + targetPort: 0 + - name: kUQU + port: 0 + protocol: TCP + targetPort: 0 + selector: + 5D3dcbYcmq: bkcA + app.kubernetes.io/component: Cg + app.kubernetes.io/instance: console + app.kubernetes.io/name: Cg + "y": TxHhxVY2tRx1i + sessionAffinity: None + type: ClusterIP +--- +# Source: connectors/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + 5D3dcbYcmq: bkcA + "8": 6L8d + app.kubernetes.io/component: Cg + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: Cg + helm.sh/chart: connectors-0.1.12 + "y": TxHhxVY2tRx1i + name: console-Cg +spec: + progressDeadlineSeconds: 741558819 + replicas: null + revisionHistoryLimit: 1560482462 + selector: + matchLabels: + 5D3dcbYcmq: bkcA + app.kubernetes.io/component: Cg + app.kubernetes.io/instance: console + app.kubernetes.io/name: Cg + "y": TxHhxVY2tRx1i + strategy: + type: "9" + template: + metadata: + annotations: + "8": 6L8d + creationTimestamp: null + labels: + 5D3dcbYcmq: bkcA + app.kubernetes.io/component: Cg + app.kubernetes.io/instance: console + app.kubernetes.io/name: Cg + "y": TxHhxVY2tRx1i + spec: + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: j3g + operator: ŷǘȵiì渭ʫ抁Ğŋ + values: + - DJoN22 + - 4Kszk + - key: KYKZgrf + operator: 櫮ƣ+Ź藦vď蔸聺3vMʪ + matchFields: + - key: di6 + operator: ɫ0l5璠û介ɗ蟦ǘ厁ɂh磊 + values: + - ct + - 3e + - YICL + weight: 1941396141 + - preference: + matchExpressions: + - key: PRs0G0 + operator: ©MʥȩɅ2ď鏓 + - key: L83 + operator: °¥¶ĕ焲粮剚e喏鑝梋ƃ5~Ìnidž + matchFields: + - key: 78fF + operator: =ŞŽ熧曪ń + weight: 1964511070 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchFields: + - key: AHvs + operator: ɵȝʩm幃 + - key: 0ac + operator: MWæ諒鸠 + - {} + - matchExpressions: + - key: wRdw + operator: VP萺鵷 + - key: "" + operator: x + values: + - Fx + - I1rNR + - key: JZ + operator: 訖 + podAffinity: {} + podAntiAffinity: null + containers: + - command: null + env: + - name: CONNECT_CONFIGURATION + value: |- + rest.advertised.port=8083 + rest.port=8083 + key.converter=org.apache.kafka.connect.converters.ByteArrayConverter + value.converter=org.apache.kafka.connect.converters.ByteArrayConverter + group.id=eOkhi4 + offset.storage.topic=IK4 + config.storage.topic=EI + status.storage.topic=WIZGj + offset.storage.redpanda.remote.read=false + offset.storage.redpanda.remote.write=false + config.storage.redpanda.remote.read=false + config.storage.redpanda.remote.write=true + status.storage.redpanda.remote.read=true + status.storage.redpanda.remote.write=true + offset.storage.replication.factor=-1901393869 + config.storage.replication.factor=-1860412640 + status.storage.replication.factor=-4761328 + producer.linger.ms=-1955065214 + producer.batch.size=-500780400 + config.providers=file,secretsManager,env + config.providers.file.class=org.apache.kafka.common.config.provider.FileConfigProvider + config.providers.env.class=org.apache.kafka.common.config.provider.EnvVarConfigProvider + - name: CONNECT_ADDITIONAL_CONFIGURATION + value: jzE + - name: CONNECT_BOOTSTRAP_SERVERS + value: as60 + - name: SCHEMA_REGISTRY_URL + value: Jrt + - name: CONNECT_GC_LOG_ENABLED + value: HG + - name: CONNECT_HEAP_OPTS + value: -Xms256M -Xmx2G + - name: CONNECT_LOG_LEVEL + value: rb + - name: CONNECT_TLS_ENABLED + value: "false" + - name: CONNECT_TRUSTED_CERTS + value: ca/fifa + - name: CONNECT_TLS_AUTH_CERT + value: cert/MY5Ss + - name: mbyKA5WPoY + value: bhMRx + envFrom: + - configMapRef: + name: e7KgN9ff + optional: false + prefix: ug4D + secretRef: + name: CzuiueSY + optional: false + - configMapRef: + name: TlIbaiI + optional: true + prefix: I + - configMapRef: + name: IuBuoY8u5xD1D7 + optional: false + prefix: 2xqoZ + image: docker.redpanda.com/redpandadata/connectors:v1.0.29 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: rest-api + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: connectors-cluster + ports: + - containerPort: 8083 + name: rest-api + protocol: TCP + - containerPort: 0 + name: ZD6QnCdlL + protocol: TCP + - containerPort: 0 + name: kUQU + protocol: TCP + readinessProbe: + failureThreshold: 137175425 + httpGet: + path: /connectors + port: rest-api + scheme: HTTP + initialDelaySeconds: 385463317 + periodSeconds: 1814148060 + successThreshold: -2130595018 + timeoutSeconds: -1983859400 + resources: + limits: + cpu: "0" + memory: "0" + requests: + cpu: "1" + memory: "0" + securityContext: + allowPrivilegeEscalation: false + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /opt/kafka/connect-certs/ca + name: truststore + - mountPath: /opt/kafka/connect-certs/cert + name: cert + - mountPath: /tmp + name: rp-connect-tmp + dnsPolicy: ClusterFirst + imagePullSecrets: + - name: kq1gha8w + - {} + nodeSelector: + 88m: ofL96viVG + lM: uR4 + restartPolicy: 奡ʄ臔ȁ + schedulerName: v + securityContext: + fsGroup: 2775178225296577500 + fsGroupChangePolicy: OnRootMismatch + runAsGroup: -873168801110302200 + runAsNonRoot: true + runAsUser: -8949664932683741000 + sysctls: + - name: u + value: 0mDq + - name: UDLOQRVGXH + value: "" + - name: eakEWdkHQ + value: UWw + serviceAccountName: ABdKo + terminationGracePeriodSeconds: 1135949557 + tolerations: + - effect: ɖ + key: lzvKb + operator: V毣«mpAp餂ĵ$İƊ俊ĺ + tolerationSeconds: 1365476841054063900 + value: HqnJ8gfT + - effect: T鏚裦黂 + key: vgU + operator: 訹gǷ×婚ǀ + tolerationSeconds: -8509532606436755000 + value: KI + - effect: ?遗x + key: 6fxivUhl + operator: KŸȘ绒Nj赤 + value: mK2Hz + topologySpreadConstraints: + - labelSelector: + matchLabels: + 5D3dcbYcmq: bkcA + app.kubernetes.io/component: Cg + app.kubernetes.io/instance: console + app.kubernetes.io/name: Cg + "y": TxHhxVY2tRx1i + maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: ScheduleAnyway + volumes: + - name: truststore + secret: + defaultMode: 292 + secretName: BmRMpc + - name: cert + secret: + defaultMode: 292 + secretName: gy7g + - emptyDir: + medium: Memory + sizeLimit: 5Mi + name: rp-connect-tmp +-- testdata/case-022.yaml.golden -- +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + 3T: w2SpAA6br + I758z7Cf: 6V + JvnbWUk: pPMb + app.kubernetes.io/component: 6MJPA + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 6MJPA + helm.sh/chart: connectors-0.1.12 + name: x4Vu7vj +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: 8083 + protocol: TCP + targetPort: 8083 + - name: G4 + port: -201865350 + protocol: TCP + targetPort: -201865350 + selector: + 3T: w2SpAA6br + I758z7Cf: 6V + JvnbWUk: pPMb + app.kubernetes.io/component: 6MJPA + app.kubernetes.io/instance: console + app.kubernetes.io/name: 6MJPA + sessionAffinity: None + type: ClusterIP +--- +# Source: connectors/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + 3T: w2SpAA6br + I758z7Cf: 6V + JvnbWUk: pPMb + app.kubernetes.io/component: 6MJPA + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 6MJPA + helm.sh/chart: connectors-0.1.12 + name: cZ4G4 +spec: + progressDeadlineSeconds: 457348204 + replicas: null + revisionHistoryLimit: -700610054 + selector: + matchLabels: + 3T: w2SpAA6br + I758z7Cf: 6V + JvnbWUk: pPMb + app.kubernetes.io/component: 6MJPA + app.kubernetes.io/instance: console + app.kubernetes.io/name: 6MJPA + strategy: + type: IbrqLLHodX + template: + metadata: + annotations: {} + creationTimestamp: null + labels: + 3T: w2SpAA6br + I758z7Cf: 6V + JvnbWUk: pPMb + app.kubernetes.io/component: 6MJPA + app.kubernetes.io/instance: console + app.kubernetes.io/name: 6MJPA + spec: + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: Ro3T + operator: aĒĴŪ*3ɀ 币6鳴Ã偯d?A`åȏ + - key: 7XExK + operator: 濻舒^T莄1Â]葉 + values: + - A61yP5MBIRlE + - PvGUE + - 3dEaVo + - key: cLddzEo + operator: 櫜毉FÊi嶙# + matchFields: + - key: 5d + operator: 葜.¼v詝擽Ĉ + - key: WSMmbygG + operator: "" + weight: 1129540323 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kwkzOO8tl + operator: ']勋Į掬+' + matchFields: + - key: CQBwi20 + operator: 餞ǚe%Af埧Q哝窓煰 + - key: 9dTBxx + operator: Ĉ|^ + - matchFields: + - key: "" + operator: Á捛ɬĿ脦ǒĈ闲F秿翕卫Ŷ~?ʞŷȎ + values: + - Lg + - key: "42" + operator: 瞍 + values: + - QQMQ + - matchExpressions: + - key: en + operator: HË熙軯-ȓ簩羗č ʏ栽竬熄s)Ó鸰 + - key: Gc9Ntp + operator: "" + matchFields: + - key: 2ZLK4z1 + operator: 捚n匸竟-6ȐÒƑ|ʁĄEʕȘ + values: + - 0GiQ + - FI + - iXXs3k + - key: uujaIM5Y0Eo + operator: Āũ7 + podAffinity: {} + podAntiAffinity: null + containers: + - command: null + env: + - name: CONNECT_CONFIGURATION + value: |- + rest.advertised.port=8083 + rest.port=8083 + key.converter=org.apache.kafka.connect.converters.ByteArrayConverter + value.converter=org.apache.kafka.connect.converters.ByteArrayConverter + group.id=3SgngS9vl + offset.storage.topic=_internal_connectors_offsets + config.storage.topic=_internal_connectors_configs + status.storage.topic=_internal_connectors_status + offset.storage.redpanda.remote.read=false + offset.storage.redpanda.remote.write=false + config.storage.redpanda.remote.read=false + config.storage.redpanda.remote.write=false + status.storage.redpanda.remote.read=false + status.storage.redpanda.remote.write=false + offset.storage.replication.factor=-1 + config.storage.replication.factor=-1 + status.storage.replication.factor=-1 + producer.linger.ms=1 + producer.batch.size=889009746 + config.providers=file,secretsManager,env + config.providers.file.class=org.apache.kafka.common.config.provider.FileConfigProvider + config.providers.env.class=org.apache.kafka.common.config.provider.EnvVarConfigProvider + - name: CONNECT_ADDITIONAL_CONFIGURATION + value: faRWi + - name: CONNECT_BOOTSTRAP_SERVERS + value: XngcT + - name: SCHEMA_REGISTRY_URL + value: b4VVbJxS + - name: CONNECT_GC_LOG_ENABLED + value: "false" + - name: CONNECT_HEAP_OPTS + value: -Xms256M -Xmx2G + - name: CONNECT_LOG_LEVEL + value: warn + - name: CONNECT_TLS_ENABLED + value: "true" + - name: CONNECT_TRUSTED_CERTS + value: ca/MDvyt3bw + - name: CONNECT_TLS_AUTH_CERT + value: cert/LP7Pcx1xGT + envFrom: [] + image: docker.redpanda.com/redpandadata/connectors:v1.0.29 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: rest-api + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: connectors-cluster + ports: + - containerPort: 8083 + name: rest-api + protocol: TCP + - containerPort: -201865350 + name: G4 + protocol: TCP + readinessProbe: + failureThreshold: 511258221 + httpGet: + path: /connectors + port: rest-api + scheme: HTTP + initialDelaySeconds: 948711230 + periodSeconds: 19027716 + successThreshold: -1810396970 + timeoutSeconds: 1797719976 + resources: + limits: + cpu: "1" + memory: 2350Mi + requests: + cpu: "1" + memory: 2350Mi + securityContext: + allowPrivilegeEscalation: false + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /opt/kafka/connect-certs/ca + name: truststore + - mountPath: /opt/kafka/connect-certs/cert + name: cert + - mountPath: /tmp + name: rp-connect-tmp + dnsPolicy: ClusterFirst + imagePullSecrets: [] + nodeSelector: {} + restartPolicy: Always + schedulerName: 6Fuyr + securityContext: + fsGroup: 101 + fsGroupChangePolicy: OnRootMismatch + runAsUser: 101 + serviceAccountName: default + terminationGracePeriodSeconds: 1222617058 + tolerations: + - key: 9v + operator: ƱSjc(ϼ霌ʒ酁2Ɣ8kRâ + tolerationSeconds: 699537150416724600 + value: w8QXL + - effect: 旼`BȞ*ąɦ纇åʝ + key: vj3BwiVyW1t + operator: 鼦詡dƅ + tolerationSeconds: -9093487529989850000 + value: i8Agp + topologySpreadConstraints: + - labelSelector: + matchLabels: + 3T: w2SpAA6br + I758z7Cf: 6V + JvnbWUk: pPMb + app.kubernetes.io/component: 6MJPA + app.kubernetes.io/instance: console + app.kubernetes.io/name: 6MJPA + maxSkew: 0 + topologyKey: AFVo + whenUnsatisfiable: M4 + - labelSelector: + matchLabels: + 3T: w2SpAA6br + I758z7Cf: 6V + JvnbWUk: pPMb + app.kubernetes.io/component: 6MJPA + app.kubernetes.io/instance: console + app.kubernetes.io/name: 6MJPA + maxSkew: -1157554939 + topologyKey: oF + whenUnsatisfiable: juzJPaV2L03 + - labelSelector: + matchLabels: + 3T: w2SpAA6br + I758z7Cf: 6V + JvnbWUk: pPMb + app.kubernetes.io/component: 6MJPA + app.kubernetes.io/instance: console + app.kubernetes.io/name: 6MJPA + maxSkew: 0 + topologyKey: P6ooy + whenUnsatisfiable: svPI + volumes: + - name: truststore + secret: + defaultMode: 292 + secretName: b809b + - name: cert + secret: + defaultMode: 292 + secretName: Gg + - emptyDir: + medium: Memory + sizeLimit: 5Mi + name: rp-connect-tmp +--- +# Source: connectors/templates/pod-monitor.yaml +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + annotations: {} + creationTimestamp: null + labels: + Eedv: 65ZfBI + name: cZ4G4 +spec: + namespaceSelector: + any: true + podMetricsEndpoints: + - bearerTokenSecret: + key: "" + path: / + port: prometheus + selector: + matchLabels: + 3T: w2SpAA6br + I758z7Cf: 6V + JvnbWUk: pPMb + app.kubernetes.io/component: 6MJPA + app.kubernetes.io/instance: console + app.kubernetes.io/name: 6MJPA +-- testdata/case-023.yaml.golden -- +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: ZI341xw + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: ZI341xw + helm.sh/chart: connectors-0.1.12 + name: 9tds +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: 8083 + protocol: TCP + targetPort: 8083 + - name: prometheus + port: 9404 + protocol: TCP + targetPort: 9404 + selector: + app.kubernetes.io/component: ZI341xw + app.kubernetes.io/instance: console + app.kubernetes.io/name: ZI341xw + sessionAffinity: None + type: ClusterIP +--- +# Source: connectors/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: ZI341xw + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: ZI341xw + helm.sh/chart: connectors-0.1.12 + name: 9tds +spec: + progressDeadlineSeconds: 600 + replicas: null + revisionHistoryLimit: 10 + selector: + matchLabels: + app.kubernetes.io/component: ZI341xw + app.kubernetes.io/instance: console + app.kubernetes.io/name: ZI341xw + strategy: + type: RollingUpdate + template: + metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/component: ZI341xw + app.kubernetes.io/instance: console + app.kubernetes.io/name: ZI341xw + spec: + affinity: + nodeAffinity: {} + podAffinity: {} + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: ZI341xw + app.kubernetes.io/instance: console + app.kubernetes.io/name: ZI341xw + namespaces: + - default + topologyKey: kubernetes.io/hostname + containers: + - command: null + env: + - name: CONNECT_CONFIGURATION + value: |- + rest.advertised.port=8083 + rest.port=8083 + key.converter=org.apache.kafka.connect.converters.ByteArrayConverter + value.converter=org.apache.kafka.connect.converters.ByteArrayConverter + group.id=connectors-cluster + offset.storage.topic=_internal_connectors_offsets + config.storage.topic=_internal_connectors_configs + status.storage.topic=_internal_connectors_status + offset.storage.redpanda.remote.read=false + offset.storage.redpanda.remote.write=false + config.storage.redpanda.remote.read=false + config.storage.redpanda.remote.write=false + status.storage.redpanda.remote.read=false + status.storage.redpanda.remote.write=false + offset.storage.replication.factor=-1 + config.storage.replication.factor=-1 + status.storage.replication.factor=-1 + producer.linger.ms=1 + producer.batch.size=131072 + config.providers=file,secretsManager,env + config.providers.file.class=org.apache.kafka.common.config.provider.FileConfigProvider + config.providers.env.class=org.apache.kafka.common.config.provider.EnvVarConfigProvider + - name: CONNECT_ADDITIONAL_CONFIGURATION + value: "" + - name: CONNECT_BOOTSTRAP_SERVERS + value: "" + - name: CONNECT_GC_LOG_ENABLED + value: t7nvcU + - name: CONNECT_HEAP_OPTS + value: -Xms256M -Xmx2G + - name: CONNECT_LOG_LEVEL + value: bP + - name: CONNECT_TLS_ENABLED + value: "false" + envFrom: [] + image: docker.redpanda.com/redpandadata/connectors:v1.0.29 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: rest-api + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: connectors-cluster + ports: + - containerPort: 8083 + name: rest-api + protocol: TCP + - containerPort: 9404 + name: prometheus + protocol: TCP + readinessProbe: + failureThreshold: 2 + httpGet: + path: /connectors + port: rest-api + scheme: HTTP + initialDelaySeconds: 60 + periodSeconds: 10 + successThreshold: 3 + timeoutSeconds: 5 + resources: + limits: + cpu: "0" + memory: "0" + requests: + cpu: "0" + memory: "0" + securityContext: + allowPrivilegeEscalation: false + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: YeET3weL4N8g + mountPropagation: d/嬈Ñ內q謯ƶ8ɳƓ肵 + name: ssEfPGv8 + readOnly: true + subPath: "7" + dnsPolicy: ClusterFirst + imagePullSecrets: + - name: t + - name: 9jeO + - name: h + nodeSelector: {} + restartPolicy: Always + schedulerName: "" + securityContext: + fsGroup: 101 + fsGroupChangePolicy: OnRootMismatch + runAsUser: 101 + serviceAccountName: TIG + terminationGracePeriodSeconds: 30 + tolerations: [] + topologySpreadConstraints: + - labelSelector: + matchLabels: + app.kubernetes.io/component: ZI341xw + app.kubernetes.io/instance: console + app.kubernetes.io/name: ZI341xw + maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: ScheduleAnyway + volumes: + - name: naPNMJ +-- testdata/case-024.yaml.golden -- +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: Y47 + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: Y47 + helm.sh/chart: connectors-0.1.12 + name: e4W +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: -1930935263 + protocol: TCP + targetPort: -1930935263 + - name: prometheus + port: 9404 + protocol: TCP + targetPort: 9404 + selector: + app.kubernetes.io/component: Y47 + app.kubernetes.io/instance: console + app.kubernetes.io/name: Y47 + sessionAffinity: None + type: ClusterIP +--- +# Source: connectors/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + FU4J: "" + HJZjva: jC8uET + app.kubernetes.io/component: Y47 + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: Y47 + helm.sh/chart: connectors-0.1.12 + name: e4W +spec: + progressDeadlineSeconds: 5438195 + replicas: null + revisionHistoryLimit: -2103181148 + selector: + matchLabels: + app.kubernetes.io/component: Y47 + app.kubernetes.io/instance: console + app.kubernetes.io/name: Y47 + strategy: + type: 7Ma6SKn + template: + metadata: + annotations: + FU4J: "" + HJZjva: jC8uET + creationTimestamp: null + labels: + app.kubernetes.io/component: Y47 + app.kubernetes.io/instance: console + app.kubernetes.io/name: Y47 + spec: + affinity: + nodeAffinity: {} + podAffinity: {} + podAntiAffinity: null + containers: + - command: null + env: + - name: CONNECT_CONFIGURATION + value: |- + rest.advertised.port=-1930935263 + rest.port=-1930935263 + key.converter=org.apache.kafka.connect.converters.ByteArrayConverter + value.converter=org.apache.kafka.connect.converters.ByteArrayConverter + group.id=d + offset.storage.topic=_internal_connectors_offsets + config.storage.topic=_internal_connectors_configs + status.storage.topic=_internal_connectors_status + offset.storage.redpanda.remote.read=false + offset.storage.redpanda.remote.write=false + config.storage.redpanda.remote.read=false + config.storage.redpanda.remote.write=false + status.storage.redpanda.remote.read=false + status.storage.redpanda.remote.write=false + offset.storage.replication.factor=-1 + config.storage.replication.factor=-1 + status.storage.replication.factor=-1 + producer.linger.ms=714735160 + producer.batch.size=1166879364 + config.providers=file,secretsManager,env + config.providers.file.class=org.apache.kafka.common.config.provider.FileConfigProvider + config.providers.env.class=org.apache.kafka.common.config.provider.EnvVarConfigProvider + - name: CONNECT_ADDITIONAL_CONFIGURATION + value: LWHk + - name: CONNECT_BOOTSTRAP_SERVERS + value: jn + - name: SCHEMA_REGISTRY_URL + value: sz + - name: CONNECT_GC_LOG_ENABLED + value: XS5 + - name: CONNECT_HEAP_OPTS + value: -Xms256M -Xmx0 + - name: CONNECT_LOG_LEVEL + value: i1QoQHfki73v + - name: CONNECT_TLS_ENABLED + value: "true" + - name: CONNECT_TRUSTED_CERTS + value: ca/qv + envFrom: [] + image: docker.redpanda.com/redpandadata/connectors:v1.0.29 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: -1400952913 + httpGet: + path: / + port: rest-api + scheme: HTTP + initialDelaySeconds: 1536143416 + periodSeconds: -971919376 + successThreshold: 1841265139 + timeoutSeconds: 1519706329 + name: connectors-cluster + ports: + - containerPort: -1930935263 + name: rest-api + protocol: TCP + - containerPort: 9404 + name: prometheus + protocol: TCP + readinessProbe: + failureThreshold: 2057031608 + httpGet: + path: /connectors + port: rest-api + scheme: HTTP + initialDelaySeconds: 1457702974 + periodSeconds: -1732886 + successThreshold: -723791053 + timeoutSeconds: -547087401 + resources: + limits: + cpu: "0" + memory: "0" + requests: + cpu: "0" + memory: "0" + securityContext: + allowPrivilegeEscalation: true + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /opt/kafka/connect-certs/ca + name: truststore + - mountPath: /tmp + name: rp-connect-tmp + dnsPolicy: ClusterFirst + imagePullSecrets: [] + nodeSelector: + ZBtz30: MaN + wEyS43Wq6sS: A + restartPolicy: Always + schedulerName: tXdQ7X + securityContext: + fsGroup: -1024384248472849700 + fsGroupChangePolicy: OnRootMismatch + runAsNonRoot: false + runAsUser: -2673836885766821000 + sysctls: + - name: z + value: 1Xx7BcpTtc + - name: ik + value: mn7hZ2O + - name: 0tRcSAR + value: s3Fmk + serviceAccountName: AepmYU + terminationGracePeriodSeconds: 1680781404 + tolerations: + - effect: '[Ȝ%1@拌魋?>Q[' + key: CM6To + operator: ȫƤP箴ɉ戮嗯嬑lwĶƼ§ʜ + tolerationSeconds: -4298573611145221600 + value: ERnxlMnsbt + topologySpreadConstraints: + - labelSelector: + matchLabels: + app.kubernetes.io/component: Y47 + app.kubernetes.io/instance: console + app.kubernetes.io/name: Y47 + maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: ScheduleAnyway + volumes: + - name: truststore + secret: + defaultMode: 292 + secretName: LRHozVF + - emptyDir: + medium: Memory + sizeLimit: 5Mi + name: rp-connect-tmp +-- testdata/case-025.yaml.golden -- +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + VGEccN: 1S6Om + app.kubernetes.io/component: z3C + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: z3C + helm.sh/chart: connectors-0.1.12 + name: UFYrvO +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: -1355681307 + protocol: TCP + targetPort: -1355681307 + - name: prometheus + port: 9404 + protocol: TCP + targetPort: 9404 + selector: + VGEccN: 1S6Om + app.kubernetes.io/component: z3C + app.kubernetes.io/instance: console + app.kubernetes.io/name: z3C + sessionAffinity: None + type: ClusterIP +--- +# Source: connectors/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + VGEccN: 1S6Om + app.kubernetes.io/component: z3C + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: z3C + helm.sh/chart: connectors-0.1.12 + p7R: EjfLOeG + th6: enWXwqe + name: uv4tHoO +spec: + progressDeadlineSeconds: 202187696 + replicas: null + revisionHistoryLimit: 1394995435 + selector: + matchLabels: + VGEccN: 1S6Om + app.kubernetes.io/component: z3C + app.kubernetes.io/instance: console + app.kubernetes.io/name: z3C + strategy: + type: RollingUpdate + template: + metadata: + annotations: + p7R: EjfLOeG + th6: enWXwqe + creationTimestamp: null + labels: + VGEccN: 1S6Om + app.kubernetes.io/component: z3C + app.kubernetes.io/instance: console + app.kubernetes.io/name: z3C + spec: + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchFields: + - key: 6nwZP6 + operator: 乆`Eɪ妶窓o黥屢! + values: + - cJtx + weight: -559166881 + - preference: + matchExpressions: + - key: eyw69 + operator: 獶ʎ^ȁ耦ǚy蝸殽虄X敉${ + values: + - cLTjur + - Ab + - key: iMnx + operator: ßljƨb委揋ǖyǭɮHɋȱ钵瑴= + values: + - oTbQw + matchFields: + - key: peZc + operator: 韨醤H3擅ĭýǚɃ氤徣»嬞籍* + - key: BwW + operator: "" + values: + - lj0f + - key: RTfBwhMV7h + operator: 愐哣碍clȲ + weight: 1712242968 + podAffinity: {} + podAntiAffinity: null + containers: + - command: null + env: + - name: CONNECT_CONFIGURATION + value: |- + rest.advertised.port=-1355681307 + rest.port=-1355681307 + key.converter=org.apache.kafka.connect.converters.ByteArrayConverter + value.converter=org.apache.kafka.connect.converters.ByteArrayConverter + group.id=2Fy + offset.storage.topic=_internal_connectors_offsets + config.storage.topic=_internal_connectors_configs + status.storage.topic=_internal_connectors_status + offset.storage.redpanda.remote.read=false + offset.storage.redpanda.remote.write=false + config.storage.redpanda.remote.read=false + config.storage.redpanda.remote.write=false + status.storage.redpanda.remote.read=false + status.storage.redpanda.remote.write=false + offset.storage.replication.factor=-1 + config.storage.replication.factor=-1 + status.storage.replication.factor=-1 + producer.linger.ms=1 + producer.batch.size=131072 + config.providers=file,secretsManager,env + config.providers.file.class=org.apache.kafka.common.config.provider.FileConfigProvider + config.providers.env.class=org.apache.kafka.common.config.provider.EnvVarConfigProvider + - name: CONNECT_ADDITIONAL_CONFIGURATION + value: "n" + - name: CONNECT_BOOTSTRAP_SERVERS + value: JhxRF4 + - name: SCHEMA_REGISTRY_URL + value: 9uSqcQk + - name: CONNECT_GC_LOG_ENABLED + value: TmzFHzZvwn + - name: CONNECT_HEAP_OPTS + value: -Xms256M -Xmx2G + - name: CONNECT_LOG_LEVEL + value: warn + - name: CONNECT_TLS_ENABLED + value: "false" + - name: 5j0yE + value: O9bMi + valueFrom: + configMapKeyRef: + key: byf25 + name: RIZv + optional: false + fieldRef: + apiVersion: NrtU + fieldPath: 3LC + resourceFieldRef: + containerName: AjmWfg6HqMgn + divisor: "0" + resource: OV + - name: 6hTC + value: r + valueFrom: + configMapKeyRef: + key: 0u + name: 7xxySBjT + optional: true + resourceFieldRef: + containerName: qAO + divisor: "0" + resource: XP + envFrom: + - configMapRef: + name: uLvK + optional: false + prefix: 2Ij + secretRef: + name: leDGyXv + optional: true + - configMapRef: + name: GK + prefix: dCB + secretRef: + name: u + optional: false + image: docker.redpanda.com/redpandadata/connectors:v1.0.29 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: -94764338 + httpGet: + path: / + port: rest-api + scheme: HTTP + initialDelaySeconds: 407315123 + periodSeconds: 165966784 + successThreshold: 970096625 + timeoutSeconds: 2091942472 + name: connectors-cluster + ports: + - containerPort: -1355681307 + name: rest-api + protocol: TCP + - containerPort: 9404 + name: prometheus + protocol: TCP + readinessProbe: + failureThreshold: 1857603986 + httpGet: + path: /connectors + port: rest-api + scheme: HTTP + initialDelaySeconds: -1402792412 + periodSeconds: 879643685 + successThreshold: 1435235361 + timeoutSeconds: 1464897550 + resources: + limits: + cpu: "1" + memory: "0" + requests: + cpu: "1" + memory: 2350Mi + securityContext: + allowPrivilegeEscalation: false + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /tmp + name: rp-connect-tmp + dnsPolicy: ClusterFirst + imagePullSecrets: + - name: wd + - name: O + nodeSelector: {} + restartPolicy: '{悛Qª槟ĈW得蹏淂專驁sēɹƐ軋剭' + schedulerName: aA + securityContext: + fsGroup: 101 + fsGroupChangePolicy: OnRootMismatch + runAsUser: 101 + serviceAccountName: default + terminationGracePeriodSeconds: 30 + tolerations: + - effect: cȩ飙 + key: 4Y9saWpr + operator: 輋ƾ跴Ȫ徐1Aǡ{gm櫩茻 + value: yI4k + topologySpreadConstraints: + - labelSelector: + matchLabels: + VGEccN: 1S6Om + app.kubernetes.io/component: z3C + app.kubernetes.io/instance: console + app.kubernetes.io/name: z3C + maxSkew: 425976069 + topologyKey: aThb + whenUnsatisfiable: G + volumes: + - emptyDir: + medium: Memory + sizeLimit: 5Mi + name: rp-connect-tmp +--- +# Source: connectors/templates/pod-monitor.yaml +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + annotations: + hvh: "" + mDK0: OWEQ0y + zpG: XWCs + creationTimestamp: null + labels: + Ie5J5: fYnrHO + YkM4u7v: iTjIow + iP2Di: ptlD2Xuar + name: uv4tHoO +spec: + namespaceSelector: + any: true + matchNames: + - 9LShi + - klNT12U + - 9e + podMetricsEndpoints: + - bearerTokenSecret: + key: "" + path: / + port: prometheus + selector: + matchLabels: + VGEccN: 1S6Om + app.kubernetes.io/component: z3C + app.kubernetes.io/instance: console + app.kubernetes.io/name: z3C +-- testdata/case-026.yaml.golden -- +--- +# Source: connectors/templates/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/component: ATJ + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: ATJ + helm.sh/chart: connectors-0.1.12 + op: VnL9o7 + name: jmzfCmHq + namespace: default +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: ATJ + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: ATJ + helm.sh/chart: connectors-0.1.12 + op: VnL9o7 + name: XfK7 +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: 8083 + protocol: TCP + targetPort: 8083 + - name: prometheus + port: 9404 + protocol: TCP + targetPort: 9404 + selector: + app.kubernetes.io/component: ATJ + app.kubernetes.io/instance: console + app.kubernetes.io/name: ATJ + op: VnL9o7 + sessionAffinity: None + type: ClusterIP +-- testdata/case-027.yaml.golden -- +--- +# Source: connectors/templates/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + annotations: + N7gZ: ExrpJkw + PD23ZYO: jlj + creationTimestamp: null + labels: + LuCiH: SWR3zOt + app.kubernetes.io/component: ffe2 + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: ffe2 + helm.sh/chart: connectors-0.1.12 + name: maeWLc + namespace: default +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + JXMpPkd: YoI + LuCiH: SWR3zOt + Z: DVS9WjadC + app.kubernetes.io/component: ffe2 + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: ffe2 + helm.sh/chart: connectors-0.1.12 + name: uSz +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: 8083 + protocol: TCP + targetPort: 8083 + - name: prometheus + port: 9404 + protocol: TCP + targetPort: 9404 + selector: + LuCiH: SWR3zOt + app.kubernetes.io/component: ffe2 + app.kubernetes.io/instance: console + app.kubernetes.io/name: ffe2 + sessionAffinity: None + type: ClusterIP +--- +# Source: connectors/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + LuCiH: SWR3zOt + app.kubernetes.io/component: ffe2 + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: ffe2 + helm.sh/chart: connectors-0.1.12 + name: OL1 +spec: + progressDeadlineSeconds: 600 + replicas: null + revisionHistoryLimit: 10 + selector: + matchLabels: + LuCiH: SWR3zOt + app.kubernetes.io/component: ffe2 + app.kubernetes.io/instance: console + app.kubernetes.io/name: ffe2 + strategy: + type: RollingUpdate + template: + metadata: + annotations: {} + creationTimestamp: null + labels: + LuCiH: SWR3zOt + app.kubernetes.io/component: ffe2 + app.kubernetes.io/instance: console + app.kubernetes.io/name: ffe2 + spec: + affinity: + nodeAffinity: {} + podAffinity: {} + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + LuCiH: SWR3zOt + app.kubernetes.io/component: ffe2 + app.kubernetes.io/instance: console + app.kubernetes.io/name: ffe2 + namespaces: + - default + topologyKey: kubernetes.io/hostname + containers: + - command: null + env: + - name: CONNECT_CONFIGURATION + value: |- + rest.advertised.port=8083 + rest.port=8083 + key.converter=org.apache.kafka.connect.converters.ByteArrayConverter + value.converter=org.apache.kafka.connect.converters.ByteArrayConverter + group.id=connectors-cluster + offset.storage.topic=_internal_connectors_offsets + config.storage.topic=_internal_connectors_configs + status.storage.topic=_internal_connectors_status + offset.storage.redpanda.remote.read=false + offset.storage.redpanda.remote.write=false + config.storage.redpanda.remote.read=false + config.storage.redpanda.remote.write=false + status.storage.redpanda.remote.read=false + status.storage.redpanda.remote.write=false + offset.storage.replication.factor=-1 + config.storage.replication.factor=-1 + status.storage.replication.factor=-1 + producer.linger.ms=1 + producer.batch.size=131072 + config.providers=file,secretsManager,env + config.providers.file.class=org.apache.kafka.common.config.provider.FileConfigProvider + config.providers.env.class=org.apache.kafka.common.config.provider.EnvVarConfigProvider + - name: CONNECT_ADDITIONAL_CONFIGURATION + value: "" + - name: CONNECT_BOOTSTRAP_SERVERS + value: "" + - name: CONNECT_GC_LOG_ENABLED + value: Rk2lueKjUZ + - name: CONNECT_HEAP_OPTS + value: -Xms256M -Xmx0 + - name: CONNECT_LOG_LEVEL + value: warn + - name: CONNECT_TLS_ENABLED + value: "false" + envFrom: [] + image: docker.redpanda.com/redpandadata/connectors:v1.0.29 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: rest-api + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: connectors-cluster + ports: + - containerPort: 8083 + name: rest-api + protocol: TCP + - containerPort: 9404 + name: prometheus + protocol: TCP + readinessProbe: + failureThreshold: 2 + httpGet: + path: /connectors + port: rest-api + scheme: HTTP + initialDelaySeconds: 60 + periodSeconds: 10 + successThreshold: 3 + timeoutSeconds: 5 + resources: + limits: + cpu: "0" + memory: 2350Mi + requests: + cpu: "1" + memory: "0" + securityContext: + allowPrivilegeEscalation: false + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: RDO + mountPropagation: 縖ʯLj觻ĶR腉赙CèS咍Xz + name: NFJO + readOnly: true + subPath: i4tgwgPir + subPathExpr: 8C3d4ln + - mountPath: I + mountPropagation: "" + name: okJHlIlhWWGN + subPath: UQu + subPathExpr: 1D7d + dnsPolicy: ClusterFirst + imagePullSecrets: [] + nodeSelector: {} + restartPolicy: Always + schedulerName: "" + securityContext: + fsGroup: 101 + fsGroupChangePolicy: OnRootMismatch + runAsUser: 101 + serviceAccountName: maeWLc + terminationGracePeriodSeconds: 30 + tolerations: [] + topologySpreadConstraints: + - labelSelector: + matchLabels: + LuCiH: SWR3zOt + app.kubernetes.io/component: ffe2 + app.kubernetes.io/instance: console + app.kubernetes.io/name: ffe2 + maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: ScheduleAnyway + volumes: + - emptyDir: + medium: Memory + sizeLimit: 5Mi + name: rp-connect-tmp +-- testdata/case-028.yaml.golden -- +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + 3yehn: hb1JTt4bE6 + 8kZ: syTRQDJ + QFMui15S766: gMn5Cet2XRLMo + app.kubernetes.io/component: "3" + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: "3" + helm.sh/chart: connectors-0.1.12 + name: 9VQ +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: 8083 + protocol: TCP + targetPort: 8083 + - name: prometheus + port: 9404 + protocol: TCP + targetPort: 9404 + selector: + app.kubernetes.io/component: "3" + app.kubernetes.io/instance: console + app.kubernetes.io/name: "3" + sessionAffinity: None + type: ClusterIP +--- +# Source: connectors/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: "3" + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: "3" + helm.sh/chart: connectors-0.1.12 + name: ZvvoA +spec: + progressDeadlineSeconds: 600 + replicas: null + revisionHistoryLimit: 1716132030 + selector: + matchLabels: + app.kubernetes.io/component: "3" + app.kubernetes.io/instance: console + app.kubernetes.io/name: "3" + strategy: + type: GG3n + template: + metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/component: "3" + app.kubernetes.io/instance: console + app.kubernetes.io/name: "3" + spec: + affinity: + nodeAffinity: {} + podAffinity: {} + podAntiAffinity: null + containers: + - command: null + env: + - name: CONNECT_CONFIGURATION + value: |- + rest.advertised.port=8083 + rest.port=8083 + key.converter=org.apache.kafka.connect.converters.ByteArrayConverter + value.converter=org.apache.kafka.connect.converters.ByteArrayConverter + group.id=connectors-cluster + offset.storage.topic=_internal_connectors_offsets + config.storage.topic=_internal_connectors_configs + status.storage.topic=_internal_connectors_status + offset.storage.redpanda.remote.read=false + offset.storage.redpanda.remote.write=false + config.storage.redpanda.remote.read=false + config.storage.redpanda.remote.write=false + status.storage.redpanda.remote.read=false + status.storage.redpanda.remote.write=false + offset.storage.replication.factor=-1 + config.storage.replication.factor=-1 + status.storage.replication.factor=-1 + producer.linger.ms=1 + producer.batch.size=131072 + config.providers=file,secretsManager,env + config.providers.file.class=org.apache.kafka.common.config.provider.FileConfigProvider + config.providers.env.class=org.apache.kafka.common.config.provider.EnvVarConfigProvider + - name: CONNECT_ADDITIONAL_CONFIGURATION + value: "" + - name: CONNECT_BOOTSTRAP_SERVERS + value: "" + - name: CONNECT_GC_LOG_ENABLED + value: 3ahn64ZT + - name: CONNECT_HEAP_OPTS + value: -Xms256M -Xmx0 + - name: CONNECT_LOG_LEVEL + value: k1wsL2of + - name: CONNECT_TLS_ENABLED + value: "false" + - name: DvkYw9Pk + value: USGTgIYZwyPh + valueFrom: + configMapKeyRef: + key: xomkxxc + name: 7a + optional: false + fieldRef: + apiVersion: tnGFZ3 + fieldPath: H + resourceFieldRef: + containerName: UD5gAM615 + divisor: "0" + resource: EplPSqP + - name: "" + valueFrom: + configMapKeyRef: + key: 2n + name: vw5ZWohT + optional: true + fieldRef: + apiVersion: THSyklTdw + fieldPath: KDDja + resourceFieldRef: + containerName: ha2tB3cM0 + divisor: "0" + resource: 467hL5 + secretKeyRef: + key: I + name: vv9hXsUY + optional: false + envFrom: + - configMapRef: + name: "y" + optional: true + prefix: 8yKCF + secretRef: + name: 7B5wyZ16F + optional: true + - configMapRef: + name: zqz + prefix: iYiSC0Au26P + - prefix: w + secretRef: + name: p4 + image: docker.redpanda.com/redpandadata/connectors:v1.0.29 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: rest-api + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: connectors-cluster + ports: + - containerPort: 8083 + name: rest-api + protocol: TCP + - containerPort: 9404 + name: prometheus + protocol: TCP + readinessProbe: + failureThreshold: 2 + httpGet: + path: /connectors + port: rest-api + scheme: HTTP + initialDelaySeconds: 60 + periodSeconds: 10 + successThreshold: 3 + timeoutSeconds: 5 + resources: + limits: + cpu: "0" + memory: "0" + requests: + cpu: "1" + memory: 2350Mi + securityContext: + allowPrivilegeEscalation: true + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /tmp + name: rp-connect-tmp + dnsPolicy: ClusterFirst + imagePullSecrets: + - name: H + - name: HOE + nodeSelector: {} + restartPolicy: my + schedulerName: KL8nKi + securityContext: + fsGroup: 6950905231485894000 + fsGroupChangePolicy: 4駝ɧɍ匑ĿŃjH(ƨ鏝搲³欍荭 + runAsNonRoot: false + runAsUser: -3842777327443310000 + sysctls: + - name: ADfyWTN + value: "" + - name: A2KbAFX + value: vfiwuHLZA3z + serviceAccountName: Ms3WxpzY6U + terminationGracePeriodSeconds: -1876643927 + tolerations: + - effect: 幉cè禟ɴ + operator: ġ襜莪_ð迾uɈkʫ~鲕Lɻ戦ʡ2ȠǷ + tolerationSeconds: -3325398021525833700 + value: QDDTEv + - effect: hǝ + key: JwoXCcww + operator: ªA[wƸ + value: NvIa14 + - effect: ŐȜŻ-簀Ȟo/.濈s呁ī + key: v + operator: 7幔ÍX靹蟳 + tolerationSeconds: -8856646878602496000 + value: zOvR + topologySpreadConstraints: + - labelSelector: + matchLabels: + app.kubernetes.io/component: "3" + app.kubernetes.io/instance: console + app.kubernetes.io/name: "3" + maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: ScheduleAnyway + volumes: + - emptyDir: + medium: Memory + sizeLimit: 5Mi + name: rp-connect-tmp +--- +# Source: connectors/templates/pod-monitor.yaml +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + annotations: {} + creationTimestamp: null + labels: {} + name: ZvvoA +spec: + namespaceSelector: + any: true + podMetricsEndpoints: + - bearerTokenSecret: + key: "" + path: / + port: prometheus + selector: + matchLabels: + app.kubernetes.io/component: "3" + app.kubernetes.io/instance: console + app.kubernetes.io/name: "3" +-- testdata/case-029.yaml.golden -- +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + PGxtxZYXR: X5 + app.kubernetes.io/component: tl2YFI + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: tl2YFI + helm.sh/chart: connectors-0.1.12 + name: IyM +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: 1337396066 + protocol: TCP + targetPort: 1337396066 + - name: 9xn + port: -684513812 + protocol: TCP + targetPort: -684513812 + - name: u4xF + port: -391479350 + protocol: TCP + targetPort: -391479350 + - name: rDTiR56X + port: 382665278 + protocol: TCP + targetPort: 382665278 + selector: + app.kubernetes.io/component: tl2YFI + app.kubernetes.io/instance: console + app.kubernetes.io/name: tl2YFI + sessionAffinity: None + type: ClusterIP +--- +# Source: connectors/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: tl2YFI + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: tl2YFI + helm.sh/chart: connectors-0.1.12 + name: IyM +spec: + progressDeadlineSeconds: 533336746 + replicas: null + revisionHistoryLimit: -121719569 + selector: + matchLabels: + app.kubernetes.io/component: tl2YFI + app.kubernetes.io/instance: console + app.kubernetes.io/name: tl2YFI + strategy: + type: RollingUpdate + template: + metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/component: tl2YFI + app.kubernetes.io/instance: console + app.kubernetes.io/name: tl2YFI + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchFields: + - key: Th8xQ0 + operator: '};ƾ:Ơȏ旊苆$ź榘ę[Ş悈ȥ' + values: + - gOPH1k + - KOsql + podAffinity: {} + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: tl2YFI + app.kubernetes.io/instance: console + app.kubernetes.io/name: tl2YFI + namespaces: + - default + topologyKey: kubernetes.io/hostname + containers: + - command: null + env: + - name: CONNECT_CONFIGURATION + value: |- + rest.advertised.port=1337396066 + rest.port=1337396066 + key.converter=org.apache.kafka.connect.converters.ByteArrayConverter + value.converter=org.apache.kafka.connect.converters.ByteArrayConverter + group.id=F3e + offset.storage.topic=_internal_connectors_offsets + config.storage.topic=_internal_connectors_configs + status.storage.topic=_internal_connectors_status + offset.storage.redpanda.remote.read=true + offset.storage.redpanda.remote.write=false + config.storage.redpanda.remote.read=false + config.storage.redpanda.remote.write=true + status.storage.redpanda.remote.read=true + status.storage.redpanda.remote.write=true + offset.storage.replication.factor=-1 + config.storage.replication.factor=-1 + status.storage.replication.factor=-1 + producer.linger.ms=-410672871 + producer.batch.size=-1760140219 + config.providers=file,secretsManager,env + config.providers.file.class=org.apache.kafka.common.config.provider.FileConfigProvider + config.providers.secretsManager.class=com.github.jcustenborder.kafka.config.aws.SecretsManagerConfigProvider + config.providers.secretsManager.param.secret.prefix=pC3emUV + config.providers.secretsManager.param.aws.region=l6uFeZtI + config.providers.env.class=org.apache.kafka.common.config.provider.EnvVarConfigProvider + - name: CONNECT_ADDITIONAL_CONFIGURATION + value: Mq9r58Wn2 + - name: CONNECT_BOOTSTRAP_SERVERS + value: GhGh + - name: SCHEMA_REGISTRY_URL + value: eVOEb + - name: CONNECT_GC_LOG_ENABLED + value: "" + - name: CONNECT_HEAP_OPTS + value: -Xms256M -Xmx2G + - name: CONNECT_LOG_LEVEL + value: MM8vHtxMK + - name: CONNECT_SASL_USERNAME + value: "206" + - name: CONNECT_SASL_MECHANISM + value: pVvPbLq8PH + - name: CONNECT_SASL_PASSWORD_FILE + value: rc-credentials/password + - name: CONNECT_TLS_ENABLED + value: "false" + - name: CONNECT_TRUSTED_CERTS + value: ca/ca.crt + - name: CONNECT_TLS_AUTH_KEY + value: key/kn1yG + - name: "" + value: a + valueFrom: + configMapKeyRef: + key: S + optional: false + fieldRef: + apiVersion: cAFu3Wwm4O + fieldPath: "" + resourceFieldRef: + containerName: K + divisor: "0" + resource: pYz + secretKeyRef: + key: rrusH7t + name: 6hR1vtMek + optional: true + - name: 62b + value: b4k + valueFrom: + resourceFieldRef: + containerName: 9Zuqk + divisor: "0" + resource: wDbwci + secretKeyRef: + key: q + name: a3Go0SITja + optional: false + - name: CAn + value: r + valueFrom: + configMapKeyRef: + key: oBsj + name: f + optional: true + fieldRef: + apiVersion: K + fieldPath: e60DM + resourceFieldRef: + containerName: 9xyY28RraQXtmbHZs9v + divisor: "0" + resource: ddr6SE + secretKeyRef: + key: HIl + name: 6i + envFrom: + - prefix: J + secretRef: + name: 4niuc27 + optional: false + - configMapRef: + name: dVR + optional: false + prefix: WUotCc + secretRef: + optional: true + image: docker.redpanda.com/redpandadata/connectors:v1.0.29 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: rest-api + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: connectors-cluster + ports: + - containerPort: 1337396066 + name: rest-api + protocol: TCP + - containerPort: -684513812 + name: 9xn + protocol: TCP + - containerPort: -391479350 + name: u4xF + protocol: TCP + - containerPort: 382665278 + name: rDTiR56X + protocol: TCP + readinessProbe: + failureThreshold: 2079208961 + httpGet: + path: /connectors + port: rest-api + scheme: HTTP + initialDelaySeconds: 1156905473 + periodSeconds: -1924622812 + successThreshold: -1575566868 + timeoutSeconds: -450997563 + resources: + limits: + cpu: "1" + memory: 2350Mi + requests: + cpu: "0" + memory: 2350Mi + securityContext: + allowPrivilegeEscalation: false + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /opt/kafka/connect-password/rc-credentials + name: rc-credentials + - mountPath: /opt/kafka/connect-certs/ca + name: truststore + - mountPath: /opt/kafka/connect-certs/key + name: key + - mountPath: /tmp + name: rp-connect-tmp + dnsPolicy: ClusterFirst + imagePullSecrets: + - name: 1tlBA + nodeSelector: {} + restartPolicy: Always + schedulerName: Z7Ne6 + securityContext: + fsGroup: -790114255836881900 + fsGroupChangePolicy: OnRootMismatch + runAsGroup: 4623887472960955000 + runAsNonRoot: true + runAsUser: 7622666161830128000 + supplementalGroups: + - -3228001931932573000 + - -7141992959148916000 + - -17407268992027108 + sysctls: + - name: 8qCsQ + value: RwRLG + - name: f2Rn + value: afHwsU + - name: 3jYk9 + value: V + serviceAccountName: default + terminationGracePeriodSeconds: -1948657833 + tolerations: + - effect: 冮味Pf鵸q\)霰¢玲&糦Ŀ怋ɌÁ燹 + key: uTzXciQ + operator: 3IJuʙNj + value: FB0Hu + topologySpreadConstraints: + - labelSelector: + matchLabels: + app.kubernetes.io/component: tl2YFI + app.kubernetes.io/instance: console + app.kubernetes.io/name: tl2YFI + maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: ScheduleAnyway + volumes: + - name: truststore + secret: + defaultMode: 292 + secretName: u + - name: key + secret: + defaultMode: 292 + secretName: CE + - name: rc-credentials + secret: + defaultMode: 292 + secretName: a8g3R + - emptyDir: + medium: Memory + sizeLimit: 5Mi + name: rp-connect-tmp +-- testdata/case-030.yaml.golden -- +--- +# Source: connectors/templates/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + GCdbeC: cQ4P1cHbv + app.kubernetes.io/component: P7 + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: P7 + helm.sh/chart: connectors-0.1.12 + name: UQ27oL + namespace: default +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + GCdbeC: cQ4P1cHbv + app.kubernetes.io/component: P7 + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: P7 + helm.sh/chart: connectors-0.1.12 + name: IVe +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: -1808248501 + protocol: TCP + targetPort: -1808248501 + - name: prometheus + port: 9404 + protocol: TCP + targetPort: 9404 + selector: + GCdbeC: cQ4P1cHbv + app.kubernetes.io/component: P7 + app.kubernetes.io/instance: console + app.kubernetes.io/name: P7 + sessionAffinity: None + type: ClusterIP +-- testdata/case-031.yaml.golden -- +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + RER: AU + app.kubernetes.io/component: pLehdV + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: pLehdV + helm.sh/chart: connectors-0.1.12 + name: MnW8I02 +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: -1300816856 + protocol: TCP + targetPort: -1300816856 + - name: 5bgCNjS + port: 0 + protocol: TCP + targetPort: 0 + - name: gh + port: 792720017 + protocol: TCP + targetPort: 792720017 + selector: + app.kubernetes.io/component: pLehdV + app.kubernetes.io/instance: console + app.kubernetes.io/name: pLehdV + sessionAffinity: None + type: ClusterIP +--- +# Source: connectors/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: pLehdV + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: pLehdV + helm.sh/chart: connectors-0.1.12 + name: pPZgwOOt +spec: + progressDeadlineSeconds: 600 + replicas: null + revisionHistoryLimit: 10 + selector: + matchLabels: + app.kubernetes.io/component: pLehdV + app.kubernetes.io/instance: console + app.kubernetes.io/name: pLehdV + strategy: + type: RollingUpdate + template: + metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/component: pLehdV + app.kubernetes.io/instance: console + app.kubernetes.io/name: pLehdV + spec: + affinity: + nodeAffinity: {} + podAffinity: {} + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: pLehdV + app.kubernetes.io/instance: console + app.kubernetes.io/name: pLehdV + namespaces: + - default + topologyKey: kubernetes.io/hostname + containers: + - command: null + env: + - name: CONNECT_CONFIGURATION + value: |- + rest.advertised.port=-1300816856 + rest.port=-1300816856 + key.converter=org.apache.kafka.connect.converters.ByteArrayConverter + value.converter=org.apache.kafka.connect.converters.ByteArrayConverter + group.id=chzc6 + offset.storage.topic=NoMzWmd + config.storage.topic=vOa + status.storage.topic=UX + offset.storage.redpanda.remote.read=true + offset.storage.redpanda.remote.write=true + config.storage.redpanda.remote.read=true + config.storage.redpanda.remote.write=false + status.storage.redpanda.remote.read=false + status.storage.redpanda.remote.write=true + offset.storage.replication.factor=-1 + config.storage.replication.factor=-1 + status.storage.replication.factor=-1 + producer.linger.ms=-1169688418 + producer.batch.size=164004875 + config.providers=file,secretsManager,env + config.providers.file.class=org.apache.kafka.common.config.provider.FileConfigProvider + config.providers.env.class=org.apache.kafka.common.config.provider.EnvVarConfigProvider + - name: CONNECT_ADDITIONAL_CONFIGURATION + value: rJQp + - name: CONNECT_BOOTSTRAP_SERVERS + value: 0y2l8XHWK + - name: SCHEMA_REGISTRY_URL + value: qb + - name: CONNECT_GC_LOG_ENABLED + value: FZNoDU + - name: CONNECT_HEAP_OPTS + value: -Xms256M -Xmx0 + - name: CONNECT_LOG_LEVEL + value: mw + - name: CONNECT_SASL_USERNAME + value: s + - name: CONNECT_SASL_MECHANISM + value: OKrEkY + - name: CONNECT_SASL_PASSWORD_FILE + value: rc-credentials/password + - name: CONNECT_TLS_ENABLED + value: "false" + - name: CONNECT_TRUSTED_CERTS + value: ca/ca.crt + - name: CONNECT_TLS_AUTH_CERT + value: cert/copKWn2 + - name: CONNECT_TLS_AUTH_KEY + value: key/IlMv6 + envFrom: [] + image: docker.redpanda.com/redpandadata/connectors:v1.0.29 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: rest-api + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: connectors-cluster + ports: + - containerPort: -1300816856 + name: rest-api + protocol: TCP + - containerPort: 0 + name: 5bgCNjS + protocol: TCP + - containerPort: 792720017 + name: gh + protocol: TCP + readinessProbe: + failureThreshold: 2 + httpGet: + path: /connectors + port: rest-api + scheme: HTTP + initialDelaySeconds: 60 + periodSeconds: 10 + successThreshold: 3 + timeoutSeconds: 5 + resources: + limits: + cpu: "0" + memory: "0" + requests: + cpu: "0" + memory: "0" + securityContext: + allowPrivilegeEscalation: true + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /opt/kafka/connect-password/rc-credentials + name: rc-credentials + - mountPath: /opt/kafka/connect-certs/ca + name: truststore + - mountPath: /opt/kafka/connect-certs/cert + name: cert + - mountPath: /opt/kafka/connect-certs/key + name: key + - mountPath: "" + mountPropagation: Ǜ绕:O+ + name: 4JTdCoLQd + readOnly: true + subPath: RUx + subPathExpr: 0E + dnsPolicy: ClusterFirst + imagePullSecrets: [] + nodeSelector: {} + restartPolicy: Always + schedulerName: "" + securityContext: + fsGroup: 101 + fsGroupChangePolicy: OnRootMismatch + runAsUser: 101 + serviceAccountName: "5" + terminationGracePeriodSeconds: 30 + tolerations: [] + topologySpreadConstraints: + - labelSelector: + matchLabels: + app.kubernetes.io/component: pLehdV + app.kubernetes.io/instance: console + app.kubernetes.io/name: pLehdV + maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: ScheduleAnyway + volumes: + - name: truststore + secret: + defaultMode: 292 + secretName: J + - name: cert + secret: + defaultMode: 292 + secretName: DNF6s + - name: key + secret: + defaultMode: 292 + secretName: NI3VUhJks3aM + - name: rc-credentials + secret: + defaultMode: 292 + secretName: 8nzj + - name: T6INhQ + - name: p0 + - name: EO +-- testdata/case-032.yaml.golden -- +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: connectors + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: connectors + helm.sh/chart: connectors-0.1.12 + name: 8geRNocLQ +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: 108700971 + protocol: TCP + targetPort: 108700971 + - name: prometheus + port: 9404 + protocol: TCP + targetPort: 9404 + selector: + app.kubernetes.io/component: connectors + app.kubernetes.io/instance: console + app.kubernetes.io/name: connectors + sessionAffinity: None + type: ClusterIP +-- testdata/case-033.yaml.golden -- +--- +# Source: connectors/templates/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + annotations: + gkbEy: M2fwFG + iP1: vVwLn + creationTimestamp: null + labels: + KZj1Dby: 4SqUXw + app.kubernetes.io/component: bz0yr + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: bz0yr + helm.sh/chart: connectors-0.1.12 + name: LVtVe0en + namespace: default +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + "": kPbb + Ch7xjM: i0HEOruP + KZj1Dby: 4SqUXw + app.kubernetes.io/component: bz0yr + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: bz0yr + helm.sh/chart: connectors-0.1.12 + kt: "" + name: crWrH +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: -1714220122 + protocol: TCP + targetPort: -1714220122 + - name: f5JB9Etw + port: 1398564584 + protocol: TCP + targetPort: 1398564584 + - name: hkCnR + port: 1899193486 + protocol: TCP + targetPort: 1899193486 + - name: DUOEQmC + port: 0 + protocol: TCP + targetPort: 0 + selector: + KZj1Dby: 4SqUXw + app.kubernetes.io/component: bz0yr + app.kubernetes.io/instance: console + app.kubernetes.io/name: bz0yr + sessionAffinity: None + type: ClusterIP +-- testdata/case-034.yaml.golden -- +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + M2Ya3Qp: efwJA + app.kubernetes.io/component: Pt + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: Pt + c: fgV + eHykHSeD: M0vI4 + helm.sh/chart: connectors-0.1.12 + ik: hu + trc: W + name: 1hV +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: -754597379 + protocol: TCP + targetPort: -754597379 + - name: 6W9P3J + port: 1027996572 + protocol: TCP + targetPort: 1027996572 + - name: UQcXQO4H6 + port: 0 + protocol: TCP + targetPort: 0 + selector: + M2Ya3Qp: efwJA + app.kubernetes.io/component: Pt + app.kubernetes.io/instance: console + app.kubernetes.io/name: Pt + trc: W + sessionAffinity: None + type: ClusterIP +-- testdata/case-035.yaml.golden -- +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + YaiOBiXa: rQx + app.kubernetes.io/component: PeueQ + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: PeueQ + co: MffSo + fdioW3StBvzyh: z + helm.sh/chart: connectors-0.1.12 + ofToM: "n" + wle: mprjb + name: mC3vFeP +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: -559590357 + protocol: TCP + targetPort: -559590357 + - name: prometheus + port: 9404 + protocol: TCP + targetPort: 9404 + selector: + app.kubernetes.io/component: PeueQ + app.kubernetes.io/instance: console + app.kubernetes.io/name: PeueQ + co: MffSo + fdioW3StBvzyh: z + wle: mprjb + sessionAffinity: None + type: ClusterIP +--- +# Source: connectors/templates/pod-monitor.yaml +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + annotations: + "4": kTkxkO + creationTimestamp: null + labels: {} + name: 6fr +spec: + namespaceSelector: + any: true + matchNames: + - FKCzSYm7gaXuLQ + podMetricsEndpoints: + - bearerTokenSecret: + key: "" + path: / + port: prometheus + selector: + matchLabels: + app.kubernetes.io/component: PeueQ + app.kubernetes.io/instance: console + app.kubernetes.io/name: PeueQ + co: MffSo + fdioW3StBvzyh: z + wle: mprjb +-- testdata/case-036.yaml.golden -- +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + 1qqW32x: "" + app.kubernetes.io/component: taotfWzUIl + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: taotfWzUIl + helm.sh/chart: connectors-0.1.12 + lp92O: 1QnD84Dhxl + name: GxFDpR9IkU +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: -1153123375 + protocol: TCP + targetPort: -1153123375 + - name: prometheus + port: 9404 + protocol: TCP + targetPort: 9404 + selector: + 1qqW32x: "" + app.kubernetes.io/component: taotfWzUIl + app.kubernetes.io/instance: console + app.kubernetes.io/name: taotfWzUIl + sessionAffinity: None + type: ClusterIP +--- +# Source: connectors/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + 1qqW32x: "" + app.kubernetes.io/component: taotfWzUIl + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: taotfWzUIl + helm.sh/chart: connectors-0.1.12 + name: VW0lF +spec: + progressDeadlineSeconds: -1260879447 + replicas: null + revisionHistoryLimit: -1294473838 + selector: + matchLabels: + 1qqW32x: "" + app.kubernetes.io/component: taotfWzUIl + app.kubernetes.io/instance: console + app.kubernetes.io/name: taotfWzUIl + strategy: + type: 5cn + template: + metadata: + annotations: {} + creationTimestamp: null + labels: + 1qqW32x: "" + app.kubernetes.io/component: taotfWzUIl + app.kubernetes.io/instance: console + app.kubernetes.io/name: taotfWzUIl + spec: + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchFields: + - key: 3bTiSjGL + operator: Pʡdz饿n抈Ʊt嬩癘Ƈ + values: + - AGfqyUGQXxyY + - FVcNDfkQ + - v3hp7MN8nVKE + - key: L3S + operator: -殊 + values: + - 97iUcu + - dXmY + - KUxQvBTJu + - key: YNi + operator: ijS泉ľ;ŒvS阸多嵠{ + values: + - xf0B + weight: -207219009 + - preference: + matchExpressions: + - key: EAkVkI70 + operator: 钚寽蛺izȭ7_掅桘 + values: + - aAWkk + - ze + - 3wGu + - key: 3RyfQc6N + operator: 5ɔ螗śLƆ扒\ƃ"氧ɉ + values: + - Vv + - key: 1vVqYpX + operator: Yto%Iƈ?暊I)琣?Ć痕猖ȕ + values: + - 9yyhe2i + weight: 2145655584 + - preference: + matchExpressions: + - key: vYGC + operator: 缈饜代u灧Ȼ + matchFields: + - key: Xbz + operator: ż苡訖ɑʟĨı齻@IJ騮削ƽ蹄濁榷鰠 + values: + - qFq5zh0O + - yG0 + - nT + - key: P3 + operator: ǧ唾潣PNJ掉ơ\庱吳.,OLX + - key: 3ATe + operator: ʦ恀^ + values: + - LUm4b + weight: 351084922 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: XLalOY + operator: 挝R凗ŵ莁5E7?Ȓʍm篫l{Č蒄 + values: + - YrzbvR + - 5awUoV + - a + - key: bhAd + operator: 鴵鈌ąt烿æy伸?^đĔʎ{Ç柧 + values: + - GqRb + - key: 8WgrpCvg + operator: bAMƺ惸鹖ŏ垇ɔǁI庫û*ɔ嶢ɚ菑 + values: + - BRd8A5 + - "9" + - K9hDIBU + matchFields: + - key: FntInb + operator: '{@əɃðŗ8''4' + - key: cPqf3 + operator: Ƌ娔殺慑 + - key: o + operator: ɧlǬ量GJ恉əŏ滸IōĈwǝ栢Jȡ + podAffinity: {} + podAntiAffinity: null + containers: + - command: null + env: + - name: CONNECT_CONFIGURATION + value: |- + rest.advertised.port=-1153123375 + rest.port=-1153123375 + key.converter=org.apache.kafka.connect.converters.ByteArrayConverter + value.converter=org.apache.kafka.connect.converters.ByteArrayConverter + group.id=XuGw0bAvU4mCl29 + offset.storage.topic=AqMgsp + config.storage.topic=BKIQd85 + status.storage.topic=cB + offset.storage.redpanda.remote.read=false + offset.storage.redpanda.remote.write=true + config.storage.redpanda.remote.read=true + config.storage.redpanda.remote.write=false + status.storage.redpanda.remote.read=true + status.storage.redpanda.remote.write=false + offset.storage.replication.factor=1816899175 + config.storage.replication.factor=935026050 + status.storage.replication.factor=1556885434 + producer.linger.ms=1479365932 + producer.batch.size=1402635005 + config.providers=file,secretsManager,env + config.providers.file.class=org.apache.kafka.common.config.provider.FileConfigProvider + config.providers.env.class=org.apache.kafka.common.config.provider.EnvVarConfigProvider + - name: CONNECT_ADDITIONAL_CONFIGURATION + value: LhQU + - name: CONNECT_BOOTSTRAP_SERVERS + value: PJXgS + - name: SCHEMA_REGISTRY_URL + value: owIrcBoHKcGy + - name: CONNECT_GC_LOG_ENABLED + value: 92CKlhkT1dY + - name: CONNECT_HEAP_OPTS + value: -Xms256M -Xmx0 + - name: CONNECT_LOG_LEVEL + value: PAOVCu + - name: CONNECT_SASL_USERNAME + value: ZTak1O6cR + - name: CONNECT_SASL_MECHANISM + value: 4pr3gf + - name: CONNECT_SASL_PASSWORD_FILE + value: rc-credentials/password + - name: CONNECT_TLS_ENABLED + value: "false" + - name: CONNECT_TRUSTED_CERTS + value: ca/pMccWpS50Tt + - name: CONNECT_TLS_AUTH_CERT + value: cert/c4sa0FA + - name: CONNECT_TLS_AUTH_KEY + value: key/EOAKr + envFrom: [] + image: docker.redpanda.com/redpandadata/connectors:v1.0.29 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: -1589865511 + httpGet: + path: / + port: rest-api + scheme: HTTP + initialDelaySeconds: -621095822 + periodSeconds: 280342995 + successThreshold: -167276282 + timeoutSeconds: -1535167124 + name: connectors-cluster + ports: + - containerPort: -1153123375 + name: rest-api + protocol: TCP + - containerPort: 9404 + name: prometheus + protocol: TCP + readinessProbe: + failureThreshold: 1985429634 + httpGet: + path: /connectors + port: rest-api + scheme: HTTP + initialDelaySeconds: 520999520 + periodSeconds: 1834416895 + successThreshold: -2144235192 + timeoutSeconds: -1654928979 + resources: + limits: + cpu: "0" + memory: "0" + requests: + cpu: "0" + memory: "0" + securityContext: + allowPrivilegeEscalation: false + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /opt/kafka/connect-password/rc-credentials + name: rc-credentials + - mountPath: /opt/kafka/connect-certs/ca + name: truststore + - mountPath: /opt/kafka/connect-certs/cert + name: cert + - mountPath: /opt/kafka/connect-certs/key + name: key + - mountPath: MMqGiv5CN + mountPropagation: 鳮耐uíȪr + name: jHofb9BQ3 + readOnly: true + subPath: aDzkmP + subPathExpr: 4sgTWM4H + - mountPath: KhsFs + mountPropagation: Ǎ繟ƣʜ + name: V02ibh + readOnly: true + subPath: LF + subPathExpr: mi + dnsPolicy: ClusterFirst + imagePullSecrets: + - name: zaKvtKNIW0 + - name: "9" + - name: fG + nodeSelector: + gQqg: rQO1 + restartPolicy: '>Ȏ縂ɴ垍ū*' + schedulerName: mlm5OhgsGh + securityContext: + fsGroup: -24635125662907280 + fsGroupChangePolicy: Ŏ痿1>a茫ȡ跦 þ + runAsGroup: -3967780041970195000 + runAsNonRoot: true + runAsUser: 8970781034706956000 + supplementalGroups: + - -8270543106812796000 + sysctls: + - name: KljKqWpUKsb3 + value: 9Zv + - name: z8scvHARn + value: sk + serviceAccountName: srWYjAnpR + terminationGracePeriodSeconds: 446877207 + tolerations: + - effect: ɟ + key: J906H + operator: Ȇ:龳虹$鿲Ȥ.t齹Ń5 + tolerationSeconds: 6789201977316389000 + value: vV1 + - effect: ©Ǯ膗Ǖ盉浝Ŝɟ + key: ju6amcMPM8UK + operator: 衭蛩ņý + tolerationSeconds: -8177010640192863000 + value: S + - effect: cÑ + operator: L晚G& + tolerationSeconds: 8159638238997451000 + value: OyDyWZoaY + topologySpreadConstraints: + - labelSelector: + matchLabels: + 1qqW32x: "" + app.kubernetes.io/component: taotfWzUIl + app.kubernetes.io/instance: console + app.kubernetes.io/name: taotfWzUIl + maxSkew: 1646710512 + topologyKey: MbS + whenUnsatisfiable: Ia0hRF8y + volumes: + - name: truststore + secret: + defaultMode: 292 + secretName: MyH + - name: cert + secret: + defaultMode: 292 + secretName: Iv + - name: key + secret: + defaultMode: 292 + secretName: no0Ke + - name: rc-credentials + secret: + defaultMode: 292 + secretName: Na4b + - name: qx + - name: XeUJ +-- testdata/case-037.yaml.golden -- +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + 5bK2xe: ZRy + HSu1: FRG692y + QExXAto3Ub2T: etTOY4y8iSmyDOe + app.kubernetes.io/component: 03U7 + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 03U7 + helm.sh/chart: connectors-0.1.12 + name: "87" +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: 1885084612 + protocol: TCP + targetPort: 1885084612 + - name: yMA8tJxHo + port: -582141187 + protocol: TCP + targetPort: -582141187 + - name: "9" + port: 830415771 + protocol: TCP + targetPort: 830415771 + selector: + HSu1: FRG692y + QExXAto3Ub2T: etTOY4y8iSmyDOe + app.kubernetes.io/component: 03U7 + app.kubernetes.io/instance: console + app.kubernetes.io/name: 03U7 + sessionAffinity: None + type: ClusterIP +--- +# Source: connectors/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + HSu1: FRG692y + PsITu: LgrI + QExXAto3Ub2T: etTOY4y8iSmyDOe + app.kubernetes.io/component: 03U7 + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 03U7 + helm.sh/chart: connectors-0.1.12 + name: vRXgQsUzl3 +spec: + progressDeadlineSeconds: -1761307563 + replicas: null + revisionHistoryLimit: -1377004535 + selector: + matchLabels: + HSu1: FRG692y + QExXAto3Ub2T: etTOY4y8iSmyDOe + app.kubernetes.io/component: 03U7 + app.kubernetes.io/instance: console + app.kubernetes.io/name: 03U7 + strategy: + type: qVm + template: + metadata: + annotations: + PsITu: LgrI + creationTimestamp: null + labels: + HSu1: FRG692y + QExXAto3Ub2T: etTOY4y8iSmyDOe + app.kubernetes.io/component: 03U7 + app.kubernetes.io/instance: console + app.kubernetes.io/name: 03U7 + spec: + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: tmEGf + operator: "" + values: + - yCcLCb + - O1NTsHk78miTJ + - key: KuvLpSp4X + operator: 獴ĝB违写õʕĠEɊ繎ª + values: + - oqAB + - "y" + - cLExkHCRfD + - key: tMxc + operator: 1Ņ鸩瀚羨鱬c)0ƶ音êA{ǷZŁȃ + values: + - W2 + - rXnf + matchFields: + - key: dvXtkKrlxr + operator: m駠祸¯獒ɌƗ'Ñnj嗰蒩,幔Ǣ + values: + - vDUy + - vzx4 + - key: UU6d + operator: 惂PqbKɕ`ǃȒCʉ鞊Ĩ% + - key: qm03jaCk + operator: a靔Pƴy%(AĔð勶乀ĥČI#ɃǙ蘨 + weight: -1872535291 + - preference: + matchExpressions: + - key: GjG + operator: űŌ + - key: UQ + operator: d欻Ɲ + values: + - zpBqznM + matchFields: + - key: gKn2 + operator: ÁŠ9玫Ʌ + values: + - Iij79g + weight: 1456486091 + - preference: + matchExpressions: + - key: 1Ef + operator: G飔8`ɒ蕸祹&匪璳拖嶴6s['%邗 + values: + - iBr + - "" + - key: RXMgUipZ + operator: Qāȃ鋘ǖ0iNɭȂuŦ褌7Èȝ鹊淋廽 + values: + - NB + - key: nb6 + operator: 杘ɯ#`慐 + weight: -1381009180 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: [] + podAffinity: {} + podAntiAffinity: null + containers: + - command: null + env: + - name: CONNECT_CONFIGURATION + value: |- + rest.advertised.port=1885084612 + rest.port=1885084612 + key.converter=org.apache.kafka.connect.converters.ByteArrayConverter + value.converter=org.apache.kafka.connect.converters.ByteArrayConverter + group.id=q + offset.storage.topic=WDtxRL37SvNV + config.storage.topic=fiLg3L + status.storage.topic=Guofk9 + offset.storage.redpanda.remote.read=true + offset.storage.redpanda.remote.write=false + config.storage.redpanda.remote.read=true + config.storage.redpanda.remote.write=true + status.storage.redpanda.remote.read=true + status.storage.redpanda.remote.write=false + offset.storage.replication.factor=-1765361377 + config.storage.replication.factor=575483838 + status.storage.replication.factor=-1294780557 + producer.linger.ms=982363719 + producer.batch.size=-1100237413 + config.providers=file,secretsManager,env + config.providers.file.class=org.apache.kafka.common.config.provider.FileConfigProvider + config.providers.env.class=org.apache.kafka.common.config.provider.EnvVarConfigProvider + - name: CONNECT_ADDITIONAL_CONFIGURATION + value: FTlQkC + - name: CONNECT_BOOTSTRAP_SERVERS + value: LeVg + - name: SCHEMA_REGISTRY_URL + value: N8 + - name: CONNECT_GC_LOG_ENABLED + value: mn + - name: CONNECT_HEAP_OPTS + value: -Xms256M -Xmx0 + - name: CONNECT_LOG_LEVEL + value: Y0gfv + - name: CONNECT_TLS_ENABLED + value: "false" + - name: CONNECT_TRUSTED_CERTS + value: ca/49XwYgsyn + - name: CONNECT_TLS_AUTH_CERT + value: cert/Wf + - name: CONNECT_TLS_AUTH_KEY + value: key/7rwbl + - name: 7PtPut9 + value: 4Uo + valueFrom: + configMapKeyRef: + key: H6 + name: JEPQ + optional: true + fieldRef: + apiVersion: yCSfB + fieldPath: HD + resourceFieldRef: + containerName: v0wW + divisor: "0" + resource: BliOlDq + secretKeyRef: + key: AOod + name: Ljqm + optional: false + - name: FItx + value: cZIyVQPdqZ + valueFrom: + configMapKeyRef: + key: O3 + name: KlO + optional: true + fieldRef: + apiVersion: BnfYTBc + fieldPath: xw + resourceFieldRef: + containerName: qzV549 + divisor: "0" + resource: sctpzNUt + secretKeyRef: + key: Ff4vJm + name: hoEa + optional: false + envFrom: [] + image: docker.redpanda.com/redpandadata/connectors:v1.0.29 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 1572051601 + httpGet: + path: / + port: rest-api + scheme: HTTP + initialDelaySeconds: -455418157 + periodSeconds: 31037144 + successThreshold: 1836675270 + timeoutSeconds: -722680942 + name: connectors-cluster + ports: + - containerPort: 1885084612 + name: rest-api + protocol: TCP + - containerPort: -582141187 + name: yMA8tJxHo + protocol: TCP + - containerPort: 830415771 + name: "9" + protocol: TCP + readinessProbe: + failureThreshold: 1393918041 + httpGet: + path: /connectors + port: rest-api + scheme: HTTP + initialDelaySeconds: -1529972341 + periodSeconds: 1791885136 + successThreshold: -1003238871 + timeoutSeconds: 516179111 + resources: + limits: + cpu: "0" + memory: "0" + requests: + cpu: "0" + memory: "0" + securityContext: + allowPrivilegeEscalation: false + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /opt/kafka/connect-certs/ca + name: truststore + - mountPath: /opt/kafka/connect-certs/cert + name: cert + - mountPath: /opt/kafka/connect-certs/key + name: key + - mountPath: FMieal + mountPropagation: q睢1Êb2y"ğJĢ + name: GRAaf7 + readOnly: true + subPath: Wvz + subPathExpr: K4St + - mountPath: E6 + mountPropagation: 2`| + name: yu + subPath: 1Qyv + subPathExpr: lq + - mountPath: "9" + mountPropagation: J仅<Ⱦù觏牨¼Ǐ蒜,J偛l挨 + name: CkWy + subPath: 1YtfYCwcHU3 + subPathExpr: xUIPjXS + dnsPolicy: ClusterFirst + imagePullSecrets: + - name: d18 + nodeSelector: {} + restartPolicy: tAȍ_祴珗ƨŐ飔矜ƧŸȺ8Ù凿吱 + schedulerName: k + securityContext: + fsGroup: -8943063634632833000 + fsGroupChangePolicy: 樜3g罡Sɺ:礁j + runAsGroup: -8183677367766310000 + runAsNonRoot: false + runAsUser: 6257019186377026000 + supplementalGroups: + - 6349796974429449000 + - -6495960424240768000 + sysctls: + - name: tNzNhbs + value: Li + - name: xw + value: wQYd + - name: rijilGaE1rE + value: O1VB + serviceAccountName: 1J + terminationGracePeriodSeconds: -340872360 + tolerations: + - effect: 旽ǷȬƱĬɔH辂W'ʩ菽懝 + key: NRzfhGYG1Y + operator: 皏棵FɁÈ棿X + tolerationSeconds: 4658882017834993000 + value: Lu + - effect: "~" + key: k + operator: 垫 + tolerationSeconds: -950306177981439200 + value: j2wtF4uhca + topologySpreadConstraints: + - labelSelector: + matchLabels: + HSu1: FRG692y + QExXAto3Ub2T: etTOY4y8iSmyDOe + app.kubernetes.io/component: 03U7 + app.kubernetes.io/instance: console + app.kubernetes.io/name: 03U7 + maxSkew: -1481065440 + topologyKey: SER + whenUnsatisfiable: 5L7rrGecd + volumes: + - name: truststore + secret: + defaultMode: 292 + secretName: 28O + - name: cert + secret: + defaultMode: 292 + secretName: EDOE + - name: key + secret: + defaultMode: 292 + secretName: TaD + - name: QbE11Wi + - name: 5p +-- testdata/case-038.yaml.golden -- +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: BX8JrNja9K1E + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: BX8JrNja9K1E + eYdK: Cku + helm.sh/chart: connectors-0.1.12 + ztF1: wwq1 + name: mCI +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: 436787525 + protocol: TCP + targetPort: 436787525 + - name: mQD4tg + port: -951318322 + protocol: TCP + targetPort: -951318322 + selector: + app.kubernetes.io/component: BX8JrNja9K1E + app.kubernetes.io/instance: console + app.kubernetes.io/name: BX8JrNja9K1E + sessionAffinity: None + type: ClusterIP +-- testdata/case-039.yaml.golden -- +--- +# Source: connectors/templates/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + annotations: + UCvD: zlN0tsbA + creationTimestamp: null + labels: + MnrW: 2y + V4b1: iOkt + app.kubernetes.io/component: mn + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: mn + helm.sh/chart: connectors-0.1.12 + name: ZkHM + namespace: default +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + MnrW: 2y + V4b1: iOkt + app.kubernetes.io/component: mn + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: mn + helm.sh/chart: connectors-0.1.12 + name: El70 +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: 1444795321 + protocol: TCP + targetPort: 1444795321 + - name: prometheus + port: 9404 + protocol: TCP + targetPort: 9404 + selector: + MnrW: 2y + V4b1: iOkt + app.kubernetes.io/component: mn + app.kubernetes.io/instance: console + app.kubernetes.io/name: mn + sessionAffinity: None + type: ClusterIP +--- +# Source: connectors/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + MnrW: 2y + V4b1: iOkt + app.kubernetes.io/component: mn + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: mn + helm.sh/chart: connectors-0.1.12 + name: jio8f +spec: + progressDeadlineSeconds: -1221802348 + replicas: null + revisionHistoryLimit: 1248617462 + selector: + matchLabels: + MnrW: 2y + V4b1: iOkt + app.kubernetes.io/component: mn + app.kubernetes.io/instance: console + app.kubernetes.io/name: mn + strategy: + type: qsB + template: + metadata: + annotations: {} + creationTimestamp: null + labels: + MnrW: 2y + V4b1: iOkt + app.kubernetes.io/component: mn + app.kubernetes.io/instance: console + app.kubernetes.io/name: mn + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: fcm8Ew + operator: 副瘫 + - key: "07" + operator: 阫ƣʊPŠ!7椃ûĺɉ呙鼲坣呐ȡ + values: + - IEopzACw + - UJT7 + - key: MUXZ + operator: äĢ + values: + - ltoOhu + - SYLAu90Sic + podAffinity: {} + podAntiAffinity: null + containers: + - command: null + env: + - name: CONNECT_CONFIGURATION + value: |- + rest.advertised.port=1444795321 + rest.port=1444795321 + key.converter=org.apache.kafka.connect.converters.ByteArrayConverter + value.converter=org.apache.kafka.connect.converters.ByteArrayConverter + group.id=BOkRc + offset.storage.topic=6kl + config.storage.topic=E + status.storage.topic=mk + offset.storage.redpanda.remote.read=true + offset.storage.redpanda.remote.write=false + config.storage.redpanda.remote.read=true + config.storage.redpanda.remote.write=false + status.storage.redpanda.remote.read=true + status.storage.redpanda.remote.write=false + offset.storage.replication.factor=577990303 + config.storage.replication.factor=1941218076 + status.storage.replication.factor=-1541756269 + producer.linger.ms=1359438163 + producer.batch.size=-2127171944 + config.providers=file,secretsManager,env + config.providers.file.class=org.apache.kafka.common.config.provider.FileConfigProvider + config.providers.env.class=org.apache.kafka.common.config.provider.EnvVarConfigProvider + - name: CONNECT_ADDITIONAL_CONFIGURATION + value: 8NGjNgy + - name: CONNECT_BOOTSTRAP_SERVERS + value: xU + - name: SCHEMA_REGISTRY_URL + value: j7V227t + - name: CONNECT_GC_LOG_ENABLED + value: mnLDVzboOU + - name: CONNECT_HEAP_OPTS + value: -Xms256M -Xmx0 + - name: CONNECT_LOG_LEVEL + value: A9j + - name: CONNECT_SASL_USERNAME + value: AsbjUhR + - name: CONNECT_SASL_MECHANISM + value: 3FmU9Mj + - name: CONNECT_SASL_PASSWORD_FILE + value: rc-credentials/password + - name: CONNECT_TLS_ENABLED + value: "false" + - name: CONNECT_TRUSTED_CERTS + value: ca/ca.crt + - name: CONNECT_TLS_AUTH_CERT + value: cert/HQ + - name: CONNECT_TLS_AUTH_KEY + value: key/tls.key + - name: MMy5 + value: H + valueFrom: + configMapKeyRef: + key: nJ2K0MV + name: zp + optional: false + fieldRef: + apiVersion: wVLbzHBVPimhM + fieldPath: AejPbHX81DSFH8Q + resourceFieldRef: + containerName: Q6jlN + divisor: "0" + resource: FVErZI + secretKeyRef: + key: fAj9qbwJX41v + name: Hlf + optional: false + - name: Sz + value: ohDj + valueFrom: + configMapKeyRef: + key: MC10 + name: Q + optional: true + fieldRef: + apiVersion: tkvB + fieldPath: Wvk + resourceFieldRef: + containerName: iX + divisor: "0" + resource: VBz4peZ + secretKeyRef: + key: zQnXIdnN + name: 4L5 + optional: false + envFrom: [] + image: docker.redpanda.com/redpandadata/connectors:v1.0.29 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: -1801401906 + httpGet: + path: / + port: rest-api + scheme: HTTP + initialDelaySeconds: -1928987976 + periodSeconds: 366101264 + successThreshold: 1101494705 + timeoutSeconds: 1657384826 + name: connectors-cluster + ports: + - containerPort: 1444795321 + name: rest-api + protocol: TCP + - containerPort: 9404 + name: prometheus + protocol: TCP + readinessProbe: + failureThreshold: 316564184 + httpGet: + path: /connectors + port: rest-api + scheme: HTTP + initialDelaySeconds: -678114858 + periodSeconds: -1932943963 + successThreshold: -1295008485 + timeoutSeconds: 1251310237 + resources: + limits: + cpu: "0" + memory: "0" + requests: + cpu: "0" + memory: "0" + securityContext: + allowPrivilegeEscalation: true + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /opt/kafka/connect-password/rc-credentials + name: rc-credentials + - mountPath: /opt/kafka/connect-certs/ca + name: truststore + - mountPath: /opt/kafka/connect-certs/cert + name: cert + - mountPath: /opt/kafka/connect-certs/key + name: key + - mountPath: /tmp + name: rp-connect-tmp + dnsPolicy: ClusterFirst + imagePullSecrets: [] + nodeSelector: + Q4e0pQre8Ui: ybd + W0tuX2DKY: t + hK1gicteS: oRdivh + restartPolicy: 刊ǵ椉Ž5荭¶@Ǻ + schedulerName: NtMcVkr + securityContext: + fsGroup: -7790002735836359000 + fsGroupChangePolicy: '猰tą3圇épțU串ɭ惟璼ʜ ' + runAsGroup: 7078321909676639000 + runAsNonRoot: true + runAsUser: -3795473018051875300 + sysctls: + - name: 4bbbOThlM9 + value: OeQ + - name: KzYDmoPm + value: RQkJ4 + - name: gSEB + value: fCw + serviceAccountName: ZkHM + terminationGracePeriodSeconds: 1536232091 + tolerations: + - key: Kme1g + operator: 鸋傚脨ʌȰę,缶 + tolerationSeconds: 9185074187324502000 + value: HP1mcWeehE + topologySpreadConstraints: + - labelSelector: + matchLabels: + MnrW: 2y + V4b1: iOkt + app.kubernetes.io/component: mn + app.kubernetes.io/instance: console + app.kubernetes.io/name: mn + maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: ScheduleAnyway + volumes: + - name: truststore + secret: + defaultMode: 292 + secretName: z0ac + - name: cert + secret: + defaultMode: 292 + secretName: Yvl1 + - name: key + secret: + defaultMode: 292 + secretName: Gq + - name: rc-credentials + secret: + defaultMode: 292 + secretName: GUdAwXVY + - name: PQgVp5UAKMh + - name: m + - name: "" +-- testdata/case-040.yaml.golden -- +--- +# Source: connectors/templates/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + annotations: + "": s + 6aAoyzS: BVK + SV0dnqH: Rk + creationTimestamp: null + labels: + 4bQpba: iVh + app.kubernetes.io/component: 4iNcef5 + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 4iNcef5 + helm.sh/chart: connectors-0.1.12 + "n": "" + name: FKhGHe3aO + namespace: default +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + 4bQpba: iVh + LG: ZJQw2J8u + app.kubernetes.io/component: 4iNcef5 + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 4iNcef5 + g: 0z9gQt4Yj + helm.sh/chart: connectors-0.1.12 + "n": "" + name: KxK +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: -1022927047 + protocol: TCP + targetPort: -1022927047 + - name: 61dR + port: 9129423 + protocol: TCP + targetPort: 9129423 + - name: p0D + port: 1391241101 + protocol: TCP + targetPort: 1391241101 + - name: 0MZ6s8 + port: 708219631 + protocol: TCP + targetPort: 708219631 + selector: + 4bQpba: iVh + app.kubernetes.io/component: 4iNcef5 + app.kubernetes.io/instance: console + app.kubernetes.io/name: 4iNcef5 + "n": "" + sessionAffinity: None + type: ClusterIP +--- +# Source: connectors/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + 4bQpba: iVh + 6WNO: UvMxPC + ItkfXr: HoRGq + OqfY9eu: U + app.kubernetes.io/component: 4iNcef5 + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 4iNcef5 + helm.sh/chart: connectors-0.1.12 + "n": "" + name: NCw6T6UcQY +spec: + progressDeadlineSeconds: 570610379 + replicas: null + revisionHistoryLimit: 1380150017 + selector: + matchLabels: + 4bQpba: iVh + app.kubernetes.io/component: 4iNcef5 + app.kubernetes.io/instance: console + app.kubernetes.io/name: 4iNcef5 + "n": "" + strategy: + type: 7Mz64 + template: + metadata: + annotations: + 6WNO: UvMxPC + ItkfXr: HoRGq + OqfY9eu: U + creationTimestamp: null + labels: + 4bQpba: iVh + app.kubernetes.io/component: 4iNcef5 + app.kubernetes.io/instance: console + app.kubernetes.io/name: 4iNcef5 + "n": "" + spec: + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: 19IV1NC + operator: ȃ}CĚ蟡ɨvǢȺ + values: + - "" + matchFields: + - key: xl + operator: VĦɓ洽Ă滕煂 + values: + - jreFryn + weight: 1586123299 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: [] + podAffinity: {} + podAntiAffinity: null + containers: + - command: null + env: + - name: CONNECT_CONFIGURATION + value: |- + rest.advertised.port=-1022927047 + rest.port=-1022927047 + key.converter=org.apache.kafka.connect.converters.ByteArrayConverter + value.converter=org.apache.kafka.connect.converters.ByteArrayConverter + group.id=br + offset.storage.topic=H + config.storage.topic=9Qtxti + status.storage.topic=BP + offset.storage.redpanda.remote.read=false + offset.storage.redpanda.remote.write=true + config.storage.redpanda.remote.read=false + config.storage.redpanda.remote.write=true + status.storage.redpanda.remote.read=true + status.storage.redpanda.remote.write=false + offset.storage.replication.factor=-1418511808 + config.storage.replication.factor=-1386973481 + status.storage.replication.factor=-748221252 + producer.linger.ms=-1500250091 + producer.batch.size=-2033745427 + config.providers=file,secretsManager,env + config.providers.file.class=org.apache.kafka.common.config.provider.FileConfigProvider + config.providers.env.class=org.apache.kafka.common.config.provider.EnvVarConfigProvider + - name: CONNECT_ADDITIONAL_CONFIGURATION + value: qvMttAMx + - name: CONNECT_BOOTSTRAP_SERVERS + value: LRTyIJY + - name: SCHEMA_REGISTRY_URL + value: cL1M + - name: CONNECT_GC_LOG_ENABLED + value: QXA6zua + - name: CONNECT_HEAP_OPTS + value: -Xms256M -Xmx0 + - name: CONNECT_LOG_LEVEL + value: Tb + - name: CONNECT_SASL_USERNAME + value: KF7Nnx + - name: CONNECT_SASL_MECHANISM + value: eXWm9 + - name: CONNECT_SASL_PASSWORD_FILE + value: rc-credentials/password + - name: CONNECT_TLS_ENABLED + value: "false" + - name: CONNECT_TRUSTED_CERTS + value: ca/rRP + - name: CONNECT_TLS_AUTH_CERT + value: cert/peG + - name: CONNECT_TLS_AUTH_KEY + value: key/Tbz + - name: pwJ0I3ZEUK7 + value: aaFCEfM + valueFrom: + configMapKeyRef: + key: DXmjvM9 + name: JYBPb + optional: false + fieldRef: + apiVersion: 9fI + fieldPath: 90keHRVll + resourceFieldRef: + containerName: rBYEwmI + divisor: "0" + resource: Sn9Gkn + secretKeyRef: + key: T3YsImGDrshtv + name: w + optional: false + envFrom: [] + image: docker.redpanda.com/redpandadata/connectors:v1.0.29 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 285554662 + httpGet: + path: / + port: rest-api + scheme: HTTP + initialDelaySeconds: 620513520 + periodSeconds: -983699293 + successThreshold: 537883135 + timeoutSeconds: 843588973 + name: connectors-cluster + ports: + - containerPort: -1022927047 + name: rest-api + protocol: TCP + - containerPort: 9129423 + name: 61dR + protocol: TCP + - containerPort: 1391241101 + name: p0D + protocol: TCP + - containerPort: 708219631 + name: 0MZ6s8 + protocol: TCP + readinessProbe: + failureThreshold: -473671565 + httpGet: + path: /connectors + port: rest-api + scheme: HTTP + initialDelaySeconds: -2130499066 + periodSeconds: -39801992 + successThreshold: -1693089511 + timeoutSeconds: -1707372527 + resources: + limits: + cpu: "0" + memory: "0" + requests: + cpu: "0" + memory: "0" + securityContext: + allowPrivilegeEscalation: false + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /opt/kafka/connect-password/rc-credentials + name: rc-credentials + - mountPath: /opt/kafka/connect-certs/ca + name: truststore + - mountPath: /opt/kafka/connect-certs/cert + name: cert + - mountPath: /opt/kafka/connect-certs/key + name: key + - mountPath: /tmp + name: rp-connect-tmp + dnsPolicy: ClusterFirst + imagePullSecrets: + - name: u + - name: 13J + - name: q9t1lU0k + nodeSelector: + ne: QT3mjpm7B + restartPolicy: °č + schedulerName: O26H + securityContext: + fsGroup: 7015643872446876 + fsGroupChangePolicy: 烳=~沽侣X + runAsGroup: -3630702614293936600 + runAsNonRoot: true + runAsUser: 4388805261963142700 + supplementalGroups: + - -7755253763247303000 + - -3310400039802532000 + - 2051254341870838000 + sysctls: + - name: 7UwNr + value: tkn + - name: nGm + value: V + - name: KhS + value: jbpUUVGjT + serviceAccountName: FKhGHe3aO + terminationGracePeriodSeconds: -1194184480 + tolerations: + - effect: 曶ámɶ役ōœE顾坳4Ńɟ蒷Ǚó + key: 3u + operator: 卭ƺ?o + tolerationSeconds: 701640152884990200 + value: N1ekj + - effect: '[ȝ伨]鸲Z;ʞ9阏' + key: 6jmY + operator: n骯Ǩ + tolerationSeconds: 6874204552685768000 + value: saUOHQxkY9 + topologySpreadConstraints: + - labelSelector: + matchLabels: + 4bQpba: iVh + app.kubernetes.io/component: 4iNcef5 + app.kubernetes.io/instance: console + app.kubernetes.io/name: 4iNcef5 + "n": "" + maxSkew: 1898212660 + topologyKey: Ovevl + whenUnsatisfiable: PFGhR + volumes: + - name: truststore + secret: + defaultMode: 292 + secretName: E + - name: cert + secret: + defaultMode: 292 + secretName: P5mPIj + - name: key + secret: + defaultMode: 292 + secretName: mBxPtYNUs + - name: rc-credentials + secret: + defaultMode: 292 + secretName: M4pqhD32D + - name: kXFFnM +--- +# Source: connectors/templates/pod-monitor.yaml +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + annotations: + eZHJsIIV4Rky: Pk + creationTimestamp: null + labels: + n5El: sDg0twGSFjIgP + name: NCw6T6UcQY +spec: + namespaceSelector: + any: true + podMetricsEndpoints: + - bearerTokenSecret: + key: "" + path: / + port: prometheus + selector: + matchLabels: + 4bQpba: iVh + app.kubernetes.io/component: 4iNcef5 + app.kubernetes.io/instance: console + app.kubernetes.io/name: 4iNcef5 + "n": "" +-- testdata/case-041.yaml.golden -- +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + AwT: yIHdj1wxg + Lr: zYUtd + Z2dqRWb: FmF + app.kubernetes.io/component: Ur + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: Ur + eP0gw: ZlmzgOXE + helm.sh/chart: connectors-0.1.12 + name: bjGFkzr +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: -1621274024 + protocol: TCP + targetPort: -1621274024 + - name: PoEHOjF + port: -510390395 + protocol: TCP + targetPort: -510390395 + - name: DH7c + port: 369451694 + protocol: TCP + targetPort: 369451694 + selector: + AwT: yIHdj1wxg + Lr: zYUtd + app.kubernetes.io/component: Ur + app.kubernetes.io/instance: console + app.kubernetes.io/name: Ur + eP0gw: ZlmzgOXE + sessionAffinity: None + type: ClusterIP +--- +# Source: connectors/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + AwT: yIHdj1wxg + Lr: zYUtd + app.kubernetes.io/component: Ur + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: Ur + eP0gw: ZlmzgOXE + helm.sh/chart: connectors-0.1.12 + name: AqjekuF +spec: + progressDeadlineSeconds: 1079618075 + replicas: null + revisionHistoryLimit: 485115195 + selector: + matchLabels: + AwT: yIHdj1wxg + Lr: zYUtd + app.kubernetes.io/component: Ur + app.kubernetes.io/instance: console + app.kubernetes.io/name: Ur + eP0gw: ZlmzgOXE + strategy: + type: z1MRV5BXaS20 + template: + metadata: + annotations: {} + creationTimestamp: null + labels: + AwT: yIHdj1wxg + Lr: zYUtd + app.kubernetes.io/component: Ur + app.kubernetes.io/instance: console + app.kubernetes.io/name: Ur + eP0gw: ZlmzgOXE + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: poCuXUDdP + operator: 3m脄Lj伭ĸ_ȢV!fĩ聿粵昫Ȼ_Ȁ + values: + - bGZy + - key: mxZi7 + operator: 噴姷ʃƸUl>" 噸Lj#ǖHǑv + values: + - vBoyb + - 2VHyI + - key: T + operator: 汜!NJ + podAffinity: {} + podAntiAffinity: null + containers: + - command: null + env: + - name: CONNECT_CONFIGURATION + value: |- + rest.advertised.port=-1621274024 + rest.port=-1621274024 + key.converter=org.apache.kafka.connect.converters.ByteArrayConverter + value.converter=org.apache.kafka.connect.converters.ByteArrayConverter + group.id=KfcZtgISe + offset.storage.topic=V + config.storage.topic=n4 + status.storage.topic=fLR + offset.storage.redpanda.remote.read=true + offset.storage.redpanda.remote.write=false + config.storage.redpanda.remote.read=true + config.storage.redpanda.remote.write=false + status.storage.redpanda.remote.read=true + status.storage.redpanda.remote.write=true + offset.storage.replication.factor=-1861439076 + config.storage.replication.factor=1120929712 + status.storage.replication.factor=-1718786575 + producer.linger.ms=540861319 + producer.batch.size=1953552561 + config.providers=file,secretsManager,env + config.providers.file.class=org.apache.kafka.common.config.provider.FileConfigProvider + config.providers.env.class=org.apache.kafka.common.config.provider.EnvVarConfigProvider + - name: CONNECT_ADDITIONAL_CONFIGURATION + value: "9" + - name: CONNECT_BOOTSTRAP_SERVERS + value: jts02PD + - name: SCHEMA_REGISTRY_URL + value: Esqu + - name: CONNECT_GC_LOG_ENABLED + value: cjZh + - name: CONNECT_HEAP_OPTS + value: -Xms256M -Xmx0 + - name: CONNECT_LOG_LEVEL + value: fhSGoGeOVO + - name: CONNECT_SASL_USERNAME + value: BxNfJ + - name: CONNECT_SASL_MECHANISM + value: I9OZ + - name: CONNECT_SASL_PASSWORD_FILE + value: rc-credentials/password + - name: CONNECT_TLS_ENABLED + value: "false" + - name: CONNECT_TRUSTED_CERTS + value: ca/i + - name: CONNECT_TLS_AUTH_CERT + value: cert/TU4R4tW0Nd + - name: CONNECT_TLS_AUTH_KEY + value: key/hDX + - name: WRSeLSQyxsq + value: 0xespo + valueFrom: + configMapKeyRef: + key: gsjkH + name: hjYCF8i3u + optional: false + fieldRef: + apiVersion: ilis2lH + fieldPath: slhYb + resourceFieldRef: + containerName: ufey2VJTCmS + divisor: "0" + resource: "" + secretKeyRef: + key: nR + name: GKz3 + optional: false + - name: ic + value: N8MdK + valueFrom: + configMapKeyRef: + key: 1QJrX + name: LxK + optional: false + fieldRef: + apiVersion: 0z + fieldPath: UgaSLG1n + resourceFieldRef: + containerName: i + divisor: "0" + resource: "4" + secretKeyRef: + key: "2" + name: ZCqRHp + optional: true + - name: 2TZr + value: P1UUXZH9 + valueFrom: + configMapKeyRef: + key: wgHcFon6xI + name: 6aZcc + optional: false + fieldRef: + apiVersion: dt8 + fieldPath: THGVGMQc + resourceFieldRef: + containerName: Ml + divisor: "0" + resource: tSc + secretKeyRef: + key: L2StNK + name: Qhiy + optional: false + envFrom: + - configMapRef: + name: "8" + optional: false + prefix: Z3pv + secretRef: + name: c + optional: false + - configMapRef: + name: O3v + optional: false + prefix: eXtX5G3zTnAr + secretRef: + name: FU1b + optional: true + - configMapRef: + name: cLEurajaTv1 + optional: false + prefix: YX + secretRef: + optional: false + image: docker.redpanda.com/redpandadata/connectors:v1.0.29 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 724202040 + httpGet: + path: / + port: rest-api + scheme: HTTP + initialDelaySeconds: 1171548340 + periodSeconds: 1136904972 + successThreshold: 1663228806 + timeoutSeconds: 1255816268 + name: connectors-cluster + ports: + - containerPort: -1621274024 + name: rest-api + protocol: TCP + - containerPort: -510390395 + name: PoEHOjF + protocol: TCP + - containerPort: 369451694 + name: DH7c + protocol: TCP + readinessProbe: + failureThreshold: -1131780392 + httpGet: + path: /connectors + port: rest-api + scheme: HTTP + initialDelaySeconds: 1799248585 + periodSeconds: 373984687 + successThreshold: -1503317917 + timeoutSeconds: 266568456 + resources: + limits: + cpu: "0" + memory: "0" + requests: + cpu: "0" + memory: "0" + securityContext: + allowPrivilegeEscalation: false + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /opt/kafka/connect-password/rc-credentials + name: rc-credentials + - mountPath: /opt/kafka/connect-certs/ca + name: truststore + - mountPath: /opt/kafka/connect-certs/cert + name: cert + - mountPath: /opt/kafka/connect-certs/key + name: key + - mountPath: /tmp + name: rp-connect-tmp + dnsPolicy: ClusterFirst + imagePullSecrets: + - name: JeYmHo + nodeSelector: {} + restartPolicy: Õ験蘺Sg怰S²蜵-Ǿ笭ī庩X圂蓦5< + schedulerName: MF3RwzBCk + securityContext: + fsGroup: -3871220937207142400 + fsGroupChangePolicy: Y蹐\¢倅J趚i転 + runAsGroup: -8140185145867863000 + runAsNonRoot: true + runAsUser: 1443110212215096300 + supplementalGroups: + - 4202411183995630000 + - 9074875661218953000 + - 3682145535007526000 + sysctls: + - name: a9wm1 + value: V48LpVsGVpu + serviceAccountName: 1LIGRd6z + terminationGracePeriodSeconds: 1526850382 + tolerations: + - effect: k積Lj + key: YsgfsWrB + operator: Žʚ8鋤縅÷ʪ镲 + tolerationSeconds: 8712200771279582000 + value: 0BC0Sc1 + - effect: a + key: pWUIfI + operator: ā5NƑ鬜牣^,儕髬ǖ藍 ŠɯǦ + tolerationSeconds: 7946113276490164000 + value: lsKkYhoC + - effect: 燀芜/ƶ@犩ɫƭ紱刃飚dēW帠 + key: VQfdy + operator: 腼ʮǬĴǠɬ + tolerationSeconds: -8924157374760988000 + value: UlBiper + topologySpreadConstraints: + - labelSelector: + matchLabels: + AwT: yIHdj1wxg + Lr: zYUtd + app.kubernetes.io/component: Ur + app.kubernetes.io/instance: console + app.kubernetes.io/name: Ur + eP0gw: ZlmzgOXE + maxSkew: -623096425 + topologyKey: fFI6B + whenUnsatisfiable: PdDm + volumes: + - name: truststore + secret: + defaultMode: 292 + secretName: zmW + - name: cert + secret: + defaultMode: 292 + secretName: G485 + - name: key + secret: + defaultMode: 292 + secretName: dQ5 + - name: rc-credentials + secret: + defaultMode: 292 + secretName: 2h + - name: JoBYh + - name: 4s31 +-- testdata/case-042.yaml.golden -- +--- +# Source: connectors/templates/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + 0F3sU: SaJRcWm + GUF2flpqQUL: KKAcWWY5 + NIiGBL37: eCFaXQGs + app.kubernetes.io/component: s9WyH2Y + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: s9WyH2Y + helm.sh/chart: connectors-0.1.12 + name: w + namespace: default +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + 0F3sU: SaJRcWm + GUF2flpqQUL: KKAcWWY5 + NIiGBL37: eCFaXQGs + app.kubernetes.io/component: s9WyH2Y + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: s9WyH2Y + fzz: CLoaDJm9w + helm.sh/chart: connectors-0.1.12 + rryVp: TZ + name: 8Tb8k +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: -1489153770 + protocol: TCP + targetPort: -1489153770 + - name: GYfGwLr + port: -1114107001 + protocol: TCP + targetPort: -1114107001 + selector: + 0F3sU: SaJRcWm + GUF2flpqQUL: KKAcWWY5 + NIiGBL37: eCFaXQGs + app.kubernetes.io/component: s9WyH2Y + app.kubernetes.io/instance: console + app.kubernetes.io/name: s9WyH2Y + sessionAffinity: None + type: ClusterIP +-- testdata/case-043.yaml.golden -- +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + 25swrT: LyMk + AgV: 2ZT + LR7E9YY7J: rc + Mv: hvvf9ur + aWpK: fy05 + app.kubernetes.io/component: WdYlcGB + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: WdYlcGB + helm.sh/chart: connectors-0.1.12 + xYCcuP: zC + name: L +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: 2118887935 + protocol: TCP + targetPort: 2118887935 + - name: "0" + port: 1958832246 + protocol: TCP + targetPort: 1958832246 + selector: + Mv: hvvf9ur + aWpK: fy05 + app.kubernetes.io/component: WdYlcGB + app.kubernetes.io/instance: console + app.kubernetes.io/name: WdYlcGB + xYCcuP: zC + sessionAffinity: None + type: ClusterIP +--- +# Source: connectors/templates/pod-monitor.yaml +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + annotations: + k8EzKZ: oXYkaOnH + creationTimestamp: null + labels: + 07sPUbsx7a: "4" + name: DPRe +spec: + namespaceSelector: + any: true + podMetricsEndpoints: + - bearerTokenSecret: + key: "" + path: / + port: prometheus + selector: + matchLabels: + Mv: hvvf9ur + aWpK: fy05 + app.kubernetes.io/component: WdYlcGB + app.kubernetes.io/instance: console + app.kubernetes.io/name: WdYlcGB + xYCcuP: zC +-- testdata/case-044.yaml.golden -- +--- +# Source: connectors/templates/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/component: R64C + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: R64C + helm.sh/chart: connectors-0.1.12 + name: c + namespace: default +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: R64C + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: R64C + helm.sh/chart: connectors-0.1.12 + t7u5eHUdpR: nq6injR + name: L +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: 871084350 + protocol: TCP + targetPort: 871084350 + - name: 2Pm + port: -597719959 + protocol: TCP + targetPort: -597719959 + - name: z + port: -1354836854 + protocol: TCP + targetPort: -1354836854 + selector: + app.kubernetes.io/component: R64C + app.kubernetes.io/instance: console + app.kubernetes.io/name: R64C + sessionAffinity: None + type: ClusterIP +--- +# Source: connectors/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: R64C + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: R64C + e1: EPUL4 + helm.sh/chart: connectors-0.1.12 + name: ZNfeDYT +spec: + progressDeadlineSeconds: -1210754760 + replicas: null + revisionHistoryLimit: 400792738 + selector: + matchLabels: + app.kubernetes.io/component: R64C + app.kubernetes.io/instance: console + app.kubernetes.io/name: R64C + strategy: + type: AQc + template: + metadata: + annotations: + e1: EPUL4 + creationTimestamp: null + labels: + app.kubernetes.io/component: R64C + app.kubernetes.io/instance: console + app.kubernetes.io/name: R64C + spec: + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: ggOgs + operator: ʆ=Ǭ + values: + - 6xOHO + weight: 1438312308 + - preference: + matchExpressions: + - key: sVT + operator: Nj溚K$P" + - key: 3i + operator: 状w¿鄏荤džöǹĄ + values: + - hl9dZyPnxN + - C87 + - key: Pt + operator: ʬƴXw/8綷 + values: + - S9I6Qrsfz + matchFields: + - key: Gvnxn3 + operator: â氠喬 + values: + - d + weight: -886172272 + - preference: + matchExpressions: + - key: oy973i + operator: 圅¢璸'ɆʥʚvǴMĴ + values: + - OBP + - "1" + - YNoey99 + - key: Zy0iQotc + operator: +g + values: + - FO1apzD9 + - epCNQ66B + matchFields: + - key: 8nakITBFg + operator: '|ȍ' + values: + - 9z + - RX + - key: "" + operator: Mȃ"ô薱黭夃< + values: + - "" + - C + - YE3 + - key: iZFE5e + operator: nǮ + values: + - LHp7ijJ + weight: 567068826 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: we + operator: ɜP苞崉汊S + values: + - 1zCAp + - DVu + - key: piI + operator: Ǔɽ觩-鸭諣0ʙɮ鈿莳CyJ2 + values: + - 8oy + - HijL4M2 + - key: Xjq + operator: d遢豾9藌NJəBǔ,ɿǸ5Ƶº'芎婑( + values: + - kGBJo + - MpcP0e2Tga + matchFields: + - key: JhC5vQ1U8 + operator: "" + values: + - t + podAffinity: {} + podAntiAffinity: null + containers: + - command: null + env: + - name: CONNECT_CONFIGURATION + value: |- + rest.advertised.port=871084350 + rest.port=871084350 + key.converter=org.apache.kafka.connect.converters.ByteArrayConverter + value.converter=org.apache.kafka.connect.converters.ByteArrayConverter + group.id=S7uyvF + offset.storage.topic=1EER + config.storage.topic=MSUfKAm + status.storage.topic=d6yOc + offset.storage.redpanda.remote.read=true + offset.storage.redpanda.remote.write=false + config.storage.redpanda.remote.read=true + config.storage.redpanda.remote.write=true + status.storage.redpanda.remote.read=true + status.storage.redpanda.remote.write=false + offset.storage.replication.factor=-1272331222 + config.storage.replication.factor=1110431616 + status.storage.replication.factor=342664574 + producer.linger.ms=-1432617314 + producer.batch.size=577860685 + config.providers=file,secretsManager,env + config.providers.file.class=org.apache.kafka.common.config.provider.FileConfigProvider + config.providers.secretsManager.class=com.github.jcustenborder.kafka.config.aws.SecretsManagerConfigProvider + config.providers.secretsManager.param.secret.prefix=5dJMIv88J + config.providers.secretsManager.param.aws.region=ToqBft85 + config.providers.env.class=org.apache.kafka.common.config.provider.EnvVarConfigProvider + - name: CONNECT_ADDITIONAL_CONFIGURATION + value: xypAC + - name: CONNECT_BOOTSTRAP_SERVERS + value: AJo + - name: SCHEMA_REGISTRY_URL + value: BMfK + - name: CONNECT_GC_LOG_ENABLED + value: "2" + - name: CONNECT_HEAP_OPTS + value: -Xms256M -Xmx0 + - name: CONNECT_LOG_LEVEL + value: p + - name: CONNECT_SASL_USERNAME + value: "n" + - name: CONNECT_SASL_MECHANISM + value: LO + - name: CONNECT_SASL_PASSWORD_FILE + value: rc-credentials/password + - name: CONNECT_TLS_ENABLED + value: "true" + - name: CONNECT_TRUSTED_CERTS + value: ca/LZ8 + - name: CONNECT_TLS_AUTH_CERT + value: cert/N + - name: CONNECT_TLS_AUTH_KEY + value: key/NGmzeL6Y + - name: Hn + value: RLmuTFKt + valueFrom: + configMapKeyRef: + key: u8iVw + name: l8S7wk + optional: true + fieldRef: + apiVersion: 5q4Wkck9Yhn + fieldPath: e56i1D + resourceFieldRef: + containerName: MP6 + divisor: "0" + resource: W + secretKeyRef: + key: Sow4h93xH + name: tK6mZbO + optional: true + envFrom: + - configMapRef: + name: 6a + optional: true + prefix: wqO + secretRef: + name: eZxNk + optional: false + image: docker.redpanda.com/redpandadata/connectors:v1.0.29 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: -179099947 + httpGet: + path: / + port: rest-api + scheme: HTTP + initialDelaySeconds: -741511239 + periodSeconds: -301254020 + successThreshold: -1795354231 + timeoutSeconds: 17970381 + name: connectors-cluster + ports: + - containerPort: 871084350 + name: rest-api + protocol: TCP + - containerPort: -597719959 + name: 2Pm + protocol: TCP + - containerPort: -1354836854 + name: z + protocol: TCP + readinessProbe: + failureThreshold: 1162556666 + httpGet: + path: /connectors + port: rest-api + scheme: HTTP + initialDelaySeconds: -1796420049 + periodSeconds: 940741811 + successThreshold: 1628971624 + timeoutSeconds: -1878581735 + resources: + limits: + cpu: "0" + memory: "0" + requests: + cpu: "0" + memory: "0" + securityContext: + allowPrivilegeEscalation: true + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /opt/kafka/connect-password/rc-credentials + name: rc-credentials + - mountPath: /opt/kafka/connect-certs/ca + name: truststore + - mountPath: /opt/kafka/connect-certs/cert + name: cert + - mountPath: /opt/kafka/connect-certs/key + name: key + - mountPath: /tmp + name: rp-connect-tmp + dnsPolicy: ClusterFirst + imagePullSecrets: + - name: HaLjyQ02L + - name: yjimP + - name: 5KCFV6 + nodeSelector: + m8ypcZn: yD + restartPolicy: OL恟´跒ɴ珛姌Ŋ + schedulerName: FfnrLnAtn3 + securityContext: + fsGroup: 5186362895627063000 + fsGroupChangePolicy: E甗dbƾ潸 + runAsGroup: 4738220116750422000 + runAsNonRoot: true + runAsUser: 4123601200118601700 + supplementalGroups: + - 5067618254965114000 + - 2922991898118782500 + sysctls: + - name: 1idwf + value: RtGFIRLv + - name: toxsb + value: "" + - name: bC + value: IcMTnt + serviceAccountName: c + terminationGracePeriodSeconds: 1834992377 + tolerations: + - effect: r"ǘ + key: 7FvMPWDDP + operator: 杍Ɍ + tolerationSeconds: -4685795240412632000 + value: G9czii + topologySpreadConstraints: + - labelSelector: + matchLabels: + app.kubernetes.io/component: R64C + app.kubernetes.io/instance: console + app.kubernetes.io/name: R64C + maxSkew: -1990808403 + topologyKey: y1s + whenUnsatisfiable: bxCWoMA + volumes: + - name: truststore + secret: + defaultMode: 292 + secretName: Qd + - name: cert + secret: + defaultMode: 292 + secretName: 4Hwd2 + - name: key + secret: + defaultMode: 292 + secretName: ak + - name: rc-credentials + secret: + defaultMode: 292 + secretName: mhOAME + - name: RXJ + - name: JJ +--- +# Source: connectors/templates/pod-monitor.yaml +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + annotations: + SF8: t7jzDFP + creationTimestamp: null + labels: + "3": P + GGM8HrAa: AroHM7WrsoM + name: ZNfeDYT +spec: + namespaceSelector: + any: true + podMetricsEndpoints: + - bearerTokenSecret: + key: "" + path: / + port: prometheus + selector: + matchLabels: + app.kubernetes.io/component: R64C + app.kubernetes.io/instance: console + app.kubernetes.io/name: R64C +-- testdata/case-045.yaml.golden -- +--- +# Source: connectors/templates/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + MbBpaa: UzKZX + app.kubernetes.io/component: 8UJFy + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 8UJFy + h52qwPFCCL1xE: q + helm.sh/chart: connectors-0.1.12 + name: Vk + namespace: default +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + H8XRE: XmuXsN + MbBpaa: UzKZX + app.kubernetes.io/component: 8UJFy + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 8UJFy + h52qwPFCCL1xE: q + helm.sh/chart: connectors-0.1.12 + name: 58KMN +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: 1110004877 + protocol: TCP + targetPort: 1110004877 + - name: 7oEiI3 + port: -1730203461 + protocol: TCP + targetPort: -1730203461 + - name: pxPCPLymcj + port: 1857328046 + protocol: TCP + targetPort: 1857328046 + selector: + MbBpaa: UzKZX + app.kubernetes.io/component: 8UJFy + app.kubernetes.io/instance: console + app.kubernetes.io/name: 8UJFy + h52qwPFCCL1xE: q + sessionAffinity: None + type: ClusterIP +--- +# Source: connectors/templates/pod-monitor.yaml +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + annotations: + ADPu3ozSd: q + IirIQ: nU4N + z1: CMu8InAI + creationTimestamp: null + labels: {} + name: uLr8eH +spec: + namespaceSelector: + any: true + matchNames: + - UCZpu + podMetricsEndpoints: + - bearerTokenSecret: + key: "" + path: / + port: prometheus + selector: + matchLabels: + MbBpaa: UzKZX + app.kubernetes.io/component: 8UJFy + app.kubernetes.io/instance: console + app.kubernetes.io/name: 8UJFy + h52qwPFCCL1xE: q +-- testdata/case-046.yaml.golden -- +--- +# Source: connectors/templates/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/component: fa1XvkvO + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: fa1XvkvO + helm.sh/chart: connectors-0.1.12 + name: cl + namespace: default +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + H: "0" + app.kubernetes.io/component: fa1XvkvO + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: fa1XvkvO + helm.sh/chart: connectors-0.1.12 + name: UrU9Bs +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: -1606573822 + protocol: TCP + targetPort: -1606573822 + - name: prometheus + port: 9404 + protocol: TCP + targetPort: 9404 + selector: + app.kubernetes.io/component: fa1XvkvO + app.kubernetes.io/instance: console + app.kubernetes.io/name: fa1XvkvO + sessionAffinity: None + type: ClusterIP +--- +# Source: connectors/templates/pod-monitor.yaml +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + annotations: + "N": "" + b: p + creationTimestamp: null + labels: + O: CY3sdu + UddrJ: zlyJcM + klftu: OSDi + name: tYC5CG +spec: + namespaceSelector: + any: true + podMetricsEndpoints: + - bearerTokenSecret: + key: "" + path: / + port: prometheus + selector: + matchLabels: + app.kubernetes.io/component: fa1XvkvO + app.kubernetes.io/instance: console + app.kubernetes.io/name: fa1XvkvO +-- testdata/case-047.yaml.golden -- +--- +# Source: connectors/templates/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + annotations: + "": mNGwfCN + creationTimestamp: null + labels: + YQJWn90y: CaduGS6 + app.kubernetes.io/component: wN + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: wN + helm.sh/chart: connectors-0.1.12 + ytV2tl: icxW + name: 3m + namespace: default +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + "": pZ + YQJWn90y: CaduGS6 + app.kubernetes.io/component: wN + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: wN + helm.sh/chart: connectors-0.1.12 + ytV2tl: icxW + name: xW +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: 660248664 + protocol: TCP + targetPort: 660248664 + - name: V + port: -1924603054 + protocol: TCP + targetPort: -1924603054 + selector: + YQJWn90y: CaduGS6 + app.kubernetes.io/component: wN + app.kubernetes.io/instance: console + app.kubernetes.io/name: wN + ytV2tl: icxW + sessionAffinity: None + type: ClusterIP +--- +# Source: connectors/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + 1taGex8O: RBXE4 + A: uiKIoNCT + NtMz: b7Zk1GQ7 + YQJWn90y: CaduGS6 + app.kubernetes.io/component: wN + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: wN + helm.sh/chart: connectors-0.1.12 + ytV2tl: icxW + name: Bl0rL2 +spec: + progressDeadlineSeconds: -1524384619 + replicas: null + revisionHistoryLimit: 1994939456 + selector: + matchLabels: + YQJWn90y: CaduGS6 + app.kubernetes.io/component: wN + app.kubernetes.io/instance: console + app.kubernetes.io/name: wN + ytV2tl: icxW + strategy: + type: RDNEX8T + template: + metadata: + annotations: + 1taGex8O: RBXE4 + A: uiKIoNCT + NtMz: b7Zk1GQ7 + creationTimestamp: null + labels: + YQJWn90y: CaduGS6 + app.kubernetes.io/component: wN + app.kubernetes.io/instance: console + app.kubernetes.io/name: wN + ytV2tl: icxW + spec: + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: ajGWX3E + operator: Ǫ囍 + values: + - HbIL2OUP + - q + matchFields: + - key: 453h + operator: DZƮìX莁Ǜ詍^屶K}豫ţoJ櫉 + values: + - h + - a4s + - key: Y1AE + operator: 4噸đƪǶS绲aģ序e$襫枠ÿ攒 + values: + - uVsu + weight: -280128439 + - preference: {} + weight: 46457932 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: [] + podAffinity: {} + podAntiAffinity: null + containers: + - command: null + env: + - name: CONNECT_CONFIGURATION + value: |- + rest.advertised.port=660248664 + rest.port=660248664 + key.converter=org.apache.kafka.connect.converters.ByteArrayConverter + value.converter=org.apache.kafka.connect.converters.ByteArrayConverter + group.id= + offset.storage.topic=s0 + config.storage.topic=zpj + status.storage.topic=e3Caq + offset.storage.redpanda.remote.read=false + offset.storage.redpanda.remote.write=false + config.storage.redpanda.remote.read=true + config.storage.redpanda.remote.write=false + status.storage.redpanda.remote.read=true + status.storage.redpanda.remote.write=true + offset.storage.replication.factor=-551216099 + config.storage.replication.factor=181733785 + status.storage.replication.factor=894783312 + producer.linger.ms=-999496889 + producer.batch.size=221474765 + config.providers=file,secretsManager,env + config.providers.file.class=org.apache.kafka.common.config.provider.FileConfigProvider + config.providers.env.class=org.apache.kafka.common.config.provider.EnvVarConfigProvider + - name: CONNECT_ADDITIONAL_CONFIGURATION + value: s + - name: CONNECT_BOOTSTRAP_SERVERS + value: "" + - name: SCHEMA_REGISTRY_URL + value: W9TUtY + - name: CONNECT_GC_LOG_ENABLED + value: zIkzV8Ox + - name: CONNECT_HEAP_OPTS + value: -Xms256M -Xmx0 + - name: CONNECT_LOG_LEVEL + value: b + - name: CONNECT_TLS_ENABLED + value: "true" + - name: CONNECT_TRUSTED_CERTS + value: ca/REGD0a + - name: CONNECT_TLS_AUTH_CERT + value: cert/aG9QIiXqg + - name: CONNECT_TLS_AUTH_KEY + value: key/D + envFrom: + - configMapRef: + name: dx + optional: true + prefix: OgoO8WCa + secretRef: + optional: true + - configMapRef: + name: Kk + optional: false + prefix: 6Rdx + secretRef: + name: nM5Hn4S + optional: false + - configMapRef: + name: nQ + optional: true + prefix: z70 + secretRef: + name: C + optional: true + image: docker.redpanda.com/redpandadata/connectors:v1.0.29 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: -2044419963 + httpGet: + path: / + port: rest-api + scheme: HTTP + initialDelaySeconds: 888211900 + periodSeconds: -42722218 + successThreshold: 337318108 + timeoutSeconds: 1870975781 + name: connectors-cluster + ports: + - containerPort: 660248664 + name: rest-api + protocol: TCP + - containerPort: -1924603054 + name: V + protocol: TCP + readinessProbe: + failureThreshold: -2099739674 + httpGet: + path: /connectors + port: rest-api + scheme: HTTP + initialDelaySeconds: -359104350 + periodSeconds: 1897832932 + successThreshold: -962367820 + timeoutSeconds: -677019415 + resources: + limits: + cpu: "0" + memory: "0" + requests: + cpu: "0" + memory: "0" + securityContext: + allowPrivilegeEscalation: true + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /opt/kafka/connect-certs/ca + name: truststore + - mountPath: /opt/kafka/connect-certs/cert + name: cert + - mountPath: /opt/kafka/connect-certs/key + name: key + - mountPath: 5aM + mountPropagation: Ěɲ'再ʖ|皑F9ĺOĆ|Oô + name: 2HGf2z + subPath: vuF7gt + subPathExpr: y6zTs2 + - mountPath: QU6 + mountPropagation: QǢx槱Sɼ湙Ȥ恑ñ鹒 + name: PbVBK + subPath: foAWHAo + subPathExpr: I8f + - mountPath: "" + mountPropagation: ƇNʆ¹¯檷AvdŜ踆ÿDȂ + name: cA + readOnly: true + subPath: y6Kasn + subPathExpr: DIUY0V + dnsPolicy: ClusterFirst + imagePullSecrets: + - name: LGwi + nodeSelector: + SFPTn: eN2 + restartPolicy: 爃ɥ90İĔ + schedulerName: i57b + securityContext: + fsGroup: 1520694499640274700 + fsGroupChangePolicy: 嫽Ǭ + runAsGroup: 3728458047896784400 + runAsNonRoot: false + runAsUser: -8957070032009945000 + sysctls: + - name: NBH + value: bXsgSc + - name: WTZnja + value: p4Du + serviceAccountName: 3m + terminationGracePeriodSeconds: 1122010486 + tolerations: [] + topologySpreadConstraints: + - labelSelector: + matchLabels: + YQJWn90y: CaduGS6 + app.kubernetes.io/component: wN + app.kubernetes.io/instance: console + app.kubernetes.io/name: wN + ytV2tl: icxW + maxSkew: 2113683386 + topologyKey: H1AWsSn + whenUnsatisfiable: VEpgY + volumes: + - name: truststore + secret: + defaultMode: 292 + secretName: ZFEDD + - name: cert + secret: + defaultMode: 292 + secretName: zrc5V + - name: key + secret: + defaultMode: 292 + secretName: dtIKjx4fd0k + - name: Cm + - name: eHp5 + - name: r1T +--- +# Source: connectors/templates/pod-monitor.yaml +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + annotations: + "": O + AFH4V: ga95qmjNhc + creationTimestamp: null + labels: + 9HWO7MGwhk: vGHnz6 + NNg3k: hbR + RXL: VxSIXgS + name: Bl0rL2 +spec: + namespaceSelector: + any: true + matchNames: + - WZxK8iNK2gdU + podMetricsEndpoints: + - bearerTokenSecret: + key: "" + path: / + port: prometheus + selector: + matchLabels: + YQJWn90y: CaduGS6 + app.kubernetes.io/component: wN + app.kubernetes.io/instance: console + app.kubernetes.io/name: wN + ytV2tl: icxW +-- testdata/case-048.yaml.golden -- +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: r7G + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: r7G + helm.sh/chart: connectors-0.1.12 + x3: e1lz + name: w4DG +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: -2097692565 + protocol: TCP + targetPort: -2097692565 + - name: prometheus + port: 9404 + protocol: TCP + targetPort: 9404 + selector: + app.kubernetes.io/component: r7G + app.kubernetes.io/instance: console + app.kubernetes.io/name: r7G + x3: e1lz + sessionAffinity: None + type: ClusterIP +--- +# Source: connectors/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: r7G + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: r7G + helm.sh/chart: connectors-0.1.12 + x3: e1lz + name: xPmln +spec: + progressDeadlineSeconds: -1933689162 + replicas: null + revisionHistoryLimit: -1768466640 + selector: + matchLabels: + app.kubernetes.io/component: r7G + app.kubernetes.io/instance: console + app.kubernetes.io/name: r7G + x3: e1lz + strategy: + type: OMXfGqbFsWh + template: + metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/component: r7G + app.kubernetes.io/instance: console + app.kubernetes.io/name: r7G + x3: e1lz + spec: + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: b + operator: 鷘泝, + values: + - 0N3rqLJ + - "4" + - 1L + matchFields: + - key: gnmK + operator: '@D煡摡o昪ɼ柤斕ɲı58,tț>' + values: + - i1 + - 5PqjZCTW + weight: -1104761106 + - preference: + matchExpressions: + - key: dT + operator: 犘ijň鉻ĴɳǁȨD + values: + - XdGct + - key: 2BYB + operator: '}閂譗輸礯Ʊx' + values: + - MU2j1Vu + - "17" + - key: ypgFjkuHHfzj + operator: '`4ʫfƗ8鲙華ė' + values: + - "y" + - LHvKvSZf2 + matchFields: + - key: GImX3 + operator: "" + values: + - xQPC + - R4R + - 3Y0mxG + weight: -521155604 + - preference: + matchExpressions: + - key: ft5L + operator: ȗ垁屹3瞬铵烱#祟渥 + matchFields: + - key: Fx + operator: ǷɂZ + values: + - WT + weight: 677594922 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: AwTQm2 + operator: 展ɏǀ襋k(ȴSǮ讶ʁ + values: + - 8i1 + - key: gQ1DB + operator: 汴F见Doĵw?Pc|昋階ʇ亸d灀麕ʞ + values: + - uqEzQKDpVw + - Q2 + - icCcpbp8 + - key: d9Z + operator: Ǽ船薲ɲĊbJĘƑƮOȄ鄹 + values: + - flK9jMt + - jt4 + - TSJ + - matchExpressions: + - key: Cf40pEWF + operator: ŌZ雯瘍 + values: + - "0" + - cSCIGvcwc + - Izvo0 + - key: mB4jp + operator: Í淙篝Hƨ_u误Ý + values: + - OTJJx + - KgWLC + - key: TxkO + operator: ȠȰsa'ʫƲ鑠 + values: + - 3gqlT + matchFields: + - key: l + operator: é糁v抯 + - key: QZFxqZ + operator: / + values: + - q0DJ + - M0 + - 6XMtos + - {} + podAffinity: {} + podAntiAffinity: null + containers: + - command: null + env: + - name: CONNECT_CONFIGURATION + value: |- + rest.advertised.port=-2097692565 + rest.port=-2097692565 + key.converter=org.apache.kafka.connect.converters.ByteArrayConverter + value.converter=org.apache.kafka.connect.converters.ByteArrayConverter + group.id=piupb6 + offset.storage.topic=ytzBE0 + config.storage.topic=FBdy5 + status.storage.topic=FHVut + offset.storage.redpanda.remote.read=false + offset.storage.redpanda.remote.write=false + config.storage.redpanda.remote.read=false + config.storage.redpanda.remote.write=true + status.storage.redpanda.remote.read=false + status.storage.redpanda.remote.write=false + offset.storage.replication.factor=864522858 + config.storage.replication.factor=-103098671 + status.storage.replication.factor=-1797067435 + producer.linger.ms=-1816218257 + producer.batch.size=-1479166006 + config.providers=file,secretsManager,env + config.providers.file.class=org.apache.kafka.common.config.provider.FileConfigProvider + config.providers.env.class=org.apache.kafka.common.config.provider.EnvVarConfigProvider + - name: CONNECT_ADDITIONAL_CONFIGURATION + value: stdaxfP + - name: CONNECT_BOOTSTRAP_SERVERS + value: fOZsu37vN + - name: SCHEMA_REGISTRY_URL + value: xg4Cxakw + - name: CONNECT_GC_LOG_ENABLED + value: Fu + - name: CONNECT_HEAP_OPTS + value: -Xms256M -Xmx0 + - name: CONNECT_LOG_LEVEL + value: QSl3 + - name: CONNECT_SASL_USERNAME + value: aXR + - name: CONNECT_SASL_MECHANISM + value: Xr + - name: CONNECT_SASL_PASSWORD_FILE + value: rc-credentials/password + - name: CONNECT_TLS_ENABLED + value: "true" + - name: CONNECT_TRUSTED_CERTS + value: ca/hln + - name: CONNECT_TLS_AUTH_CERT + value: cert/s47Hy + - name: CONNECT_TLS_AUTH_KEY + value: key/Wxw + envFrom: + - configMapRef: + name: w9vIEs + optional: true + prefix: oFWtF + secretRef: + name: Z1 + optional: true + - configMapRef: + name: 9wMxsz + optional: false + secretRef: + name: zLL2kR + optional: false + image: docker.redpanda.com/redpandadata/connectors:v1.0.29 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 1532121771 + httpGet: + path: / + port: rest-api + scheme: HTTP + initialDelaySeconds: -893256878 + periodSeconds: -674475842 + successThreshold: -1740698110 + timeoutSeconds: 326371790 + name: connectors-cluster + ports: + - containerPort: -2097692565 + name: rest-api + protocol: TCP + - containerPort: 9404 + name: prometheus + protocol: TCP + readinessProbe: + failureThreshold: -2100702858 + httpGet: + path: /connectors + port: rest-api + scheme: HTTP + initialDelaySeconds: 1930411693 + periodSeconds: 1985310483 + successThreshold: 769125679 + timeoutSeconds: -1364329005 + resources: + limits: + cpu: "0" + memory: "0" + requests: + cpu: "0" + memory: "0" + securityContext: + allowPrivilegeEscalation: true + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /opt/kafka/connect-password/rc-credentials + name: rc-credentials + - mountPath: /opt/kafka/connect-certs/ca + name: truststore + - mountPath: /opt/kafka/connect-certs/cert + name: cert + - mountPath: /opt/kafka/connect-certs/key + name: key + - mountPath: FgUy2D + mountPropagation: ül幯wȅƑʀ,姅 + name: kUw2 + subPath: D0Qb + subPathExpr: EemIo6uDnv0 + - mountPath: r + mountPropagation: 剐ƥ<¶抿菋ɯ粦梘ȡ( + name: 15LL4 + readOnly: true + subPath: tcGS + subPathExpr: pwB + - mountPath: aC8MZYmVC + mountPropagation: ʢǮZ薽R擽ē1Xȭ硡衕卣A礖XÚY2 + name: "9" + subPath: qg + subPathExpr: cPz1rA + dnsPolicy: ClusterFirst + imagePullSecrets: + - name: P0 + - name: AoBx4D0STGS8Z + nodeSelector: + DdMU: TvKI + cxzoe: "41" + i6KwA0A6qU1g: E6j + restartPolicy: À潌貛ă貈懍Eŵɀȩ + schedulerName: RMki + securityContext: + fsGroup: -3162007349665637000 + fsGroupChangePolicy: F@AǶvĭȟū琐噌黣坩Ǚɮŀ + runAsGroup: 164107928150233300 + runAsNonRoot: false + runAsUser: -6374867922909643000 + serviceAccountName: YIo + terminationGracePeriodSeconds: 1025063088 + tolerations: + - effect: ƸL諟Hv餣A嶌ɣYƵ轝脡sT酉 + key: rvPW78A + tolerationSeconds: 2277475321707653600 + value: zmQU7sY + - effect: 瘅1Ʉ夆 + key: 0p + operator: 冂÷s廥肚Zj陎1aÚkĤɀǟR + tolerationSeconds: 1191004605682561500 + value: sZcoDHahsR79 + topologySpreadConstraints: + - labelSelector: + matchLabels: + app.kubernetes.io/component: r7G + app.kubernetes.io/instance: console + app.kubernetes.io/name: r7G + x3: e1lz + maxSkew: -1723926017 + topologyKey: KnB17 + whenUnsatisfiable: WpP6r0 + volumes: + - name: truststore + secret: + defaultMode: 292 + secretName: k5U1 + - name: cert + secret: + defaultMode: 292 + secretName: ljqjD + - name: key + secret: + defaultMode: 292 + secretName: icjt + - name: rc-credentials + secret: + defaultMode: 292 + secretName: i5 + - name: I0 +-- testdata/case-049.yaml.golden -- +--- +# Source: connectors/templates/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + annotations: + "": 0h6QKRWo + ayiUDPgwgG9: Wh + creationTimestamp: null + labels: + AxgO: ie + a: xGJKP + app.kubernetes.io/component: pyCdF + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: pyCdF + helm.sh/chart: connectors-0.1.12 + wy9DijfF9: pY + name: zr1OY + namespace: default +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + AxgO: ie + a: xGJKP + app.kubernetes.io/component: pyCdF + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: pyCdF + helm.sh/chart: connectors-0.1.12 + uH: o + wy9DijfF9: pY + name: 37ihe +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: -447671166 + protocol: TCP + targetPort: -447671166 + - name: prometheus + port: 9404 + protocol: TCP + targetPort: 9404 + selector: + AxgO: ie + a: xGJKP + app.kubernetes.io/component: pyCdF + app.kubernetes.io/instance: console + app.kubernetes.io/name: pyCdF + wy9DijfF9: pY + sessionAffinity: None + type: ClusterIP +-- testdata/custom-anti-affinity.yaml.golden -- +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: connectors + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: connectors + helm.sh/chart: connectors-0.1.12 + name: console-connectors +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: 8083 + protocol: TCP + targetPort: 8083 + - name: prometheus + port: 9404 + protocol: TCP + targetPort: 9404 + selector: + app.kubernetes.io/component: connectors + app.kubernetes.io/instance: console + app.kubernetes.io/name: connectors + sessionAffinity: None + type: ClusterIP +--- +# Source: connectors/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: connectors + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: connectors + helm.sh/chart: connectors-0.1.12 + name: console-connectors +spec: + progressDeadlineSeconds: 600 + replicas: null + revisionHistoryLimit: 10 + selector: + matchLabels: + app.kubernetes.io/component: connectors + app.kubernetes.io/instance: console + app.kubernetes.io/name: connectors + strategy: + type: RollingUpdate + template: + metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/component: connectors + app.kubernetes.io/instance: console + app.kubernetes.io/name: connectors + spec: + affinity: + nodeAffinity: {} + podAffinity: {} + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + foo: bar + topologyKey: "" + weight: 40 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + foo: bar + topologyKey: "" + containers: + - command: null + env: + - name: CONNECT_CONFIGURATION + value: |- + rest.advertised.port=8083 + rest.port=8083 + key.converter=org.apache.kafka.connect.converters.ByteArrayConverter + value.converter=org.apache.kafka.connect.converters.ByteArrayConverter + group.id=connectors-cluster + offset.storage.topic=_internal_connectors_offsets + config.storage.topic=_internal_connectors_configs + status.storage.topic=_internal_connectors_status + offset.storage.redpanda.remote.read=false + offset.storage.redpanda.remote.write=false + config.storage.redpanda.remote.read=false + config.storage.redpanda.remote.write=false + status.storage.redpanda.remote.read=false + status.storage.redpanda.remote.write=false + offset.storage.replication.factor=-1 + config.storage.replication.factor=-1 + status.storage.replication.factor=-1 + producer.linger.ms=1 + producer.batch.size=131072 + config.providers=file,secretsManager,env + config.providers.file.class=org.apache.kafka.common.config.provider.FileConfigProvider + config.providers.env.class=org.apache.kafka.common.config.provider.EnvVarConfigProvider + - name: CONNECT_ADDITIONAL_CONFIGURATION + value: "" + - name: CONNECT_BOOTSTRAP_SERVERS + value: "" + - name: CONNECT_GC_LOG_ENABLED + value: "false" + - name: CONNECT_HEAP_OPTS + value: -Xms256M -Xmx2G + - name: CONNECT_LOG_LEVEL + value: warn + - name: CONNECT_TLS_ENABLED + value: "false" + envFrom: [] + image: docker.redpanda.com/redpandadata/connectors:v1.0.29 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: rest-api + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: connectors-cluster + ports: + - containerPort: 8083 + name: rest-api + protocol: TCP + - containerPort: 9404 + name: prometheus + protocol: TCP + readinessProbe: + failureThreshold: 2 + httpGet: + path: /connectors + port: rest-api + scheme: HTTP + initialDelaySeconds: 60 + periodSeconds: 10 + successThreshold: 3 + timeoutSeconds: 5 + resources: + limits: + cpu: "1" + memory: 2350Mi + requests: + cpu: "1" + memory: 2350Mi + securityContext: + allowPrivilegeEscalation: false + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /tmp + name: rp-connect-tmp + dnsPolicy: ClusterFirst + imagePullSecrets: [] + nodeSelector: {} + restartPolicy: Always + schedulerName: "" + securityContext: + fsGroup: 101 + fsGroupChangePolicy: OnRootMismatch + runAsUser: 101 + serviceAccountName: default + terminationGracePeriodSeconds: 30 + tolerations: [] + topologySpreadConstraints: + - labelSelector: + matchLabels: + app.kubernetes.io/component: connectors + app.kubernetes.io/instance: console + app.kubernetes.io/name: connectors + maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: ScheduleAnyway + volumes: + - emptyDir: + medium: Memory + sizeLimit: 5Mi + name: rp-connect-tmp +-- testdata/defaults.yaml.golden -- +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: connectors + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: connectors + helm.sh/chart: connectors-0.1.12 + name: console-connectors +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: 8083 + protocol: TCP + targetPort: 8083 + - name: prometheus + port: 9404 + protocol: TCP + targetPort: 9404 + selector: + app.kubernetes.io/component: connectors + app.kubernetes.io/instance: console + app.kubernetes.io/name: connectors + sessionAffinity: None + type: ClusterIP +--- +# Source: connectors/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: connectors + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: connectors + helm.sh/chart: connectors-0.1.12 + name: console-connectors +spec: + progressDeadlineSeconds: 600 + replicas: null + revisionHistoryLimit: 10 + selector: + matchLabels: + app.kubernetes.io/component: connectors + app.kubernetes.io/instance: console + app.kubernetes.io/name: connectors + strategy: + type: RollingUpdate + template: + metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/component: connectors + app.kubernetes.io/instance: console + app.kubernetes.io/name: connectors + spec: + affinity: + nodeAffinity: {} + podAffinity: {} + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: connectors + app.kubernetes.io/instance: console + app.kubernetes.io/name: connectors + namespaces: + - default + topologyKey: kubernetes.io/hostname + containers: + - command: null + env: + - name: CONNECT_CONFIGURATION + value: |- + rest.advertised.port=8083 + rest.port=8083 + key.converter=org.apache.kafka.connect.converters.ByteArrayConverter + value.converter=org.apache.kafka.connect.converters.ByteArrayConverter + group.id=connectors-cluster + offset.storage.topic=_internal_connectors_offsets + config.storage.topic=_internal_connectors_configs + status.storage.topic=_internal_connectors_status + offset.storage.redpanda.remote.read=false + offset.storage.redpanda.remote.write=false + config.storage.redpanda.remote.read=false + config.storage.redpanda.remote.write=false + status.storage.redpanda.remote.read=false + status.storage.redpanda.remote.write=false + offset.storage.replication.factor=-1 + config.storage.replication.factor=-1 + status.storage.replication.factor=-1 + producer.linger.ms=1 + producer.batch.size=131072 + config.providers=file,secretsManager,env + config.providers.file.class=org.apache.kafka.common.config.provider.FileConfigProvider + config.providers.env.class=org.apache.kafka.common.config.provider.EnvVarConfigProvider + - name: CONNECT_ADDITIONAL_CONFIGURATION + value: "" + - name: CONNECT_BOOTSTRAP_SERVERS + value: "" + - name: CONNECT_GC_LOG_ENABLED + value: "false" + - name: CONNECT_HEAP_OPTS + value: -Xms256M -Xmx2G + - name: CONNECT_LOG_LEVEL + value: warn + - name: CONNECT_TLS_ENABLED + value: "false" + envFrom: [] + image: docker.redpanda.com/redpandadata/connectors:v1.0.29 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: rest-api + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: connectors-cluster + ports: + - containerPort: 8083 + name: rest-api + protocol: TCP + - containerPort: 9404 + name: prometheus + protocol: TCP + readinessProbe: + failureThreshold: 2 + httpGet: + path: /connectors + port: rest-api + scheme: HTTP + initialDelaySeconds: 60 + periodSeconds: 10 + successThreshold: 3 + timeoutSeconds: 5 + resources: + limits: + cpu: "1" + memory: 2350Mi + requests: + cpu: "1" + memory: 2350Mi + securityContext: + allowPrivilegeEscalation: false + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /tmp + name: rp-connect-tmp + dnsPolicy: ClusterFirst + imagePullSecrets: [] + nodeSelector: {} + restartPolicy: Always + schedulerName: "" + securityContext: + fsGroup: 101 + fsGroupChangePolicy: OnRootMismatch + runAsUser: 101 + serviceAccountName: default + terminationGracePeriodSeconds: 30 + tolerations: [] + topologySpreadConstraints: + - labelSelector: + matchLabels: + app.kubernetes.io/component: connectors + app.kubernetes.io/instance: console + app.kubernetes.io/name: connectors + maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: ScheduleAnyway + volumes: + - emptyDir: + medium: Memory + sizeLimit: 5Mi + name: rp-connect-tmp +-- testdata/hard-anti-affinity.yaml.golden -- +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: connectors + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: connectors + helm.sh/chart: connectors-0.1.12 + name: console-connectors +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: 8083 + protocol: TCP + targetPort: 8083 + - name: prometheus + port: 9404 + protocol: TCP + targetPort: 9404 + selector: + app.kubernetes.io/component: connectors + app.kubernetes.io/instance: console + app.kubernetes.io/name: connectors + sessionAffinity: None + type: ClusterIP +--- +# Source: connectors/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: connectors + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: connectors + helm.sh/chart: connectors-0.1.12 + name: console-connectors +spec: + progressDeadlineSeconds: 600 + replicas: null + revisionHistoryLimit: 10 + selector: + matchLabels: + app.kubernetes.io/component: connectors + app.kubernetes.io/instance: console + app.kubernetes.io/name: connectors + strategy: + type: RollingUpdate + template: + metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/component: connectors + app.kubernetes.io/instance: console + app.kubernetes.io/name: connectors + spec: + affinity: + nodeAffinity: {} + podAffinity: {} + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: connectors + app.kubernetes.io/instance: console + app.kubernetes.io/name: connectors + namespaces: + - default + topologyKey: kubernetes.io/hostname + containers: + - command: null + env: + - name: CONNECT_CONFIGURATION + value: |- + rest.advertised.port=8083 + rest.port=8083 + key.converter=org.apache.kafka.connect.converters.ByteArrayConverter + value.converter=org.apache.kafka.connect.converters.ByteArrayConverter + group.id=connectors-cluster + offset.storage.topic=_internal_connectors_offsets + config.storage.topic=_internal_connectors_configs + status.storage.topic=_internal_connectors_status + offset.storage.redpanda.remote.read=false + offset.storage.redpanda.remote.write=false + config.storage.redpanda.remote.read=false + config.storage.redpanda.remote.write=false + status.storage.redpanda.remote.read=false + status.storage.redpanda.remote.write=false + offset.storage.replication.factor=-1 + config.storage.replication.factor=-1 + status.storage.replication.factor=-1 + producer.linger.ms=1 + producer.batch.size=131072 + config.providers=file,secretsManager,env + config.providers.file.class=org.apache.kafka.common.config.provider.FileConfigProvider + config.providers.env.class=org.apache.kafka.common.config.provider.EnvVarConfigProvider + - name: CONNECT_ADDITIONAL_CONFIGURATION + value: "" + - name: CONNECT_BOOTSTRAP_SERVERS + value: "" + - name: CONNECT_GC_LOG_ENABLED + value: "false" + - name: CONNECT_HEAP_OPTS + value: -Xms256M -Xmx2G + - name: CONNECT_LOG_LEVEL + value: warn + - name: CONNECT_TLS_ENABLED + value: "false" + envFrom: [] + image: docker.redpanda.com/redpandadata/connectors:v1.0.29 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: rest-api + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: connectors-cluster + ports: + - containerPort: 8083 + name: rest-api + protocol: TCP + - containerPort: 9404 + name: prometheus + protocol: TCP + readinessProbe: + failureThreshold: 2 + httpGet: + path: /connectors + port: rest-api + scheme: HTTP + initialDelaySeconds: 60 + periodSeconds: 10 + successThreshold: 3 + timeoutSeconds: 5 + resources: + limits: + cpu: "1" + memory: 2350Mi + requests: + cpu: "1" + memory: 2350Mi + securityContext: + allowPrivilegeEscalation: false + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /tmp + name: rp-connect-tmp + dnsPolicy: ClusterFirst + imagePullSecrets: [] + nodeSelector: {} + restartPolicy: Always + schedulerName: "" + securityContext: + fsGroup: 101 + fsGroupChangePolicy: OnRootMismatch + runAsUser: 101 + serviceAccountName: default + terminationGracePeriodSeconds: 30 + tolerations: [] + topologySpreadConstraints: + - labelSelector: + matchLabels: + app.kubernetes.io/component: connectors + app.kubernetes.io/instance: console + app.kubernetes.io/name: connectors + maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: ScheduleAnyway + volumes: + - emptyDir: + medium: Memory + sizeLimit: 5Mi + name: rp-connect-tmp +-- testdata/soft-anti-affinity.yaml.golden -- +--- +# Source: connectors/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: connectors + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: connectors + helm.sh/chart: connectors-0.1.12 + name: console-connectors +spec: + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: rest-api + port: 8083 + protocol: TCP + targetPort: 8083 + - name: prometheus + port: 9404 + protocol: TCP + targetPort: 9404 + selector: + app.kubernetes.io/component: connectors + app.kubernetes.io/instance: console + app.kubernetes.io/name: connectors + sessionAffinity: None + type: ClusterIP +--- +# Source: connectors/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: connectors + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: connectors + helm.sh/chart: connectors-0.1.12 + name: console-connectors +spec: + progressDeadlineSeconds: 600 + replicas: null + revisionHistoryLimit: 10 + selector: + matchLabels: + app.kubernetes.io/component: connectors + app.kubernetes.io/instance: console + app.kubernetes.io/name: connectors + strategy: + type: RollingUpdate + template: + metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/component: connectors + app.kubernetes.io/instance: console + app.kubernetes.io/name: connectors + spec: + affinity: + nodeAffinity: {} + podAffinity: {} + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/component: connectors + app.kubernetes.io/instance: console + app.kubernetes.io/name: connectors + namespaces: + - default + topologyKey: kubernetes.io/hostname + weight: 100 + containers: + - command: null + env: + - name: CONNECT_CONFIGURATION + value: |- + rest.advertised.port=8083 + rest.port=8083 + key.converter=org.apache.kafka.connect.converters.ByteArrayConverter + value.converter=org.apache.kafka.connect.converters.ByteArrayConverter + group.id=connectors-cluster + offset.storage.topic=_internal_connectors_offsets + config.storage.topic=_internal_connectors_configs + status.storage.topic=_internal_connectors_status + offset.storage.redpanda.remote.read=false + offset.storage.redpanda.remote.write=false + config.storage.redpanda.remote.read=false + config.storage.redpanda.remote.write=false + status.storage.redpanda.remote.read=false + status.storage.redpanda.remote.write=false + offset.storage.replication.factor=-1 + config.storage.replication.factor=-1 + status.storage.replication.factor=-1 + producer.linger.ms=1 + producer.batch.size=131072 + config.providers=file,secretsManager,env + config.providers.file.class=org.apache.kafka.common.config.provider.FileConfigProvider + config.providers.env.class=org.apache.kafka.common.config.provider.EnvVarConfigProvider + - name: CONNECT_ADDITIONAL_CONFIGURATION + value: "" + - name: CONNECT_BOOTSTRAP_SERVERS + value: "" + - name: CONNECT_GC_LOG_ENABLED + value: "false" + - name: CONNECT_HEAP_OPTS + value: -Xms256M -Xmx2G + - name: CONNECT_LOG_LEVEL + value: warn + - name: CONNECT_TLS_ENABLED + value: "false" + envFrom: [] + image: docker.redpanda.com/redpandadata/connectors:v1.0.29 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: rest-api + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: connectors-cluster + ports: + - containerPort: 8083 + name: rest-api + protocol: TCP + - containerPort: 9404 + name: prometheus + protocol: TCP + readinessProbe: + failureThreshold: 2 + httpGet: + path: /connectors + port: rest-api + scheme: HTTP + initialDelaySeconds: 60 + periodSeconds: 10 + successThreshold: 3 + timeoutSeconds: 5 + resources: + limits: + cpu: "1" + memory: 2350Mi + requests: + cpu: "1" + memory: 2350Mi + securityContext: + allowPrivilegeEscalation: false + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /tmp + name: rp-connect-tmp + dnsPolicy: ClusterFirst + imagePullSecrets: [] + nodeSelector: {} + restartPolicy: Always + schedulerName: "" + securityContext: + fsGroup: 101 + fsGroupChangePolicy: OnRootMismatch + runAsUser: 101 + serviceAccountName: default + terminationGracePeriodSeconds: 30 + tolerations: [] + topologySpreadConstraints: + - labelSelector: + matchLabels: + app.kubernetes.io/component: connectors + app.kubernetes.io/instance: console + app.kubernetes.io/name: connectors + maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: ScheduleAnyway + volumes: + - emptyDir: + medium: Memory + sizeLimit: 5Mi + name: rp-connect-tmp diff --git a/charts/redpanda/redpanda/5.9.2/charts/connectors/testdata/template-cases.txtar b/charts/redpanda/redpanda/5.9.2/charts/connectors/testdata/template-cases.txtar new file mode 100644 index 0000000000..f7c4acf38a --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/connectors/testdata/template-cases.txtar @@ -0,0 +1,31 @@ +-- defaults -- +# Intentionally left blank (Default values) +-- hard-anti-affinity -- +deployment: + podAntiAffinity: + topologyKey: kubernetes.io/hostname + type: hard + weight: 100 + +-- soft-anti-affinity -- +deployment: + podAntiAffinity: + topologyKey: kubernetes.io/hostname + type: soft + weight: 100 + +-- custom-anti-affinity -- +deployment: + podAntiAffinity: + type: custom + custom: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + foo: bar + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 40 + podAffinityTerm: + labelSelector: + matchLabels: + foo: bar diff --git a/charts/redpanda/redpanda/5.9.2/charts/connectors/values.go b/charts/redpanda/redpanda/5.9.2/charts/connectors/values.go new file mode 100644 index 0000000000..e5f58544b2 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/connectors/values.go @@ -0,0 +1,212 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You 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. +// +// +gotohelm:filename=_values.go.tpl +package connectors + +import ( + _ "embed" + + monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" + "github.com/redpanda-data/helm-charts/pkg/gotohelm/helmette" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +//go:embed values.yaml +var DefaultValuesYAML []byte + +type Values struct { + NameOverride string `json:"nameOverride"` + FullnameOverride string `json:"fullnameOverride"` + CommonLabels map[string]string `json:"commonLabels"` + Tolerations []corev1.Toleration `json:"tolerations"` + Image Image `json:"image"` + ImagePullSecrets []corev1.LocalObjectReference `json:"imagePullSecrets"` + Test Creatable `json:"test"` + Connectors Connectors `json:"connectors"` + Auth Auth `json:"auth"` + Logging Logging `json:"logging"` + Monitoring MonitoringConfig `json:"monitoring"` + Container Container `json:"container"` + Deployment DeploymentConfig `json:"deployment"` + Storage Storage `json:"storage"` + ServiceAccount ServiceAccountConfig `json:"serviceAccount"` + Service ServiceConfig `json:"service"` +} + +type Image struct { + Repository string `json:"repository"` + PullPolicy corev1.PullPolicy `json:"pullPolicy"` + Tag string `json:"tag"` +} + +type Connectors struct { + RestPort int32 `json:"restPort"` + BootstrapServers string `json:"bootstrapServers"` + SchemaRegistryURL string `json:"schemaRegistryURL"` + AdditionalConfiguration string `json:"additionalConfiguration"` + SecretManager SecretManager `json:"secretManager"` + ProducerBatchSize int32 `json:"producerBatchSize"` + ProducerLingerMS int32 `json:"producerLingerMS"` + Storage ConnectorsStorage `json:"storage"` + GroupID string `json:"groupID"` + BrokerTLS TLS `json:"brokerTLS"` +} + +type SecretManager struct { + Enabled bool `json:"enabled"` + Region string `json:"region"` + ConsolePrefix string `json:"consolePrefix"` + ConnectorsPrefix string `json:"connectorsPrefix"` +} + +type ConnectorsStorage struct { + ReplicationFactor struct { + Offset int32 `json:"offset"` + Config int32 `json:"config"` + Status int32 `json:"status"` + } `json:"replicationFactor"` + Remote struct { + Read struct { + Offset bool `json:"offset"` + Config bool `json:"config"` + Status bool `json:"status"` + } `json:"read"` + Write struct { + Offset bool `json:"offset"` + Config bool `json:"config"` + Status bool `json:"status"` + } `json:"write"` + } `json:"remote"` + Topic struct { + Offset string `json:"offset"` + Config string `json:"config"` + Status string `json:"status"` + } `json:"topic"` +} + +type TLS struct { + Enabled bool `json:"enabled"` + CA struct { + SecretRef string `json:"secretRef"` + SecretNameOverwrite string `json:"secretNameOverwrite"` + } `json:"ca"` + Cert struct { + SecretRef string `json:"secretRef"` + SecretNameOverwrite string `json:"secretNameOverwrite"` + } `json:"cert"` + Key struct { + SecretRef string `json:"secretRef"` + SecretNameOverwrite string `json:"secretNameOverwrite"` + } `json:"key"` +} + +type Auth struct { + SASL struct { + Enabled bool `json:"enabled"` + Mechanism string `json:"mechanism"` + SecretRef string `json:"secretRef"` + UserName string `json:"userName"` + } `json:"sasl"` +} + +func (c *Auth) SASLEnabled() bool { + saslEnabled := !helmette.Empty(c.SASL.UserName) + saslEnabled = saslEnabled && !helmette.Empty(c.SASL.Mechanism) + saslEnabled = saslEnabled && !helmette.Empty(c.SASL.SecretRef) + return saslEnabled +} + +type Logging struct { + Level string `json:"level"` +} + +type MonitoringConfig struct { + Enabled bool `json:"enabled"` + ScrapeInterval metav1.Duration `json:"scrapeInterval"` + Labels map[string]string `json:"labels"` + Annotations map[string]string `json:"annotations"` + NamespaceSelector monitoringv1.NamespaceSelector `json:"namespaceSelector"` +} + +type Container struct { + SecurityContext corev1.SecurityContext `json:"securityContext"` + Resources struct { + Request corev1.ResourceList `json:"request"` + Limits corev1.ResourceList `json:"limits"` + JavaMaxHeapSize *resource.Quantity `json:"javaMaxHeapSize"` + } `json:"resources"` + JavaGCLogEnabled string `json:"javaGCLogEnabled"` // XXX ugh - it ends up as an env var +} + +type DeploymentConfig struct { + Replicas *int32 `json:"replicas,omitempty"` + Create bool `json:"create"` + Command []string `json:"command,omitempty"` + Strategy appsv1.DeploymentStrategy `json:"strategy,omitempty"` + SchedulerName string `json:"schedulerName"` + Budget struct { + MaxUnavailable int32 `json:"maxUnavailable"` + } `json:"budget"` + Annotations map[string]string `json:"annotations"` + LivenessProbe *corev1.Probe `json:"livenessProbe,omitempty"` + ReadinessProbe *corev1.Probe `json:"readinessProbe,omitempty"` + ExtraEnv []corev1.EnvVar `json:"extraEnv"` + ExtraEnvFrom []corev1.EnvFromSource `json:"extraEnvFrom"` + ProgressDeadlineSeconds int32 `json:"progressDeadlineSeconds"` + RevisionHistoryLimit *int32 `json:"revisionHistoryLimit,omitempty"` + PodAffinity *corev1.PodAffinity `json:"podAffinity,omitempty"` + NodeAffinity *corev1.NodeAffinity `json:"nodeAffinity,omitempty"` + PodAntiAffinity *struct { + TopologyKey string `json:"topologyKey"` + Type string `json:"type"` + Weight *int32 `json:"weight,omitempty"` + Custom *corev1.PodAntiAffinity `json:"custom,omitempty"` + } `json:"podAntiAffinity,omitempty"` + NodeSelector map[string]string `json:"nodeSelector"` + PriorityClassName *string `json:"priorityClassName,omitempty"` // XXX uused in original template + Tolerations []corev1.Toleration `json:"tolerations"` + TopologySpreadConstraints []corev1.TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty"` + SecurityContext *corev1.PodSecurityContext `json:"securityContext,omitempty"` + TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty"` + RestartPolicy corev1.RestartPolicy `json:"restartPolicy"` +} + +type Storage struct { + Volume []corev1.Volume `json:"volume"` + VolumeMounts []corev1.VolumeMount `json:"volumeMounts"` +} + +type ServiceAccountConfig struct { + Create bool `json:"create"` + Annotations map[string]string `json:"annotations"` + Name string `json:"name"` +} + +type ServiceConfig struct { + Annotations map[string]string `json:"annotations"` + Name string `json:"name"` + Ports []struct { + Name string `json:"name"` + Port int32 `json:"port"` + } `json:"ports"` +} + +type Creatable struct { + Create bool `json:"create"` +} diff --git a/charts/redpanda/redpanda/5.9.2/charts/connectors/values.yaml b/charts/redpanda/redpanda/5.9.2/charts/connectors/values.yaml new file mode 100644 index 0000000000..f230a84d37 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/connectors/values.yaml @@ -0,0 +1,311 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You 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. + +# This file contains values for variables referenced from yaml files in the templates directory. +# +# For further information on Helm templating see the documentation at: +# https://helm.sh/docs/chart_template_guide/values_files/ + +# +# >>> This chart requires Helm version 3.6.0 or greater <<< +# + +# Common settings +# +# -- Override `connectors.name` template. +nameOverride: "" +# -- Override `connectors.fullname` template. +fullnameOverride: "" +# -- Additional labels to add to all Kubernetes objects. +# For example, `my.k8s.service: redpanda`. +commonLabels: {} +# -- Taints to be tolerated by Pods. +# For details, +# see the [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/). +tolerations: [] + +# -- Redpanda Docker image settings. +image: + # -- Docker repository from which to pull the Redpanda Docker image. + repository: docker.redpanda.com/redpandadata/connectors + # -- The Redpanda version. + # See DockerHub for: + # [All stable versions](https://hub.docker.com/r/redpandadata/redpanda/tags) + # and [all unstable versions](https://hub.docker.com/r/redpandadata/redpanda-unstable/tags). + # @default -- `Chart.appVersion`. + tag: "" + # -- The imagePullPolicy. + # If `image.tag` is 'latest', the default is `Always`. + pullPolicy: IfNotPresent + +# -- Pull secrets may be used to provide credentials to image repositories +# See https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ +imagePullSecrets: [] + +test: + create: true + +connectors: + # -- The port on which the Kafka Connect REST API listens. The API is used for administrative tasks. + restPort: 8083 + # -- A comma-separated list of Redpanda broker addresses in the format of IP:Port or DNS:Port. Kafka Connect uses this to connect to the Redpanda/Kafka cluster. + bootstrapServers: "" + # A comma-separated list of Schema Registry addresses in the format IP:Port or DNS:Port. The Schema Registry is a service that manages the schemas used by producers and consumers. + schemaRegistryURL: "" + # -- A placeholder for any Java configuration settings for Kafka Connect that are not explicitly defined in this Helm chart. Java configuration settings are passed to the Kafka Connect startup script. + additionalConfiguration: "" + secretManager: + enabled: false + region: "" + consolePrefix: "" + connectorsPrefix: "" + # -- The number of bytes of records a producer will attempt to batch together before sending to Redpanda. Batching improves throughput. + producerBatchSize: 131072 + # -- The time, in milliseconds, that a producer will wait before sending a batch of records. Waiting allows the producer to gather more records in the same batch and improve throughput. + producerLingerMS: 1 + storage: + # -- The number of replicas for each of the internal topics that Kafka Connect uses. + replicationFactor: + # -- Replication factor for the offset topic. + offset: -1 + # -- Replication factor for the configuration topic. + config: -1 + # -- Replication factor for the status topic. + status: -1 + # -- Indicates if read and write operations for the respective topics are allowed remotely. + remote: + read: + offset: false + config: false + status: false + write: + offset: false + config: false + status: false + topic: + # -- The name of the internal topic that Kafka Connect uses to store source connector offsets. + offset: _internal_connectors_offsets + # -- The name of the internal topic that Kafka Connect uses to store connector and task configurations. + config: _internal_connectors_configs + # -- The name of the internal topic that Kafka Connect uses to store connector and task status updates. + status: _internal_connectors_status + # -- A unique string that identifies the Kafka Connect cluster. It's used in the formation of the internal topic names, ensuring that multiple Kafka Connect clusters can connect to the same Redpanda cluster without interfering with each other. + groupID: connectors-cluster + brokerTLS: + enabled: false + ca: + # -- The name of the Secret where the ca.crt file content is located. + secretRef: "" + # -- If `secretRef` points to a Secret where the certificate authority (CA) is not under the + # `ca.crt` key, use `secretNameOverwrite` to overwrite it e.g. `corp-ca.crt`. + secretNameOverwrite: "" + cert: + # -- The name of the secret where client signed certificate is located + secretRef: "" + # -- If secretRef points to secret where client signed certificate is not under + # tls.crt key then please use secretNameOverwrite to overwrite it e.g. corp-tls.crt + secretNameOverwrite: "" + key: + # -- The name of the secret where client private key is located + secretRef: "" + # -- If secretRef points to secret where client private key is not under + # tls.key key then please use secretNameOverwrite to overwrite it e.g. corp-tls.key + secretNameOverwrite: "" + +# -- Authentication settings. +# For details, +# see the [SASL documentation](https://docs.redpanda.com/docs/manage/kubernetes/security/sasl-kubernetes/). +# The first line of the secret file is used. So the first superuser is used to authenticate to the Redpanda cluster. +auth: + sasl: + enabled: false + # -- The authentication mechanism to use for the superuser. Options are `scram-sha-256` and `scram-sha-512`. + mechanism: scram-sha-512 + # -- A Secret that contains your SASL user password. + secretRef: "" + userName: "" + +# -- Log-level settings. +logging: + # -- Log level + # Valid values (from least to most verbose) are: `error`, `warn`, `info` and `debug`. + level: warn + +# -- Monitoring. +# When set to `true`, the Helm chart creates a PodMonitor that can be used by Prometheus-Operator or VictoriaMetrics-Operator to scrape the metrics. +monitoring: + enabled: false + scrapeInterval: 30s + labels: {} + annotations: {} + namespaceSelector: + any: true + +container: + # + # -- Security context for the Redpanda Connectors container. + # See also `deployment.securityContext` for Pod-level settings. + securityContext: + allowPrivilegeEscalation: false + # -- Pod resource management. + resources: + request: + # Numeric values here are also acceptable. + cpu: "1" + memory: 2350Mi + limits: + cpu: "1" + memory: 2350Mi + # -- Java maximum heap size must not be greater than `container.resources.limits.memory`. + javaMaxHeapSize: 2G + javaGCLogEnabled: "false" + +deployment: + # Replicas can be used to scale Deployment + # replicas + + create: true + # Customize the command to use as the entrypoint of the Deployment. + # command: [] + strategy: + type: RollingUpdate + schedulerName: "" + budget: + maxUnavailable: 1 + # -- Additional annotations to apply to the Pods of this Deployment. + annotations: {} + # -- Adjust the period for your probes to meet your needs. + # For details, + # see the [Kubernetes documentation](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes). + livenessProbe: + initialDelaySeconds: 10 + failureThreshold: 3 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + readinessProbe: + initialDelaySeconds: 60 + failureThreshold: 2 + periodSeconds: 10 + successThreshold: 3 + timeoutSeconds: 5 + + # -- Additional environment variables for the Pods. + extraEnv: [] + # - name: RACK_ID + # value: "1" + + # -- Configure extra environment variables from Secrets and ConfigMaps. + extraEnvFrom: [] + # - secretRef: + # name: my-secret + # - configMapRef: + # name: my-configmap + + # -- The maximum time in seconds for a deployment to make progress before it is + # considered to be failed. The deployment controller will continue to process + # failed deployments and a condition with a ProgressDeadlineExceeded reason + # will be surfaced in the deployment status. Note that progress will not be + # estimated during the time a deployment is paused. + progressDeadlineSeconds: 600 + + # -- The number of old ReplicaSets to retain to allow rollback. This is a pointer + # to distinguish between explicit zero and not specified. + revisionHistoryLimit: 10 + + # -- Inter-Pod Affinity rules for scheduling Pods of this Deployment. + # For details, + # see the [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#inter-pod-affinity-and-anti-affinity). + podAffinity: {} + # -- Node Affinity rules for scheduling Pods of this Deployment. + # The suggestion would be to spread Pods according to topology zone. + # For details, + # see the [Kubernetes documentation](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity). + nodeAffinity: {} + # -- Anti-affinity rules for scheduling Pods of this Deployment. + # For details, + # see the [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#inter-pod-affinity-and-anti-affinity). + # You may either edit the default settings for anti-affinity rules, + # or specify new anti-affinity rules to use instead of the defaults. + podAntiAffinity: + # -- The `topologyKey` to be used. + # Can be used to spread across different nodes, AZs, regions etc. + topologyKey: kubernetes.io/hostname + # -- Valid anti-affinity types are `soft`, `hard`, or `custom`. + # Use `custom` if you want to supply your own anti-affinity rules in the `podAntiAffinity.custom` object. + type: hard + # -- Weight for `soft` anti-affinity rules. + # Does not apply for other anti-affinity types. + weight: 100 + # -- Change `podAntiAffinity.type` to `custom` and provide your own podAntiAffinity rules here. + custom: {} + # -- Node selection constraints for scheduling Pods of this Deployment. + # These constraints override the global `nodeSelector` value. + # For details, + # see the [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector). + nodeSelector: {} + # -- PriorityClassName given to Pods of this Deployment. + # For details, + # see the [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#priorityclass). + priorityClassName: "" + # -- Taints to be tolerated by Pods of this Deployment. + # These tolerations override the global tolerations value. + # For details, + # see the [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/). + tolerations: [] + # For details, + # see the [Kubernetes documentation](https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/). + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: ScheduleAnyway + securityContext: + fsGroup: 101 + runAsUser: 101 + fsGroupChangePolicy: OnRootMismatch + terminationGracePeriodSeconds: 30 + restartPolicy: Always + +storage: + volume: + - emptyDir: + medium: Memory + sizeLimit: 5Mi + name: rp-connect-tmp + volumeMounts: + - mountPath: /tmp + name: rp-connect-tmp + +# -- ServiceAccount management. +serviceAccount: + # -- Specifies whether a ServiceAccount should be created. + create: false + # -- Annotations to add to the ServiceAccount. + annotations: {} + # -- The name of the ServiceAccount to use. + # If not set and `serviceAccount.create` is `true`, + # a name is generated using the `connectors.fullname` template. + name: "" + +# -- Service management. +service: + # -- Annotations to add to the Service. + annotations: {} + # -- The name of the service to use. + # If not set, a name is generated using the `connectors.fullname` template. + name: "" + ports: + - name: prometheus + port: 9404 diff --git a/charts/redpanda/redpanda/5.9.2/charts/connectors/values_partial.gen.go b/charts/redpanda/redpanda/5.9.2/charts/connectors/values_partial.gen.go new file mode 100644 index 0000000000..e13a1b2173 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/connectors/values_partial.gen.go @@ -0,0 +1,188 @@ +//go:build !generate + +// +gotohelm:ignore=true +// +// Code generated by genpartial DO NOT EDIT. +package connectors + +import ( + monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type PartialValues struct { + NameOverride *string "json:\"nameOverride,omitempty\"" + FullnameOverride *string "json:\"fullnameOverride,omitempty\"" + CommonLabels map[string]string "json:\"commonLabels,omitempty\"" + Tolerations []corev1.Toleration "json:\"tolerations,omitempty\"" + Image *PartialImage "json:\"image,omitempty\"" + ImagePullSecrets []corev1.LocalObjectReference "json:\"imagePullSecrets,omitempty\"" + Test *PartialCreatable "json:\"test,omitempty\"" + Connectors *PartialConnectors "json:\"connectors,omitempty\"" + Auth *PartialAuth "json:\"auth,omitempty\"" + Logging *PartialLogging "json:\"logging,omitempty\"" + Monitoring *PartialMonitoringConfig "json:\"monitoring,omitempty\"" + Container *PartialContainer "json:\"container,omitempty\"" + Deployment *PartialDeploymentConfig "json:\"deployment,omitempty\"" + Storage *PartialStorage "json:\"storage,omitempty\"" + ServiceAccount *PartialServiceAccountConfig "json:\"serviceAccount,omitempty\"" + Service *PartialServiceConfig "json:\"service,omitempty\"" +} + +type PartialImage struct { + Repository *string "json:\"repository,omitempty\"" + PullPolicy *corev1.PullPolicy "json:\"pullPolicy,omitempty\"" + Tag *string "json:\"tag,omitempty\"" +} + +type PartialCreatable struct { + Create *bool "json:\"create,omitempty\"" +} + +type PartialConnectors struct { + RestPort *int32 "json:\"restPort,omitempty\"" + BootstrapServers *string "json:\"bootstrapServers,omitempty\"" + SchemaRegistryURL *string "json:\"schemaRegistryURL,omitempty\"" + AdditionalConfiguration *string "json:\"additionalConfiguration,omitempty\"" + SecretManager *PartialSecretManager "json:\"secretManager,omitempty\"" + ProducerBatchSize *int32 "json:\"producerBatchSize,omitempty\"" + ProducerLingerMS *int32 "json:\"producerLingerMS,omitempty\"" + Storage *PartialConnectorsStorage "json:\"storage,omitempty\"" + GroupID *string "json:\"groupID,omitempty\"" + BrokerTLS *PartialTLS "json:\"brokerTLS,omitempty\"" +} + +type PartialAuth struct { + SASL *struct { + Enabled *bool "json:\"enabled,omitempty\"" + Mechanism *string "json:\"mechanism,omitempty\"" + SecretRef *string "json:\"secretRef,omitempty\"" + UserName *string "json:\"userName,omitempty\"" + } "json:\"sasl,omitempty\"" +} + +type PartialLogging struct { + Level *string "json:\"level,omitempty\"" +} + +type PartialMonitoringConfig struct { + Enabled *bool "json:\"enabled,omitempty\"" + ScrapeInterval *metav1.Duration "json:\"scrapeInterval,omitempty\"" + Labels map[string]string "json:\"labels,omitempty\"" + Annotations map[string]string "json:\"annotations,omitempty\"" + NamespaceSelector *monitoringv1.NamespaceSelector "json:\"namespaceSelector,omitempty\"" +} + +type PartialContainer struct { + SecurityContext *corev1.SecurityContext "json:\"securityContext,omitempty\"" + Resources *struct { + Request corev1.ResourceList "json:\"request,omitempty\"" + Limits corev1.ResourceList "json:\"limits,omitempty\"" + JavaMaxHeapSize *resource.Quantity "json:\"javaMaxHeapSize,omitempty\"" + } "json:\"resources,omitempty\"" + JavaGCLogEnabled *string "json:\"javaGCLogEnabled,omitempty\"" +} + +type PartialDeploymentConfig struct { + Replicas *int32 "json:\"replicas,omitempty\"" + Create *bool "json:\"create,omitempty\"" + Command []string "json:\"command,omitempty\"" + Strategy *appsv1.DeploymentStrategy "json:\"strategy,omitempty\"" + SchedulerName *string "json:\"schedulerName,omitempty\"" + Budget *struct { + MaxUnavailable *int32 "json:\"maxUnavailable,omitempty\"" + } "json:\"budget,omitempty\"" + Annotations map[string]string "json:\"annotations,omitempty\"" + LivenessProbe *corev1.Probe "json:\"livenessProbe,omitempty\"" + ReadinessProbe *corev1.Probe "json:\"readinessProbe,omitempty\"" + ExtraEnv []corev1.EnvVar "json:\"extraEnv,omitempty\"" + ExtraEnvFrom []corev1.EnvFromSource "json:\"extraEnvFrom,omitempty\"" + ProgressDeadlineSeconds *int32 "json:\"progressDeadlineSeconds,omitempty\"" + RevisionHistoryLimit *int32 "json:\"revisionHistoryLimit,omitempty\"" + PodAffinity *corev1.PodAffinity "json:\"podAffinity,omitempty\"" + NodeAffinity *corev1.NodeAffinity "json:\"nodeAffinity,omitempty\"" + PodAntiAffinity *struct { + TopologyKey *string "json:\"topologyKey,omitempty\"" + Type *string "json:\"type,omitempty\"" + Weight *int32 "json:\"weight,omitempty\"" + Custom *corev1.PodAntiAffinity "json:\"custom,omitempty\"" + } "json:\"podAntiAffinity,omitempty\"" + NodeSelector map[string]string "json:\"nodeSelector,omitempty\"" + PriorityClassName *string "json:\"priorityClassName,omitempty\"" + Tolerations []corev1.Toleration "json:\"tolerations,omitempty\"" + TopologySpreadConstraints []corev1.TopologySpreadConstraint "json:\"topologySpreadConstraints,omitempty\"" + SecurityContext *corev1.PodSecurityContext "json:\"securityContext,omitempty\"" + TerminationGracePeriodSeconds *int64 "json:\"terminationGracePeriodSeconds,omitempty\"" + RestartPolicy *corev1.RestartPolicy "json:\"restartPolicy,omitempty\"" +} + +type PartialStorage struct { + Volume []corev1.Volume "json:\"volume,omitempty\"" + VolumeMounts []corev1.VolumeMount "json:\"volumeMounts,omitempty\"" +} + +type PartialServiceAccountConfig struct { + Create *bool "json:\"create,omitempty\"" + Annotations map[string]string "json:\"annotations,omitempty\"" + Name *string "json:\"name,omitempty\"" +} + +type PartialServiceConfig struct { + Annotations map[string]string "json:\"annotations,omitempty\"" + Name *string "json:\"name,omitempty\"" + Ports []struct { + Name *string "json:\"name,omitempty\"" + Port *int32 "json:\"port,omitempty\"" + } "json:\"ports,omitempty\"" +} + +type PartialSecretManager struct { + Enabled *bool "json:\"enabled,omitempty\"" + Region *string "json:\"region,omitempty\"" + ConsolePrefix *string "json:\"consolePrefix,omitempty\"" + ConnectorsPrefix *string "json:\"connectorsPrefix,omitempty\"" +} + +type PartialConnectorsStorage struct { + ReplicationFactor *struct { + Offset *int32 "json:\"offset,omitempty\"" + Config *int32 "json:\"config,omitempty\"" + Status *int32 "json:\"status,omitempty\"" + } "json:\"replicationFactor,omitempty\"" + Remote *struct { + Read *struct { + Offset *bool "json:\"offset,omitempty\"" + Config *bool "json:\"config,omitempty\"" + Status *bool "json:\"status,omitempty\"" + } "json:\"read,omitempty\"" + Write *struct { + Offset *bool "json:\"offset,omitempty\"" + Config *bool "json:\"config,omitempty\"" + Status *bool "json:\"status,omitempty\"" + } "json:\"write,omitempty\"" + } "json:\"remote,omitempty\"" + Topic *struct { + Offset *string "json:\"offset,omitempty\"" + Config *string "json:\"config,omitempty\"" + Status *string "json:\"status,omitempty\"" + } "json:\"topic,omitempty\"" +} + +type PartialTLS struct { + Enabled *bool "json:\"enabled,omitempty\"" + CA *struct { + SecretRef *string "json:\"secretRef,omitempty\"" + SecretNameOverwrite *string "json:\"secretNameOverwrite,omitempty\"" + } "json:\"ca,omitempty\"" + Cert *struct { + SecretRef *string "json:\"secretRef,omitempty\"" + SecretNameOverwrite *string "json:\"secretNameOverwrite,omitempty\"" + } "json:\"cert,omitempty\"" + Key *struct { + SecretRef *string "json:\"secretRef,omitempty\"" + SecretNameOverwrite *string "json:\"secretNameOverwrite,omitempty\"" + } "json:\"key,omitempty\"" +} diff --git a/charts/redpanda/redpanda/5.9.2/charts/console/.helmignore b/charts/redpanda/redpanda/5.9.2/charts/console/.helmignore new file mode 100644 index 0000000000..04ecd888b5 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/console/.helmignore @@ -0,0 +1,24 @@ +# 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 +README.md.gotmpl +# 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/redpanda/redpanda/5.9.2/charts/console/Chart.yaml b/charts/redpanda/redpanda/5.9.2/charts/console/Chart.yaml new file mode 100644 index 0000000000..dd51b48d8a --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/console/Chart.yaml @@ -0,0 +1,23 @@ +annotations: + artifacthub.io/images: | + - name: redpanda + image: docker.redpanda.com/redpandadata/console:v2.7.0 + artifacthub.io/license: Apache-2.0 + artifacthub.io/links: | + - name: Documentation + url: https://docs.redpanda.com + - name: "Helm (>= 3.6.0)" + url: https://helm.sh/docs/intro/install/ +apiVersion: v2 +appVersion: v2.7.0 +description: Helm chart to deploy Redpanda Console. +icon: https://images.ctfassets.net/paqvtpyf8rwu/3cYHw5UzhXCbKuR24GDFGO/73fb682e6157d11c10d5b2b5da1d5af0/skate-stand-panda.svg +kubeVersion: '>= 1.21.0-0' +maintainers: +- name: redpanda-data + url: https://github.com/orgs/redpanda-data/people +name: console +sources: +- https://github.com/redpanda-data/helm-charts +type: application +version: 0.7.29 diff --git a/charts/redpanda/redpanda/5.9.2/charts/console/README.md b/charts/redpanda/redpanda/5.9.2/charts/console/README.md new file mode 100644 index 0000000000..9bd93425f8 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/console/README.md @@ -0,0 +1,353 @@ +# Redpanda Console Helm Chart Specification +--- +description: Find the default values and descriptions of settings in the Redpanda Console Helm chart. +--- + +![Version: 0.7.29](https://img.shields.io/badge/Version-0.7.29-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v2.7.0](https://img.shields.io/badge/AppVersion-v2.7.0-informational?style=flat-square) + +This page describes the official Redpanda Console Helm Chart. In particular, this page describes the contents of the chart’s [`values.yaml` file](https://github.com/redpanda-data/helm-charts/blob/main/charts/console/values.yaml). +Each of the settings is listed and described on this page, along with any default values. + +The Redpanda Console Helm chart is included as a subchart in the Redpanda Helm chart so that you can deploy and configure Redpanda and Redpanda Console together. +For instructions on how to install and use the chart, refer to the [deployment documentation](https://docs.redpanda.com/docs/deploy/deployment-option/self-hosted/kubernetes/kubernetes-deploy/). +For instructions on how to override and customize the chart’s values, see [Configure Redpanda Console](https://docs.redpanda.com/docs/manage/kubernetes/configure-helm-chart/#configure-redpanda-console). + +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) + +## Source Code + +* + +## Requirements + +Kubernetes: `>= 1.21.0-0` + +## Settings + +### [affinity](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=affinity) + +**Default:** `{}` + +### [annotations](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=annotations) + +Annotations to add to the deployment. + +**Default:** `{}` + +### [automountServiceAccountToken](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=automountServiceAccountToken) + +Automount API credentials for the Service Account into the pod. + +**Default:** `true` + +### [autoscaling.enabled](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=autoscaling.enabled) + +**Default:** `false` + +### [autoscaling.maxReplicas](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=autoscaling.maxReplicas) + +**Default:** `100` + +### [autoscaling.minReplicas](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=autoscaling.minReplicas) + +**Default:** `1` + +### [autoscaling.targetCPUUtilizationPercentage](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=autoscaling.targetCPUUtilizationPercentage) + +**Default:** `80` + +### [commonLabels](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=commonLabels) + +**Default:** `{}` + +### [configmap.create](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=configmap.create) + +**Default:** `true` + +### [console.config](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=console.config) + +Settings for the `Config.yaml` (required). For a reference of configuration settings, see the [Redpanda Console documentation](https://docs.redpanda.com/docs/reference/console/config/). + +**Default:** `{}` + +### [deployment.create](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=deployment.create) + +**Default:** `true` + +### [enterprise](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=enterprise) + +Settings for license key, as an alternative to secret.enterprise when a license secret is available + +**Default:** + +``` +{"licenseSecretRef":{"key":"","name":""}} +``` + +### [extraContainers](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=extraContainers) + +Add additional containers, such as for oauth2-proxy. + +**Default:** `[]` + +### [extraEnv](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=extraEnv) + +Additional environment variables for the Redpanda Console Deployment. + +**Default:** `[]` + +### [extraEnvFrom](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=extraEnvFrom) + +Additional environment variables for Redpanda Console mapped from Secret or ConfigMap. + +**Default:** `[]` + +### [extraVolumeMounts](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=extraVolumeMounts) + +Add additional volume mounts, such as for TLS keys. + +**Default:** `[]` + +### [extraVolumes](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=extraVolumes) + +Add additional volumes, such as for TLS keys. + +**Default:** `[]` + +### [fullnameOverride](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=fullnameOverride) + +Override `console.fullname` template. + +**Default:** `""` + +### [image](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=image) + +Redpanda Console Docker image settings. + +**Default:** + +``` +{"pullPolicy":"IfNotPresent","registry":"docker.redpanda.com","repository":"redpandadata/console","tag":""} +``` + +### [image.pullPolicy](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=image.pullPolicy) + +The imagePullPolicy. + +**Default:** `"IfNotPresent"` + +### [image.repository](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=image.repository) + +Docker repository from which to pull the Redpanda Docker image. + +**Default:** `"redpandadata/console"` + +### [image.tag](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=image.tag) + +The Redpanda Console version. See DockerHub for: [All stable versions](https://hub.docker.com/r/redpandadata/console/tags) and [all unstable versions](https://hub.docker.com/r/redpandadata/console-unstable/tags). + +**Default:** `Chart.appVersion` + +### [imagePullSecrets](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=imagePullSecrets) + +Pull secrets may be used to provide credentials to image repositories See https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + +**Default:** `[]` + +### [ingress.annotations](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=ingress.annotations) + +**Default:** `{}` + +### [ingress.className](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=ingress.className) + +**Default:** `nil` + +### [ingress.enabled](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=ingress.enabled) + +**Default:** `false` + +### [ingress.hosts[0].host](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=ingress.hosts[0].host) + +**Default:** `"chart-example.local"` + +### [ingress.hosts[0].paths[0].path](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=ingress.hosts[0].paths[0].path) + +**Default:** `"/"` + +### [ingress.hosts[0].paths[0].pathType](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=ingress.hosts[0].paths[0].pathType) + +**Default:** `"ImplementationSpecific"` + +### [ingress.tls](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=ingress.tls) + +**Default:** `[]` + +### [initContainers](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=initContainers) + +Any initContainers defined should be written here + +**Default:** `{"extraInitContainers":""}` + +### [initContainers.extraInitContainers](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=initContainers.extraInitContainers) + +Additional set of init containers + +**Default:** `""` + +### [livenessProbe](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=livenessProbe) + +Settings for liveness and readiness probes. For details, see the [Kubernetes documentation](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes). + +**Default:** + +``` +{"failureThreshold":3,"periodSeconds":10,"successThreshold":1,"timeoutSeconds":1} +``` + +### [nameOverride](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=nameOverride) + +Override `console.name` template. + +**Default:** `""` + +### [nodeSelector](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=nodeSelector) + +**Default:** `{}` + +### [podAnnotations](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=podAnnotations) + +**Default:** `{}` + +### [podLabels](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=podLabels) + +**Default:** `{}` + +### [podSecurityContext.fsGroup](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=podSecurityContext.fsGroup) + +**Default:** `99` + +### [podSecurityContext.runAsUser](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=podSecurityContext.runAsUser) + +**Default:** `99` + +### [priorityClassName](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=priorityClassName) + +PriorityClassName given to Pods. For details, see the [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#priorityclass). + +**Default:** `""` + +### [readinessProbe.failureThreshold](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=readinessProbe.failureThreshold) + +**Default:** `3` + +### [readinessProbe.initialDelaySeconds](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=readinessProbe.initialDelaySeconds) + +Grant time to test connectivity to upstream services such as Kafka and Schema Registry. + +**Default:** `10` + +### [readinessProbe.periodSeconds](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=readinessProbe.periodSeconds) + +**Default:** `10` + +### [readinessProbe.successThreshold](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=readinessProbe.successThreshold) + +**Default:** `1` + +### [readinessProbe.timeoutSeconds](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=readinessProbe.timeoutSeconds) + +**Default:** `1` + +### [replicaCount](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=replicaCount) + +**Default:** `1` + +### [resources](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=resources) + +**Default:** `{}` + +### [secret](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=secret) + +Create a new Kubernetes Secret for all sensitive configuration inputs. Each provided Secret is mounted automatically and made available to the Pod. If you want to use one or more existing Secrets, you can use the `extraEnvFrom` list to mount environment variables from string and secretMounts to mount files such as Certificates from Secrets. + +**Default:** + +``` +{"create":true,"enterprise":{},"kafka":{},"login":{"github":{},"google":{},"jwtSecret":"","oidc":{},"okta":{}},"redpanda":{"adminApi":{}}} +``` + +### [secret.kafka](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=secret.kafka) + +Kafka Secrets. + +**Default:** `{}` + +### [secretMounts](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=secretMounts) + +SecretMounts is an abstraction to make a Secret available in the container's filesystem. Under the hood it creates a volume and a volume mount for the Redpanda Console container. + +**Default:** `[]` + +### [securityContext.runAsNonRoot](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=securityContext.runAsNonRoot) + +**Default:** `true` + +### [service.annotations](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=service.annotations) + +**Default:** `{}` + +### [service.port](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=service.port) + +**Default:** `8080` + +### [service.targetPort](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=service.targetPort) + +Override the value in `console.config.server.listenPort` if not `nil` + +**Default:** `nil` + +### [service.type](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=service.type) + +**Default:** `"ClusterIP"` + +### [serviceAccount.annotations](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=serviceAccount.annotations) + +Annotations to add to the service account. + +**Default:** `{}` + +### [serviceAccount.automountServiceAccountToken](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=serviceAccount.automountServiceAccountToken) + +Specifies whether a service account should automount API-Credentials + +**Default:** `true` + +### [serviceAccount.create](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=serviceAccount.create) + +Specifies whether a service account should be created. + +**Default:** `true` + +### [serviceAccount.name](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=serviceAccount.name) + +The name of the service account to use. If not set and `serviceAccount.create` is `true`, a name is generated using the `console.fullname` template + +**Default:** `""` + +### [strategy](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=strategy) + +**Default:** `{}` + +### [tests.enabled](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=tests.enabled) + +**Default:** `true` + +### [tolerations](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=tolerations) + +**Default:** `[]` + +### [topologySpreadConstraints](https://artifacthub.io/packages/helm/redpanda-data/console?modal=values&path=topologySpreadConstraints) + +**Default:** `[]` + diff --git a/charts/redpanda/redpanda/5.9.2/charts/console/chart_test.go b/charts/redpanda/redpanda/5.9.2/charts/console/chart_test.go new file mode 100644 index 0000000000..0e652c13e1 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/console/chart_test.go @@ -0,0 +1,158 @@ +package console + +import ( + "encoding/json" + "fmt" + "os" + "regexp" + "slices" + "testing" + + fuzz "github.com/google/gofuzz" + "github.com/redpanda-data/helm-charts/pkg/helm" + "github.com/redpanda-data/helm-charts/pkg/testutil" + "github.com/santhosh-tekuri/jsonschema/v5" + "github.com/stretchr/testify/require" + "golang.org/x/tools/txtar" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/yaml" +) + +// TestValues asserts that the chart's values.yaml file can be losslessly +// loaded into our type [Values] struct. +// NB: values.yaml should round trip through [Values], not [PartialValues], as +// [Values]'s omitempty tags are models after values.yaml. +func TestValues(t *testing.T) { + var typedValues Values + var unstructuredValues map[string]any + + require.NoError(t, yaml.Unmarshal(DefaultValuesYAML, &typedValues)) + require.NoError(t, yaml.Unmarshal(DefaultValuesYAML, &unstructuredValues)) + + typedValuesJSON, err := json.Marshal(typedValues) + require.NoError(t, err) + + unstructuredValuesJSON, err := json.Marshal(unstructuredValues) + require.NoError(t, err) + + require.JSONEq(t, string(unstructuredValuesJSON), string(typedValuesJSON)) +} + +func TestTemplate(t *testing.T) { + ctx := testutil.Context(t) + client, err := helm.New(helm.Options{ConfigHome: testutil.TempDir(t)}) + require.NoError(t, err) + + casesArchive, err := txtar.ParseFile("testdata/template-cases.txtar") + require.NoError(t, err) + + generatedCasesArchive, err := txtar.ParseFile("testdata/template-cases-generated.txtar") + require.NoError(t, err) + + goldens := testutil.NewTxTar(t, "testdata/template-cases.golden.txtar") + + for _, tc := range append(casesArchive.Files, generatedCasesArchive.Files...) { + tc := tc + t.Run(tc.Name, func(t *testing.T) { + var values PartialValues + require.NoError(t, yaml.Unmarshal(tc.Data, &values)) + + out, err := client.Template(ctx, ".", helm.TemplateOptions{ + Name: "console", + Values: values, + Set: []string{ + // jwtSecret defaults to a random string. Can't have that + // in snapshot testing so set it to a static value. + "secret.login.jwtSecret=SECRETKEY", + }, + }) + require.NoError(t, err) + goldens.AssertGolden(t, testutil.YAML, fmt.Sprintf("testdata/%s.yaml.golden", tc.Name), out) + }) + } +} + +// TestGenerateCases is not a test case (sorry) but a test case generator for +// the console chart. +func TestGenerateCases(t *testing.T) { + // Nasty hack to avoid making a main function somewhere. Sorry not sorry. + if !slices.Contains(os.Args, fmt.Sprintf("-test.run=%s", t.Name())) { + t.Skipf("%s will only run if explicitly specified (-run %q)", t.Name(), t.Name()) + } + + // Makes strings easier to read. + asciiStrs := func(s *string, c fuzz.Continue) { + const alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + var x []byte + for i := 0; i < c.Intn(25); i++ { + x = append(x, alphabet[c.Intn(len(alphabet))]) + } + *s = string(x) + } + smallInts := func(s *int, c fuzz.Continue) { + *s = c.Intn(501) + } + + fuzzer := fuzz.New().NumElements(0, 3).SkipFieldsWithPattern( + regexp.MustCompile("^(SELinuxOptions|WindowsOptions|SeccompProfile|TCPSocket|HTTPHeaders|VolumeSource)$"), + ).Funcs( + asciiStrs, + smallInts, + func(t *corev1.ServiceType, c fuzz.Continue) { + types := []corev1.ServiceType{ + corev1.ServiceTypeClusterIP, + corev1.ServiceTypeExternalName, + corev1.ServiceTypeNodePort, + corev1.ServiceTypeLoadBalancer, + } + *t = types[c.Intn(len(types))] + }, + func(s *corev1.ResourceName, c fuzz.Continue) { asciiStrs((*string)(s), c) }, + func(_ *any, c fuzz.Continue) {}, + func(_ *[]corev1.ResourceClaim, c fuzz.Continue) {}, + func(_ *[]metav1.ManagedFieldsEntry, c fuzz.Continue) {}, + ) + + schema, err := jsonschema.CompileString("", string(ValuesSchemaJSON)) + require.NoError(t, err) + + nilChance := float64(0.8) + + files := make([]txtar.File, 0, 50) + for i := 0; i < 50; i++ { + // Every 5 iterations, decrease nil chance to ensure that we're biased + // towards exploring most cases. + if i%5 == 0 && nilChance > .1 { + nilChance -= .1 + } + + var values PartialValues + fuzzer.NilChance(nilChance).Fuzz(&values) + + out, err := yaml.Marshal(values) + require.NoError(t, err) + + merged, err := helm.MergeYAMLValues(t.TempDir(), DefaultValuesYAML, out) + require.NoError(t, err) + + // Ensure that our generated values comply with the schema set by the chart. + if err := schema.Validate(merged); err != nil { + t.Logf("Generated invalid values; trying again...\n%v", err) + i-- + continue + } + + files = append(files, txtar.File{ + Name: fmt.Sprintf("case-%03d", i), + Data: out, + }) + } + + archive := txtar.Format(&txtar.Archive{ + Comment: []byte(fmt.Sprintf(`Generated by %s`, t.Name())), + Files: files, + }) + + require.NoError(t, os.WriteFile("testdata/template-cases-generated.txtar", archive, 0o644)) +} diff --git a/charts/redpanda/redpanda/5.9.2/charts/console/configmap.go b/charts/redpanda/redpanda/5.9.2/charts/console/configmap.go new file mode 100644 index 0000000000..c4fa382915 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/console/configmap.go @@ -0,0 +1,61 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You 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. +// +// +gotohelm:filename=_configmap.go.tpl +package console + +import ( + "fmt" + + "github.com/redpanda-data/helm-charts/pkg/gotohelm/helmette" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func ConfigMap(dot *helmette.Dot) *corev1.ConfigMap { + values := helmette.Unwrap[Values](dot.Values) + + if !values.ConfigMap.Create { + return nil + } + + data := map[string]string{ + "config.yaml": fmt.Sprintf("# from .Values.console.config\n%s\n", helmette.Tpl(helmette.ToYaml(values.Console.Config), dot)), + } + + if len(values.Console.Roles) > 0 { + data["roles.yaml"] = helmette.Tpl(helmette.ToYaml(map[string]any{ + "roles": values.Console.Roles, + }), dot) + } + + if len(values.Console.RoleBindings) > 0 { + data["role-bindings.yaml"] = helmette.Tpl(helmette.ToYaml(map[string]any{ + "roleBindings": values.Console.RoleBindings, + }), dot) + } + + return &corev1.ConfigMap{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "v1", + Kind: "ConfigMap", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: Fullname(dot), + Labels: Labels(dot), + }, + Data: data, + } +} diff --git a/charts/redpanda/redpanda/5.9.2/charts/console/deployment.go b/charts/redpanda/redpanda/5.9.2/charts/console/deployment.go new file mode 100644 index 0000000000..47537d40d2 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/console/deployment.go @@ -0,0 +1,535 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You 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. +// +// +gotohelm:filename=_deployment.go.tpl +package console + +import ( + "fmt" + + "github.com/redpanda-data/helm-charts/pkg/gotohelm/helmette" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/utils/ptr" +) + +// Console's HTTP server Port. +// The port is defined from the provided config but can be overridden +// by setting service.targetPort and if that is missing defaults to 8080. +func ContainerPort(dot *helmette.Dot) int32 { + values := helmette.Unwrap[Values](dot.Values) + + listenPort := int32(8080) + if values.Service.TargetPort != nil { + listenPort = *values.Service.TargetPort + } + + configListenPort := helmette.Dig(values.Console.Config, nil, "server", "listenPort") + if asInt, ok := helmette.AsIntegral[int](configListenPort); ok { + return int32(asInt) + } + + return listenPort +} + +func Deployment(dot *helmette.Dot) *appsv1.Deployment { + values := helmette.Unwrap[Values](dot.Values) + + if !values.Deployment.Create { + return nil + } + + var replicas *int32 + if !values.Autoscaling.Enabled { + replicas = ptr.To(values.ReplicaCount) + } + + var initContainers []corev1.Container + if values.InitContainers.ExtraInitContainers != nil { + initContainers = helmette.UnmarshalYamlArray[corev1.Container](helmette.Tpl(*values.InitContainers.ExtraInitContainers, dot)) + } + + volumeMounts := []corev1.VolumeMount{ + { + Name: "configs", + MountPath: "/etc/console/configs", + ReadOnly: true, + }, + } + + if values.Secret.Create { + volumeMounts = append(volumeMounts, corev1.VolumeMount{ + Name: "secrets", + MountPath: "/etc/console/secrets", + ReadOnly: true, + }) + } + + for _, mount := range values.SecretMounts { + volumeMounts = append(volumeMounts, corev1.VolumeMount{ + Name: mount.Name, + MountPath: mount.Path, + SubPath: ptr.Deref(mount.SubPath, ""), + }) + } + + volumeMounts = append(volumeMounts, values.ExtraVolumeMounts...) + + return &appsv1.Deployment{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "apps/v1", + Kind: "Deployment", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: Fullname(dot), + Labels: Labels(dot), + Namespace: dot.Release.Namespace, + Annotations: values.Annotations, + }, + Spec: appsv1.DeploymentSpec{ + Replicas: replicas, + Selector: &metav1.LabelSelector{ + MatchLabels: SelectorLabels(dot), + }, + Strategy: values.Strategy, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: helmette.Merge(map[string]string{ + "checksum/config": helmette.Sha256Sum(helmette.ToYaml(ConfigMap(dot))), + }, values.PodAnnotations), + Labels: helmette.Merge(SelectorLabels(dot), values.PodLabels), + }, + Spec: corev1.PodSpec{ + ImagePullSecrets: values.ImagePullSecrets, + ServiceAccountName: ServiceAccountName(dot), + AutomountServiceAccountToken: &values.AutomountServiceAccountToken, + SecurityContext: &values.PodSecurityContext, + NodeSelector: values.NodeSelector, + Affinity: &values.Affinity, + TopologySpreadConstraints: values.TopologySpreadConstraints, + PriorityClassName: values.PriorityClassName, + Tolerations: values.Tolerations, + Volumes: consolePodVolumes(dot), + InitContainers: initContainers, + Containers: append([]corev1.Container{ + { + Name: dot.Chart.Name, + Command: values.Deployment.Command, + Args: append([]string{ + "--config.filepath=/etc/console/configs/config.yaml", + }, values.Deployment.ExtraArgs...), + SecurityContext: &values.SecurityContext, + Image: containerImage(dot), + ImagePullPolicy: values.Image.PullPolicy, + Ports: []corev1.ContainerPort{ + { + Name: "http", + ContainerPort: ContainerPort(dot), + Protocol: corev1.ProtocolTCP, + }, + }, + VolumeMounts: volumeMounts, + LivenessProbe: &corev1.Probe{ + InitialDelaySeconds: values.LivenessProbe.InitialDelaySeconds, // TODO what to do with this?? + PeriodSeconds: values.LivenessProbe.PeriodSeconds, + TimeoutSeconds: values.LivenessProbe.TimeoutSeconds, + SuccessThreshold: values.LivenessProbe.SuccessThreshold, + FailureThreshold: values.LivenessProbe.FailureThreshold, + ProbeHandler: corev1.ProbeHandler{ + HTTPGet: &corev1.HTTPGetAction{ + Path: "/admin/health", + Port: intstr.FromString("http"), + }, + }, + }, + ReadinessProbe: &corev1.Probe{ + InitialDelaySeconds: values.ReadinessProbe.InitialDelaySeconds, + PeriodSeconds: values.ReadinessProbe.PeriodSeconds, + TimeoutSeconds: values.ReadinessProbe.TimeoutSeconds, + SuccessThreshold: values.ReadinessProbe.SuccessThreshold, + FailureThreshold: values.ReadinessProbe.FailureThreshold, + ProbeHandler: corev1.ProbeHandler{ + HTTPGet: &corev1.HTTPGetAction{ + Path: "/admin/health", + Port: intstr.FromString("http"), + }, + }, + }, + Resources: values.Resources, + Env: consoleContainerEnv(dot), + EnvFrom: values.ExtraEnvFrom, + }, + }, values.ExtraContainers...), + }, + }, + }, + } +} + +// ConsoleImage +func containerImage(dot *helmette.Dot) string { + values := helmette.Unwrap[Values](dot.Values) + + tag := dot.Chart.AppVersion + if !helmette.Empty(values.Image.Tag) { + tag = *values.Image.Tag + } + + image := fmt.Sprintf("%s:%s", values.Image.Repository, tag) + + if !helmette.Empty(values.Image.Registry) { + return fmt.Sprintf("%s/%s", values.Image.Registry, image) + } + + return image +} + +type PossibleEnvVar struct { + Value any + EnvVar corev1.EnvVar +} + +func consoleContainerEnv(dot *helmette.Dot) []corev1.EnvVar { + values := helmette.Unwrap[Values](dot.Values) + + if !values.Secret.Create { + vars := values.ExtraEnv + + if !helmette.Empty(values.Enterprise.LicenseSecretRef.Name) { + vars = append(values.ExtraEnv, corev1.EnvVar{ + Name: "LICENSE", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: values.Enterprise.LicenseSecretRef.Name, + }, + Key: helmette.Default("enterprise-license", values.Enterprise.LicenseSecretRef.Key), + }, + }, + }) + } + + return vars + } + + possibleVars := []PossibleEnvVar{ + { + Value: values.Secret.Kafka.SASLPassword, + EnvVar: corev1.EnvVar{ + Name: "KAFKA_SASL_PASSWORD", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: Fullname(dot), + }, + Key: "kafka-sasl-password", + }, + }, + }, + }, + { + Value: values.Secret.Kafka.ProtobufGitBasicAuthPassword, + EnvVar: corev1.EnvVar{ + Name: "KAFKA_PROTOBUF_GIT_BASICAUTH_PASSWORD", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: Fullname(dot), + }, + Key: "kafka-protobuf-git-basicauth-password", + }, + }, + }, + }, + { + Value: values.Secret.Kafka.AWSMSKIAMSecretKey, + EnvVar: corev1.EnvVar{ + Name: "KAFKA_SASL_AWSMSKIAM_SECRETKEY", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: Fullname(dot), + }, + Key: "kafka-sasl-aws-msk-iam-secret-key", + }, + }, + }, + }, + { + Value: values.Secret.Kafka.TLSCA, + EnvVar: corev1.EnvVar{ + Name: "KAFKA_TLS_CAFILEPATH", + Value: "/etc/console/secrets/kafka-tls-ca", + }, + }, + { + Value: values.Secret.Kafka.TLSCert, + EnvVar: corev1.EnvVar{ + Name: "KAFKA_TLS_CERTFILEPATH", + Value: "/etc/console/secrets/kafka-tls-cert", + }, + }, + { + Value: values.Secret.Kafka.TLSKey, + EnvVar: corev1.EnvVar{ + Name: "KAFKA_TLS_KEYFILEPATH", + Value: "/etc/console/secrets/kafka-tls-key", + }, + }, + { + Value: values.Secret.Kafka.SchemaRegistryTLSCA, + EnvVar: corev1.EnvVar{ + Name: "KAFKA_SCHEMAREGISTRY_TLS_CAFILEPATH", + Value: "/etc/console/secrets/kafka-schemaregistry-tls-ca", + }, + }, + { + Value: values.Secret.Kafka.SchemaRegistryTLSCert, + EnvVar: corev1.EnvVar{ + Name: "KAFKA_SCHEMAREGISTRY_TLS_CERTFILEPATH", + Value: "/etc/console/secrets/kafka-schemaregistry-tls-cert", + }, + }, + { + Value: values.Secret.Kafka.SchemaRegistryTLSKey, + EnvVar: corev1.EnvVar{ + Name: "KAFKA_SCHEMAREGISTRY_TLS_KEYFILEPATH", + Value: "/etc/console/secrets/kafka-schemaregistry-tls-key", + }, + }, + { + Value: values.Secret.Kafka.SchemaRegistryPassword, + EnvVar: corev1.EnvVar{ + Name: "KAFKA_SCHEMAREGISTRY_PASSWORD", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: Fullname(dot), + }, + Key: "kafka-schema-registry-password", + }, + }, + }, + }, + { + Value: true, + EnvVar: corev1.EnvVar{ + Name: "LOGIN_JWTSECRET", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: Fullname(dot), + }, + Key: "login-jwt-secret", + }, + }, + }, + }, + { + Value: values.Secret.Login.Google.ClientSecret, + EnvVar: corev1.EnvVar{ + Name: "LOGIN_GOOGLE_CLIENTSECRET", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: Fullname(dot), + }, + Key: "login-google-oauth-client-secret", + }, + }, + }, + }, + + { + Value: values.Secret.Login.Google.GroupsServiceAccount, + EnvVar: corev1.EnvVar{ + Name: "LOGIN_GOOGLE_DIRECTORY_SERVICEACCOUNTFILEPATH", + Value: "/etc/console/secrets/login-google-groups-service-account.json", + }, + }, + { + Value: values.Secret.Login.Github.ClientSecret, + EnvVar: corev1.EnvVar{ + Name: "LOGIN_GITHUB_CLIENTSECRET", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: Fullname(dot), + }, + Key: "login-github-oauth-client-secret", + }, + }, + }, + }, + { + Value: values.Secret.Login.Github.PersonalAccessToken, + EnvVar: corev1.EnvVar{ + Name: "LOGIN_GITHUB_DIRECTORY_PERSONALACCESSTOKEN", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: Fullname(dot), + }, + Key: "login-github-personal-access-token", + }, + }, + }, + }, + { + Value: values.Secret.Login.Okta.ClientSecret, + EnvVar: corev1.EnvVar{ + Name: "LOGIN_OKTA_CLIENTSECRET", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: Fullname(dot), + }, + Key: "login-okta-client-secret", + }, + }, + }, + }, + { + Value: values.Secret.Login.Okta.DirectoryAPIToken, + EnvVar: corev1.EnvVar{ + Name: "LOGIN_OKTA_DIRECTORY_APITOKEN", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: Fullname(dot), + }, + Key: "login-okta-directory-api-token", + }, + }, + }, + }, + { + Value: values.Secret.Login.OIDC.ClientSecret, + EnvVar: corev1.EnvVar{ + Name: "LOGIN_OIDC_CLIENTSECRET", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: Fullname(dot), + }, + Key: "login-oidc-client-secret", + }, + }, + }, + }, + { + Value: values.Secret.Enterprise.License, + EnvVar: corev1.EnvVar{ + Name: "LICENSE", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: Fullname(dot), + }, + Key: "enterprise-license", + }, + }, + }, + }, + { + Value: values.Secret.Redpanda.AdminAPI.Password, + EnvVar: corev1.EnvVar{ + Name: "REDPANDA_ADMINAPI_PASSWORD", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: Fullname(dot), + }, + Key: "redpanda-admin-api-password", + }, + }, + }, + }, + { + Value: values.Secret.Redpanda.AdminAPI.TLSCA, + EnvVar: corev1.EnvVar{ + Name: "REDPANDA_ADMINAPI_TLS_CAFILEPATH", + Value: "/etc/console/secrets/redpanda-admin-api-tls-ca", + }, + }, + { + Value: values.Secret.Redpanda.AdminAPI.TLSKey, + EnvVar: corev1.EnvVar{ + Name: "REDPANDA_ADMINAPI_TLS_KEYFILEPATH", + Value: "/etc/console/secrets/redpanda-admin-api-tls-key", + }, + }, + { + Value: values.Secret.Redpanda.AdminAPI.TLSCert, + EnvVar: corev1.EnvVar{ + Name: "REDPANDA_ADMINAPI_TLS_CERTFILEPATH", + Value: "/etc/console/secrets/redpanda-admin-api-tls-cert", + }, + }, + } + + vars := values.ExtraEnv + for _, possible := range possibleVars { + if !helmette.Empty(possible.Value) { + vars = append(vars, possible.EnvVar) + } + } + + return vars +} + +func consolePodVolumes(dot *helmette.Dot) []corev1.Volume { + values := helmette.Unwrap[Values](dot.Values) + + volumes := []corev1.Volume{ + { + Name: "configs", + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: Fullname(dot), + }, + }, + }, + }, + } + + if values.Secret.Create { + volumes = append(volumes, corev1.Volume{ + Name: "secrets", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: Fullname(dot), + }, + }, + }) + } + + for _, mount := range values.SecretMounts { + volumes = append(volumes, corev1.Volume{ + Name: mount.Name, + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: mount.SecretName, + DefaultMode: mount.DefaultMode, + }, + }, + }) + } + + return append(volumes, values.ExtraVolumes...) +} diff --git a/charts/redpanda/redpanda/5.9.2/charts/console/examples/console-enterprise.yaml b/charts/redpanda/redpanda/5.9.2/charts/console/examples/console-enterprise.yaml new file mode 100644 index 0000000000..dc3f29197d --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/console/examples/console-enterprise.yaml @@ -0,0 +1,94 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You 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. + +image: + tag: master-8fcce39 + +resources: + limits: + cpu: 1 + memory: 2Gi + requests: + cpu: 100m + memory: 512Mi + +console: + config: + kafka: + brokers: + - bootstrap.mybrokers.com:9092 + clientId: redpanda-console + sasl: + enabled: true + mechanism: SCRAM-SHA-256 + username: console + # password: set via Helm secret / Env variable + tls: + enabled: false + login: + google: + enabled: true + clientId: redacted.apps.googleusercontent.com + # clientSecret: set via Helm secret / Env variable + directory: + # serviceAccountFilepath: set via Helm secret / Env variable + targetPrincipal: admin@mycompany.com + enterprise: + rbac: + enabled: true + roleBindingsFilepath: /etc/console/configs/role-bindings.yaml + roleBindings: + - roleName: viewer + metadata: + # Metadata properties will be shown in the UI. You can omit it if you want to + name: Developers + subjects: + # You can specify all groups or users from different providers here which shall be bound to the same role + - kind: group + provider: Google + name: engineering@mycompany.com + - kind: user + provider: Google + name: singleuser@mycompany.com + - roleName: admin + metadata: + name: Admin + subjects: + - kind: user + provider: Google + name: adminperson@mycompany.com + +secret: + create: true + kafka: + saslPassword: "redacted" + enterprise: + license: "redacted" + login: + google: + clientSecret: "redacted" + groupsServiceAccount: | + { + "type": "service_account", + "project_id": "redacted", + "private_key_id": "redacted", + "private_key": "-----BEGIN PRIVATE KEY-----\nREDACTED\n-----END PRIVATE KEY-----\n", + "client_email": "redacted@projectid.iam.gserviceaccount.com", + "client_id": "redacted", + "auth_uri": "https://accounts.google.com/o/oauth2/auth", + "token_uri": "https://oauth2.googleapis.com/token", + "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", + "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/redacted.iam.gserviceaccount.com" + } diff --git a/charts/redpanda/redpanda/5.9.2/charts/console/helpers.go b/charts/redpanda/redpanda/5.9.2/charts/console/helpers.go new file mode 100644 index 0000000000..eed4aa7119 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/console/helpers.go @@ -0,0 +1,84 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You 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. +// +// +gotohelm:filename=_helpers.go.tpl +package console + +import ( + "fmt" + "strings" + + "github.com/redpanda-data/helm-charts/pkg/gotohelm/helmette" +) + +// Expand the name of the chart. +func Name(dot *helmette.Dot) string { + values := helmette.Unwrap[Values](dot.Values) + + name := helmette.Default(dot.Chart.Name, values.NameOverride) + return cleanForK8s(name) +} + +// 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. +func Fullname(dot *helmette.Dot) string { + values := helmette.Unwrap[Values](dot.Values) + + if values.FullnameOverride != "" { + return cleanForK8s(values.FullnameOverride) + } + + name := helmette.Default(dot.Chart.Name, values.NameOverride) + + if helmette.Contains(name, dot.Release.Name) { + return cleanForK8s(dot.Release.Name) + } + + return cleanForK8s(fmt.Sprintf("%s-%s", dot.Release.Name, name)) +} + +// Create chart name and version as used by the chart label. +func Chart(dot *helmette.Dot) string { + chart := fmt.Sprintf("%s-%s", dot.Chart.Name, dot.Chart.Version) + return cleanForK8s(strings.ReplaceAll(chart, "+", "_")) +} + +// Common labels +func Labels(dot *helmette.Dot) map[string]string { + values := helmette.Unwrap[Values](dot.Values) + + labels := map[string]string{ + "helm.sh/chart": Chart(dot), + "app.kubernetes.io/managed-by": dot.Release.Service, + } + + if dot.Chart.AppVersion != "" { + labels["app.kubernetes.io/version"] = dot.Chart.AppVersion + } + + return helmette.Merge(labels, SelectorLabels(dot), values.CommonLabels) +} + +func SelectorLabels(dot *helmette.Dot) map[string]string { + return map[string]string{ + "app.kubernetes.io/name": Name(dot), + "app.kubernetes.io/instance": dot.Release.Name, + } +} + +func cleanForK8s(s string) string { + return helmette.TrimSuffix("-", helmette.Trunc(63, s)) +} diff --git a/charts/redpanda/redpanda/5.9.2/charts/console/hpa.go b/charts/redpanda/redpanda/5.9.2/charts/console/hpa.go new file mode 100644 index 0000000000..3b0458cffe --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/console/hpa.go @@ -0,0 +1,82 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You 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. +// +// +gotohelm:filename=_hpa.go.tpl +package console + +import ( + "github.com/redpanda-data/helm-charts/pkg/gotohelm/helmette" + autoscalingv2 "k8s.io/api/autoscaling/v2" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/utils/ptr" +) + +func HorizontalPodAutoscaler(dot *helmette.Dot) *autoscalingv2.HorizontalPodAutoscaler { + values := helmette.Unwrap[Values](dot.Values) + + if !values.Autoscaling.Enabled { + return nil + } + + metrics := []autoscalingv2.MetricSpec{} + + if values.Autoscaling.TargetCPUUtilizationPercentage != nil { + metrics = append(metrics, autoscalingv2.MetricSpec{ + Type: "Resource", + Resource: &autoscalingv2.ResourceMetricSource{ + Name: corev1.ResourceCPU, + Target: autoscalingv2.MetricTarget{ + Type: autoscalingv2.UtilizationMetricType, + AverageUtilization: values.Autoscaling.TargetCPUUtilizationPercentage, + }, + }, + }) + } + + if values.Autoscaling.TargetMemoryUtilizationPercentage != nil { + metrics = append(metrics, autoscalingv2.MetricSpec{ + Type: "Resource", + Resource: &autoscalingv2.ResourceMetricSource{ + Name: corev1.ResourceMemory, + Target: autoscalingv2.MetricTarget{ + Type: autoscalingv2.UtilizationMetricType, + AverageUtilization: values.Autoscaling.TargetMemoryUtilizationPercentage, + }, + }, + }) + } + + return &autoscalingv2.HorizontalPodAutoscaler{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "autoscaling/v2", + Kind: "HorizontalPodAutoscaler", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: Fullname(dot), + Labels: Labels(dot), + }, + Spec: autoscalingv2.HorizontalPodAutoscalerSpec{ + ScaleTargetRef: autoscalingv2.CrossVersionObjectReference{ + APIVersion: "apps/v1", + Kind: "Deployment", + Name: Fullname(dot), + }, + MinReplicas: ptr.To(values.Autoscaling.MinReplicas), + MaxReplicas: values.Autoscaling.MaxReplicas, + Metrics: metrics, + }, + } +} diff --git a/charts/redpanda/redpanda/5.9.2/charts/console/ingress.go b/charts/redpanda/redpanda/5.9.2/charts/console/ingress.go new file mode 100644 index 0000000000..926c286f18 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/console/ingress.go @@ -0,0 +1,88 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You 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. +// +// +gotohelm:filename=_ingress.go.tpl +package console + +import ( + "github.com/redpanda-data/helm-charts/pkg/gotohelm/helmette" + networkingv1 "k8s.io/api/networking/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func Ingress(dot *helmette.Dot) *networkingv1.Ingress { + values := helmette.Unwrap[Values](dot.Values) + + if !values.Ingress.Enabled { + return nil + } + + var tls []networkingv1.IngressTLS + for _, t := range values.Ingress.TLS { + var hosts []string + for _, host := range t.Hosts { + hosts = append(hosts, helmette.Tpl(host, dot)) + } + tls = append(tls, networkingv1.IngressTLS{ + SecretName: t.SecretName, + Hosts: hosts, + }) + } + + var rules []networkingv1.IngressRule + for _, host := range values.Ingress.Hosts { + var paths []networkingv1.HTTPIngressPath + for _, path := range host.Paths { + paths = append(paths, networkingv1.HTTPIngressPath{ + Path: path.Path, + PathType: path.PathType, + Backend: networkingv1.IngressBackend{ + Service: &networkingv1.IngressServiceBackend{ + Name: Fullname(dot), + Port: networkingv1.ServiceBackendPort{ + Number: values.Service.Port, + }, + }, + }, + }) + } + + rules = append(rules, networkingv1.IngressRule{ + Host: helmette.Tpl(host.Host, dot), + IngressRuleValue: networkingv1.IngressRuleValue{ + HTTP: &networkingv1.HTTPIngressRuleValue{ + Paths: paths, + }, + }, + }) + } + + return &networkingv1.Ingress{ + TypeMeta: metav1.TypeMeta{ + Kind: "Ingress", + APIVersion: "networking.k8s.io/v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: Fullname(dot), + Labels: Labels(dot), + Annotations: values.Ingress.Annotations, + }, + Spec: networkingv1.IngressSpec{ + IngressClassName: values.Ingress.ClassName, + TLS: tls, + Rules: rules, + }, + } +} diff --git a/charts/redpanda/redpanda/5.9.2/charts/console/notes.go b/charts/redpanda/redpanda/5.9.2/charts/console/notes.go new file mode 100644 index 0000000000..1f652dbaf8 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/console/notes.go @@ -0,0 +1,67 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You 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. +// +// +gotohelm:filename=_notes.go.tpl +package console + +import ( + "fmt" + + "github.com/redpanda-data/helm-charts/pkg/gotohelm/helmette" +) + +func Notes(dot *helmette.Dot) []string { + values := helmette.Unwrap[Values](dot.Values) + + commands := []string{ + `1. Get the application URL by running these commands:`, + } + if values.Ingress.Enabled { + scheme := "http" + if len(values.Ingress.TLS) > 0 { + scheme = "https" + } + for _, host := range values.Ingress.Hosts { + for _, path := range host.Paths { + commands = append(commands, fmt.Sprintf("%s://%s%s", scheme, host.Host, path.Path)) + } + } + } else if helmette.Contains("NodePort", string(values.Service.Type)) { + commands = append( + commands, + fmt.Sprintf(` export NODE_PORT=$(kubectl get --namespace %s -o jsonpath="{.spec.ports[0].nodePort}" services %s)`, dot.Release.Namespace, Fullname(dot)), + fmt.Sprintf(` export NODE_IP=$(kubectl get nodes --namespace %s -o jsonpath="{.items[0].status.addresses[0].address}")`, dot.Release.Namespace), + " echo http://$NODE_IP:$NODE_PORT", + ) + } else if helmette.Contains("NodePort", string(values.Service.Type)) { + commands = append( + commands, + ` NOTE: It may take a few minutes for the LoadBalancer IP to be available.`, + fmt.Sprintf(` You can watch the status of by running 'kubectl get --namespace %s svc -w %s'`, dot.Release.Namespace, Fullname(dot)), + fmt.Sprintf(` export SERVICE_IP=$(kubectl get svc --namespace %s %s --template "{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}")`, dot.Release.Namespace, Fullname(dot)), + fmt.Sprintf(` echo http://$SERVICE_IP:%d`, values.Service.Port), + ) + } else if helmette.Contains("ClusterIP", string(values.Service.Type)) { + commands = append( + commands, + fmt.Sprintf(` export POD_NAME=$(kubectl get pods --namespace %s -l "app.kubernetes.io/name=%s,app.kubernetes.io/instance=%s" -o jsonpath="{.items[0].metadata.name}")`, dot.Release.Namespace, Name(dot), dot.Release.Name), + fmt.Sprintf(` export CONTAINER_PORT=$(kubectl get pod --namespace %s $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")`, dot.Release.Namespace), + ` echo "Visit http://127.0.0.1:8080 to use your application"`, + fmt.Sprintf(` kubectl --namespace %s port-forward $POD_NAME 8080:$CONTAINER_PORT`, dot.Release.Namespace), + ) + } + + return commands +} diff --git a/charts/redpanda/redpanda/5.9.2/charts/console/secret.go b/charts/redpanda/redpanda/5.9.2/charts/console/secret.go new file mode 100644 index 0000000000..d23951cbd2 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/console/secret.go @@ -0,0 +1,84 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You 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. +// +// +gotohelm:filename=_secret.go.tpl +package console + +import ( + "github.com/redpanda-data/helm-charts/pkg/gotohelm/helmette" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/utils/ptr" +) + +func Secret(dot *helmette.Dot) *corev1.Secret { + values := helmette.Unwrap[Values](dot.Values) + + if !values.Secret.Create { + return nil + } + + jwtSecret := values.Secret.Login.JWTSecret + if jwtSecret == "" { + jwtSecret = helmette.RandAlphaNum(32) + } + + return &corev1.Secret{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "v1", + Kind: "Secret", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: Fullname(dot), + Labels: Labels(dot), + }, + Type: corev1.SecretTypeOpaque, + StringData: map[string]string{ + // Set empty defaults, so that we can always mount them as env variable even if they are not used. + // For this reason we can't use `with` to change the scope. + + // Kafka + "kafka-sasl-password": ptr.Deref(values.Secret.Kafka.SASLPassword, ""), + "kafka-protobuf-git-basicauth-password": ptr.Deref(values.Secret.Kafka.ProtobufGitBasicAuthPassword, ""), + "kafka-sasl-aws-msk-iam-secret-key": ptr.Deref(values.Secret.Kafka.AWSMSKIAMSecretKey, ""), + "kafka-tls-ca": ptr.Deref(values.Secret.Kafka.TLSCA, ""), + "kafka-tls-cert": ptr.Deref(values.Secret.Kafka.TLSCert, ""), + "kafka-tls-key": ptr.Deref(values.Secret.Kafka.TLSKey, ""), + "kafka-schema-registry-password": ptr.Deref(values.Secret.Kafka.SchemaRegistryPassword, ""), + "kafka-schemaregistry-tls-ca": ptr.Deref(values.Secret.Kafka.SchemaRegistryTLSCA, ""), + "kafka-schemaregistry-tls-cert": ptr.Deref(values.Secret.Kafka.SchemaRegistryTLSCert, ""), + "kafka-schemaregistry-tls-key": ptr.Deref(values.Secret.Kafka.SchemaRegistryTLSKey, ""), + + // Login + "login-jwt-secret": jwtSecret, + "login-google-oauth-client-secret": ptr.Deref(values.Secret.Login.Google.ClientSecret, ""), + "login-google-groups-service-account.json": ptr.Deref(values.Secret.Login.Google.GroupsServiceAccount, ""), + "login-github-oauth-client-secret": ptr.Deref(values.Secret.Login.Github.ClientSecret, ""), + "login-github-personal-access-token": ptr.Deref(values.Secret.Login.Github.PersonalAccessToken, ""), + "login-okta-client-secret": ptr.Deref(values.Secret.Login.Okta.ClientSecret, ""), + "login-okta-directory-api-token": ptr.Deref(values.Secret.Login.Okta.DirectoryAPIToken, ""), + "login-oidc-client-secret": ptr.Deref(values.Secret.Login.OIDC.ClientSecret, ""), + + // Enterprise + "enterprise-license": ptr.Deref(values.Secret.Enterprise.License, ""), + + // Redpanda + "redpanda-admin-api-password": ptr.Deref(values.Secret.Redpanda.AdminAPI.Password, ""), + "redpanda-admin-api-tls-ca": ptr.Deref(values.Secret.Redpanda.AdminAPI.TLSCA, ""), + "redpanda-admin-api-tls-cert": ptr.Deref(values.Secret.Redpanda.AdminAPI.TLSCert, ""), + "redpanda-admin-api-tls-key": ptr.Deref(values.Secret.Redpanda.AdminAPI.TLSKey, ""), + }, + } +} diff --git a/charts/redpanda/redpanda/5.9.2/charts/console/service.go b/charts/redpanda/redpanda/5.9.2/charts/console/service.go new file mode 100644 index 0000000000..65214bf3ed --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/console/service.go @@ -0,0 +1,60 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You 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. +// +// +gotohelm:filename=_service.go.tpl +package console + +import ( + "github.com/redpanda-data/helm-charts/pkg/gotohelm/helmette" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" +) + +func Service(dot *helmette.Dot) *corev1.Service { + values := helmette.Unwrap[Values](dot.Values) + + port := corev1.ServicePort{ + Name: "http", + Port: int32(values.Service.Port), + Protocol: corev1.ProtocolTCP, + } + + if values.Service.TargetPort != nil { + port.TargetPort = intstr.FromInt32(*values.Service.TargetPort) + } + + if helmette.Contains("NodePort", string(values.Service.Type)) && values.Service.NodePort != nil { + port.NodePort = *values.Service.NodePort + } + + return &corev1.Service{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "v1", + Kind: "Service", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: Fullname(dot), + Namespace: dot.Release.Namespace, + Labels: Labels(dot), + Annotations: values.Service.Annotations, + }, + Spec: corev1.ServiceSpec{ + Type: values.Service.Type, + Selector: SelectorLabels(dot), + Ports: []corev1.ServicePort{port}, + }, + } +} diff --git a/charts/redpanda/redpanda/5.9.2/charts/console/serviceaccount.go b/charts/redpanda/redpanda/5.9.2/charts/console/serviceaccount.go new file mode 100644 index 0000000000..c23e5c92c6 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/console/serviceaccount.go @@ -0,0 +1,60 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You 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. +// +// +gotohelm:filename=_serviceaccount.go.tpl +package console + +import ( + "github.com/redpanda-data/helm-charts/pkg/gotohelm/helmette" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/utils/ptr" +) + +// Create the name of the service account to use +func ServiceAccountName(dot *helmette.Dot) string { + values := helmette.Unwrap[Values](dot.Values) + + if values.ServiceAccount.Create { + if values.ServiceAccount.Name != "" { + return values.ServiceAccount.Name + } + return Fullname(dot) + } + + return helmette.Default("default", values.ServiceAccount.Name) +} + +func ServiceAccount(dot *helmette.Dot) *corev1.ServiceAccount { + values := helmette.Unwrap[Values](dot.Values) + + if !values.ServiceAccount.Create { + return nil + } + + return &corev1.ServiceAccount{ + TypeMeta: metav1.TypeMeta{ + Kind: "ServiceAccount", + APIVersion: "v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: ServiceAccountName(dot), + Labels: Labels(dot), + Namespace: dot.Release.Namespace, + Annotations: values.ServiceAccount.Annotations, + }, + AutomountServiceAccountToken: ptr.To(values.ServiceAccount.AutomountServiceAccountToken), + } +} diff --git a/charts/redpanda/redpanda/5.9.2/charts/console/templates/NOTES.txt b/charts/redpanda/redpanda/5.9.2/charts/console/templates/NOTES.txt new file mode 100644 index 0000000000..7541881fc9 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/console/templates/NOTES.txt @@ -0,0 +1,20 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You 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. +*/}} +{{- $notes := (get ((include "console.Notes" (dict "a" (list .))) | fromJson) "r") -}} +{{- range $_, $note := $notes }} +{{ $note }} +{{- end }} diff --git a/charts/redpanda/redpanda/5.9.2/charts/console/templates/_configmap.go.tpl b/charts/redpanda/redpanda/5.9.2/charts/console/templates/_configmap.go.tpl new file mode 100644 index 0000000000..14673b0249 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/console/templates/_configmap.go.tpl @@ -0,0 +1,25 @@ +{{- /* Generated from "configmap.go" */ -}} + +{{- define "console.ConfigMap" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (not $values.configmap.create) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $data := (dict "config.yaml" (printf "# from .Values.console.config\n%s\n" (tpl (toYaml $values.console.config) $dot)) ) -}} +{{- if (gt ((get (fromJson (include "_shims.len" (dict "a" (list $values.console.roles) ))) "r") | int) (0 | int)) -}} +{{- $_ := (set $data "roles.yaml" (tpl (toYaml (dict "roles" $values.console.roles )) $dot)) -}} +{{- end -}} +{{- if (gt ((get (fromJson (include "_shims.len" (dict "a" (list $values.console.roleBindings) ))) "r") | int) (0 | int)) -}} +{{- $_ := (set $data "role-bindings.yaml" (tpl (toYaml (dict "roleBindings" $values.console.roleBindings )) $dot)) -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) ) (mustMergeOverwrite (dict ) (dict "apiVersion" "v1" "kind" "ConfigMap" )) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "name" (get (fromJson (include "console.Fullname" (dict "a" (list $dot) ))) "r") "labels" (get (fromJson (include "console.Labels" (dict "a" (list $dot) ))) "r") )) "data" $data ))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + diff --git a/charts/redpanda/redpanda/5.9.2/charts/console/templates/_deployment.go.tpl b/charts/redpanda/redpanda/5.9.2/charts/console/templates/_deployment.go.tpl new file mode 100644 index 0000000000..71696bb257 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/console/templates/_deployment.go.tpl @@ -0,0 +1,133 @@ +{{- /* Generated from "deployment.go" */ -}} + +{{- define "console.ContainerPort" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $listenPort := ((8080 | int) | int) -}} +{{- if (ne $values.service.targetPort (coalesce nil)) -}} +{{- $listenPort = $values.service.targetPort -}} +{{- end -}} +{{- $configListenPort := (dig "server" "listenPort" (coalesce nil) $values.console.config) -}} +{{- $tmp_tuple_1 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.asintegral" (dict "a" (list $configListenPort) ))) "r")) ))) "r") -}} +{{- $ok_2 := $tmp_tuple_1.T2 -}} +{{- $asInt_1 := ($tmp_tuple_1.T1 | int) -}} +{{- if $ok_2 -}} +{{- $_is_returning = true -}} +{{- (dict "r" ($asInt_1 | int)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $listenPort) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "console.Deployment" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (not $values.deployment.create) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $replicas := (coalesce nil) -}} +{{- if (not $values.autoscaling.enabled) -}} +{{- $replicas = ($values.replicaCount | int) -}} +{{- end -}} +{{- $initContainers := (coalesce nil) -}} +{{- if (ne $values.initContainers.extraInitContainers (coalesce nil)) -}} +{{- $initContainers = (fromYamlArray (tpl $values.initContainers.extraInitContainers $dot)) -}} +{{- end -}} +{{- $volumeMounts := (list (mustMergeOverwrite (dict "name" "" "mountPath" "" ) (dict "name" "configs" "mountPath" "/etc/console/configs" "readOnly" true ))) -}} +{{- if $values.secret.create -}} +{{- $volumeMounts = (concat (default (list ) $volumeMounts) (list (mustMergeOverwrite (dict "name" "" "mountPath" "" ) (dict "name" "secrets" "mountPath" "/etc/console/secrets" "readOnly" true )))) -}} +{{- end -}} +{{- range $_, $mount := $values.secretMounts -}} +{{- $volumeMounts = (concat (default (list ) $volumeMounts) (list (mustMergeOverwrite (dict "name" "" "mountPath" "" ) (dict "name" $mount.name "mountPath" $mount.path "subPath" (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $mount.subPath "") ))) "r") )))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $volumeMounts = (concat (default (list ) $volumeMounts) (default (list ) $values.extraVolumeMounts)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "spec" (dict "selector" (coalesce nil) "template" (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "spec" (dict "containers" (coalesce nil) ) ) "strategy" (dict ) ) "status" (dict ) ) (mustMergeOverwrite (dict ) (dict "apiVersion" "apps/v1" "kind" "Deployment" )) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "name" (get (fromJson (include "console.Fullname" (dict "a" (list $dot) ))) "r") "labels" (get (fromJson (include "console.Labels" (dict "a" (list $dot) ))) "r") "namespace" $dot.Release.Namespace "annotations" $values.annotations )) "spec" (mustMergeOverwrite (dict "selector" (coalesce nil) "template" (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "spec" (dict "containers" (coalesce nil) ) ) "strategy" (dict ) ) (dict "replicas" $replicas "selector" (mustMergeOverwrite (dict ) (dict "matchLabels" (get (fromJson (include "console.SelectorLabels" (dict "a" (list $dot) ))) "r") )) "strategy" $values.strategy "template" (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "spec" (dict "containers" (coalesce nil) ) ) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "annotations" (merge (dict ) (dict "checksum/config" (sha256sum (toYaml (get (fromJson (include "console.ConfigMap" (dict "a" (list $dot) ))) "r"))) ) $values.podAnnotations) "labels" (merge (dict ) (get (fromJson (include "console.SelectorLabels" (dict "a" (list $dot) ))) "r") $values.podLabels) )) "spec" (mustMergeOverwrite (dict "containers" (coalesce nil) ) (dict "imagePullSecrets" $values.imagePullSecrets "serviceAccountName" (get (fromJson (include "console.ServiceAccountName" (dict "a" (list $dot) ))) "r") "automountServiceAccountToken" $values.automountServiceAccountToken "securityContext" $values.podSecurityContext "nodeSelector" $values.nodeSelector "affinity" $values.affinity "topologySpreadConstraints" $values.topologySpreadConstraints "priorityClassName" $values.priorityClassName "tolerations" $values.tolerations "volumes" (get (fromJson (include "console.consolePodVolumes" (dict "a" (list $dot) ))) "r") "initContainers" $initContainers "containers" (concat (default (list ) (list (mustMergeOverwrite (dict "name" "" "resources" (dict ) ) (dict "name" $dot.Chart.Name "command" $values.deployment.command "args" (concat (default (list ) (list "--config.filepath=/etc/console/configs/config.yaml")) (default (list ) $values.deployment.extraArgs)) "securityContext" $values.securityContext "image" (get (fromJson (include "console.containerImage" (dict "a" (list $dot) ))) "r") "imagePullPolicy" $values.image.pullPolicy "ports" (list (mustMergeOverwrite (dict "containerPort" 0 ) (dict "name" "http" "containerPort" ((get (fromJson (include "console.ContainerPort" (dict "a" (list $dot) ))) "r") | int) "protocol" "TCP" ))) "volumeMounts" $volumeMounts "livenessProbe" (mustMergeOverwrite (dict ) (mustMergeOverwrite (dict ) (dict "httpGet" (mustMergeOverwrite (dict "port" 0 ) (dict "path" "/admin/health" "port" "http" )) )) (dict "initialDelaySeconds" ($values.livenessProbe.initialDelaySeconds | int) "periodSeconds" ($values.livenessProbe.periodSeconds | int) "timeoutSeconds" ($values.livenessProbe.timeoutSeconds | int) "successThreshold" ($values.livenessProbe.successThreshold | int) "failureThreshold" ($values.livenessProbe.failureThreshold | int) )) "readinessProbe" (mustMergeOverwrite (dict ) (mustMergeOverwrite (dict ) (dict "httpGet" (mustMergeOverwrite (dict "port" 0 ) (dict "path" "/admin/health" "port" "http" )) )) (dict "initialDelaySeconds" ($values.readinessProbe.initialDelaySeconds | int) "periodSeconds" ($values.readinessProbe.periodSeconds | int) "timeoutSeconds" ($values.readinessProbe.timeoutSeconds | int) "successThreshold" ($values.readinessProbe.successThreshold | int) "failureThreshold" ($values.readinessProbe.failureThreshold | int) )) "resources" $values.resources "env" (get (fromJson (include "console.consoleContainerEnv" (dict "a" (list $dot) ))) "r") "envFrom" $values.extraEnvFrom )))) (default (list ) $values.extraContainers)) )) )) )) ))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "console.containerImage" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $tag := $dot.Chart.AppVersion -}} +{{- if (not (empty $values.image.tag)) -}} +{{- $tag = $values.image.tag -}} +{{- end -}} +{{- $image := (printf "%s:%s" $values.image.repository $tag) -}} +{{- if (not (empty $values.image.registry)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (printf "%s/%s" $values.image.registry $image)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $image) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "console.consoleContainerEnv" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (not $values.secret.create) -}} +{{- $vars := $values.extraEnv -}} +{{- if (not (empty $values.enterprise.licenseSecretRef.name)) -}} +{{- $vars = (concat (default (list ) $values.extraEnv) (list (mustMergeOverwrite (dict "name" "" ) (dict "name" "LICENSE" "valueFrom" (mustMergeOverwrite (dict ) (dict "secretKeyRef" (mustMergeOverwrite (dict "key" "" ) (mustMergeOverwrite (dict ) (dict "name" $values.enterprise.licenseSecretRef.name )) (dict "key" (default "enterprise-license" $values.enterprise.licenseSecretRef.key) )) )) )))) -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $vars) | toJson -}} +{{- break -}} +{{- end -}} +{{- $possibleVars := (list (mustMergeOverwrite (dict "Value" (coalesce nil) "EnvVar" (dict "name" "" ) ) (dict "Value" $values.secret.kafka.saslPassword "EnvVar" (mustMergeOverwrite (dict "name" "" ) (dict "name" "KAFKA_SASL_PASSWORD" "valueFrom" (mustMergeOverwrite (dict ) (dict "secretKeyRef" (mustMergeOverwrite (dict "key" "" ) (mustMergeOverwrite (dict ) (dict "name" (get (fromJson (include "console.Fullname" (dict "a" (list $dot) ))) "r") )) (dict "key" "kafka-sasl-password" )) )) )) )) (mustMergeOverwrite (dict "Value" (coalesce nil) "EnvVar" (dict "name" "" ) ) (dict "Value" $values.secret.kafka.protobufGitBasicAuthPassword "EnvVar" (mustMergeOverwrite (dict "name" "" ) (dict "name" "KAFKA_PROTOBUF_GIT_BASICAUTH_PASSWORD" "valueFrom" (mustMergeOverwrite (dict ) (dict "secretKeyRef" (mustMergeOverwrite (dict "key" "" ) (mustMergeOverwrite (dict ) (dict "name" (get (fromJson (include "console.Fullname" (dict "a" (list $dot) ))) "r") )) (dict "key" "kafka-protobuf-git-basicauth-password" )) )) )) )) (mustMergeOverwrite (dict "Value" (coalesce nil) "EnvVar" (dict "name" "" ) ) (dict "Value" $values.secret.kafka.awsMskIamSecretKey "EnvVar" (mustMergeOverwrite (dict "name" "" ) (dict "name" "KAFKA_SASL_AWSMSKIAM_SECRETKEY" "valueFrom" (mustMergeOverwrite (dict ) (dict "secretKeyRef" (mustMergeOverwrite (dict "key" "" ) (mustMergeOverwrite (dict ) (dict "name" (get (fromJson (include "console.Fullname" (dict "a" (list $dot) ))) "r") )) (dict "key" "kafka-sasl-aws-msk-iam-secret-key" )) )) )) )) (mustMergeOverwrite (dict "Value" (coalesce nil) "EnvVar" (dict "name" "" ) ) (dict "Value" $values.secret.kafka.tlsCa "EnvVar" (mustMergeOverwrite (dict "name" "" ) (dict "name" "KAFKA_TLS_CAFILEPATH" "value" "/etc/console/secrets/kafka-tls-ca" )) )) (mustMergeOverwrite (dict "Value" (coalesce nil) "EnvVar" (dict "name" "" ) ) (dict "Value" $values.secret.kafka.tlsCert "EnvVar" (mustMergeOverwrite (dict "name" "" ) (dict "name" "KAFKA_TLS_CERTFILEPATH" "value" "/etc/console/secrets/kafka-tls-cert" )) )) (mustMergeOverwrite (dict "Value" (coalesce nil) "EnvVar" (dict "name" "" ) ) (dict "Value" $values.secret.kafka.tlsKey "EnvVar" (mustMergeOverwrite (dict "name" "" ) (dict "name" "KAFKA_TLS_KEYFILEPATH" "value" "/etc/console/secrets/kafka-tls-key" )) )) (mustMergeOverwrite (dict "Value" (coalesce nil) "EnvVar" (dict "name" "" ) ) (dict "Value" $values.secret.kafka.schemaRegistryTlsCa "EnvVar" (mustMergeOverwrite (dict "name" "" ) (dict "name" "KAFKA_SCHEMAREGISTRY_TLS_CAFILEPATH" "value" "/etc/console/secrets/kafka-schemaregistry-tls-ca" )) )) (mustMergeOverwrite (dict "Value" (coalesce nil) "EnvVar" (dict "name" "" ) ) (dict "Value" $values.secret.kafka.schemaRegistryTlsCert "EnvVar" (mustMergeOverwrite (dict "name" "" ) (dict "name" "KAFKA_SCHEMAREGISTRY_TLS_CERTFILEPATH" "value" "/etc/console/secrets/kafka-schemaregistry-tls-cert" )) )) (mustMergeOverwrite (dict "Value" (coalesce nil) "EnvVar" (dict "name" "" ) ) (dict "Value" $values.secret.kafka.schemaRegistryTlsKey "EnvVar" (mustMergeOverwrite (dict "name" "" ) (dict "name" "KAFKA_SCHEMAREGISTRY_TLS_KEYFILEPATH" "value" "/etc/console/secrets/kafka-schemaregistry-tls-key" )) )) (mustMergeOverwrite (dict "Value" (coalesce nil) "EnvVar" (dict "name" "" ) ) (dict "Value" $values.secret.kafka.schemaRegistryPassword "EnvVar" (mustMergeOverwrite (dict "name" "" ) (dict "name" "KAFKA_SCHEMAREGISTRY_PASSWORD" "valueFrom" (mustMergeOverwrite (dict ) (dict "secretKeyRef" (mustMergeOverwrite (dict "key" "" ) (mustMergeOverwrite (dict ) (dict "name" (get (fromJson (include "console.Fullname" (dict "a" (list $dot) ))) "r") )) (dict "key" "kafka-schema-registry-password" )) )) )) )) (mustMergeOverwrite (dict "Value" (coalesce nil) "EnvVar" (dict "name" "" ) ) (dict "Value" true "EnvVar" (mustMergeOverwrite (dict "name" "" ) (dict "name" "LOGIN_JWTSECRET" "valueFrom" (mustMergeOverwrite (dict ) (dict "secretKeyRef" (mustMergeOverwrite (dict "key" "" ) (mustMergeOverwrite (dict ) (dict "name" (get (fromJson (include "console.Fullname" (dict "a" (list $dot) ))) "r") )) (dict "key" "login-jwt-secret" )) )) )) )) (mustMergeOverwrite (dict "Value" (coalesce nil) "EnvVar" (dict "name" "" ) ) (dict "Value" $values.secret.login.google.clientSecret "EnvVar" (mustMergeOverwrite (dict "name" "" ) (dict "name" "LOGIN_GOOGLE_CLIENTSECRET" "valueFrom" (mustMergeOverwrite (dict ) (dict "secretKeyRef" (mustMergeOverwrite (dict "key" "" ) (mustMergeOverwrite (dict ) (dict "name" (get (fromJson (include "console.Fullname" (dict "a" (list $dot) ))) "r") )) (dict "key" "login-google-oauth-client-secret" )) )) )) )) (mustMergeOverwrite (dict "Value" (coalesce nil) "EnvVar" (dict "name" "" ) ) (dict "Value" $values.secret.login.google.groupsServiceAccount "EnvVar" (mustMergeOverwrite (dict "name" "" ) (dict "name" "LOGIN_GOOGLE_DIRECTORY_SERVICEACCOUNTFILEPATH" "value" "/etc/console/secrets/login-google-groups-service-account.json" )) )) (mustMergeOverwrite (dict "Value" (coalesce nil) "EnvVar" (dict "name" "" ) ) (dict "Value" $values.secret.login.github.clientSecret "EnvVar" (mustMergeOverwrite (dict "name" "" ) (dict "name" "LOGIN_GITHUB_CLIENTSECRET" "valueFrom" (mustMergeOverwrite (dict ) (dict "secretKeyRef" (mustMergeOverwrite (dict "key" "" ) (mustMergeOverwrite (dict ) (dict "name" (get (fromJson (include "console.Fullname" (dict "a" (list $dot) ))) "r") )) (dict "key" "login-github-oauth-client-secret" )) )) )) )) (mustMergeOverwrite (dict "Value" (coalesce nil) "EnvVar" (dict "name" "" ) ) (dict "Value" $values.secret.login.github.personalAccessToken "EnvVar" (mustMergeOverwrite (dict "name" "" ) (dict "name" "LOGIN_GITHUB_DIRECTORY_PERSONALACCESSTOKEN" "valueFrom" (mustMergeOverwrite (dict ) (dict "secretKeyRef" (mustMergeOverwrite (dict "key" "" ) (mustMergeOverwrite (dict ) (dict "name" (get (fromJson (include "console.Fullname" (dict "a" (list $dot) ))) "r") )) (dict "key" "login-github-personal-access-token" )) )) )) )) (mustMergeOverwrite (dict "Value" (coalesce nil) "EnvVar" (dict "name" "" ) ) (dict "Value" $values.secret.login.okta.clientSecret "EnvVar" (mustMergeOverwrite (dict "name" "" ) (dict "name" "LOGIN_OKTA_CLIENTSECRET" "valueFrom" (mustMergeOverwrite (dict ) (dict "secretKeyRef" (mustMergeOverwrite (dict "key" "" ) (mustMergeOverwrite (dict ) (dict "name" (get (fromJson (include "console.Fullname" (dict "a" (list $dot) ))) "r") )) (dict "key" "login-okta-client-secret" )) )) )) )) (mustMergeOverwrite (dict "Value" (coalesce nil) "EnvVar" (dict "name" "" ) ) (dict "Value" $values.secret.login.okta.directoryApiToken "EnvVar" (mustMergeOverwrite (dict "name" "" ) (dict "name" "LOGIN_OKTA_DIRECTORY_APITOKEN" "valueFrom" (mustMergeOverwrite (dict ) (dict "secretKeyRef" (mustMergeOverwrite (dict "key" "" ) (mustMergeOverwrite (dict ) (dict "name" (get (fromJson (include "console.Fullname" (dict "a" (list $dot) ))) "r") )) (dict "key" "login-okta-directory-api-token" )) )) )) )) (mustMergeOverwrite (dict "Value" (coalesce nil) "EnvVar" (dict "name" "" ) ) (dict "Value" $values.secret.login.oidc.clientSecret "EnvVar" (mustMergeOverwrite (dict "name" "" ) (dict "name" "LOGIN_OIDC_CLIENTSECRET" "valueFrom" (mustMergeOverwrite (dict ) (dict "secretKeyRef" (mustMergeOverwrite (dict "key" "" ) (mustMergeOverwrite (dict ) (dict "name" (get (fromJson (include "console.Fullname" (dict "a" (list $dot) ))) "r") )) (dict "key" "login-oidc-client-secret" )) )) )) )) (mustMergeOverwrite (dict "Value" (coalesce nil) "EnvVar" (dict "name" "" ) ) (dict "Value" $values.secret.enterprise.License "EnvVar" (mustMergeOverwrite (dict "name" "" ) (dict "name" "LICENSE" "valueFrom" (mustMergeOverwrite (dict ) (dict "secretKeyRef" (mustMergeOverwrite (dict "key" "" ) (mustMergeOverwrite (dict ) (dict "name" (get (fromJson (include "console.Fullname" (dict "a" (list $dot) ))) "r") )) (dict "key" "enterprise-license" )) )) )) )) (mustMergeOverwrite (dict "Value" (coalesce nil) "EnvVar" (dict "name" "" ) ) (dict "Value" $values.secret.redpanda.adminApi.password "EnvVar" (mustMergeOverwrite (dict "name" "" ) (dict "name" "REDPANDA_ADMINAPI_PASSWORD" "valueFrom" (mustMergeOverwrite (dict ) (dict "secretKeyRef" (mustMergeOverwrite (dict "key" "" ) (mustMergeOverwrite (dict ) (dict "name" (get (fromJson (include "console.Fullname" (dict "a" (list $dot) ))) "r") )) (dict "key" "redpanda-admin-api-password" )) )) )) )) (mustMergeOverwrite (dict "Value" (coalesce nil) "EnvVar" (dict "name" "" ) ) (dict "Value" $values.secret.redpanda.adminApi.tlsCa "EnvVar" (mustMergeOverwrite (dict "name" "" ) (dict "name" "REDPANDA_ADMINAPI_TLS_CAFILEPATH" "value" "/etc/console/secrets/redpanda-admin-api-tls-ca" )) )) (mustMergeOverwrite (dict "Value" (coalesce nil) "EnvVar" (dict "name" "" ) ) (dict "Value" $values.secret.redpanda.adminApi.tlsKey "EnvVar" (mustMergeOverwrite (dict "name" "" ) (dict "name" "REDPANDA_ADMINAPI_TLS_KEYFILEPATH" "value" "/etc/console/secrets/redpanda-admin-api-tls-key" )) )) (mustMergeOverwrite (dict "Value" (coalesce nil) "EnvVar" (dict "name" "" ) ) (dict "Value" $values.secret.redpanda.adminApi.tlsCert "EnvVar" (mustMergeOverwrite (dict "name" "" ) (dict "name" "REDPANDA_ADMINAPI_TLS_CERTFILEPATH" "value" "/etc/console/secrets/redpanda-admin-api-tls-cert" )) ))) -}} +{{- $vars := $values.extraEnv -}} +{{- range $_, $possible := $possibleVars -}} +{{- if (not (empty $possible.Value)) -}} +{{- $vars = (concat (default (list ) $vars) (list $possible.EnvVar)) -}} +{{- end -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $vars) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "console.consolePodVolumes" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $volumes := (list (mustMergeOverwrite (dict "name" "" ) (mustMergeOverwrite (dict ) (dict "configMap" (mustMergeOverwrite (dict ) (mustMergeOverwrite (dict ) (dict "name" (get (fromJson (include "console.Fullname" (dict "a" (list $dot) ))) "r") )) (dict )) )) (dict "name" "configs" ))) -}} +{{- if $values.secret.create -}} +{{- $volumes = (concat (default (list ) $volumes) (list (mustMergeOverwrite (dict "name" "" ) (mustMergeOverwrite (dict ) (dict "secret" (mustMergeOverwrite (dict ) (dict "secretName" (get (fromJson (include "console.Fullname" (dict "a" (list $dot) ))) "r") )) )) (dict "name" "secrets" )))) -}} +{{- end -}} +{{- range $_, $mount := $values.secretMounts -}} +{{- $volumes = (concat (default (list ) $volumes) (list (mustMergeOverwrite (dict "name" "" ) (mustMergeOverwrite (dict ) (dict "secret" (mustMergeOverwrite (dict ) (dict "secretName" $mount.secretName "defaultMode" $mount.defaultMode )) )) (dict "name" $mount.name )))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (concat (default (list ) $volumes) (default (list ) $values.extraVolumes))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + diff --git a/charts/redpanda/redpanda/5.9.2/charts/console/templates/_helpers.go.tpl b/charts/redpanda/redpanda/5.9.2/charts/console/templates/_helpers.go.tpl new file mode 100644 index 0000000000..88b00025d7 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/console/templates/_helpers.go.tpl @@ -0,0 +1,82 @@ +{{- /* Generated from "helpers.go" */ -}} + +{{- define "console.Name" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $name := (default $dot.Chart.Name $values.nameOverride) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (get (fromJson (include "console.cleanForK8s" (dict "a" (list $name) ))) "r")) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "console.Fullname" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (ne $values.fullnameOverride "") -}} +{{- $_is_returning = true -}} +{{- (dict "r" (get (fromJson (include "console.cleanForK8s" (dict "a" (list $values.fullnameOverride) ))) "r")) | toJson -}} +{{- break -}} +{{- end -}} +{{- $name := (default $dot.Chart.Name $values.nameOverride) -}} +{{- if (contains $name $dot.Release.Name) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (get (fromJson (include "console.cleanForK8s" (dict "a" (list $dot.Release.Name) ))) "r")) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (get (fromJson (include "console.cleanForK8s" (dict "a" (list (printf "%s-%s" $dot.Release.Name $name)) ))) "r")) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "console.Chart" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $chart := (printf "%s-%s" $dot.Chart.Name $dot.Chart.Version) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (get (fromJson (include "console.cleanForK8s" (dict "a" (list (replace "+" "_" $chart)) ))) "r")) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "console.Labels" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $labels := (dict "helm.sh/chart" (get (fromJson (include "console.Chart" (dict "a" (list $dot) ))) "r") "app.kubernetes.io/managed-by" $dot.Release.Service ) -}} +{{- if (ne $dot.Chart.AppVersion "") -}} +{{- $_ := (set $labels "app.kubernetes.io/version" $dot.Chart.AppVersion) -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (merge (dict ) $labels (get (fromJson (include "console.SelectorLabels" (dict "a" (list $dot) ))) "r") $values.commonLabels)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "console.SelectorLabels" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $_is_returning = true -}} +{{- (dict "r" (dict "app.kubernetes.io/name" (get (fromJson (include "console.Name" (dict "a" (list $dot) ))) "r") "app.kubernetes.io/instance" $dot.Release.Name )) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "console.cleanForK8s" -}} +{{- $s := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $_is_returning = true -}} +{{- (dict "r" (trimSuffix "-" (trunc (63 | int) $s))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + diff --git a/charts/redpanda/redpanda/5.9.2/charts/console/templates/_helpers.tpl b/charts/redpanda/redpanda/5.9.2/charts/console/templates/_helpers.tpl new file mode 100644 index 0000000000..ee2ab5d9b8 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/console/templates/_helpers.tpl @@ -0,0 +1,25 @@ +{{/* +Expand the name of the chart. +Used by tests/test-connection.yaml +*/}} +{{- define "console.name" -}} +{{- get ((include "console.Name" (dict "a" (list .))) | fromJson) "r" }} +{{- 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. +Used by tests/test-connection.yaml +*/}} +{{- define "console.fullname" -}} +{{- get ((include "console.Fullname" (dict "a" (list .))) | fromJson) "r" }} +{{- end }} + +{{/* +Common labels +Used by tests/test-connection.yaml +*/}} +{{- define "console.labels" -}} +{{- (get ((include "console.Labels" (dict "a" (list .))) | fromJson) "r") | toYaml -}} +{{- end }} diff --git a/charts/redpanda/redpanda/5.9.2/charts/console/templates/_hpa.go.tpl b/charts/redpanda/redpanda/5.9.2/charts/console/templates/_hpa.go.tpl new file mode 100644 index 0000000000..5957633d22 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/console/templates/_hpa.go.tpl @@ -0,0 +1,25 @@ +{{- /* Generated from "hpa.go" */ -}} + +{{- define "console.HorizontalPodAutoscaler" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (not $values.autoscaling.enabled) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $metrics := (list ) -}} +{{- if (ne $values.autoscaling.targetCPUUtilizationPercentage (coalesce nil)) -}} +{{- $metrics = (concat (default (list ) $metrics) (list (mustMergeOverwrite (dict "type" "" ) (dict "type" "Resource" "resource" (mustMergeOverwrite (dict "name" "" "target" (dict "type" "" ) ) (dict "name" "cpu" "target" (mustMergeOverwrite (dict "type" "" ) (dict "type" "Utilization" "averageUtilization" $values.autoscaling.targetCPUUtilizationPercentage )) )) )))) -}} +{{- end -}} +{{- if (ne $values.autoscaling.targetMemoryUtilizationPercentage (coalesce nil)) -}} +{{- $metrics = (concat (default (list ) $metrics) (list (mustMergeOverwrite (dict "type" "" ) (dict "type" "Resource" "resource" (mustMergeOverwrite (dict "name" "" "target" (dict "type" "" ) ) (dict "name" "memory" "target" (mustMergeOverwrite (dict "type" "" ) (dict "type" "Utilization" "averageUtilization" $values.autoscaling.targetMemoryUtilizationPercentage )) )) )))) -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "spec" (dict "scaleTargetRef" (dict "kind" "" "name" "" ) "maxReplicas" 0 ) "status" (dict "desiredReplicas" 0 "currentMetrics" (coalesce nil) ) ) (mustMergeOverwrite (dict ) (dict "apiVersion" "autoscaling/v2" "kind" "HorizontalPodAutoscaler" )) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "name" (get (fromJson (include "console.Fullname" (dict "a" (list $dot) ))) "r") "labels" (get (fromJson (include "console.Labels" (dict "a" (list $dot) ))) "r") )) "spec" (mustMergeOverwrite (dict "scaleTargetRef" (dict "kind" "" "name" "" ) "maxReplicas" 0 ) (dict "scaleTargetRef" (mustMergeOverwrite (dict "kind" "" "name" "" ) (dict "apiVersion" "apps/v1" "kind" "Deployment" "name" (get (fromJson (include "console.Fullname" (dict "a" (list $dot) ))) "r") )) "minReplicas" ($values.autoscaling.minReplicas | int) "maxReplicas" ($values.autoscaling.maxReplicas | int) "metrics" $metrics )) ))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + diff --git a/charts/redpanda/redpanda/5.9.2/charts/console/templates/_ingress.go.tpl b/charts/redpanda/redpanda/5.9.2/charts/console/templates/_ingress.go.tpl new file mode 100644 index 0000000000..0df05e870b --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/console/templates/_ingress.go.tpl @@ -0,0 +1,46 @@ +{{- /* Generated from "ingress.go" */ -}} + +{{- define "console.Ingress" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (not $values.ingress.enabled) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $tls := (coalesce nil) -}} +{{- range $_, $t := $values.ingress.tls -}} +{{- $hosts := (coalesce nil) -}} +{{- range $_, $host := $t.hosts -}} +{{- $hosts = (concat (default (list ) $hosts) (list (tpl $host $dot))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $tls = (concat (default (list ) $tls) (list (mustMergeOverwrite (dict ) (dict "secretName" $t.secretName "hosts" $hosts )))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $rules := (coalesce nil) -}} +{{- range $_, $host := $values.ingress.hosts -}} +{{- $paths := (coalesce nil) -}} +{{- range $_, $path := $host.paths -}} +{{- $paths = (concat (default (list ) $paths) (list (mustMergeOverwrite (dict "pathType" (coalesce nil) "backend" (dict ) ) (dict "path" $path.path "pathType" $path.pathType "backend" (mustMergeOverwrite (dict ) (dict "service" (mustMergeOverwrite (dict "name" "" "port" (dict ) ) (dict "name" (get (fromJson (include "console.Fullname" (dict "a" (list $dot) ))) "r") "port" (mustMergeOverwrite (dict ) (dict "number" ($values.service.port | int) )) )) )) )))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $rules = (concat (default (list ) $rules) (list (mustMergeOverwrite (dict ) (mustMergeOverwrite (dict ) (dict "http" (mustMergeOverwrite (dict "paths" (coalesce nil) ) (dict "paths" $paths )) )) (dict "host" (tpl $host.host $dot) )))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "spec" (dict ) "status" (dict "loadBalancer" (dict ) ) ) (mustMergeOverwrite (dict ) (dict "kind" "Ingress" "apiVersion" "networking.k8s.io/v1" )) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "name" (get (fromJson (include "console.Fullname" (dict "a" (list $dot) ))) "r") "labels" (get (fromJson (include "console.Labels" (dict "a" (list $dot) ))) "r") "annotations" $values.ingress.annotations )) "spec" (mustMergeOverwrite (dict ) (dict "ingressClassName" $values.ingress.className "tls" $tls "rules" $rules )) ))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + diff --git a/charts/redpanda/redpanda/5.9.2/charts/console/templates/_notes.go.tpl b/charts/redpanda/redpanda/5.9.2/charts/console/templates/_notes.go.tpl new file mode 100644 index 0000000000..6b58b21ef4 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/console/templates/_notes.go.tpl @@ -0,0 +1,40 @@ +{{- /* Generated from "notes.go" */ -}} + +{{- define "console.Notes" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $commands := (list `1. Get the application URL by running these commands:`) -}} +{{- if $values.ingress.enabled -}} +{{- $scheme := "http" -}} +{{- if (gt ((get (fromJson (include "_shims.len" (dict "a" (list $values.ingress.tls) ))) "r") | int) (0 | int)) -}} +{{- $scheme = "https" -}} +{{- end -}} +{{- range $_, $host := $values.ingress.hosts -}} +{{- range $_, $path := $host.paths -}} +{{- $commands = (concat (default (list ) $commands) (list (printf "%s://%s%s" $scheme $host.host $path.path))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- else -}}{{- if (contains "NodePort" (toString $values.service.type)) -}} +{{- $commands = (concat (default (list ) $commands) (list (printf ` export NODE_PORT=$(kubectl get --namespace %s -o jsonpath="{.spec.ports[0].nodePort}" services %s)` $dot.Release.Namespace (get (fromJson (include "console.Fullname" (dict "a" (list $dot) ))) "r")) (printf ` export NODE_IP=$(kubectl get nodes --namespace %s -o jsonpath="{.items[0].status.addresses[0].address}")` $dot.Release.Namespace) " echo http://$NODE_IP:$NODE_PORT")) -}} +{{- else -}}{{- if (contains "NodePort" (toString $values.service.type)) -}} +{{- $commands = (concat (default (list ) $commands) (list ` NOTE: It may take a few minutes for the LoadBalancer IP to be available.` (printf ` You can watch the status of by running 'kubectl get --namespace %s svc -w %s'` $dot.Release.Namespace (get (fromJson (include "console.Fullname" (dict "a" (list $dot) ))) "r")) (printf ` export SERVICE_IP=$(kubectl get svc --namespace %s %s --template "{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}")` $dot.Release.Namespace (get (fromJson (include "console.Fullname" (dict "a" (list $dot) ))) "r")) (printf ` echo http://$SERVICE_IP:%d` ($values.service.port | int)))) -}} +{{- else -}}{{- if (contains "ClusterIP" (toString $values.service.type)) -}} +{{- $commands = (concat (default (list ) $commands) (list (printf ` export POD_NAME=$(kubectl get pods --namespace %s -l "app.kubernetes.io/name=%s,app.kubernetes.io/instance=%s" -o jsonpath="{.items[0].metadata.name}")` $dot.Release.Namespace (get (fromJson (include "console.Name" (dict "a" (list $dot) ))) "r") $dot.Release.Name) (printf ` export CONTAINER_PORT=$(kubectl get pod --namespace %s $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")` $dot.Release.Namespace) ` echo "Visit http://127.0.0.1:8080 to use your application"` (printf ` kubectl --namespace %s port-forward $POD_NAME 8080:$CONTAINER_PORT` $dot.Release.Namespace))) -}} +{{- end -}} +{{- end -}} +{{- end -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $commands) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + diff --git a/charts/redpanda/redpanda/5.9.2/charts/console/templates/_secret.go.tpl b/charts/redpanda/redpanda/5.9.2/charts/console/templates/_secret.go.tpl new file mode 100644 index 0000000000..49e6289930 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/console/templates/_secret.go.tpl @@ -0,0 +1,22 @@ +{{- /* Generated from "secret.go" */ -}} + +{{- define "console.Secret" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (not $values.secret.create) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $jwtSecret := $values.secret.login.jwtSecret -}} +{{- if (eq $jwtSecret "") -}} +{{- $jwtSecret = (randAlphaNum (32 | int)) -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) ) (mustMergeOverwrite (dict ) (dict "apiVersion" "v1" "kind" "Secret" )) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "name" (get (fromJson (include "console.Fullname" (dict "a" (list $dot) ))) "r") "labels" (get (fromJson (include "console.Labels" (dict "a" (list $dot) ))) "r") )) "type" "Opaque" "stringData" (dict "kafka-sasl-password" (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $values.secret.kafka.saslPassword "") ))) "r") "kafka-protobuf-git-basicauth-password" (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $values.secret.kafka.protobufGitBasicAuthPassword "") ))) "r") "kafka-sasl-aws-msk-iam-secret-key" (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $values.secret.kafka.awsMskIamSecretKey "") ))) "r") "kafka-tls-ca" (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $values.secret.kafka.tlsCa "") ))) "r") "kafka-tls-cert" (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $values.secret.kafka.tlsCert "") ))) "r") "kafka-tls-key" (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $values.secret.kafka.tlsKey "") ))) "r") "kafka-schema-registry-password" (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $values.secret.kafka.schemaRegistryPassword "") ))) "r") "kafka-schemaregistry-tls-ca" (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $values.secret.kafka.schemaRegistryTlsCa "") ))) "r") "kafka-schemaregistry-tls-cert" (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $values.secret.kafka.schemaRegistryTlsCert "") ))) "r") "kafka-schemaregistry-tls-key" (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $values.secret.kafka.schemaRegistryTlsKey "") ))) "r") "login-jwt-secret" $jwtSecret "login-google-oauth-client-secret" (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $values.secret.login.google.clientSecret "") ))) "r") "login-google-groups-service-account.json" (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $values.secret.login.google.groupsServiceAccount "") ))) "r") "login-github-oauth-client-secret" (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $values.secret.login.github.clientSecret "") ))) "r") "login-github-personal-access-token" (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $values.secret.login.github.personalAccessToken "") ))) "r") "login-okta-client-secret" (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $values.secret.login.okta.clientSecret "") ))) "r") "login-okta-directory-api-token" (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $values.secret.login.okta.directoryApiToken "") ))) "r") "login-oidc-client-secret" (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $values.secret.login.oidc.clientSecret "") ))) "r") "enterprise-license" (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $values.secret.enterprise.License "") ))) "r") "redpanda-admin-api-password" (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $values.secret.redpanda.adminApi.password "") ))) "r") "redpanda-admin-api-tls-ca" (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $values.secret.redpanda.adminApi.tlsCa "") ))) "r") "redpanda-admin-api-tls-cert" (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $values.secret.redpanda.adminApi.tlsCert "") ))) "r") "redpanda-admin-api-tls-key" (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $values.secret.redpanda.adminApi.tlsKey "") ))) "r") ) ))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + diff --git a/charts/redpanda/redpanda/5.9.2/charts/console/templates/_service.go.tpl b/charts/redpanda/redpanda/5.9.2/charts/console/templates/_service.go.tpl new file mode 100644 index 0000000000..64cef3f8dd --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/console/templates/_service.go.tpl @@ -0,0 +1,20 @@ +{{- /* Generated from "service.go" */ -}} + +{{- define "console.Service" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $port := (mustMergeOverwrite (dict "port" 0 "targetPort" 0 ) (dict "name" "http" "port" (($values.service.port | int) | int) "protocol" "TCP" )) -}} +{{- if (ne $values.service.targetPort (coalesce nil)) -}} +{{- $_ := (set $port "targetPort" $values.service.targetPort) -}} +{{- end -}} +{{- if (and (contains "NodePort" (toString $values.service.type)) (ne $values.service.nodePort (coalesce nil))) -}} +{{- $_ := (set $port "nodePort" $values.service.nodePort) -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "spec" (dict ) "status" (dict "loadBalancer" (dict ) ) ) (mustMergeOverwrite (dict ) (dict "apiVersion" "v1" "kind" "Service" )) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "name" (get (fromJson (include "console.Fullname" (dict "a" (list $dot) ))) "r") "namespace" $dot.Release.Namespace "labels" (get (fromJson (include "console.Labels" (dict "a" (list $dot) ))) "r") "annotations" $values.service.annotations )) "spec" (mustMergeOverwrite (dict ) (dict "type" $values.service.type "selector" (get (fromJson (include "console.SelectorLabels" (dict "a" (list $dot) ))) "r") "ports" (list $port) )) ))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + diff --git a/charts/redpanda/redpanda/5.9.2/charts/console/templates/_serviceaccount.go.tpl b/charts/redpanda/redpanda/5.9.2/charts/console/templates/_serviceaccount.go.tpl new file mode 100644 index 0000000000..5a49ba3fdb --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/console/templates/_serviceaccount.go.tpl @@ -0,0 +1,39 @@ +{{- /* Generated from "serviceaccount.go" */ -}} + +{{- define "console.ServiceAccountName" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if $values.serviceAccount.create -}} +{{- if (ne $values.serviceAccount.name "") -}} +{{- $_is_returning = true -}} +{{- (dict "r" $values.serviceAccount.name) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (get (fromJson (include "console.Fullname" (dict "a" (list $dot) ))) "r")) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (default "default" $values.serviceAccount.name)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "console.ServiceAccount" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (not $values.serviceAccount.create) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) ) (mustMergeOverwrite (dict ) (dict "kind" "ServiceAccount" "apiVersion" "v1" )) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "name" (get (fromJson (include "console.ServiceAccountName" (dict "a" (list $dot) ))) "r") "labels" (get (fromJson (include "console.Labels" (dict "a" (list $dot) ))) "r") "namespace" $dot.Release.Namespace "annotations" $values.serviceAccount.annotations )) "automountServiceAccountToken" $values.serviceAccount.automountServiceAccountToken ))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + diff --git a/charts/redpanda/redpanda/5.9.2/charts/console/templates/_shims.tpl b/charts/redpanda/redpanda/5.9.2/charts/console/templates/_shims.tpl new file mode 100644 index 0000000000..e3bb40e415 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/console/templates/_shims.tpl @@ -0,0 +1,289 @@ +{{- /* Generated from "bootstrap.go" */ -}} + +{{- define "_shims.typetest" -}} +{{- $typ := (index .a 0) -}} +{{- $value := (index .a 1) -}} +{{- $zero := (index .a 2) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (typeIs $typ $value) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list $value true)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list $zero false)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.typeassertion" -}} +{{- $typ := (index .a 0) -}} +{{- $value := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (not (typeIs $typ $value)) -}} +{{- $_ := (fail (printf "expected type of %q got: %T" $typ $value)) -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $value) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.dicttest" -}} +{{- $m := (index .a 0) -}} +{{- $key := (index .a 1) -}} +{{- $zero := (index .a 2) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (hasKey $m $key) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list (index $m $key) true)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list $zero false)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.compact" -}} +{{- $args := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $out := (dict ) -}} +{{- range $i, $e := $args -}} +{{- $_ := (set $out (printf "T%d" ((add (1 | int) $i) | int)) $e) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $out) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.deref" -}} +{{- $ptr := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (eq $ptr (coalesce nil)) -}} +{{- $_ := (fail "nil dereference") -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $ptr) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.len" -}} +{{- $m := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (eq $m (coalesce nil)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (0 | int)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (len $m)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.ptr_Deref" -}} +{{- $ptr := (index .a 0) -}} +{{- $def := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (ne $ptr (coalesce nil)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $ptr) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $def) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.ptr_Equal" -}} +{{- $a := (index .a 0) -}} +{{- $b := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (and (eq $a (coalesce nil)) (eq $b (coalesce nil))) -}} +{{- $_is_returning = true -}} +{{- (dict "r" true) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (eq $a $b)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.lookup" -}} +{{- $apiVersion := (index .a 0) -}} +{{- $kind := (index .a 1) -}} +{{- $namespace := (index .a 2) -}} +{{- $name := (index .a 3) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $result := (lookup $apiVersion $kind $namespace $name) -}} +{{- if (empty $result) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list (coalesce nil) false)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list $result true)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.asnumeric" -}} +{{- $value := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (typeIs "float64" $value) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list $value true)) | toJson -}} +{{- break -}} +{{- end -}} +{{- if (typeIs "int64" $value) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list $value true)) | toJson -}} +{{- break -}} +{{- end -}} +{{- if (typeIs "int" $value) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list $value true)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list (0 | int) false)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.asintegral" -}} +{{- $value := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (or (typeIs "int64" $value) (typeIs "int" $value)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list $value true)) | toJson -}} +{{- break -}} +{{- end -}} +{{- if (and (typeIs "float64" $value) (eq (floor $value) $value)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list $value true)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list (0 | int) false)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.parseResource" -}} +{{- $repr := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (typeIs "float64" $repr) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list (float64 $repr) 1.0)) | toJson -}} +{{- break -}} +{{- end -}} +{{- if (not (typeIs "string" $repr)) -}} +{{- $_ := (fail (printf "invalid Quantity expected string or float64 got: %T (%v)" $repr $repr)) -}} +{{- end -}} +{{- if (not (regexMatch `^[0-9]+(\.[0-9]{0,6})?(k|m|M|G|T|P|Ki|Mi|Gi|Ti|Pi)?$` $repr)) -}} +{{- $_ := (fail (printf "invalid Quantity: %q" $repr)) -}} +{{- end -}} +{{- $reprStr := (toString $repr) -}} +{{- $unit := (regexFind "(k|m|M|G|T|P|Ki|Mi|Gi|Ti|Pi)$" $repr) -}} +{{- $numeric := (float64 (substr (0 | int) ((sub ((get (fromJson (include "_shims.len" (dict "a" (list $reprStr) ))) "r") | int) ((get (fromJson (include "_shims.len" (dict "a" (list $unit) ))) "r") | int)) | int) $reprStr)) -}} +{{- $tmp_tuple_1 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.dicttest" (dict "a" (list (dict "" 1.0 "m" 0.001 "k" (1000 | int) "M" (1000000 | int) "G" (1000000000 | int) "T" (1000000000000 | int) "P" (1000000000000000 | int) "Ki" (1024 | int) "Mi" (1048576 | int) "Gi" (1073741824 | int) "Ti" (1099511627776 | int) "Pi" (1125899906842624 | int) ) $unit (coalesce nil)) ))) "r")) ))) "r") -}} +{{- $ok := $tmp_tuple_1.T2 -}} +{{- $scale := ($tmp_tuple_1.T1 | float64) -}} +{{- if (not $ok) -}} +{{- $_ := (fail (printf "unknown unit: %q" $unit)) -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list $numeric $scale)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.resource_MustParse" -}} +{{- $repr := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $tmp_tuple_2 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.parseResource" (dict "a" (list $repr) ))) "r")) ))) "r") -}} +{{- $scale := ($tmp_tuple_2.T2 | float64) -}} +{{- $numeric := ($tmp_tuple_2.T1 | float64) -}} +{{- $strs := (list "" "m" "k" "M" "G" "T" "P" "Ki" "Mi" "Gi" "Ti" "Pi") -}} +{{- $scales := (list 1.0 0.001 (1000 | int) (1000000 | int) (1000000000 | int) (1000000000000 | int) (1000000000000000 | int) (1024 | int) (1048576 | int) (1073741824 | int) (1099511627776 | int) (1125899906842624 | int)) -}} +{{- $idx := -1 -}} +{{- range $i, $s := $scales -}} +{{- if (eq ($s | float64) ($scale | float64)) -}} +{{- $idx = $i -}} +{{- break -}} +{{- end -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- if (eq $idx -1) -}} +{{- $_ := (fail (printf "unknown scale: %v" $scale)) -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (printf "%s%s" (toString $numeric) (index $strs $idx))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.resource_Value" -}} +{{- $repr := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $tmp_tuple_3 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.parseResource" (dict "a" (list $repr) ))) "r")) ))) "r") -}} +{{- $scale := ($tmp_tuple_3.T2 | float64) -}} +{{- $numeric := ($tmp_tuple_3.T1 | float64) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (int64 (ceil ((mulf $numeric $scale) | float64)))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.resource_MilliValue" -}} +{{- $repr := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $tmp_tuple_4 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.parseResource" (dict "a" (list $repr) ))) "r")) ))) "r") -}} +{{- $scale := ($tmp_tuple_4.T2 | float64) -}} +{{- $numeric := ($tmp_tuple_4.T1 | float64) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (int64 (ceil ((mulf ((mulf $numeric 1000.0) | float64) $scale) | float64)))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.render-manifest" -}} +{{- $tpl := (index . 0) -}} +{{- $dot := (index . 1) -}} +{{- $manifests := (get ((include $tpl (dict "a" (list $dot))) | fromJson) "r") -}} +{{- if not (typeIs "[]interface {}" $manifests) -}} +{{- $manifests = (list $manifests) -}} +{{- end -}} +{{- range $_, $manifest := $manifests -}} +{{- if ne $manifest nil }} +--- +{{toYaml (unset (unset $manifest "status") "creationTimestamp")}} +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/charts/redpanda/redpanda/5.9.2/charts/console/templates/configmap.yaml b/charts/redpanda/redpanda/5.9.2/charts/console/templates/configmap.yaml new file mode 100644 index 0000000000..cffd69938f --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/console/templates/configmap.yaml @@ -0,0 +1,17 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You 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. +*/}} +{{- include "_shims.render-manifest" (list "console.ConfigMap" .) -}} diff --git a/charts/redpanda/redpanda/5.9.2/charts/console/templates/deployment.yaml b/charts/redpanda/redpanda/5.9.2/charts/console/templates/deployment.yaml new file mode 100644 index 0000000000..48a149041b --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/console/templates/deployment.yaml @@ -0,0 +1,17 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You 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. +*/}} +{{- include "_shims.render-manifest" (list "console.Deployment" .) -}} diff --git a/charts/redpanda/redpanda/5.9.2/charts/console/templates/hpa.yaml b/charts/redpanda/redpanda/5.9.2/charts/console/templates/hpa.yaml new file mode 100644 index 0000000000..9cfc4a132e --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/console/templates/hpa.yaml @@ -0,0 +1,17 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You 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. +*/}} +{{- include "_shims.render-manifest" (list "console.HorizontalPodAutoscaler" .) -}} diff --git a/charts/redpanda/redpanda/5.9.2/charts/console/templates/ingress.yaml b/charts/redpanda/redpanda/5.9.2/charts/console/templates/ingress.yaml new file mode 100644 index 0000000000..ef3867869c --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/console/templates/ingress.yaml @@ -0,0 +1,17 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You 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. +*/}} +{{- include "_shims.render-manifest" (list "console.Ingress" .) -}} diff --git a/charts/redpanda/redpanda/5.9.2/charts/console/templates/secret.yaml b/charts/redpanda/redpanda/5.9.2/charts/console/templates/secret.yaml new file mode 100644 index 0000000000..aeeeba25e1 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/console/templates/secret.yaml @@ -0,0 +1,17 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You 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. +*/}} +{{- include "_shims.render-manifest" (list "console.Secret" .) -}} diff --git a/charts/redpanda/redpanda/5.9.2/charts/console/templates/service.yaml b/charts/redpanda/redpanda/5.9.2/charts/console/templates/service.yaml new file mode 100644 index 0000000000..0f1621fafc --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/console/templates/service.yaml @@ -0,0 +1,17 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You 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. +*/}} +{{- include "_shims.render-manifest" (list "console.Service" .) -}} diff --git a/charts/redpanda/redpanda/5.9.2/charts/console/templates/serviceaccount.yaml b/charts/redpanda/redpanda/5.9.2/charts/console/templates/serviceaccount.yaml new file mode 100644 index 0000000000..9215af70ed --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/console/templates/serviceaccount.yaml @@ -0,0 +1,17 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You 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. +*/}} +{{- include "_shims.render-manifest" (list "console.ServiceAccount" .) -}} diff --git a/charts/redpanda/redpanda/5.9.2/charts/console/templates/tests/test-connection.yaml b/charts/redpanda/redpanda/5.9.2/charts/console/templates/tests/test-connection.yaml new file mode 100644 index 0000000000..de17fb2b1d --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/console/templates/tests/test-connection.yaml @@ -0,0 +1,22 @@ +{{- if .Values.tests.enabled }} +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "console.fullname" . }}-test-connection" + namespace: {{ .Release.Namespace | quote }} + labels: + {{- include "console.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test +spec: +{{- with .Values.imagePullSecrets }} + imagePullSecrets: {{- toYaml . | nindent 4 }} +{{- end }} + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['{{ include "console.fullname" . }}:{{ .Values.service.port }}'] + restartPolicy: Never + priorityClassName: {{ .Values.priorityClassName }} +{{- end }} \ No newline at end of file diff --git a/charts/redpanda/redpanda/5.9.2/charts/console/testdata/template-cases-generated.txtar b/charts/redpanda/redpanda/5.9.2/charts/console/testdata/template-cases-generated.txtar new file mode 100644 index 0000000000..7fd56f9de3 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/console/testdata/template-cases-generated.txtar @@ -0,0 +1,22208 @@ +Generated by TestGenerateCases +-- case-000 -- +affinity: {} +annotations: + Q9AVJD4: G9TEnp +autoscaling: + maxReplicas: 206 + minReplicas: 312 + targetCPUUtilizationPercentage: 41 + targetMemoryUtilizationPercentage: 72 +commonLabels: + "": 31q1Pbz +extraEnv: +- name: Z2BpO + value: 0ggF3ha7D +extraVolumes: +- name: 7iCCax +- name: meEH +- name: xYVSV +fullnameOverride: hvGoJL +livenessProbe: + failureThreshold: 1028486626 + httpGet: + host: AOZs + path: YKi + port: Q8C3tKEBBI + scheme: ćpʔS欻鯡 + initialDelaySeconds: 1713123405 + periodSeconds: -1411200119 + successThreshold: -1362510905 + timeoutSeconds: 1375594715 +nameOverride: "n" +podAnnotations: + lyW: mn + pjq6fDr: YA2w301 + uXvFB: VQ5gP9 +priorityClassName: vQhDS +replicaCount: 387 +resources: + limits: + x0StjCjt: "0" +securityContext: {} +serviceAccount: + automountServiceAccountToken: false + create: true + name: HRoLg +strategy: + type: Ò泆A +-- case-001 -- +automountServiceAccountToken: true +extraContainers: +- image: LlCU3if + imagePullPolicy: RɷVȄ×ʤǫĠ侻Ɏźx跻Å榜 + lifecycle: {} + name: l0 + resources: {} + securityContext: + allowPrivilegeEscalation: true + privileged: true + startupProbe: + exec: {} + failureThreshold: -1510490758 + initialDelaySeconds: 112782468 + periodSeconds: -738545847 + successThreshold: -1801864225 + timeoutSeconds: 1026753125 + terminationMessagePath: gCG + terminationMessagePolicy: hmƂÚÕʏ疅耪鯉瓉Ɏ煐8qĺ + tty: true + workingDir: ixD7Jq +extraEnv: +- name: 3Nf + value: vATdo0CH + valueFrom: + configMapKeyRef: + key: IRw5 + name: fa + fieldRef: + apiVersion: 93Fjhay + fieldPath: LRa2I +- name: T0 + value: trXO4 +- name: P9hPooVH + value: yii5lolb + valueFrom: + configMapKeyRef: + key: spAKa + name: U0EYAAe0 +fullnameOverride: T50cZi +initContainers: + extraInitContainers: qur +nameOverride: Sh +priorityClassName: NyOpfr +replicaCount: 414 +resources: {} +tolerations: +- effect: Mǣ鍙x奬Ø裗Ʈ唿踣ʘ)ɒâÄ + key: AWx + operator: yīÄLJʑʢ避 + value: cO +- effect: ï楡ɜƐf鱖À夹ǙȤK + key: Gk23T + operator: è6槈$_ȋ6}rvĕ曉¸顋ŀÓ + value: DCkzy +- effect: 蠯u牰ŇɔnÜȎĤ原H + key: qSC + operator: "n" + tolerationSeconds: -7696192156323826068 + value: z +-- case-002 -- +deployment: {} +enterprise: {} +extraEnvFrom: +- prefix: cfVf + secretRef: + name: ha +- prefix: i2E2Jvnc +extraVolumeMounts: +- mountPath: Y40 + mountPropagation: $寕洦敬苖ēRõøȀ + name: vn5hd + readOnly: true + subPath: oXCY9 + subPathExpr: p +fullnameOverride: xZty +imagePullSecrets: +- {} +- name: YPVBzxvx +nameOverride: vN4yH7I +podAnnotations: + 8vRMfVroYC2: QXbUbLea + VV4w: s4sL + upwTMuIqflmD: 9J0H45zXX +priorityClassName: TeCy +replicaCount: 417 +resources: + limits: + 27ywV: "0" + nMnjjF4kM: "0" + xar2JX: "0" +service: + nodePort: 292 + port: 413 + targetPort: 267 + type: ILpSX2Cy +serviceAccount: + automountServiceAccountToken: true + name: R1Yar8 +tolerations: +- effect: ǩ趥螏|F8ǻĬ嵍Ğ错ʂĺƠǷ俆峻噸 + key: b + operator: wąȹV{İ刡嚮ȜJ + value: ZuTw +- effect: D稕栥[Ǟ$焫昲 + key: NnhmxYy + operator: Xʀ + value: v65W +- effect: 岂bĤ晏#DĢº + key: MOgT + operator: 礩懜蹻ǍBȟvɸ堊 + value: 3iXh +-- case-003 -- +annotations: + 6HCwaF8XIH: uIbMN + MRwga: Fq5s + mgpV: 4f +autoscaling: + maxReplicas: 411 + minReplicas: 432 + targetCPUUtilizationPercentage: 169 + targetMemoryUtilizationPercentage: 155 +configmap: + create: false +deployment: + create: false +extraVolumes: +- name: 1CIX +fullnameOverride: 8nE +ingress: + className: EqUYi + enabled: true + hosts: + - host: bKQCmfZ + - host: djItx5GtejC6 + - host: 2wLaQU8 + tls: + - hosts: + - V8BpuMCig + - 7LqG4w92 + - el3u4v + secretName: nUlu5bMwB8 + - hosts: + - 4HLzq + - 2i4g + secretName: lSgQIKwj5 +nameOverride: w6 +podSecurityContext: + fsGroup: 1512968668502336058 + runAsUser: -2578305880243425477 +priorityClassName: HNqN9h2 +replicaCount: 17 +resources: {} +secret: + create: true + kafka: + awsMskIamSecretKey: SrYY84t + protobufGitBasicAuthPassword: Fb + saslPassword: xCc3TeVY + schemaRegistryPassword: ovCqxwz9Bf + schemaRegistryTlsCa: JL + schemaRegistryTlsCert: cS + schemaRegistryTlsKey: UMwYx4F + tlsCa: HFpsnPdw + tlsCert: hseIt + tlsPassphrase: Wc0 +-- case-004 -- +affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: {} + weight: -1713447377 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: null + podAntiAffinity: {} +commonLabels: + "": PtQ7JxIAdPjt +fullnameOverride: "" +nameOverride: YMl +podAnnotations: + 1iK8Ic: Qo3FCg9qi + 63SsVxDT: v + A1Q4J4: U9jygY2t1F +priorityClassName: JT0MK +replicaCount: 261 +secretMounts: +- defaultMode: 197 + name: QmzFlXE + path: Oj + secretName: 7gi +service: + nodePort: 366 + port: 112 + targetPort: 173 + type: dO7eovC +strategy: + type: ɡv?ĨJ姯ɚƟć匪cb +-- case-005 -- +autoscaling: + enabled: false + maxReplicas: 26 + minReplicas: 380 + targetCPUUtilizationPercentage: 395 + targetMemoryUtilizationPercentage: 140 +configmap: + create: false +deployment: {} +extraVolumeMounts: +- mountPath: JU4z + name: QEJyD + subPath: ZBEy2m0m + subPathExpr: S1Kk +- mountPath: RjUw5sX7NP + name: ett1n + subPath: NmZKwz + subPathExpr: QOMT +fullnameOverride: pN +image: + registry: 7iw15D + repository: RnJFs0 + tag: OQDirE +imagePullSecrets: +- name: ATcT6Hd +- name: l15Hhw +initContainers: + extraInitContainers: Me +livenessProbe: + exec: + command: + - AJd + - HZf + - YHivxIsAJ738b5Q + failureThreshold: -1921365096 + initialDelaySeconds: -1548958176 + periodSeconds: -1952555242 + successThreshold: -1289242499 + timeoutSeconds: -265051013 +nameOverride: MW +priorityClassName: KnLhcy2cw +replicaCount: 396 +secret: + create: true + login: + github: + clientSecret: R4Zj + personalAccessToken: N85av + jwtSecret: g + oidc: + clientSecret: enei1WIcV +tests: {} +-- case-006 -- +affinity: + podAffinity: {} + podAntiAffinity: {} +configmap: + create: true +console: {} +enterprise: {} +extraVolumeMounts: +- mountPath: 5uhd1qMX + mountPropagation: ȵS鈛ZQì暗 + name: "N" + readOnly: true + subPath: lbeciOZZ + subPathExpr: Pd88cwE +- mountPath: yVo + mountPropagation: ÑƇ[嫨ĸŁ幵鿯它(ȡ~嘶ƌO情=į臺 + name: Z + readOnly: true + subPath: Nrqx + subPathExpr: Q4ChfT +fullnameOverride: rzd +image: + registry: zT38Q + repository: V + tag: iSGm6MT1 +ingress: + className: XOZv8 + enabled: false + hosts: + - host: WGn + paths: + - path: NVV + pathType: 0DK + - host: "" +initContainers: + extraInitContainers: SCgmJTj +nameOverride: gCH15URsJZr +podAnnotations: + s2D: DMU7 +podLabels: + CoBI: 20aOZaZvs + e0xqmoOD: Nb5V + ylGQE: p +priorityClassName: 1x11c0q +replicaCount: 176 +resources: + requests: + PY: "0" +secret: + enterprise: + licenseSecretRef: + key: eF + name: fQ02KR + kafka: + awsMskIamSecretKey: 1tq + protobufGitBasicAuthPassword: G + saslPassword: K8kPgIp6 + schemaRegistryPassword: "" + schemaRegistryTlsCa: Zr + schemaRegistryTlsCert: KN + schemaRegistryTlsKey: t + tlsCa: CQ + tlsCert: 6xZ8 + tlsPassphrase: JpScAmVx6 +serviceAccount: + automountServiceAccountToken: false + create: true + name: nd7TSb2mNTS +tests: + enabled: false +-- case-007 -- +commonLabels: + cV05TKdtF: 55lItpeJD + h: 1Y7dqm4wZL +configmap: {} +console: + roleBindings: + - "": null + 5w1YcAu: null +extraEnv: +- name: qY0f + value: Wu +- name: 9zVp + value: g +extraEnvFrom: +- configMapRef: + name: OUS + optional: true + prefix: YWvtgT +- configMapRef: + name: 4xZZ + prefix: Djbp99U +extraVolumes: +- name: dCz +fullnameOverride: "y" +initContainers: + extraInitContainers: RiAu +livenessProbe: + exec: + command: + - 3Ujf + - EOmDk + failureThreshold: 1105213631 + grpc: + port: -199686432 + service: H + initialDelaySeconds: -1727299217 + periodSeconds: -579129147 + successThreshold: -1278687101 + terminationGracePeriodSeconds: 7570283898099180047 + timeoutSeconds: -603846855 +nameOverride: HWL +nodeSelector: + CAy: 19kW + R2z: OpcDywz9x +podSecurityContext: + fsGroupChangePolicy: 驸Ǩiµ慷泱世 + runAsGroup: 6873387834465682841 + runAsUser: 7937848737866681002 + sysctls: + - name: mp + value: SkIvFN + - name: E + value: RknyuPB + - name: kcY + value: us1 +priorityClassName: rs +readinessProbe: + failureThreshold: 114758306 + grpc: + port: 774513900 + service: GICRd2O + initialDelaySeconds: 457836757 + periodSeconds: -1914503008 + successThreshold: 1926018786 + timeoutSeconds: 458769630 +replicaCount: 103 +resources: + requests: + 4P1f3: "0" + DmuY: "0" +secret: + login: + google: + clientSecret: Ln0 + groupsServiceAccount: gp + jwtSecret: 2j6NF + okta: + clientSecret: 3A593BjCuu + directoryApiToken: mSSz8MZ + redpanda: + adminApi: + password: t + tlsCa: QD1x71f + tlsCert: 744Ysvi + tlsKey: 56VaHh +service: + nodePort: 238 + port: 286 + targetPort: 404 + type: Vvrvx +serviceAccount: + automountServiceAccountToken: false + name: RFjc7 +-- case-008 -- +annotations: + hfXF: v4uLEC6f8m +automountServiceAccountToken: false +console: {} +deployment: {} +fullnameOverride: GbgHqD +ingress: + className: XfqwM +livenessProbe: + failureThreshold: 1421249778 + initialDelaySeconds: 1194618095 + periodSeconds: 1245060237 + successThreshold: -641096828 + timeoutSeconds: -617099936 +nameOverride: RW +podAnnotations: + BTlN: z8t + a: Pqjhw +podSecurityContext: + fsGroupChangePolicy: ǶȚ/廻 + runAsGroup: 3241750191956122115 + runAsNonRoot: false + runAsUser: 2693812519144067821 + supplementalGroups: + - -7558357415363805139 + - -9152494874115651655 + - -906805565867492888 + sysctls: + - name: CBe8XsS + value: bh + - name: pUYyG9c + value: xPm1 +priorityClassName: 0fXQqWA96 +readinessProbe: + failureThreshold: -10750427 + httpGet: + host: yftc + path: 7MDOtCNf + port: -1919050774 + scheme: ȧ楢谚 + initialDelaySeconds: 208988771 + periodSeconds: -2096658971 + successThreshold: -233405863 + timeoutSeconds: 2042765580 +replicaCount: 475 +secret: + create: false + enterprise: + licenseSecretRef: + key: "" + name: vGB +securityContext: + procMount: ȃ蘗ʮǺ踰蒐佛桸gɋ + readOnlyRootFilesystem: false + runAsGroup: 5367218369967093267 +serviceAccount: + create: true + name: YcV5zP8 +strategy: + rollingUpdate: {} + type: 堯飉J侚桤 合w犌ŝ|#è:(蹝Ƀy輐 +topologySpreadConstraints: +- maxSkew: -722842418 + nodeTaintsPolicy: uã链掎ŏȅ噘籥邟澶N3-昃嗽(七|犘 + topologyKey: vq + whenUnsatisfiable: Ȭť'Ùt苷ŲĤ蘝 +- labelSelector: {} + maxSkew: 1436245353 + nodeAffinityPolicy: 0ʠƃ氁ʆZ + topologyKey: t + whenUnsatisfiable: x叾džʜƽ耨 +- labelSelector: {} + matchLabelKeys: + - 6T2 + - FqrwFd + maxSkew: -172720268 + nodeAffinityPolicy: 觏败TʙȎ喧5婬ȑªgȢ'!ÅWp襎 + nodeTaintsPolicy: ÛB¹]ʐ梳Ě + topologyKey: VyU9 + whenUnsatisfiable: 烹wɹȐN坿¨叻ʊ鴥/Ŭ屎釽C欼 +-- case-009 -- +affinity: + nodeAffinity: {} + podAffinity: {} + podAntiAffinity: {} +automountServiceAccountToken: true +configmap: + create: false +deployment: {} +fullnameOverride: l1Bnpx +imagePullSecrets: +- name: x42RbB4KLm +livenessProbe: + failureThreshold: -1420734522 + httpGet: + host: fFkzqM8 + path: aVVHbe + port: TkNE + scheme: ǂɷ烷Į~鼹ǵǃ楅ǰ + initialDelaySeconds: 753838163 + periodSeconds: -444344576 + successThreshold: -1003403229 + timeoutSeconds: -172453343 +nameOverride: BKV +nodeSelector: + OBRBvRK: hMXDLGN5 + ky: sv +podSecurityContext: + fsGroupChangePolicy: 灆Zeɪ霅ǭɒ<ǖ韆 + runAsGroup: -2394155475284911371 + runAsNonRoot: true + supplementalGroups: + - 802667379359895872 + - 8316082600801371691 +priorityClassName: p0ShP6Yru +readinessProbe: + failureThreshold: -286281002 + initialDelaySeconds: 138566964 + periodSeconds: -361700659 + successThreshold: 422528479 + terminationGracePeriodSeconds: 495828610939530481 + timeoutSeconds: 352721839 +replicaCount: 315 +secret: {} +secretMounts: +- defaultMode: 414 + name: yWBr98zs1 + path: xShE + secretName: YMpib3J +- defaultMode: 402 + name: qUQ5 + path: Wnbf + secretName: Pw8 +- defaultMode: 410 + name: hpqapQJQ + path: fgV + secretName: 1JLIOjZI8 +service: + annotations: + efgehQaV5UI0y: GymqDudh + nodePort: 75 + port: 229 + targetPort: 85 + type: yZy +topologySpreadConstraints: +- maxSkew: -73453467 + minDomains: 326628755 + nodeAffinityPolicy: "" + topologyKey: zWgGRC + whenUnsatisfiable: 黚堳ʈ¡ +-- case-010 -- +affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: hu5a9Q0m + operator: Ʊ飁Ɲŗʫf + values: + - fDVpOP + - fUBu2Zhz + matchFields: + - key: zOA + operator: 豔|Ĺ霱鑕yȮM錕陰蔆 + - key: uqlr1 + operator: ʏ + weight: -157546286 + - preference: + matchExpressions: + - key: yI2tB1c6Om + operator: 槼湝@)萢=\Ɇ剋Ś>(.aC俥?蔔 + values: + - 5QB3 + - C + - key: IhL2k3 + operator: "" + matchFields: + - key: Kn1 + operator: q'ʏC効L¶ƋMʐģƥƝnĤe + weight: -1818860211 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - {} + podAffinity: {} +configmap: + create: false +console: + roles: + - null +deployment: + create: true +enterprise: + licenseSecretRef: + key: 6Y + name: juyv +extraContainers: +- env: + - name: nE8 + value: hFfGzdv + valueFrom: + configMapKeyRef: + key: 9Sc + name: kviW + fieldRef: + fieldPath: bzL + resourceFieldRef: + containerName: ky9X6 + divisor: "0" + resource: RgwF + image: mEMnGhDi + imagePullPolicy: <Ǐ(嬘箓閁1_Y.脯鮉娇腾1 + name: ZyDivTyKOX + readinessProbe: + failureThreshold: 368214623 + initialDelaySeconds: 1711545214 + periodSeconds: -1669571514 + successThreshold: 830602444 + timeoutSeconds: -1406663042 + resources: + requests: + Ta: "0" + restartPolicy: M#L粓Ojw+ĸɊcƗ镃聆琮ǘ滂W + stdin: true + terminationMessagePath: 7hyobl + terminationMessagePolicy: gŜĶ蔓林驲%嶄ʚ轿竷 + volumeDevices: + - devicePath: zlgauG + name: Uy7Ds5N + - devicePath: pturCrgNMxS + name: "1" + volumeMounts: + - mountPath: 2ftw3U97pI + mountPropagation: ǮmW + name: NeLq9zvIQ + subPath: 5XYnpNAb + subPathExpr: rAeHuQk + - mountPath: aOj5TCBKn + name: DWFR + subPath: G + - mountPath: ovoJMYcQZ7 + mountPropagation: ɷ&娈瘱 + name: o6QaPD8 + subPath: rIo + subPathExpr: j0F1wa + workingDir: tj +- env: + - name: KO7zek + value: AE8r + valueFrom: {} + envFrom: + - prefix: T4nvtH0yCoJCx + - prefix: KaMGNcK + image: m + imagePullPolicy: 牀 + lifecycle: + preStop: + exec: {} + sleep: + seconds: -1229802121654850448 + livenessProbe: + failureThreshold: 1036399450 + grpc: + port: 1383801223 + service: nm0jd39Ta + httpGet: + host: VhafGy + path: CP9 + port: BnhNd + scheme: hxu崚奵Y + initialDelaySeconds: 141265356 + periodSeconds: 251484282 + successThreshold: 257415096 + terminationGracePeriodSeconds: 3476093234934519616 + timeoutSeconds: -1657896181 + name: UCZJ + ports: + - containerPort: 574867450 + hostPort: 156179933 + name: 0re + protocol: 頶韜»釟ţKFƂƄp錴畗~[禬B琡9 + - containerPort: -374880824 + hostPort: 1342282100 + name: OeyfSkg3EJIuD + protocol: 佃ŦŬ穷唂&2ŌĜ,gF躊貀j寝ô + readinessProbe: + failureThreshold: 978947885 + httpGet: + host: A + path: Ngfyt + port: "" + scheme: Í蠕窩獙 + initialDelaySeconds: 60101484 + periodSeconds: 1102760384 + successThreshold: 1260060937 + terminationGracePeriodSeconds: 1157546254675437089 + timeoutSeconds: -465800822 + resizePolicy: + - resourceName: P6b56 + restartPolicy: 冿÷Ý萦{[P貍ȕ,Sɕ錼 + - resourceName: azLsfqbuYlr + restartPolicy: 蒃Ký阹ǒ1T獽蛍峸伦ƨ(Ƭ-央á + - resourceName: skOpL + restartPolicy: 鸿dŶ徥w^ȏ嘳Ƙ唓Ęɸ-ɫ鷠C + resources: {} + terminationMessagePath: vmp + terminationMessagePolicy: Ƒh庛ʘ$8L藑奾ń4說 + workingDir: rgrA +extraVolumeMounts: +- mountPath: C3nMA + name: 0sxSVsP + readOnly: true + subPath: V + subPathExpr: 1E5cYdMw +fullnameOverride: ivK +image: + pullPolicy: "" + registry: 4A + repository: 0YeLdES + tag: 1a4iH +nameOverride: JFcK +priorityClassName: x0ISc2 +readinessProbe: + exec: {} + failureThreshold: 1992527736 + initialDelaySeconds: 1233698472 + periodSeconds: 1177961840 + successThreshold: -1634725396 + terminationGracePeriodSeconds: 236063688080704715 + timeoutSeconds: -1493252430 +replicaCount: 250 +secret: + create: false + enterprise: {} + kafka: + awsMskIamSecretKey: K + protobufGitBasicAuthPassword: HMiCm9 + saslPassword: dlWblwkM + schemaRegistryPassword: DQXNeX + schemaRegistryTlsCa: Xe1cT2AuIi + schemaRegistryTlsCert: gaHcYjD + schemaRegistryTlsKey: 96V + tlsCa: "" + tlsCert: WEDNhiC + tlsPassphrase: lP2w1T + login: + github: + clientSecret: vpO + personalAccessToken: pn05iLc53z + google: + clientSecret: OX + groupsServiceAccount: LB64mTpyF + jwtSecret: GQ0Yw + redpanda: {} +serviceAccount: + annotations: + TTsn5: s3xEhO + tZiUN: CtjX + create: true + name: kIzbDF +-- case-011 -- +affinity: + podAffinity: {} + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: {} + matchLabelKeys: + - E9nCu6aLM + topologyKey: PfPCGvStt + weight: -1379963896 + - podAffinityTerm: + namespaceSelector: {} + topologyKey: CgA4 + weight: -726546395 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: ijh1hJb + operator: ƏŧD續筚朊 + values: + - BOfF5xB + - 3iu4 + - key: "93" + operator: Dij%{欬ɽ + - key: NEd + operator: ÿD + values: + - r + - B7E1BoYQ4Njb + - BTV + matchLabelKeys: + - FuyLvc + - Lh60qi + namespaceSelector: + matchExpressions: + - key: w + operator: 嘑 + - key: eQ6nY99xw + operator: H辄萟蘎Ÿ塪²;暃 + - key: 8JrCFA + operator: "" + values: + - wVO + topologyKey: ByO + - namespaceSelector: {} + topologyKey: b21 + - namespaces: + - Ifv + topologyKey: F9j5 +annotations: + pJ: f0brcnhV +automountServiceAccountToken: true +autoscaling: + enabled: false + maxReplicas: 239 + minReplicas: 83 + targetCPUUtilizationPercentage: 68 + targetMemoryUtilizationPercentage: 468 +commonLabels: + JwK5MKTa: WW + v7E: 1g6JB +console: {} +deployment: {} +extraEnv: +- name: XW + value: PCPsJt + valueFrom: + configMapKeyRef: + key: Zk0vTu6kC + name: d9zm3 + optional: false + secretKeyRef: + key: mRF + name: CW + optional: false +- name: loir2K + value: Ti0q +- name: lAxIKF7cbLlc + value: 1ksS + valueFrom: + fieldRef: + apiVersion: 8i2Z + fieldPath: vD7H + resourceFieldRef: + containerName: yqY + divisor: "0" + resource: ebRDAl + secretKeyRef: + key: E9514U + name: g3Rbzs + optional: false +extraEnvFrom: +- configMapRef: + name: d + prefix: Fl1 + secretRef: + name: X8xDu + optional: true +- prefix: M + secretRef: + name: 10or1C2m + optional: false +- configMapRef: + name: BBj + optional: false + prefix: Xy + secretRef: + name: ZA3 +extraVolumeMounts: +- mountPath: O + mountPropagation: ŜQLhlkU穒´宕Ïůŝƪ + name: JeSPIB + readOnly: true + subPath: RTiJ + subPathExpr: wad +- mountPath: QV6Kf + name: Pj7R + subPath: qBOd + subPathExpr: kN3Uujt +fullnameOverride: hbe +image: + registry: gjR + repository: U + tag: Tl0EP +initContainers: + extraInitContainers: OgPf +livenessProbe: + failureThreshold: 653767212 + grpc: + port: -53435273 + service: fv5J + initialDelaySeconds: 832425522 + periodSeconds: -1810991482 + successThreshold: 1954581711 + terminationGracePeriodSeconds: 1550995604326825538 + timeoutSeconds: -574178850 +nameOverride: Cy9eHCiP +nodeSelector: + HC7: EI8 +podLabels: + "2": RgUAFm + D2V: V80aQ +podSecurityContext: + fsGroup: 4103142176308445041 + fsGroupChangePolicy: Ő6­撱悤ÅC`碸 + runAsUser: 9170579519391070953 + sysctls: + - name: 4OKA + value: P7ouRq + - name: iD9Oz + value: gL6ARE +priorityClassName: sJXoA3V +readinessProbe: + exec: {} + failureThreshold: 1745353710 + grpc: + port: -2051399147 + service: G + initialDelaySeconds: 1504484890 + periodSeconds: -846859037 + successThreshold: -1564014824 + terminationGracePeriodSeconds: 7625838354502176909 + timeoutSeconds: 888372342 +replicaCount: 65 +resources: + requests: + "Y": "0" +secretMounts: +- defaultMode: 12 + name: n4BPeF + path: 2Qy8k + secretName: auIr +service: + annotations: + "": NbuyvXjW + 2CTz: vRGLHMO53rD + yLzpKqz: uBjXvD + nodePort: 83 + port: 478 + targetPort: 90 + type: sl +-- case-012 -- +affinity: {} +annotations: + v: D +configmap: {} +console: {} +enterprise: + licenseSecretRef: + key: oG0N9s8 + name: fmqBE +extraContainers: +- command: + - "" + - 7yJE + envFrom: + - prefix: kRXk + secretRef: + name: TJsCapqoxl + - prefix: ucUEP + secretRef: + name: 1zCfpPiVt9o + optional: true + image: hwJ + imagePullPolicy: dh + name: Ody4zqt + readinessProbe: + exec: {} + failureThreshold: 1607990521 + grpc: + port: 2033135747 + service: "" + initialDelaySeconds: -889776869 + periodSeconds: -35190825 + successThreshold: -958310065 + terminationGracePeriodSeconds: 3166888730011246345 + timeoutSeconds: 806015074 + resources: + requests: + mg2KyOVo97: "0" + restartPolicy: 档媘řĖ焘傐Yʮ,+Ƽ梽讫ƭ焇 + securityContext: + readOnlyRootFilesystem: true + runAsGroup: -2035296945120192462 + stdinOnce: true + terminationMessagePolicy: '*.Q' + workingDir: 0g9 +- command: + - ktel2 + - 2gO + image: Kq1K2HexLL + imagePullPolicy: 蟫黳jª0狫ĝ| + lifecycle: + postStart: + exec: + command: + - I + name: XmcrosJ9Art + resizePolicy: + - resourceName: 8dOXgKMh + restartPolicy: T@罞 + resources: + limits: + Qf424: "0" + UkBWyCgR: "0" + yS9FH: "0" + securityContext: + allowPrivilegeEscalation: true + capabilities: + drop: + - Ǐ蟯ƛU賊稁uv/u讎胗< + - 1湹 + privileged: false + readOnlyRootFilesystem: false + runAsGroup: -281571585037868414 + runAsUser: 8469885005475493831 + stdin: true + stdinOnce: true + terminationMessagePath: 6ii28 + terminationMessagePolicy: ȊGī3慺Ŏ + volumeDevices: + - devicePath: "" + name: lqvpF + - devicePath: 3vTez + name: pD6EOo + workingDir: QEqnPlY6YE +- args: + - eiyTiCxBp + envFrom: + - configMapRef: + name: uxUzs + prefix: 0Oq + secretRef: + name: ahghhjB + - configMapRef: + name: yjx + prefix: cOCr6ajjpSTT + - configMapRef: + name: "4" + prefix: 0XtWv + secretRef: + name: oKDQ + image: PV + imagePullPolicy: d?遼gŜT纬ɷšǧ餝Ƨ + livenessProbe: + exec: {} + failureThreshold: 746140291 + grpc: + port: 1197495917 + service: "" + httpGet: + host: x78yAB + path: P5mSLs + port: Cb2 + scheme: 儰试9ȷǴ燀ǃ¦籇射,ǠöcƲ伙 + initialDelaySeconds: 1418617842 + periodSeconds: 187037501 + successThreshold: -1821323321 + timeoutSeconds: -894994792 + name: ToH + resizePolicy: + - resourceName: 7Ut8kM + restartPolicy: gěǏ* + - resourceName: gvoJz7 + restartPolicy: ł0Iɷ»u诎żȋ貏C炭 + - resourceName: VpTvtNnJOw + restartPolicy: 阠eR'k.Ơ糦啮ŋ睷N譺 + resources: + limits: + cYhO6a: "0" + startupProbe: + exec: {} + failureThreshold: -1040244189 + grpc: + port: 1921669257 + service: Me + httpGet: + host: 5fL4Z + path: BwLac + port: SKrb2z + scheme: ľ<Ƽ浳s剪ɍ + initialDelaySeconds: -1064995957 + periodSeconds: 230643461 + successThreshold: -1865926881 + timeoutSeconds: 1102271416 + terminationMessagePath: ZbnnI + terminationMessagePolicy: 阳壀ɀS强pŇȆDž鹩 + tty: true + volumeDevices: + - devicePath: pP2eHwth + name: S9Sy + workingDir: Z +extraEnvFrom: +- prefix: RyT9JuZ +fullnameOverride: tmn2Kt +initContainers: + extraInitContainers: SIhGa +livenessProbe: + failureThreshold: 666524470 + grpc: + port: 1398516128 + service: "" + httpGet: + host: bR1aDlNV + path: yDJgyD4 + port: PU8gXWTBf + scheme: 8BƔ7, + initialDelaySeconds: 1841184951 + periodSeconds: 465079780 + successThreshold: -1928046688 + terminationGracePeriodSeconds: -4709298711736612221 + timeoutSeconds: 1377323766 +nameOverride: Qr03ts +podLabels: + "": S7BNyT + r1F: Fsc + yeY4LjT: MRlwtd +priorityClassName: vMcB +replicaCount: 407 +resources: {} +securityContext: + allowPrivilegeEscalation: false + privileged: true + readOnlyRootFilesystem: false + runAsGroup: -6536894786619939509 + runAsNonRoot: false +strategy: + rollingUpdate: {} + type: 9Cɠ+餌µ骽O惠LƬɇɦ鉍挶 +tests: {} +-- case-013 -- +automountServiceAccountToken: true +enterprise: {} +extraContainers: +- env: + - name: bNyX + value: DpJ + valueFrom: + secretKeyRef: + key: r3ZL + name: GM2zRN8 + optional: false + - name: dS + value: u2CpI14PZ + - name: JVoNndPj + value: eCfRy + image: 9nkfM + imagePullPolicy: v洓p褾NJ翛Y/笸i洞偀fX綤鰐 + livenessProbe: + exec: + command: + - TzQ + - 5tBBhynsjV + failureThreshold: -1613952147 + httpGet: + host: gYV + path: 9qC2GovT + port: Gh + initialDelaySeconds: 1651935443 + periodSeconds: -1307313312 + successThreshold: 1553368137 + terminationGracePeriodSeconds: -4575724788805099082 + timeoutSeconds: -499895377 + name: aOBSLF + readinessProbe: + failureThreshold: 687754614 + initialDelaySeconds: -1880005074 + periodSeconds: 794268536 + successThreshold: -1510519942 + terminationGracePeriodSeconds: 3334702514671978014 + timeoutSeconds: -178867660 + resources: + requests: + hiWTQ: "0" + m7CDU: "0" + stdin: true + terminationMessagePath: Yj9V + terminationMessagePolicy: js$昦夁糎fț + tty: true + volumeMounts: + - mountPath: Xaoy + name: XuLXzMm + readOnly: true + subPath: NI8v + subPathExpr: nPRuyC + - mountPath: S + mountPropagation: ĜX鴮璫ȓĢ + name: c2o + readOnly: true + subPath: DEcziG + subPathExpr: 7UjF6H + workingDir: yPE +extraVolumeMounts: +- mountPath: DVlVa1jiDIh5G + name: zaV + subPath: lXnque8 + subPathExpr: aFzzfyzr +- mountPath: 7VmD + name: bNuYmK + readOnly: true + subPath: zsTvmtU0 + subPathExpr: uNyQSZ +- mountPath: p + name: q3 + readOnly: true + subPathExpr: k4yfc0H +fullnameOverride: RttlJN +initContainers: + extraInitContainers: Gnt +nameOverride: dDkIKgMwXv +priorityClassName: BDUfm1wSRDI +readinessProbe: + exec: {} + failureThreshold: -225696508 + initialDelaySeconds: 1573121125 + periodSeconds: -1561542711 + successThreshold: 1804677264 + terminationGracePeriodSeconds: 5224127779959308812 + timeoutSeconds: -1540252725 +replicaCount: 412 +resources: + limits: + f7Jr: "0" + fl: "0" + requests: + Q4O7nA: "0" +secret: + enterprise: {} + redpanda: {} +securityContext: + privileged: true + readOnlyRootFilesystem: false + runAsUser: -8804799239371185443 +tolerations: +- effect: ƞ嬂 + key: wnH + operator: Ā蔥ąʏƅȑǚ缗'r~熐{Ǎ楯&鑫咂] + value: LYZYjeFUmK29wdL +- effect: 硞撤幅娰tȬ婒ĎɕÏǜ蚭馸諄W)偒½ + key: e2 + operator: bƤrZ + value: 8ssobF8u +-- case-014 -- +autoscaling: + maxReplicas: 297 + minReplicas: 375 + targetCPUUtilizationPercentage: 161 + targetMemoryUtilizationPercentage: 154 +console: + roleBindings: + - null +deployment: + create: false +extraContainers: +- args: + - Z62Is + - Hbh02LW4 + env: + - name: YW1G + value: 0GWAuZSLomGzW + valueFrom: + configMapKeyRef: + key: G23Iugy + name: TkEMhJ + secretKeyRef: + key: BTU + name: g1 + optional: false + - name: uL + value: FFIE5os + valueFrom: + configMapKeyRef: + key: "Y" + name: auRMap + resourceFieldRef: + containerName: q0II1T + divisor: "0" + resource: HT + secretKeyRef: + key: dzuljE + name: G7WQLg + envFrom: + - prefix: gP + secretRef: + name: OVJe + optional: false + image: rJIHfr2OEa135 + imagePullPolicy: YÙ姯?斕_9xŠɏɉɬ脸埫窿 + name: AH0Q + ports: + - containerPort: 228562644 + hostIP: IoQ1 + hostPort: -1878543188 + name: Rfal + - containerPort: -894592742 + hostIP: WL1wuF + hostPort: -1156574467 + name: kaBC3xQ4W + protocol: ǀw黽Ɂ態y歳饏S鰚醭 + readinessProbe: + exec: + command: + - SSKDo + failureThreshold: 2133132404 + grpc: + port: 1749726411 + service: mXvc + httpGet: + host: pc5My + path: Xb4w6 + port: 478437545 + scheme: X甡蓸^qĠ屘g槛雍d伨ɾ + initialDelaySeconds: -966001365 + periodSeconds: 714178271 + successThreshold: -1714884162 + timeoutSeconds: 152300629 + resources: + limits: + QD: "0" + eQShuVrO: "0" + requests: + xWdhFr9: "0" + restartPolicy: 吥蓔ȫ唿瀘V輇f蓵犆Ȑ]œʢ鶍MƧ樤_ + startupProbe: + exec: {} + failureThreshold: 623319858 + grpc: + port: -1442127150 + service: C6 + initialDelaySeconds: 128345274 + periodSeconds: -1861677604 + successThreshold: 1112169900 + timeoutSeconds: 120934069 + stdin: true + stdinOnce: true + terminationMessagePath: CVFCc8 + terminationMessagePolicy: 欥ɻ斩隫0撊GƲ{ + tty: true + workingDir: IZB +- image: DOt5K + imagePullPolicy: Q燢Ƈʃǻĝ + lifecycle: + postStart: + sleep: + seconds: -2443463859616450892 + preStop: + exec: + command: + - 74I + - RU + sleep: + seconds: -3090258659267849140 + livenessProbe: + failureThreshold: -1269681865 + grpc: + port: -1568193429 + service: X1LyDnjv64JEDb + initialDelaySeconds: -1309179527 + periodSeconds: -1814451145 + successThreshold: -2073223886 + terminationGracePeriodSeconds: -7380892635099163371 + timeoutSeconds: 2123408205 + name: QbUkrjO + readinessProbe: + failureThreshold: -1858848657 + grpc: + port: 349774039 + service: jxJ + httpGet: + path: aAkRuN + port: AGGDH + scheme: Aʝ詷Cţm憻菁裰ś + initialDelaySeconds: -1986091889 + periodSeconds: -775693671 + successThreshold: 930243436 + terminationGracePeriodSeconds: -4158765076015214976 + timeoutSeconds: -1930165730 + resources: + limits: + QL: "0" + startupProbe: + failureThreshold: 79584809 + httpGet: + host: IYI + path: jpfp + port: h + scheme: ÎŲ媱5\æ}QQǤoƲ^8%嵕_踽 + initialDelaySeconds: 1384447753 + periodSeconds: 364207137 + successThreshold: 1778504178 + timeoutSeconds: 1437969450 + stdinOnce: true + terminationMessagePath: z + terminationMessagePolicy: ūJ + tty: true + workingDir: RQkvQON +fullnameOverride: htymHJ +image: + pullPolicy: 袪Ȓ緶Ð菝ȋ擮@Ŧ + registry: ulLeWQWUJdjnk + repository: J + tag: KQ +initContainers: + extraInitContainers: JvUWbM +nameOverride: Vi2vH +podAnnotations: + Tt: CHbO7BF +podSecurityContext: + fsGroupChangePolicy: A%Âȁµ郞星懐,t语Ā詘IJÊ铮Q + runAsUser: -4832235381641550418 +priorityClassName: rcxHoi +replicaCount: 424 +resources: + limits: + AS: "0" +service: + nodePort: 66 + port: 41 + targetPort: 168 + type: Oiwzbmtjpb +serviceAccount: + create: true + name: h6eHrUr +tests: {} +tolerations: +- effect: 鞼CÞŲɮȧɖņ魉**護Å岴hFʎ篅2 + key: ffSN + operator: 葓C巰qĩŹ脠~蒵 + value: fkh +- effect: ȯ绸 + key: meTpNZ + operator: ĥ恃精hw"蘄谇H潔ʎȴ豅©嫗笨 + value: uyTD +-- case-015 -- +affinity: + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: 7eVqbmnw4 + operator: 屈ǧȔŗS#~¸Dd馔uÈ飏ƌĔ魼ȓ + values: + - eZapFDhb + - dBr2cD + - key: Z13Kq48NE0 + operator: ª + values: + - 03LE6GE + - key: s + operator: 箱+ʑ圼;0丢顃M媆熋熼妄瞬 + values: + - E + - jC2mNBN + matchLabels: + 4tdQRoO: Tgv + 7Apxz: EPl5 + bPvG5Bf: sCS + namespaceSelector: {} + namespaces: + - bkN0U + topologyKey: haPJ + weight: -1043017794 + - podAffinityTerm: + labelSelector: + matchLabels: + PP8DxAPJwUzY: z9RL6 + U1a: J + due4: eRc0tKn + namespaceSelector: + matchExpressions: + - key: "y" + operator: 霮ʡ`罵瀖Kʓa嚃*Q`UV邠想ɷġ + namespaces: + - M2GNeyD + - eDNVdz1ne46 + topologyKey: kQ + weight: -1134437930 + - podAffinityTerm: + namespaceSelector: + matchExpressions: + - key: SnD + operator: 6愔ȶ獧:öȰ浻珼»ǰs睑,s頀旓eX + - key: yt197hBb + operator: ȒǦ^(á咟獐赠5ĺĜ嶜庌愖V揺ɞ\Ș + values: + - pu5 + - Ywv1TEhK + - pAo + matchLabels: + "": rZ + topologyKey: WSD + weight: 613733383 + requiredDuringSchedulingIgnoredDuringExecution: + - topologyKey: 4b6nMCalUl1 +annotations: + 2V: 50l + jFB7K: 5ZqGXdsD94 +autoscaling: + maxReplicas: 483 + minReplicas: 178 + targetCPUUtilizationPercentage: 362 + targetMemoryUtilizationPercentage: 33 +commonLabels: + B0Pmybnj: gh8 + MdyMnFBP0Cd1: UUVRKbjhv + ShHkukRGF9k: KlIyX6upO +enterprise: + licenseSecretRef: + key: 5MWDqlE + name: UoZ4 +extraEnv: +- name: iQE + value: Aj6RWPJE +- name: QwMCc + value: N9g6bDNI +- name: U5Qg5Qc0NWE + valueFrom: + configMapKeyRef: + key: R + name: n8 + optional: false + fieldRef: + apiVersion: zg0 + fieldPath: fNjpqJ + secretKeyRef: + key: MlF + name: h +extraVolumeMounts: +- mountPath: y5BZm9v9L5 + name: mE9WF + readOnly: true + subPathExpr: 3vKqLj2 +fullnameOverride: 9RweMGWqBs +image: + pullPolicy: '&Ŕ<駄AG' + registry: FezgEM + repository: b4CZb + tag: OoX +ingress: + annotations: + "": ZKQ6I + ES: uo + className: x7Um + enabled: true + tls: + - secretName: Ye6 + - hosts: + - nNQW2NL + - g + - "N" + secretName: YQl +initContainers: + extraInitContainers: FZnnB +nameOverride: KD8DmV +nodeSelector: + vy4h: rk +podLabels: + FlwBgvWNMrbg5: YKgnz8q + TGDbR: 4egH + Xr8XMOk: 1DAii +podSecurityContext: + fsGroupChangePolicy: ¶鮬眴帘ʥb豚DIĂ + runAsGroup: 4190388773600423895 + supplementalGroups: + - 6652209348598506050 + - 5521245057591625878 + - 6754698685787706527 + sysctls: + - name: "7" + value: vp +priorityClassName: "68" +readinessProbe: + exec: {} + failureThreshold: 398655641 + httpGet: + host: NaspK + path: Bgdl + port: 1587383135 + scheme: ǰ|鬩E橴s + initialDelaySeconds: 1516319657 + periodSeconds: -635156272 + successThreshold: 1338596793 + terminationGracePeriodSeconds: 6302545905526400855 + timeoutSeconds: -905426079 +replicaCount: 128 +resources: + requests: + I: "0" + b7jbi: "0" + r1cN: "0" +securityContext: + privileged: false + procMount: d聉l蝲ɓH>狱(Ȁ胄hʍy龝Ȼ埓Y + readOnlyRootFilesystem: false + runAsGroup: 2951274493718237098 + runAsUser: -1772317555576666168 +serviceAccount: + annotations: + IH: 3W + K5hNNf: "" + r: 9cmm + automountServiceAccountToken: true + name: zmr +tests: {} +tolerations: +- effect: '#U媷ɑɥ±箑妌RɱfÈB矅蒟(' + key: g + operator: Řg~歟1ƹ,纙蝝垺 + tolerationSeconds: -9038490283678033542 + value: x6T1NM +- effect: ė{ɼ 5;^ʤàOKv泣0ƫ¢ + key: wdW6LI1a5 + operator: ú4ʫ-哖ýȻȣŦiĩġ膳". + tolerationSeconds: -5247520709138794849 + value: NXt +topologySpreadConstraints: +- labelSelector: + matchExpressions: + - key: dme + operator: )\鹮İ又Ȥ鏥Ĝ + matchLabels: + Cdk: atEBel + PhEVPxOjN: QTW4 + fC0YTiwm: fdAQN8t + maxSkew: 472867304 + minDomains: 1802867157 + nodeAffinityPolicy: ʈǔ聿ŶŹ&y鰜# + nodeTaintsPolicy: '"篍Ɛɰl鄱' + topologyKey: fqmSu + whenUnsatisfiable: äƟĻ鍣ųø啼ǫǷ" +- labelSelector: + matchExpressions: + - key: BEj + operator: Ɠ墳 + values: + - qBJ + - KZbk + - key: 9wxm2wFXlY + operator: ì蠁{\媽;ě8ɠ + values: + - yiuVv9DzzRse + - "N" + - z + - key: SWu + operator: Ī½曖1șWb3 + maxSkew: 774109577 + minDomains: -110979462 + nodeAffinityPolicy: 醿卨¬婾豜ʦKd` + topologyKey: 4iskW3Hbv + whenUnsatisfiable: ǮXƞ棤Ǘ +-- case-016 -- +affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: 2Ldss9 + operator: ?霏ƦxǰA7ȇ(堃R + values: + - Ce7pGgB5o + - B8EWZ + - key: pJKw3VVY5 + operator: 2wq6JK?Ȏ惙徵r儊ǒ嵀匫W + matchFields: + - key: EQvFQjoLm1 + operator: «/o咑澇ƉɑȨŞƙ|5時 + weight: -508343495 + - preference: + matchExpressions: + - key: VRoHsoMNa + operator: cƄábŊɕg追ĦǙȿ男)hŬ + values: + - tcCIpd9m + - FsoFrK + - key: ReH4ocoZ + operator: "" + values: + - bnUyPckbz + - AE + - njW + - key: fZBGR + operator: 租ǜ藇錼 + weight: -1003115262 + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + namespaceSelector: + matchLabels: + qGlBCw: zUBwqj2xV + zlHLG: TDTkLQOC + namespaces: + - QWFH + - TEzgQKPSQ + topologyKey: "" + weight: 682123393 + - podAffinityTerm: + labelSelector: {} + matchLabelKeys: + - 1MiHrQ + namespaceSelector: + matchExpressions: + - key: JUYumiiJFrY + operator: .ƽCDZo& + values: + - t3wDXa + - 70HCTbI6g + - C + - key: ik + operator: Œ8v + values: + - Wp + - Zf + - c2q7e + topologyKey: Sc1Q + weight: 869908297 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: ore + operator: ?ɴ$瀜蝪ĪźȀŐƌS莣幮屒n×U锇Ľ + values: + - mJM + - oc + - aU + - key: SQmv + operator: ȥī+ūĬ诧犂¹ + - key: Hh1r9 + operator: h蓟x蹵D¨谧罬 + matchLabelKeys: + - mDk + - Hki8 + topologyKey: x2q0Rx1f1N + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + namespaceSelector: + matchExpressions: + - key: H1Ni + operator: Ȧ厜OŊ + values: + - UWzAFu2 + - key: M + operator: 罐hĹ;'ǫ貉yĊ啉刉DzQį + - key: zZ + operator: 颉śĴJ|@W補A篐S献;ɾ[_鶙ȱ + values: + - 4BL + namespaces: + - Thgfgf7Z + topologyKey: XBju19e + weight: 1392601493 +automountServiceAccountToken: false +console: + roleBindings: + - Q0kslM: null + - null +deployment: {} +extraContainers: +- command: + - opIk + - v9eJ + - 4V + env: + - name: 5Q + value: o + envFrom: + - prefix: eBWmLK + secretRef: + name: FedJi + optional: false + - configMapRef: + name: M + optional: false + prefix: vUvV7W8k0 + secretRef: + name: IA + image: T4SYV + imagePullPolicy: Ƈ祃ǗǤɈ遖竀壙/ + livenessProbe: + failureThreshold: 20929095 + grpc: + port: -1775507003 + service: UZ6BT7NDI + httpGet: + host: QFkZxI6kA + path: tzQ + port: "" + scheme: Ƞ揞á惗É莏6XȪ/ʡ忨償 + initialDelaySeconds: 1046895310 + periodSeconds: -1971173139 + successThreshold: -476756841 + terminationGracePeriodSeconds: 144861231583008737 + timeoutSeconds: 814968592 + name: gEB + ports: + - containerPort: 2060914354 + hostIP: 9IXWKx38q5 + hostPort: -1191426039 + name: 5Mw7k + protocol: 悛ķ鳉ɍ恽j頔Œ6Eʮnx + resources: {} + restartPolicy: 樦ýȃ梪ĵ + stdin: true + stdinOnce: true + terminationMessagePath: c0e +fullnameOverride: 6maz +image: + registry: PYDGV + repository: HV3 + tag: cI8TzaYkws +ingress: + className: JpoCC + hosts: + - host: mE + paths: + - path: znvL + pathType: u4c1 +livenessProbe: + exec: + command: + - 1aqSw0 + - A277oB + failureThreshold: 713465020 + grpc: + port: 1803086428 + service: h1wwv + initialDelaySeconds: 1849009003 + periodSeconds: 2079209425 + successThreshold: 1679782943 + terminationGracePeriodSeconds: 4331994492414219168 + timeoutSeconds: 2000039211 +nameOverride: SC +podAnnotations: + JYLUc483y: gTnWiG +podSecurityContext: + fsGroup: -1425599568169885252 + fsGroupChangePolicy: ƶ Ÿ恢 + runAsGroup: -8737472966684836915 + supplementalGroups: + - 809809813702093180 + - 6124706841582844730 + - 6159358527003037747 +priorityClassName: XtKq +replicaCount: 331 +securityContext: + allowPrivilegeEscalation: false + procMount: 垮Ř2 + readOnlyRootFilesystem: true + runAsGroup: 5797501600954334245 + runAsUser: -8444673787636983397 +serviceAccount: + automountServiceAccountToken: true + name: DdF7ALq +strategy: + rollingUpdate: {} + type: ŀ剭º(;ƍ4兖ȇ +tests: {} +topologySpreadConstraints: +- labelSelector: {} + maxSkew: 972537130 + minDomains: -499606767 + topologyKey: q5 + whenUnsatisfiable: 鳯°ôŕƨʪuɘ"h貇榧0?cɉjA蜝 +- labelSelector: + matchExpressions: + - key: lAV + operator: 嵖xߟ擱ʄ衯"xɂ + - key: U6 + operator: =换J+Ř:嫚ʥ畠餐ǒŃ + values: + - Vj + - snF6cyZ + - 0sW9y4T5 + matchLabelKeys: + - 2wCjBs + maxSkew: -324080521 + minDomains: 695322418 + nodeAffinityPolicy: ʖ[兘Ũ鬎盦İƲ + topologyKey: z5y4Q8jyHH + whenUnsatisfiable: =Y~É.J樢ȃŤƫ甶Ȍ* +- labelSelector: {} + maxSkew: -1720129802 + minDomains: 1017048856 + nodeTaintsPolicy: 龨9猶e僦ɻ髧Ȍc + topologyKey: qKf6Ef3o + whenUnsatisfiable: ʂ?$鳴寘ŧ6脹餗ſ媷,峇埽 +-- case-017 -- +annotations: + J5Z: aLYd149 + LCqYvOjK: Qsk + bU: "" +automountServiceAccountToken: false +autoscaling: + enabled: false + maxReplicas: 164 + minReplicas: 101 + targetCPUUtilizationPercentage: 355 + targetMemoryUtilizationPercentage: 310 +console: + roles: + - JlwOk: null + QUzHpm: null + ch3WnNF: null + - {} + - null +extraContainers: +- args: + - Bd + command: + - QwtEp + - lLi7 + - kxB1 + image: RpMWaJ + imagePullPolicy: ~崆Ǭe侊k + livenessProbe: + exec: {} + failureThreshold: -2101638962 + grpc: + port: -208999597 + service: jICxjA + initialDelaySeconds: 925230214 + periodSeconds: -996383814 + successThreshold: 152844544 + terminationGracePeriodSeconds: -7802949917649733275 + timeoutSeconds: -188255799 + name: qwOkQZ + ports: + - containerPort: -255758148 + hostIP: R + hostPort: 316791912 + name: 09i3b5oQR + protocol: 腴醗9-鐶 + - containerPort: 247145105 + hostIP: L4 + hostPort: 1727912240 + name: bz7Y1N7 + protocol: 暄璎 + readinessProbe: + exec: + command: + - 2fQQ + failureThreshold: -873648342 + grpc: + port: 889903834 + service: C3 + httpGet: + host: IPHal + path: 5Nb6iW9 + port: tkqo + scheme: m说Ď盐2Ƹ,约h鰥Ȕť3 + initialDelaySeconds: 1391319902 + periodSeconds: -1638942635 + successThreshold: 644454270 + timeoutSeconds: -553602240 + resources: + requests: + 0XxId: "0" + VsY2R9: "0" + ZLtS2: "0" + restartPolicy: ų蓶Lj,g珯i'Sû竒 + terminationMessagePath: Mx7V + terminationMessagePolicy: =Jƈ乚貃庪ș¯ÑVȯ6筌巨华ɀ(v + tty: true + workingDir: nKFDPLJvOh +- args: + - AV3kjV + - Gwq78lY2 + - wq + command: + - D + - EI + - fY5J + env: + - name: eCtpNU + value: jLkcq8S + - name: rynLbx + value: CdqgJabHhM + valueFrom: + configMapKeyRef: + key: uBUH5 + name: Uxei4G1 + optional: false + fieldRef: + apiVersion: Ul9al + fieldPath: vtGid + resourceFieldRef: + containerName: Oc + divisor: "0" + resource: "" + - name: GmDNpa0 + value: 7VJM2XsPm8N + valueFrom: + configMapKeyRef: + key: x3J0PMWE + resourceFieldRef: + containerName: x9Q + divisor: "0" + resource: EKFgoq + secretKeyRef: + key: lOZRvK9 + name: V + image: 1xn6 + imagePullPolicy: ɀ稤¼Mɻ«鐾6Ú{ŬtŮ鄖SSɌ戲 + lifecycle: + postStart: + exec: {} + httpGet: + host: sT2dWyT + path: vvbIxNVANZ + port: aCK8 + scheme: 昿孊卿昤軒JYƜÁ嶠şe灶 + sleep: + seconds: -3542823673709563150 + preStop: + exec: + command: + - "N" + - qkHmJ + - HupYy + httpGet: + host: 137dx + path: y3u7HE + port: -1357399425 + scheme: '@济ɉ鳛讧跕(#7NJɓũǸ]ɨ梊sj' + sleep: + seconds: -2408406850575106311 + name: J6VFtJd3giFt + resources: + requests: + 3dqK0M: "0" + restartPolicy: 70ʆ氶応爱怙鉉塼tƗhY嚇 + securityContext: + allowPrivilegeEscalation: false + capabilities: {} + privileged: false + procMount: ȚƼ提瀴t8oƥc + startupProbe: + exec: {} + failureThreshold: 1782005431 + grpc: + port: 676289916 + service: 3xqeCsf + httpGet: + host: YDL1TP + path: "8" + port: lLWR + scheme: BKō筹 + initialDelaySeconds: 134613881 + periodSeconds: 1547524591 + successThreshold: 1778605907 + terminationGracePeriodSeconds: -7593859121613942317 + timeoutSeconds: 2026260743 + terminationMessagePath: E + terminationMessagePolicy: 碓 + workingDir: kl +- command: + - "" + env: + - name: TG1HQA + value: 5X + valueFrom: + fieldRef: + apiVersion: Vhn + fieldPath: jluMkQnv9 + resourceFieldRef: + containerName: rLfbH + divisor: "0" + resource: "" + - name: "" + value: TOTyqqGn + valueFrom: + fieldRef: + apiVersion: 0CAdSa + fieldPath: LWMRC + resourceFieldRef: + divisor: "0" + resource: G5eZP4R + secretKeyRef: + key: xYOgJL + name: vMTywG + image: 2Z + imagePullPolicy: z.鎸ƦʖFNj棪Ƃ鯌b抵#Dzr + lifecycle: + postStart: + exec: {} + httpGet: + host: k8z + path: TxNa2e + port: -573570086 + scheme: oɌdǹ[M灙螮伪芛探塢庖Njȕ仸 + sleep: + seconds: 4118046687980193779 + preStop: + exec: + command: + - 6iZbF + - OeZTW + httpGet: + host: rbqq + path: sno + port: -429531729 + scheme: s璙Ȼȗ榛ǵ0ƿ.忋闳溨 + name: Cms + ports: + - containerPort: -211101225 + hostIP: 8v + hostPort: 1994344080 + name: kyMvksZa + protocol: fȞ蚊悘ū錩Ȩ龒ċŴ + - containerPort: -806313867 + hostIP: Ky2F2 + hostPort: 1605736520 + name: oe0nMMl + protocol: 慿)"Ǒ3浹襈}(VE-B³閪叒k1绝 + readinessProbe: + exec: {} + failureThreshold: 1398486074 + grpc: + port: 1157090744 + service: oFrTS0 + httpGet: + host: 5pfrE + port: TJb4 + scheme: 畢î + initialDelaySeconds: -1830121652 + periodSeconds: -1398007905 + successThreshold: 1183454316 + timeoutSeconds: 1797763090 + resizePolicy: + - resourceName: hzxTj + restartPolicy: 渣箢樳掯ȉÏǼ店喘©g + resources: + limits: + zGvF9poISMtK: "0" + requests: + lUp3T: "0" + restartPolicy: '}賩6''V霟足''È''*F÷ƙǕ' + stdin: true + terminationMessagePath: 4tn + terminationMessagePolicy: ɢ荵鯴庡ǁ婛埽猜犝笖á7譃ǁ¦GɖC + volumeDevices: + - devicePath: eGfD9B + name: G3Bd + - devicePath: x + name: TB + workingDir: iKksE1 +extraEnv: +- name: Z + value: 1PasJFATvz + valueFrom: + configMapKeyRef: + key: Out + name: Z +- name: pUN + value: QTGN + valueFrom: + configMapKeyRef: + key: BLzs5FKV + name: xsgY3vBvZ + optional: true + fieldRef: + apiVersion: 5Ng + fieldPath: Psowh + resourceFieldRef: + containerName: pMz + divisor: "0" + resource: "" + secretKeyRef: + key: IY9s0 + optional: false +extraEnvFrom: +- prefix: oK16T1 +- configMapRef: + name: GxM9 + optional: false + prefix: Hj8 + secretRef: + name: o5P67 +fullnameOverride: 9XG3SZW +image: + pullPolicy: k痿蹒 + registry: 3s + repository: kPWhaC + tag: BcBi +ingress: + className: N91gS + hosts: + - host: ucSBH + - host: "" + - host: tmOhOR +nameOverride: tPiY +podLabels: + LBQpbD: AHB4hNVL + ey1GpAHh: fA +priorityClassName: qcIlT +readinessProbe: + exec: {} + failureThreshold: 738983906 + grpc: + port: 832752600 + service: 3tLbx + initialDelaySeconds: -1729478206 + periodSeconds: 902558671 + successThreshold: 989047880 + timeoutSeconds: -402268186 +replicaCount: 173 +resources: + limits: + 0fvc8: "0" + W19cC: "0" + loZ4: "0" +secret: + create: true + enterprise: + licenseSecretRef: + key: cjqTR + name: e + login: + github: + clientSecret: jw6tY22 + personalAccessToken: JvG1jx + jwtSecret: DwgaGI + oidc: + clientSecret: MalR2 + okta: + clientSecret: mDILgPMjOS9 + directoryApiToken: M2ywAiP +secretMounts: +- defaultMode: 442 + name: 3SwG7HrS + path: TLaWLIiD + secretName: VR +- defaultMode: 383 + name: Bfv9SGjlbgN + path: dXXPfK + secretName: T +- defaultMode: 13 + name: wz4K9oIYM + path: YEOA49 + secretName: WzM +securityContext: + capabilities: + add: + - "" + - 鸼ǀɛ_Y + - 利ƯǢ謼Ŀʇ佔4銣 + privileged: false + procMount: 頿ū詁ǎTɁ¯PlFd只鶗ƝǛƤ臃 + readOnlyRootFilesystem: true + runAsNonRoot: true +tests: + enabled: false +tolerations: +- effect: 懻 + key: JifsKW + operator: 檧űÊǮȡ廄儱RəȏĮ顪ÅÞ + tolerationSeconds: 4501363800484543116 + value: KkCBzwToBMjJ +- effect: B囧ƉOß + key: Q3cj + operator: ɲ朁ß栢 + tolerationSeconds: 4944598504260379086 + value: Z5 +- effect: 敘愰ɰuƪ晐 + key: K8wM + operator: ș + tolerationSeconds: 8375376960471889043 + value: TnWS +-- case-018 -- +affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: {} + weight: -37659402 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: [] + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + matchLabelKeys: + - ajbCE + - Y0MRgpE8 + namespaceSelector: + matchExpressions: + - key: Auai + operator: ùfƽÜQķɨ逑ʒÅģ + values: + - Q + - key: 1S2Nfq + operator: 臺瑷tƎ鍤p}滳`竦ÙǾ晖ǃʏȵ + namespaces: + - 4GTSAZF + topologyKey: NS733 + weight: -968286112 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: eyt3TPSYPBWDt + operator: e偁&蔄癳.ŚƘ + matchLabelKeys: + - eE7PA8D + - cKalkvb + mismatchLabelKeys: + - Lan + topologyKey: v + weight: -2133598054 + - podAffinityTerm: + mismatchLabelKeys: + - "5" + namespaceSelector: + matchExpressions: + - key: UrrD + operator: ƞ + - key: rkfCsnUcx + operator: ȇ睾¦棌鉝-m糤LPjX.;Ğ× + - key: kla + operator: '"竮壣祠ł9抵墙' + namespaces: + - gyF + topologyKey: ZG + weight: -428742233 + requiredDuringSchedulingIgnoredDuringExecution: + - matchLabelKeys: + - tZZj + namespaces: + - VuG + - I5XU + topologyKey: V2CZqa + - labelSelector: {} + mismatchLabelKeys: + - "" + - q9L4 + - C4YJ57 + namespaces: + - 8xRk06ngy + - WeZO2 + - 7tbTFK + topologyKey: rnpto +annotations: + "": 3E5rtKA +automountServiceAccountToken: false +autoscaling: + maxReplicas: 140 + minReplicas: 91 + targetCPUUtilizationPercentage: 499 + targetMemoryUtilizationPercentage: 324 +configmap: + create: false +console: + roleBindings: + - "": null + DlOD: null + - null + - cDJiV: null + eO: null + qlokva4: null + roles: + - 0E2l1K3: null + pIu5qwn: null +enterprise: + licenseSecretRef: + key: oqyc + name: HL +extraContainers: +- envFrom: + - prefix: EVZ + secretRef: + name: MxD + optional: true + - configMapRef: + name: A + optional: false + prefix: HuqxI + secretRef: + name: A + optional: true + image: SU + imagePullPolicy: 禵7璙p + lifecycle: + postStart: + httpGet: + host: YZMjhOUO8IS + path: nzYfH + port: Fcx + scheme: 矪Q9 + sleep: + seconds: 3463625415546708077 + livenessProbe: + failureThreshold: -560403806 + grpc: + port: 1751268094 + service: I + httpGet: + host: 0Sb + path: Utm2X + port: 395973041 + scheme: 醆蚎忨ŕ縨ƍ爋釬šÒ暺ƒŎO記岣 + initialDelaySeconds: -1011110535 + periodSeconds: -1229381750 + successThreshold: 260149510 + timeoutSeconds: 74546945 + name: e + resizePolicy: + - resourceName: XNKV + restartPolicy: ì焹.¬哄ȾŢȎȴe$p尶m`飻Ȭ + - resourceName: "" + restartPolicy: 閭I哗.寢荨ʪɛ侭ȵ(8 + resources: + requests: + 3nUsL: "0" + securityContext: + allowPrivilegeEscalation: false + privileged: false + readOnlyRootFilesystem: false + runAsGroup: -8616852535795885155 + terminationMessagePath: FjZ + terminationMessagePolicy: ÿb熿3,ćp寫ʃ#叺渍ƣș + volumeDevices: + - devicePath: Xvjm + name: 7yLA + - devicePath: 1Ci + name: Y0AloAQS + - devicePath: Gt + name: ZMKKc + workingDir: Mh +extraEnvFrom: +- prefix: hg + secretRef: + name: eLM59WyoAXO +fullnameOverride: ExFU3 +image: + pullPolicy: 螣暛擂ɾ#鏲*胭8饭1胠 + registry: iCFSIwyDtoG + repository: 6V6 + tag: 6uR +imagePullSecrets: +- name: vlnGQbo3y +nameOverride: 1qyLP36T +nodeSelector: + Vckw: ifBZ9p7 +priorityClassName: 6jxv +replicaCount: 297 +resources: + limits: + QZqMxIAt: "0" + SUsu9: "0" + requests: + EMOXCuje: "0" + EzKKMIR: "0" +secret: + kafka: + awsMskIamSecretKey: 8GlUc + protobufGitBasicAuthPassword: IsvQ9 + saslPassword: Vb + schemaRegistryPassword: UJ7Zl + schemaRegistryTlsCa: T1Q + schemaRegistryTlsCert: 17r + schemaRegistryTlsKey: O44 + tlsCa: n8k9 + tlsCert: aK + tlsPassphrase: Qk8 + login: + github: + clientSecret: t6z0n + personalAccessToken: "" + google: + clientSecret: h + groupsServiceAccount: fpuCEFLL + jwtSecret: 7J + oidc: + clientSecret: t + okta: + clientSecret: 3CcKl + directoryApiToken: AZt8H77 + redpanda: + adminApi: + password: NUkb3zIpwAR + tlsCa: t + tlsCert: zttTAvj + tlsKey: "" +service: + nodePort: 270 + port: 415 + targetPort: 489 + type: 2cM +serviceAccount: + annotations: + X7E: CRSzr + lPi: bGP + name: uAvlOXf +strategy: + rollingUpdate: {} + type: ɬ搢.Ƒ躂ɻɅȄ莨qc婔Åå +tolerations: +- effect: č喅Ȳ崥ï{禙ÊÿC逻準?霘2 + key: YJE + operator: 珟 + tolerationSeconds: 3838637075734495592 + value: 1VemeDTEk1 +- effect: 艋Ƿ淛襀|Ǽ&矠Ģ凍J賜ɰō + key: ggxS8L + operator: 閞判ŏ + tolerationSeconds: -2249155605077506227 + value: m3c +- effect: 'Ljə]IŴ:' + key: 4BkJSo + value: Le +topologySpreadConstraints: +- matchLabelKeys: + - uyTA + - rJcqdY3 + maxSkew: 1887613958 + nodeAffinityPolicy: u鞝侠轁蛃6Ơfrt迄ʇQ勭ĶÇǻě + topologyKey: 3f9j + whenUnsatisfiable: µ +-- case-019 -- +annotations: + lgiIA: u + wK8: JrSfKH +automountServiceAccountToken: true +configmap: + create: true +console: {} +enterprise: + licenseSecretRef: + key: Nr8uSKR + name: nucerZE +extraEnv: +- name: pJ + value: whmTukCTD + valueFrom: + configMapKeyRef: + key: OHk + name: "3" + fieldRef: + apiVersion: TSp7 + fieldPath: mEUVMSp7vUo + resourceFieldRef: + containerName: bBDw + divisor: "0" + resource: tIcs3z + secretKeyRef: + key: jIR5V + name: "9" +- name: ZCEPmHP + value: FhwE4R + valueFrom: + fieldRef: + apiVersion: Nv + fieldPath: WMXeIjk + resourceFieldRef: + containerName: Hbt + divisor: "0" + resource: mo7F +extraVolumeMounts: +- mountPath: UF6 + mountPropagation: ĻsŸ氂ǐ钋鮠Ĺ咳渼.pɫ + name: W1LIZa3 + subPath: qdDtjk + subPathExpr: Ew +fullnameOverride: NZ7h9 +image: + pullPolicy: 韃ĝ + registry: GNXgFQ + repository: W3 + tag: 2vPed +initContainers: + extraInitContainers: "" +livenessProbe: + exec: + command: + - Vc01z + failureThreshold: -1736131786 + initialDelaySeconds: 538755540 + periodSeconds: -937262167 + successThreshold: 2014961170 + timeoutSeconds: -614674118 +nameOverride: 8MIg +priorityClassName: FERw +readinessProbe: + exec: + command: + - 96w + failureThreshold: -1936056692 + grpc: + port: 939760843 + service: "" + httpGet: + host: K + path: dIrFM + port: GfrdWiqgUZBPW + scheme: 芧ʒȔ堌 + initialDelaySeconds: -2019126091 + periodSeconds: -1696700553 + successThreshold: 398361977 + timeoutSeconds: -184667912 +replicaCount: 79 +securityContext: + allowPrivilegeEscalation: true + capabilities: + drop: + - 狞濮噞饅烥H}湛m=U+卓Ǭï呣8Ú + privileged: true + runAsUser: -471077223001866506 +strategy: + type: 鎦v財ɕŪ +tests: {} +tolerations: +- effect: 飝壊%ǂP胅ɂǏ趸疷擁鹒DŽ营風顺z拇 + key: Ku2m + operator: ŲǪFTǗǔȟʥȰȎǎo玼Ü + value: 1u +- effect: 雾Ź歘ɇƇ昨OČƑɎ騨Ŗ=Ì楯 + key: 12vKa + operator: ( + value: u +-- case-020 -- +affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - {} + - matchExpressions: + - key: a23jbG + operator: yb庇ɍ闒ǰPâƟVsJu + values: + - "" + - 1lQmmGa8 + - XzVleDXV4YoRc + - key: 3Gwd9r + operator: 4Nj7Ġ$Ea狆Ö絞Ƙ殈廔as知 + - key: 7C4FjM + operator: ɩ.叧¬ʧ倒 + matchFields: + - key: H + operator: Ğų* + values: + - 0i + - qK + - key: 7ocDt + operator: 餯ǚ璗汭槰<ƤƐ評ź膹棅珢ȹ3鮑 + values: + - g5Aa1Hm + - LKNvXrtO + - key: o + operator: ŎJ甧鷓 + values: + - vJQQjLRrqIK + - Isj + - 6EBsy + - matchFields: + - key: H0oh1dBCg + operator: 鉔qƿ氵[' + initialDelaySeconds: 1994767434 + periodSeconds: 1832245274 + successThreshold: 598112607 + timeoutSeconds: 1119900418 + name: "" + ports: + - containerPort: -330026000 + hostIP: lrMGYnI5Nd + hostPort: -823142941 + name: zuZWb + protocol: Ȳ + resources: + requests: + 4gK: "0" + restartPolicy: 腼癋ğÑ;漘傩鶷 + securityContext: + privileged: true + procMount: ʍ/O9*:zb飯Gɱ朵醴#ŌKp9嬡 + readOnlyRootFilesystem: true + runAsNonRoot: false + startupProbe: + exec: + command: + - "4" + failureThreshold: -950017148 + grpc: + port: -1475121627 + service: 8veUJnWU5 + initialDelaySeconds: 2007069941 + periodSeconds: -1193308189 + successThreshold: 22288729 + timeoutSeconds: -1492112511 + stdin: true + terminationMessagePath: HIj0kQ + terminationMessagePolicy: ȔNj + volumeDevices: + - devicePath: M + name: sDeN + workingDir: V +- args: + - "" + - ihLoishU + command: + - 8Jx + - j + env: + - name: IDOQ6d + value: 12G + image: b4Wv84l + imagePullPolicy: n暨e懔)k + lifecycle: + postStart: + exec: {} + httpGet: + host: Zl2z + path: pzUIO + port: faRx + scheme: 痣甘 + sleep: + seconds: -632399399483384435 + preStop: + exec: {} + httpGet: + host: pklCf2clqD + path: wk27n2gw1L + port: Ufz19 + scheme: ɷņƑG m刡Ęj敂鏸eāa + livenessProbe: + exec: + command: + - Ar2msVeG + - Uzq6cRL + - dujaQs + failureThreshold: -1776611485 + grpc: + port: 835455646 + service: t + httpGet: + host: hri + path: "Y" + port: 1115673796 + scheme: ʟɏķLYÆŨŔ+Č`4Đl + initialDelaySeconds: -739643640 + periodSeconds: -343509466 + successThreshold: -1698086578 + terminationGracePeriodSeconds: 1800922741783400611 + timeoutSeconds: 1182031959 + name: Bq5FHOsB11r + readinessProbe: + exec: + command: + - XaJ8ft + - 57jh + - sAD + failureThreshold: -1798651306 + grpc: + port: -1714447694 + service: ETY + httpGet: + host: V5DSH + path: g8Ygrn + port: Yp9d22 + initialDelaySeconds: 1612392972 + periodSeconds: 1418157100 + successThreshold: -1106593780 + timeoutSeconds: -1970400805 + resizePolicy: + - resourceName: 93At9v + restartPolicy: 涭ɍƍ蕂 + resources: + limits: + 9g69: "0" + h20A4o: "0" + jh: "0" + requests: + h: "0" + ub364wL: "0" + restartPolicy: Ǎ\ƽţ(鄑鴋Őńy餲ÍwWÅ + startupProbe: + failureThreshold: -513807271 + grpc: + port: -788679788 + service: 3vt1qVexq + httpGet: + host: As + path: gG3Jyf6fQ5R + port: 1058443669 + scheme: I?ʐɡ湚犭檚蚗į*o + initialDelaySeconds: 2034517113 + periodSeconds: 2103822699 + successThreshold: 343263788 + timeoutSeconds: 264518020 + stdin: true + stdinOnce: true + terminationMessagePath: AAYYpB1c + terminationMessagePolicy: 贌.[ĉ熶7dzRVç^'谣蔨d搇ĺÎ + tty: true + volumeDevices: + - devicePath: "8" + name: KZo0u22qdit + - devicePath: Fahm + name: lmO + workingDir: tGNhx3deFLdC +extraEnvFrom: +- prefix: 7DB9SS + secretRef: + name: 5rl + optional: true +- configMapRef: {} + prefix: hPVGtWNNR +- configMapRef: + name: FYMIJ1 + prefix: TEtFB3 +extraVolumes: +- name: 2LSr +- name: J +fullnameOverride: Wpq +image: + pullPolicy: M鉃裹Ú&蚑ƈñĎdzɢ/Ɲ9Ws棝 + registry: 0aw5q + repository: PTy + tag: fclX4 +imagePullSecrets: +- name: p95GzFm3JP +ingress: + annotations: + aH: YQ3 + className: IPc + tls: + - secretName: Ec4sB + - secretName: txdIkdw4sg8IB4i9 + - hosts: + - ypg9XtRg8 + - "3" + secretName: DNdM +livenessProbe: + exec: {} + failureThreshold: 913752382 + grpc: + port: 1322195744 + service: iQNfI + initialDelaySeconds: -1439870739 + periodSeconds: 178258715 + successThreshold: -1591263857 + terminationGracePeriodSeconds: 2751522374216629585 + timeoutSeconds: -1117637199 +nameOverride: aD +nodeSelector: + WUADh: 2ruBNaWxT +podLabels: + Avs0UCvd6: "" + LSaZFj: "" + N3gEYOpkd: zqsd +priorityClassName: 2v89v +readinessProbe: + failureThreshold: 1842275861 + grpc: + port: -1389426650 + service: 0bSW249 + httpGet: + host: 0T + path: RnP5zy + port: -514153800 + scheme: k*x"!掫瘑Ʀ扄]Ĝʅƭȑ + initialDelaySeconds: -1077422490 + periodSeconds: 666536934 + successThreshold: 1405066396 + terminationGracePeriodSeconds: -3980601911100433183 + timeoutSeconds: 665413705 +replicaCount: 330 +secret: + create: false + kafka: + awsMskIamSecretKey: 48EJ + protobufGitBasicAuthPassword: U4TfI + saslPassword: xbKdWIc + schemaRegistryPassword: C + schemaRegistryTlsCa: vACi + schemaRegistryTlsCert: l2SQ + schemaRegistryTlsKey: QXTWL2 + tlsCa: sxqA + tlsCert: MZR + tlsPassphrase: Bf18k +secretMounts: +- defaultMode: 278 + name: Vk + path: HIDtODq + secretName: ycVDxFmgC +service: + nodePort: 413 + port: 310 + targetPort: 265 + type: uvupqC6hE4 +strategy: + rollingUpdate: {} + type: ü +tests: {} +tolerations: +- effect: ƛ=åM綁塈'Ʈ7 + key: X + operator: Y葞ęŊ6ùųŗQ膼芏棔ĿF綩 + tolerationSeconds: -7958891124471630696 + value: iw +-- case-025 -- +affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - {} + - matchFields: + - key: Jdk + operator: '''妋ū摺wȋ½骭枰ux' + values: + - L3vrBo + - key: AJyvPdo + operator: QBǏ揅饹\欤ĩ# + values: + - KA4X87 + - kAynjW + - key: INtaCgB9Suw + operator: '"' + values: + - sT5QAUbIK + - matchExpressions: + - key: B1ivFyT + operator: ıD芌ʪÌʡ6坨LʞQ蓠kl + values: + - ZM3ncD + - MaDZJN23 + - nQDH + - key: j1 + operator: ^{Q唤涭 + - key: FMwYRC4 + operator: 構ÁHƲ)ǹō + values: + - tc + - 5w4tJ + - gNCNm5J4 + matchFields: + - key: pIsVqr + operator: j@RUȃfǘ·ɏ!Ǖ灃Ņǟ + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + matchLabelKeys: + - oNBV + - ZW2Upd + mismatchLabelKeys: + - XpmujYp + - zQUvv + - o + namespaces: + - xAojOZ + - 53d1p + topologyKey: wupaWwF + weight: -813250565 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: hRMf + operator: 璢ɂo豢埆o + - key: gByq + operator: '|藐Ç钃[qȂřÜ{南湹裻ßŗyŪ赉' + mismatchLabelKeys: + - 4aBT9oEi8 + topologyKey: "" + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - matchLabelKeys: + - qDyyFpFgn0 + - qAR2Fz8Jbiq9oz + namespaceSelector: {} + namespaces: + - NKeVvij2 + topologyKey: 7OPEY5MMS +annotations: + 7YN: WjRdnTY + J0Eg: alDk +automountServiceAccountToken: false +configmap: + create: false +console: + roles: + - BU: null + - {} +deployment: {} +enterprise: + licenseSecretRef: + key: 3UhYW + name: Ooxn6uesqBg8 +extraContainers: +- args: + - zj + - Z5D + command: + - QfnH4gn + - B1xl + env: + - name: 4X + value: Bw + valueFrom: + configMapKeyRef: + key: Pdqw0Fl3V + name: v3KgbGdzsLvC + optional: true + fieldRef: + apiVersion: NUZjeNE + fieldPath: 9HRTR + resourceFieldRef: + containerName: p + divisor: "0" + resource: shkxnjmC2 + - name: 2i + value: Zxb + valueFrom: + configMapKeyRef: + key: w + name: WzK6UiO + fieldRef: + apiVersion: GnFqZ3 + fieldPath: W + resourceFieldRef: + containerName: 7JDYpnHIpM + divisor: "0" + resource: vt2RbP + secretKeyRef: + key: yl + name: 36xB2Q + optional: true + envFrom: + - configMapRef: + name: V2xmAgfwBn1 + optional: true + prefix: seW + secretRef: + name: Nt + optional: true + - configMapRef: + name: IluKDPq + prefix: N6Uhe + secretRef: + name: TvN6Z3p + image: 3fh + imagePullPolicy: Ǜmʥ薑ōB愌熹g樿ƒ畬ʙ襫,PD + lifecycle: + postStart: + exec: + command: + - wIfuPiat + sleep: + seconds: 6128979882442257912 + name: 0U + ports: + - containerPort: -975012330 + hostIP: nNpK2 + hostPort: -554886438 + name: aE + - containerPort: -2098096147 + hostIP: FeG8 + hostPort: -651932845 + name: xKI1Tv + protocol: :鿅Ǐ!Ʋ卫_ʕȼʗ壷薮蒰NJŌ + - containerPort: 520035268 + hostIP: GyA + hostPort: -1998834660 + name: PR61 + protocol: ŗ蜥aɝWCb锨ȐsO忷ODž)Ŗʃ觃輘 + readinessProbe: + failureThreshold: 1975710195 + grpc: + port: 8949492 + service: USXa + httpGet: + host: 6J2Mk51 + path: FL4SJXOTR + port: c2vVT + scheme: B哰Hȼ涪Ÿȣę + initialDelaySeconds: 1164971701 + periodSeconds: -1267122769 + successThreshold: -102609571 + terminationGracePeriodSeconds: 6799552209277780019 + timeoutSeconds: -995107635 + resources: + requests: + 2j: "0" + restartPolicy: V牜(p + securityContext: + allowPrivilegeEscalation: true + privileged: false + procMount: '@' + readOnlyRootFilesystem: true + runAsGroup: 8605999305673537166 + runAsUser: 1347603438902927360 + startupProbe: + exec: + command: + - JZX + failureThreshold: 1080874840 + grpc: + port: 1467429214 + service: NWBu1S + httpGet: + host: 4ta7S + path: RcBu6 + port: RapJB5x + scheme: ']襰騊缜ă4蘆Ȓ0礓厨獸枓8D' + initialDelaySeconds: -2008822207 + periodSeconds: -614674587 + successThreshold: -402818223 + terminationGracePeriodSeconds: -7949916801988602426 + timeoutSeconds: 209096121 + stdin: true + stdinOnce: true + terminationMessagePath: KRYz + terminationMessagePolicy: Âǚ凍ʄĒ(#Ñ狶8脍ÅdɅș妙觶.祍 + volumeMounts: + - mountPath: LdSrOQ + mountPropagation: Ɗ?ǚ[澆槱ɢ丗7鍚6A + name: sqOobya + subPath: JZEkD + subPathExpr: eJU + - mountPath: K4kwb + mountPropagation: "" + name: YNNb + readOnly: true + subPath: Z0mne + subPathExpr: ngxE + - mountPath: E2GSzT0 + mountPropagation: ȝ註鴔 + name: fRhgta + subPath: y6Y3BdtA + subPathExpr: P0gcNQL + workingDir: rCAtq +- args: + - tJjzGKfki2 + - "" + - furHsPXM1J + command: + - DK3Wlo2n + env: + - name: ud + value: FOyG7u4mv + - name: YM + value: T8mzKDDU + valueFrom: + configMapKeyRef: + key: "" + name: YlrM + optional: true + fieldRef: + apiVersion: TysS9Olq + fieldPath: RX4 + resourceFieldRef: + containerName: o + divisor: "0" + resource: HVzew + secretKeyRef: + key: moOz + name: 9IePG + optional: true + image: hy6X7dY + imagePullPolicy: 秊q魷讍暳ɁiitǦ梒Ʀ疗ǘt + lifecycle: + postStart: + exec: {} + httpGet: + host: 1bv + path: 3IXIEBTRQc + port: dHTyBrOPT + scheme: hƉǤ\ɯ竔}gŘ + sleep: + seconds: 3802753693240438477 + name: mieVkOhQ4 + ports: + - containerPort: 1406294206 + hostIP: XrMHc + hostPort: 1756733537 + name: xrlM3Cv9 + protocol: ^箅瑦|ȭ,Ī憘ʓ焯 + - containerPort: 1867162726 + hostIP: p8Zguos + hostPort: 1052086554 + name: NCa4 + protocol: Ǽ丝等I塸)kɹ~颁!跼S薒SrM + - containerPort: 1770363328 + hostIP: WPUeJ + hostPort: -1882733223 + name: gAUfp + protocol: u舨[ķ獚m灑朷ƶ慹Ʀ + resources: + requests: + CK: "0" + c6WG16NOR: "0" + restartPolicy: 欣ƎȄŚ&廚FË倔Ŋ寬Lw秮x捨 + securityContext: + allowPrivilegeEscalation: false + capabilities: + add: + - Ƶəʣ饅ōǧ营Sȑ粴ƞȜj嬷俋箊ʫ + - Yǻ)Iƕƺ:檂躡J勬垒ď%ɦ + drop: + - f{2Ƭɢ~lĕ猆å~? + - 曣晜Ȅ笛 + - 牧 =鄅銣閦ʜ(lȏ + privileged: true + procMount: Âȼ + readOnlyRootFilesystem: true + runAsGroup: -5895892166477051871 + runAsNonRoot: false + startupProbe: + exec: {} + failureThreshold: 1512924080 + grpc: + port: -55537357 + service: 9KQ + initialDelaySeconds: 1472203720 + periodSeconds: 1367361112 + successThreshold: -1486557603 + terminationGracePeriodSeconds: 2382050275815801400 + timeoutSeconds: 246291848 + stdin: true + terminationMessagePath: E7wMC + terminationMessagePolicy: h僊冢ʐȑ + volumeMounts: + - mountPath: "" + mountPropagation: uÞ揶椬=L>ȕ凭Śȅ3džȿȳ + name: xYM + subPath: nMMkHAUoYIsN + subPathExpr: 579Yn2LXk + - mountPath: 5z + mountPropagation: Ƀ陪7k惿Ɏǚ霤ƨƱ«ɤ»ȣ薥頠媉fʠ + name: KIX5g + readOnly: true + subPath: CGOswgk + subPathExpr: oxiB23ZW2KX + workingDir: IzOAr +- args: + - jrZTvs + env: + - name: jxl5Q + value: fm2F7DzZA + image: r7sTpTP8N + imagePullPolicy: 眒弿 + lifecycle: + preStop: + httpGet: + host: WEBUk + path: "1" + port: -377365982 + scheme: 娖阋顿|儴Éȱ鋦 + livenessProbe: + exec: + command: + - 2j + failureThreshold: -1631622345 + grpc: + port: -188887701 + service: s + httpGet: + host: "6" + path: 07rm4AD + port: DCtZ5 + scheme: ʼnK襡5殛鯙ȋʛ稲(C姓 + initialDelaySeconds: -1011676147 + periodSeconds: -1141844037 + successThreshold: -1528778970 + terminationGracePeriodSeconds: 422553046190448128 + timeoutSeconds: 99607263 + name: rhg + ports: + - containerPort: 1265703793 + hostIP: lYiq + hostPort: -931710582 + name: r2OdlKyZ + protocol: ŌK4Ʒ霖R婧,Ģ墤ʠ_Ƒ亽vĨO + - containerPort: -1093198499 + hostIP: xHuDhI2 + hostPort: 1423992590 + name: WdH + protocol: K嚜pn犓ɯ`劮ƫķPLm + resizePolicy: + - resourceName: M3EK5NW + restartPolicy: Ɲ囩 + resources: + limits: + 4zeCyo: "0" + PgUjG: "0" + requests: + IseC3: "0" + WHgRSz: "0" + yzZn: "0" + restartPolicy: ijƞ墫噌L诠=脳%Ɗ + securityContext: + privileged: false + readOnlyRootFilesystem: false + runAsGroup: -1074724161449891976 + runAsUser: 8255497511479977438 + startupProbe: + exec: {} + failureThreshold: -1172398717 + grpc: + port: 1919051215 + service: "" + initialDelaySeconds: 2020291403 + periodSeconds: 450860281 + successThreshold: 193397000 + timeoutSeconds: -665894379 + stdin: true + terminationMessagePath: MCVu + terminationMessagePolicy: ŷÍ:+壩ùI賎Rɜ卮cɣS惕mIɭ + tty: true + workingDir: 2L97y +extraEnvFrom: +- configMapRef: + name: Es + optional: false + prefix: sb4Y + secretRef: + name: 5boSPUJ +extraVolumeMounts: +- mountPath: "" + mountPropagation: ė1)ʩ瀚汋跁撯 + name: jFvwz + readOnly: true + subPath: JP5wgP3 + subPathExpr: J +extraVolumes: +- name: Jq0CSftnp +- name: QMHGzzYC2HW +- name: 1PkbzhfK +fullnameOverride: Uo +image: + registry: gFOwHIo + repository: tdq9GJrg + tag: J +imagePullSecrets: +- name: iA1C +- name: ZOdo +- name: qTOK0W +initContainers: + extraInitContainers: UHL +livenessProbe: + exec: {} + failureThreshold: 1473046311 + httpGet: + host: z + path: qQEf + port: -1047428780 + scheme: ȭ龙ğ疹ǜ"ȹȫ怆Ȉiʊ泹牫綖K + initialDelaySeconds: 272400025 + periodSeconds: -1682707125 + successThreshold: -2007433775 + terminationGracePeriodSeconds: 7823760182761119586 + timeoutSeconds: 2024118005 +nameOverride: Mh +podAnnotations: + bHXzf: nOiRsvEXH +podSecurityContext: + fsGroup: -6946946538076897241 + fsGroupChangePolicy: 呆ɔȂwijà + runAsGroup: 3944693697856007637 + runAsNonRoot: true + runAsUser: -732766343758518304 + supplementalGroups: + - -5691922089175975080 +priorityClassName: 0bGHQk7gL +readinessProbe: + exec: {} + failureThreshold: 1554150391 + grpc: + port: -2094102439 + service: 0dg5DO + initialDelaySeconds: -564389480 + periodSeconds: -266349500 + successThreshold: -428571163 + terminationGracePeriodSeconds: -4351299803972335390 + timeoutSeconds: 1803246595 +replicaCount: 345 +resources: + limits: + LxNMXlMD: "0" +secret: + create: false + enterprise: {} + kafka: + awsMskIamSecretKey: SDPuUt + protobufGitBasicAuthPassword: nq + saslPassword: TLAP + schemaRegistryPassword: AFn + schemaRegistryTlsCa: KbZhZV + schemaRegistryTlsCert: dGfweV + schemaRegistryTlsKey: X2B + tlsCa: Zmu + tlsCert: Lv4BgewmU + tlsPassphrase: bCygOn9yJR + redpanda: + adminApi: + password: AE + tlsCa: CEhIkvxe10u + tlsCert: mjaN + tlsKey: j2mDL +serviceAccount: + automountServiceAccountToken: true + name: H5TDAALUdD +tolerations: +- effect: 媄 + key: IQD9Yww8 + operator: bǾå鱍 + tolerationSeconds: -7454358062612206872 + value: odxS1Q2Sd +- effect: Ɣv璔}oȡʞ¤ + key: ySGX + operator: ƪ渺¸貗ȹV廋ȉňu増嬎Ë韍ǘz茩Ƹ怯 + tolerationSeconds: -1083807005557333468 + value: bAy +-- case-026 -- +affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: GP94 + operator: 駑Ŀ峇[ɕdž0 + values: + - jjNFKv8 + - uG7Rs + - ApO075 + weight: -549077137 + - preference: + matchExpressions: + - key: R88 + operator: Dzv)bôȏ磜覐橮波赘T^ + values: + - DscaGMdgXV + - uy + - N3d + - key: "" + operator: 誮Vw!/毴Z匌忶ª渆 + values: + - 4mX0s + - key: byy + operator: 鿟y馡錥HJ鶟b左Ő*čt顭塶 + values: + - 6oQ + - 9r22TM + matchFields: + - key: fNLkt + operator: "" + values: + - tW + - M03GnpfhQn + - key: WQQs + operator: 騡(Í芝x焍麅ɰ窓ɶÜò鵹 + weight: 579622465 + podAffinity: {} + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: {} + namespaceSelector: + matchLabels: + IYAfjz: GloAc + namespaces: + - hfFjlR + - KWIdaP11Y + - 3Dn + topologyKey: UB + - labelSelector: + matchExpressions: + - key: B7LSh + operator: ɉ邦夝ɷ1傹Þ袳@ɲ鉴 + matchLabelKeys: + - "n" + namespaceSelector: {} + namespaces: + - 88M + - fIEJUewFK + topologyKey: i +autoscaling: + maxReplicas: 86 + minReplicas: 445 + targetCPUUtilizationPercentage: 362 + targetMemoryUtilizationPercentage: 8 +commonLabels: + "": h0uSAPIi + kuKPk7: "" +configmap: + create: false +console: + roleBindings: + - null + - 9T: null + fxu2XaR: null +extraVolumeMounts: +- mountPath: q + mountPropagation: 跐ʩ4鄧SD炿ɜǚhU + name: "" + subPath: SCLzbAMUW3x + subPathExpr: nzFw +- mountPath: cX8U + mountPropagation: b幈簇@艭K + name: b + readOnly: true + subPath: u5fY + subPathExpr: TRymQ +extraVolumes: +- name: LeIYAb +- name: 176OvjD +- name: b6NpMGfVo1N +fullnameOverride: qhaD +ingress: + annotations: + Lftu: PjroKEh + qvZJNWSzR: Jpoyc0 + className: cAir + enabled: true + hosts: + - host: o + - host: i18Wi + paths: + - path: apsXYvp + pathType: 7q5 + - host: 8eBXg + paths: + - path: cMbMbCQl + pathType: gJT + - path: XvfTwH + pathType: 4se + tls: + - hosts: + - fqD + - JDOgIG + secretName: vzUD + - hosts: + - M6H + - T + - twxgtsi + secretName: lg5siLdo +initContainers: + extraInitContainers: 9KiOC +livenessProbe: + exec: + command: + - 0gsq + - "" + failureThreshold: 1372450161 + grpc: + port: 347104155 + service: Vtf + httpGet: + host: 3Is + path: mFQXEnm + port: -207107285 + scheme: u + initialDelaySeconds: -913177144 + periodSeconds: 912808843 + successThreshold: -765941931 + terminationGracePeriodSeconds: 220495921853460964 + timeoutSeconds: 1174210794 +nameOverride: vLjrafvp +nodeSelector: + ggwC: SQ + rIwToCbB: tUBM5 +podAnnotations: + LtAjph: 8Q + MiPvJub: 0x + j: xR98FRh +podSecurityContext: + fsGroup: -2594082004410587315 + fsGroupChangePolicy: 'ċV1鯍E ' + runAsGroup: -880388195249084168 + runAsNonRoot: false + runAsUser: -9051010573896129766 + supplementalGroups: + - -2777109499517677979 +priorityClassName: JnI8 +readinessProbe: + exec: + command: + - GZAhRFJb + failureThreshold: 1666039794 + grpc: + port: 1689867278 + service: eUJ + httpGet: + host: 6M6GMp + path: hr5gg + port: -751083361 + scheme: 戉窻¦ǃ楓Ëʆ張ǛȤʊLȉŐX5 + initialDelaySeconds: 989921147 + periodSeconds: 536392931 + successThreshold: 1020018972 + terminationGracePeriodSeconds: -955330372102946036 + timeoutSeconds: 1790731281 +replicaCount: 78 +secret: + create: false + enterprise: + licenseSecretRef: + key: yi3 + name: "" + kafka: + awsMskIamSecretKey: J36kR7z6r + protobufGitBasicAuthPassword: xf + saslPassword: jW + schemaRegistryPassword: Z5gF2 + schemaRegistryTlsCa: eGSsHDQm + schemaRegistryTlsCert: NmVf1RW + schemaRegistryTlsKey: DKqtW + tlsCa: 8WuqzUG + tlsCert: yrd + tlsPassphrase: swQ7r + redpanda: + adminApi: + password: mN1ZSR + tlsCa: hrjyEhM + tlsCert: YozBWkwcZ + tlsKey: 1p2 +secretMounts: +- defaultMode: 45 + name: ooYxXE + path: U6f3w + secretName: LyH9zvv +- defaultMode: 429 + name: Hmms9 + path: qzOMXCl + secretName: zvR +- defaultMode: 39 + name: "" + path: dXa6uPxR + secretName: PC2Ms7 +securityContext: + capabilities: + drop: + - ɿX齀蹪 + privileged: true + procMount: Ƚ[孠犥ƶʒ)遷U竕 + runAsGroup: 5229411704597623894 + runAsNonRoot: true +serviceAccount: + annotations: + "": tWl + 5mzy: 4t87VKeHA + a: UqD3iv5LoNYP + automountServiceAccountToken: false + create: true + name: Utu8ZHG2 +strategy: + rollingUpdate: {} + type: I6终j2炅ȲbȻ +tests: + enabled: false +topologySpreadConstraints: +- labelSelector: {} + maxSkew: -154369657 + minDomains: -319419210 + nodeTaintsPolicy: '#Vʅ糗斬ƈ橮IJȶ纀' + topologyKey: dTnKex + whenUnsatisfiable: '@OȤ驮Ʀ琓' +-- case-027 -- +automountServiceAccountToken: true +autoscaling: + maxReplicas: 432 + minReplicas: 265 + targetCPUUtilizationPercentage: 239 + targetMemoryUtilizationPercentage: 130 +commonLabels: + Q0: "" + T4ZmAFi: nfIb0b +configmap: + create: false +console: + roleBindings: + - ElN: null + roles: + - DZcCdT: null + imlLddN: null + - null + - 0MFHoDlkID: null + Xe: null + daS: null +deployment: + create: false +enterprise: {} +extraContainers: +- command: + - WY + - F9X2FePO + env: + - name: MbWT2gynlq + value: S + valueFrom: + fieldRef: + apiVersion: 4msaX + fieldPath: XvlI + resourceFieldRef: + containerName: LEQ + divisor: "0" + resource: oHigE + secretKeyRef: + key: feJnSFqmYy + name: m3lrGM + optional: false + - name: omlZ5 + value: w + valueFrom: + configMapKeyRef: + key: w3iwXnte + name: LqORIZ + fieldRef: + apiVersion: D + fieldPath: bG + secretKeyRef: + key: UeU9m8 + name: 1asSl0l + optional: true + envFrom: + - prefix: HYy4 + secretRef: + name: Q2DTvNx + optional: false + image: jqvBPfz + imagePullPolicy: 庛Ƴ2ɥÔǦ /d2&xȉLJǸAƟ + lifecycle: + postStart: + exec: {} + sleep: + seconds: -1579243177624029331 + livenessProbe: + exec: {} + failureThreshold: 1986638671 + grpc: + port: -1841897347 + service: iUEc + httpGet: + host: CN + path: Dg + port: SYkYMHB + scheme: Ě緷8ĸ)=©ʢ昆ſ9 + initialDelaySeconds: 1029653594 + periodSeconds: 1999066162 + successThreshold: 1106634015 + terminationGracePeriodSeconds: -9022596879374385638 + timeoutSeconds: -809472655 + name: 4D + readinessProbe: + exec: + command: + - iBTD4t + - MY + - Nf + failureThreshold: -1222179068 + httpGet: + host: kgZUkVZPDf + path: hM0yLfiTS7 + port: 846109331 + initialDelaySeconds: 1673719989 + periodSeconds: 1380685354 + successThreshold: -606822450 + terminationGracePeriodSeconds: 2325612573519357970 + timeoutSeconds: 1351631713 + resizePolicy: + - resourceName: KQTh + restartPolicy: 變ȶjȤðʂȈE9ȹɵ礌蓍p殗Ɏ$蟙預 + - resourceName: BATAmUasox + restartPolicy: G寄7]^v腘 + resources: + limits: + 1mn: "0" + 8dnmgn7Vur: "0" + QUXI: "0" + restartPolicy: Ė + securityContext: + allowPrivilegeEscalation: false + capabilities: + add: + - 餋Ƹ + - ǂnlș + - VLJ2範足诮ÈƋʡĻ + procMount: u¸`TE擴弌/yƦ6帜ǏT鱷潈ř蚒 + readOnlyRootFilesystem: true + runAsGroup: -2334732936143374752 + runAsNonRoot: true + runAsUser: 8673583599260752552 + stdin: true + terminationMessagePath: M934 + terminationMessagePolicy: VF¾弎6a巭ġʥţƟ贯Ǐ飙卮ǥĤȸ + tty: true + volumeMounts: + - mountPath: DzNFL + mountPropagation: 单嶃ɠȕƢ砩寢烕TnǣɅƩ帳 + name: "75" + subPath: Up5FB + subPathExpr: 6nD + - mountPath: qj1c9JPX8 + name: 1K + readOnly: true + subPath: H + subPathExpr: LEVSxozubwU + - mountPath: Ll8X + mountPropagation: '@ï禺pƱ=庶ŊJĤ那[:晙dYĸ獘' + name: PGcOpQ3CM + subPath: 1eBZtMIP + subPathExpr: CRyBKRO + workingDir: s +extraEnv: +- name: k7DjEACXyN + value: Pa4mYEUC + valueFrom: + configMapKeyRef: + key: "" + name: RHdV76r + optional: false + fieldRef: + apiVersion: wxIgM + fieldPath: aBDwplYtr + resourceFieldRef: + containerName: xIL7REN8 + divisor: "0" + resource: QCgp9k + secretKeyRef: + key: ag7Jr1e0 + name: I8vGzsJX + optional: true +- name: pG + value: yTh3djvsV +- name: fjV8k4J8 + value: KHKYS + valueFrom: + configMapKeyRef: + key: DFyBHQO + name: s + resourceFieldRef: + containerName: vd0tsh + divisor: "0" + resource: IgH + secretKeyRef: + key: F + name: a34HcjMyaQ +extraVolumes: +- name: "n" +fullnameOverride: 61hunk +imagePullSecrets: +- name: jkqm +ingress: + annotations: + "": ZtbWlWc + y1ML9Hmg: d6h9 + className: Ijdd3 + enabled: true + tls: + - secretName: x + - secretName: aSf1 +initContainers: + extraInitContainers: vN +livenessProbe: + exec: {} + failureThreshold: 302661968 + grpc: + port: -418561550 + service: kQV1xc + httpGet: + host: UlBEGBj3 + path: qjxTH + port: n7 + scheme: '''(旆PT馷J溠F斃ɦ娴含Q嘱\t9' + initialDelaySeconds: -1367097431 + periodSeconds: 2073795341 + successThreshold: -1800407036 + terminationGracePeriodSeconds: -3519876905947517853 + timeoutSeconds: 1644960855 +nameOverride: h9P +nodeSelector: + B1PiWrl0VUETb: x + DhTxFTV: 3O4Y106 + i8QiXusZ: YBeiJfZK9g +podLabels: + Zrl6: 0D0M + wbG: ZcWnb +podSecurityContext: + fsGroup: 3334237787347678751 + runAsGroup: -5325418670707949502 + runAsNonRoot: true + supplementalGroups: + - -2717337443247240979 + sysctls: + - name: "" + value: R +priorityClassName: bpi +readinessProbe: + exec: + command: + - xz + - e2gf + failureThreshold: -1765420422 + grpc: + port: 879468582 + service: bqFsvC9nR0 + httpGet: + host: CrL + path: 9Jt + port: 7Y + scheme: )ǔ軛醲]8z傏$荸觖稄鱑Í朹s狑Ȱ螪;ǃ嘲 + values: + - gIlS + - 5lD7AvT7I + - "8" + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: hi0zfFEN + operator: 裧禿 + values: + - SymXRnv + - iKr + mismatchLabelKeys: + - wesfXhv + - Z78yvK + namespaceSelector: + matchExpressions: + - key: jqHt + operator: ûų:碃;ė燱5ìb-垢xźɆ + values: + - u8cOuqy + matchLabels: + "8": nCrnu + Fd: 5YhLJD3 + r5sMi70hp4TeB: KrDX7d + namespaces: + - LOH + - 9EvOI7HWh + - 5sHJp + topologyKey: "" + weight: 403248696 + - podAffinityTerm: + mismatchLabelKeys: + - Vrf + namespaceSelector: + matchExpressions: + - key: 5w + operator: '|泀ŏ咙ƚ' + matchLabels: + 4vRvwhR: Nz + T6uTCUGiwx: lS + ZuFER: Db8xhFevK + topologyKey: K7NA + weight: 249855905 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: No2 + operator: Ɗ]鿇躠骐 + matchLabels: + 7nohEoAMei: WrMV + ddLK: 2ehkh + qtrhf: EAAqHFcrjgT + mismatchLabelKeys: + - DrrBoq + - Nh + namespaceSelector: + matchExpressions: + - key: BEXHPr1wQ + operator: 傝魦voȪwć撈 + values: + - i3 + - gUU + - 7nmbvkGs + matchLabels: + Rh65F: rKR + namespaces: + - 1x9DGG + - xKj137E + topologyKey: CSNQy1M + - labelSelector: + matchExpressions: + - key: psq4G + operator: ɓƦ + - key: 3IlNf + operator: ćȬ4鏉1, + values: + - L0 + namespaceSelector: + matchExpressions: + - key: nVgt + operator: ɤ湿ŭò-ɋ鼴)箥Ȅ鋖ʄBK + - key: GD7 + operator: 峄9ƚ涙閉ʃ謩云飠:鎂玚wƁȖ] + values: + - i8cg6A + - TeOYSsj + topologyKey: rEB + - labelSelector: + matchLabels: + s0PrY366si5H: Qwj + ytBgNf0: e + mismatchLabelKeys: + - eylzvu + - q + namespaceSelector: + matchExpressions: + - key: os4H6DpxQ + operator: 5õċ鋵葿葄痄ɍ览逪ȋ`j + matchLabels: + vL3arho: gPmLG + namespaces: + - PjQTIWTFeK + - g5HCelWpMjnF + - QN3mXW + topologyKey: I5osiWTrzhb +annotations: + WVwaqt: gTMC + s6HZpOA: bc0 + sZaCXy: LXRQNTghxb1 +automountServiceAccountToken: true +autoscaling: + maxReplicas: 404 + minReplicas: 186 + targetCPUUtilizationPercentage: 200 + targetMemoryUtilizationPercentage: 383 +commonLabels: + HzuQ: mCfbHBQ + xi7L: ibI45 +console: + roles: + - null + - null +deployment: + create: true +enterprise: + licenseSecretRef: + key: 8MG + name: 83OH +extraContainers: +- args: + - K9 + - 02olyp + env: + - name: F + value: rhVGTadjT + valueFrom: + configMapKeyRef: + key: 3TA0cg2R2 + name: DLZ + fieldRef: + apiVersion: s + fieldPath: Ux + resourceFieldRef: + containerName: avop + divisor: "0" + resource: itl5J4xK4 + secretKeyRef: + key: Av9eKok + optional: false + - name: QaOLYDLT + value: FQu + image: 1MFnpZG + imagePullPolicy: 脓 + livenessProbe: + exec: + command: + - lH4S + failureThreshold: 1311534645 + grpc: + port: 1048835191 + service: p5EtELTs + httpGet: + path: Zjrv + port: Ypah5av + scheme: þʙ龠ȉ%Vę皓ŏ蟝ǙĿìɋN + initialDelaySeconds: 1980070741 + periodSeconds: -728109708 + successThreshold: 1412960079 + terminationGracePeriodSeconds: 4797597904045467368 + timeoutSeconds: -1164059804 + name: oron + readinessProbe: + failureThreshold: -1734715333 + grpc: + port: -673781482 + service: 20iHh + initialDelaySeconds: 270804414 + periodSeconds: 1240219458 + successThreshold: 957649997 + terminationGracePeriodSeconds: -7921460752123720147 + timeoutSeconds: 2069469191 + resizePolicy: + - resourceName: M29 + restartPolicy: tL + - resourceName: WK + restartPolicy: T軂>ȋ1觫蚴Ș + resources: + limits: + KS: "0" + ZDx: "0" + kIjQHQZ: "0" + requests: + BSB: "0" + restartPolicy: LJW獮 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ɺ嚹晐囕胐ƻ + - ņɹ桴O塾q6賤呋f铰}Ʒ輽ʁ[顝 + runAsGroup: 6868723237582569296 + runAsNonRoot: true + runAsUser: 433131246318901172 + startupProbe: + exec: + command: + - mB6 + - Om9w + - "" + failureThreshold: -1184477652 + grpc: + port: -1276243610 + service: m6d + httpGet: + host: VzPuwIiTpY + path: C + port: 0NYj1C + scheme: V=@彆鈂t³Ɉµs斾m蛊ɲ + initialDelaySeconds: -898287287 + periodSeconds: -413255468 + successThreshold: -1510482870 + terminationGracePeriodSeconds: 4884332649151510354 + timeoutSeconds: -1445193311 + stdinOnce: true + terminationMessagePath: DQTH7 + terminationMessagePolicy: ÈɁ;ň);ɑI×ĕ觫'ɣ + volumeDevices: + - devicePath: v + name: AZ6wCimJFM + - devicePath: ZtIx + name: GFe3 + volumeMounts: + - mountPath: tt + mountPropagation: 侮E墝調cé攊疀" + name: UJ + readOnly: true + subPath: JlqP + subPathExpr: lA2v + workingDir: OV90 +- command: + - 8jHRuz + envFrom: + - configMapRef: + optional: false + prefix: yfl3PI + secretRef: + name: r7eR + optional: true + image: m4Etaoz8Bf + imagePullPolicy: okÛļ閷YƗzƄǧ + lifecycle: + postStart: + exec: {} + httpGet: + host: zu9aQLsX + path: xIFogzAoC + port: 1MjUE + scheme: 斔疏ʟn菝 + preStop: + exec: {} + livenessProbe: + failureThreshold: -1399917612 + grpc: + port: -876522011 + service: 2y + httpGet: + host: X9nNdf + path: 8mVJlz + port: 220487349 + scheme: 兇)hr裳ǔ湟钑>ȓn厠tū晣颊 + initialDelaySeconds: -968878635 + periodSeconds: 411754743 + successThreshold: 2083381130 + terminationGracePeriodSeconds: 2736468416107855115 + timeoutSeconds: -423937148 + name: Or + readinessProbe: + failureThreshold: 1628351372 + grpc: + port: -1466105410 + service: b + httpGet: + host: 8kOz + path: IhSlrBw8tiX + port: 1Vd + scheme: qV·dƖ> + initialDelaySeconds: 735135195 + periodSeconds: -175995819 + successThreshold: 1379601279 + terminationGracePeriodSeconds: 386635447886660712 + timeoutSeconds: 125503732 + resources: + limits: + LuudLJ9i: "0" + iXpYUWY: "0" + mHi: "0" + requests: + XLnFU: "0" + mSq9e3u: "0" + t6WYwzmga: "0" + securityContext: + allowPrivilegeEscalation: false + capabilities: + add: + - ɭ鎣肪綢ȀNj8)屫鈄骸嗢æ憰qWTƶ剡 + - "n" + - OwkʙƝk}ɾ丧< + drop: + - Ť<嶼ȯ愉9宆嵧pɡ%ɐxė鹞鸵鏞 + - ƅgʆ炊ƞąÙ$Ǯ帶SȔ黌畕ǦƖȫV9 + - Ŏʠ羮ɍ痘摬 + privileged: true + runAsGroup: 5710532895986022625 + runAsUser: -7207500526873245606 + startupProbe: + failureThreshold: 2053062827 + grpc: + port: -1076044334 + service: s8s7 + initialDelaySeconds: 7348194 + periodSeconds: 889500482 + successThreshold: -645465298 + terminationGracePeriodSeconds: 4356974427366499939 + timeoutSeconds: 136481601 + stdinOnce: true + terminationMessagePath: t4pW + terminationMessagePolicy: ƣ + volumeDevices: + - devicePath: Df8O3UFZ + name: QL93u + - devicePath: WKg + name: nD4H + volumeMounts: + - mountPath: xs9 + mountPropagation: e羝ș+oũ蘘汉 + name: grr + readOnly: true + subPath: aUYSuUM6f + subPathExpr: mm773yL + workingDir: o +extraVolumeMounts: +- mountPath: P + name: zBgE7HVQ + subPath: hw6PBLgv5R + subPathExpr: YAI5mPj5 +extraVolumes: +- name: "" +- name: SXJ +fullnameOverride: HK +image: + registry: nZ5PG + repository: 5q2qCT + tag: z10JAfCu +ingress: + className: fq2w +initContainers: + extraInitContainers: DVbGC0v6g +livenessProbe: + exec: {} + failureThreshold: -1989869025 + grpc: + port: -580257384 + service: xF + httpGet: + host: EFelM2 + path: NL + port: -1619787350 + scheme: eƌ閽2溧估槞 + initialDelaySeconds: 56050789 + periodSeconds: 193173949 + successThreshold: -1606638368 + terminationGracePeriodSeconds: 9170924509557781641 + timeoutSeconds: -1117024654 +nameOverride: 3Wh +nodeSelector: + Jy9: v + VcMeUW2U: xOwcDQYY + wkI: TbemvxUUg +podAnnotations: + IVy: ho3qpcI +podSecurityContext: + runAsGroup: -9040107238323408835 + runAsNonRoot: false +priorityClassName: sLkcwZ +readinessProbe: + exec: {} + failureThreshold: -509957017 + grpc: + port: -1088874416 + service: kVlcoq + httpGet: + host: yJj + path: SWu6bW + port: V + initialDelaySeconds: 1816814831 + periodSeconds: 406466643 + successThreshold: 450108513 + timeoutSeconds: -1862950899 +replicaCount: 385 +resources: {} +securityContext: + allowPrivilegeEscalation: true + capabilities: + drop: + - 邻ȸNJ"纴ý汫篤訙铵寄貹Z[逗ą弣 + - lǀ敕ɖ + privileged: true + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 3375680259081538534 +service: + annotations: + 33Yi: tesf5 + nodePort: 286 + port: 389 + targetPort: 52 + type: sIQBZD +serviceAccount: + annotations: + 0E6ZFg: nO7Yr55 + 8JN3: B + create: false + name: 43zobnL +strategy: + rollingUpdate: {} +tolerations: +- effect: 蜆³Ə抴璖獍ä鷲炥/=霒0ǷU伀稂ı + key: EMvrrkeG3 + operator: Ȓǒs夃Ȑɉ鋄蛓m÷,旂 + value: yd +- effect: 旌;"ȡ媟窐:ljʥh蓭殰Ȩƴ邃ȬIȻL + key: n87GpiB + operator: '偵~ȥʢȈ珎ſ龕5sʠŇưT4-§Ƀ ' + value: TUaznROmQffrRe1 +-- case-030 -- +affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: i3NrGin + operator: LȜɯı偎鵬ćƾ輨ɒ诏Ƞ韾ʂɅ袅 + values: + - ceEnH + - hk + - key: NcZdG + operator: 4# + matchFields: + - key: iJJ + operator: 椤甏Q"dč膌嶁ŵ + values: + - pqbO2v + weight: -888291486 + - preference: + matchExpressions: + - key: 6yk + operator: +[`¥鯦Kqlǣ詆繉ĔNjUƆ + values: + - 9jizdnZ + - 1HUyNhM + - qxDTvf + matchFields: + - key: hCPEY + operator: Ɇ>隣,讽鬓捍+瞶媘暺ɭEƙ + values: + - Ripsc + - CqS + - key: DVFDiRmz7 + operator: U[ + weight: 1468051205 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: v + operator: 舘LJwMa煗 + values: + - 8yax8 + - acSVUNTfJ + - "" + - key: oeJI7K + operator: Ȩ岵Ư塠ŕ惆^ȹ]Ǥ(蓂心[6 + values: + - VT3avr + - 1sP4V + - key: INgeGc + operator: 7ȋ_ƫ俾NīÂ缷 + values: + - K6yWR + - matchExpressions: + - key: s + operator: ǖ鱝U9y,ijO<ǯŹ斔ɥɍQŝŘ + values: + - V7Cj8gd672O + - Jxq7EqU + - "" + - key: gYq6n + operator: J30ǂ涉Ǖ絜拃Ȃ隰韤Ko + values: + - cFfLM2a + - cmwJ5 + - NvVSgzPk0K + - key: ha1vIvxMS + operator: 鹶ƦÍR\Y + values: + - kno2LivX + - ZBSIfmJ1 + - Xy + - matchFields: + - key: cGJbcb + operator: M$铯但ƙ崍0塁7ɔ籇ȏč3ţħ + - key: t9tN + operator: ĴĹApŰƎyģ+7ɬ5 + - key: q + operator: ĂǮȅ魥ď疪@ɓ擼 + values: + - GHyvS63U + - lupcwbTbly + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + q: oY6el1mi0 + w: C7Cxyx + matchLabelKeys: + - HMg6IP + namespaceSelector: + matchExpressions: + - key: Crz + operator: əɃ笕P頔ɾ絿ɟ秜Ć冦Ǒ钹圤|讪ɩ + values: + - Dtei + - 1zhZl + - bd + - key: RjH6F + operator: æ監F箂Ñ9 + values: + - n91j6BXw + - 3RLy + - m + namespaces: + - N0Oqq32Q + - TJpJ52Je1Ikj + - "" + topologyKey: HeJdmR + weight: -259316091 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: R + operator: 麦谐ƺɐqNJ7篐瘘ƊƧR菴qȃ + values: + - 8p + matchLabels: + WW: GL0oC8Fkf + mismatchLabelKeys: + - cdHA3 + namespaceSelector: + matchExpressions: + - key: ar9Y3Br + operator: pK屨鑊聫翶鲔举腏熝ɴ鷏žŝ + namespaces: + - U9UV + topologyKey: cpw + weight: -400075332 + - podAffinityTerm: + labelSelector: + matchLabels: + hYm: "" + mismatchLabelKeys: + - fCOHEas + - uHnZlu + - zhGS + namespaceSelector: + matchExpressions: + - key: HZEOkit1i + operator: '@ÍȪ蟔ʖ' + values: + - t9Xj + matchLabels: + "": so + topologyKey: "" + weight: 2103394856 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: 5LP9ZW14 + operator: "" + values: + - O4Urq + - key: f3f + operator: õǷ膀3堢ƧŸ + values: + - GJnsN0 + - key: MOJiCs9Qi + operator: Ȥ:危L昝×秲d3ğd曱窸 + values: + - 3keSh + - Uyy + matchLabels: + R: dUyJ0OOVapc + mismatchLabelKeys: + - Xjqx8f + - I5k + - wq0 + namespaceSelector: + matchExpressions: + - key: UP + operator: ȡ畅fȐiú鍿6+襄懬Uċ + values: + - NmZvVOQ + - key: P0hfM + operator: 黣`倴Ŝʪ鰷淸 + values: + - 0GsglT + - MMOe + - uU7Q9 + - key: qnv + operator: æ钹eťǧI薶瘃預ʑ歪yʖb7IwɄ + values: + - McuTAiUq + - XvSAD + - 4e9Vd4vq4 + matchLabels: + "": 4O2glzZ + namespaces: + - wblXzeT2 + - qKILJo + - lPV + topologyKey: Jnwfpfk + - labelSelector: {} + matchLabelKeys: + - tMph8mi + - Ry31wp + mismatchLabelKeys: + - tBHze4gtm0s + namespaceSelector: + matchExpressions: + - key: RpYdzfZ + operator: 攆KRɮõ涸WæĥŽ¡犇fʼn利$蘁干 + values: + - 8Pxd + - V50 + - key: I0O + operator: w"ʈö褥屑ɣAR(憍Nj松趯ĩȁ + values: + - "" + - 6yt2J + - key: fR7 + operator: GǼ舿 + values: + - gP + - LxpC1 + - brLBqM + matchLabels: + "": D5eSOeauL + namespaces: + - xrd20T0 + - GVD45 + - UU3YxE + topologyKey: augu3G + - labelSelector: + matchExpressions: + - key: c17UgoCbg + operator: -蟁楉mƸ赢UȇEŏ + values: + - cr + - CSYe + - key: FM6GBGy + operator: ;疩Ȯ慫ʂy_Ɛ碷ʩʀđ忮 + matchLabels: + Q4hS: 2Z + w: pvyR + matchLabelKeys: + - PLi + - G2W4IV + namespaceSelector: + matchExpressions: + - key: 8Z + operator: Ȩ卭閃N弲ʠǠ驯Ɩ8Ýʊ + values: + - rEFXZ1 + - oXxjjBM + - iovjqaN7g + matchLabels: + 3ZwMBixAo: QeYp0O + topologyKey: AH3A + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + 7hX7: uCFlimRES0ZJ + matchLabelKeys: + - CxxMt + namespaceSelector: + matchExpressions: + - key: Xra0M + operator: ʙƤ潯ɔ + - key: "" + operator: 8媮­Ů籌<ǫ + values: + - RsIq + - wqR2cm + - key: ottvJh4 + operator: ¢M&<叇誆戛!Ʒ"(Z氇z錉¬$ + values: + - 5sMUIY + - SV + matchLabels: + iciKwm: xkq + vPG: oQs + namespaces: + - AtM4 + - rZdQ + topologyKey: 9FnG + weight: 1109931313 +annotations: + 5ya: nNowhQY2Bp +automountServiceAccountToken: false +autoscaling: + enabled: true + maxReplicas: 10 + minReplicas: 306 + targetCPUUtilizationPercentage: 227 + targetMemoryUtilizationPercentage: 477 +commonLabels: + T: f0 + jwrBMvwfg: K6I5HsI5 + nk8eJc: nS +configmap: + create: false +console: + roleBindings: + - E: null + W67WBz: null + nYCT7q9: null + - 2S0: null + Nx24C: null + WacOKFS1: null + roles: + - i5oc: null + - {} +deployment: + create: false +enterprise: + licenseSecretRef: + key: ZJGo + name: oxACi6X0cy +extraContainers: +- env: + - name: rV6MouQf3 + value: E21XoHIB + valueFrom: + configMapKeyRef: + key: LDu + name: Flu + optional: false + fieldRef: + apiVersion: Rc8broTqb + fieldPath: "6" + resourceFieldRef: + containerName: VPb + divisor: "0" + resource: PUL + secretKeyRef: + key: xwKJr5 + name: 8K3IIl70g + optional: false + image: d3e1 + imagePullPolicy: 梅E垉丿ȁƘg/§Oaq嵌艷ɖ½飚 + lifecycle: + postStart: + exec: {} + httpGet: + host: WyIob + path: sVvxO + port: SivnsYEe + scheme: Ǖɜsk煨a% + sleep: + seconds: -5241114468416153504 + preStop: + exec: + command: + - h0 + - PbwM + - xML1a5IbGl + httpGet: + host: i8l7K + path: v0TIlzugj + port: UO1j5 + scheme: 痍´荭鲪 + sleep: + seconds: -5262918982231100330 + livenessProbe: + exec: + command: + - MAKziqqn2 + - RtC + failureThreshold: 301723627 + grpc: + port: 1522990624 + service: Y2uF8U + httpGet: + host: 8E6hLWDfL + path: ptr + port: -819495670 + scheme: 畊傲Ā5ʇġ杭ăïƺƢh]薰 + initialDelaySeconds: 975121998 + periodSeconds: 1462200965 + successThreshold: -1868145610 + terminationGracePeriodSeconds: 438373319570860757 + timeoutSeconds: -992167018 + name: xGfw + ports: + - containerPort: 1210092140 + hostIP: aXzKT + hostPort: -1118392417 + name: A5VIRuB0ki + protocol: 巔B兓汳LDŽ5ǒʛ岹璜ʂá&Ɠ + - containerPort: -1184047055 + hostIP: nLlzZ + hostPort: 1916025056 + name: CSeXd7M + protocol: 朿! + readinessProbe: + exec: + command: + - AfVsN7lM + - SoZ + - yZ2uB93C + failureThreshold: -1305050809 + grpc: + port: -1574571534 + service: vhf8x + httpGet: + host: 2zqRpIh + path: ZRe + port: 1109632462 + scheme: '*h嶳椗痢%īƺ' + initialDelaySeconds: 157767030 + periodSeconds: -538159566 + successThreshold: -909232559 + terminationGracePeriodSeconds: -1089882796882580867 + timeoutSeconds: 1392958383 + resizePolicy: + - resourceName: JCDaktfU + restartPolicy: 鈇Hƣv蘺 + - resourceName: "" + restartPolicy: 魔ţv毇俺ɚ + resources: + requests: + DA9: "0" + XdW14: "0" + lUcQG: "0" + restartPolicy: 淣遦髺tMőƤ橷僟 + securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - 兪q6赀覱勯痜.I膴6+V旱Ő佀 + - 焤Ċʐæ舁ŕ齸Ġ + - uo妿Iǥ2JǟAŊ訖ʆD + privileged: true + procMount: Ɋ胘ſȾ鞣殦ơɧ­ǶǴU譶 + readOnlyRootFilesystem: false + runAsGroup: 5199515302292266073 + runAsNonRoot: false + runAsUser: -7335995488954570305 + startupProbe: + exec: {} + failureThreshold: -777300462 + grpc: + port: 2095052331 + service: bfVTOPN1hv + httpGet: + host: Kp + path: b1bcG9oDl + port: 1383634294 + scheme: 谳涿v衃$Ơʓȳ浲呯 + initialDelaySeconds: -1373123738 + periodSeconds: -1183287381 + successThreshold: 685684993 + terminationGracePeriodSeconds: -4093444870298300516 + timeoutSeconds: -1903691809 + terminationMessagePath: olo1u + terminationMessagePolicy: 怚PʢŸiųŞv嶷宇ƏȌ¥ƀ + volumeDevices: + - devicePath: qFB10P + name: "" + volumeMounts: + - mountPath: YW9lWgZeNE + mountPropagation: 鰛8Ȗ×ʞ + name: Tot + subPath: Ty + subPathExpr: spiOgT0A + - mountPath: SgUmz6Q + mountPropagation: Ă別Z醰棘纀C蘂× + name: ddMHT + readOnly: true + subPath: 8J3YB + subPathExpr: K + workingDir: OQ4 +- args: + - bAsse7O + - u + command: + - MzlyVYHO2w + - oRBJF + - Nafr + env: + - name: U + value: RNGsZ + valueFrom: + configMapKeyRef: + key: YX6H + name: ab92 + optional: true + fieldRef: + fieldPath: 1SR7mfWfzFL + resourceFieldRef: + containerName: C92ipM + divisor: "0" + resource: x4S7 + secretKeyRef: + key: WhzPa + name: lAvfz + optional: true + image: nP + imagePullPolicy: ǫyɮȯ + lifecycle: + postStart: + exec: + command: + - ucft + - K8XaCG + httpGet: + host: rza + path: JhnYc + port: e0 + sleep: + seconds: 6253871176572388811 + preStop: + exec: + command: + - Uiuiougu + - "" + - 3Gx5Gu + httpGet: + host: VQzMXk + path: ws + port: -474919374 + scheme: w媦÷帹ȅW閫ĭ# + sleep: + seconds: 4571098797230986244 + livenessProbe: + exec: + command: + - pHp + - MDPb7 + failureThreshold: 871873843 + grpc: + port: -422130433 + service: nC + httpGet: + host: M + path: p00iJRicrG + port: bS0X1wo + scheme: m鈎Z趟樥R%飅 + initialDelaySeconds: -604803912 + periodSeconds: 1886242291 + successThreshold: -1386436865 + terminationGracePeriodSeconds: 3067492874024630757 + timeoutSeconds: -1583378445 + name: Si46O7YRR + ports: + - containerPort: 1700510643 + hostPort: 251260843 + name: JkZyRGNq + protocol: ȅz,ǹ昉 + - containerPort: -1859013382 + hostIP: NHKaXL + hostPort: 831309722 + name: y9vWUO + protocol: ʡƊX| + - containerPort: -2125300283 + hostIP: jj3qc4 + hostPort: -278349921 + name: Aa + protocol: 耛v6]jç錛洘¶緛uȁ竿 + readinessProbe: + exec: + command: + - "" + failureThreshold: -784645974 + grpc: + port: 1390591548 + service: "" + httpGet: + host: lNyXDdzed + path: W9q4gnCB + port: 4YUq5drSLjLPw + scheme: 唡家調Ô蘓狥ć4^謋遭ŧ厑Ƕ¤ + initialDelaySeconds: -315867707 + periodSeconds: -1221044118 + successThreshold: -2057597685 + terminationGracePeriodSeconds: 8064296597671882818 + timeoutSeconds: -1128414965 + resizePolicy: + - resourceName: MA + restartPolicy: tÜ榋ɼ + - resourceName: bwI + restartPolicy: 斪4瓏鍣ĊYƞ睽%ü劘ĥÑC­ + resources: {} + restartPolicy: ǫ歩ʏ朄DŽ8Ǫȩ;毆|ȕ潆Zʚ輘殈ɔ + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - '*驲' + - 纒寻$KŞ菤Ľ恎eɈ鏽 + - ě宭`羧\LƝ攅嫜ɫʡɞǍ緭p誂 + privileged: true + procMount: 楛钞óŰ)5鞊tY榋肦Ȓ + readOnlyRootFilesystem: true + runAsGroup: -3200847944437364683 + runAsNonRoot: true + runAsUser: -5188355058620722927 + startupProbe: + exec: {} + failureThreshold: -718122732 + grpc: + port: -2045013242 + service: Zg34 + httpGet: + host: slqfokZ + path: SlStyexr + port: 101605170 + scheme: Ȅ.隊ou纾ƙŨ`aʭ + initialDelaySeconds: -467990622 + periodSeconds: 446042771 + successThreshold: -504446684 + terminationGracePeriodSeconds: 1811254130314346303 + timeoutSeconds: -1983992134 + stdin: true + terminationMessagePath: zLDb + terminationMessagePolicy: ōe谕ńg"qy暵ȵ抷¬Ʃ蔚盓 + values: + - tQP + - lAyg + - "" + - key: qaIUADOI + operator: '&Ɗ³ĵLJ鎌ɝǏ縉j' + values: + - 6ot8DTU + weight: 969637277 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: j9Rzed0C + operator: Ò + - key: 02b + operator: "" + matchFields: + - key: "0" + operator: 9Š篅)笕Õ^ɤ疫ɜȬ + values: + - "n" + - key: 96k + operator: 觱踊ĝğOɎʁ胳}$g鄈ʮ誦Ň鱝炠抡凓 + values: + - pJdgL + - 00uMch + - key: pz1WHTJ + operator: 濐r! + values: + - i4rsr5 + - PI8GPtiCkkahh + - matchFields: + - key: oTjdt + operator: $ƹȔLj硍čȒŪ涏ȰŞdų悋ĶA + values: + - KOyvX + - 6JNFdnH + - e59WgamF + - key: lu3OH + operator: ǽəơȽĬt嶫cŭ + values: + - 9SKaOYPiL + - 1ioL + - pZde + - key: Jd6LB + operator: ']洔璗3NZ貦ʞ%ȮǵȺ絥ņ' + values: + - dKyLtzFaqg + - yCg + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: siTiGS + operator: ʐȱe峫LJ鐻cȚEqkwt!ģ + values: + - "" + matchLabels: + Aj: V + P5zpV: 8hC + mismatchLabelKeys: + - 4wtTpNGnV + namespaceSelector: + matchExpressions: + - key: K2ZsAt + operator: 妗巪Wɱ鲵Ǯ洭 + values: + - jxl5gm5E + - X2 + matchLabels: + ly6r: 9k + o0G: "Y" + namespaces: + - Q + - XpXqm + topologyKey: Qrt + weight: -1221853228 + - podAffinityTerm: + labelSelector: + matchLabels: + Jc9: Ftx4sR + Zi0PNgVi: EUuTsR + dQt607d6aSO: RSEoObj9yY + matchLabelKeys: + - odAAyA + - ZUwkRz709gR + namespaceSelector: + matchLabels: + Ag0Kix1n: laC2fYO + topologyKey: izD + weight: 600976747 + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: {} + matchLabelKeys: + - QRHiPYut + - KfMAojY + - Vww + mismatchLabelKeys: + - TTnksi7Ob70 + - gGyPv + namespaceSelector: + matchExpressions: + - key: XYpda + operator: q砐ʌƭʩ烬P§Ǩ + values: + - k7 + - SKn + - eefGAA + namespaces: + - ZYe + - nivMj26 + - OhZ6 + topologyKey: xIpuYH7 + weight: -1130732649 + - podAffinityTerm: + labelSelector: + matchLabels: + ApF: Gsyd94h39Q + H: r + mismatchLabelKeys: + - aWHz7q + - xuzLo + - 5ASY1R + namespaceSelector: + matchExpressions: + - key: Zg + operator: 篃b + values: + - vh + - Rgd3V6 + - key: PNqIEbD + operator: \Ų叢T'ɰď乁ʤ駧ɧ + matchLabels: + ugZKNnsp: bUttL + topologyKey: GRNlK86 + weight: 1964668305 + - podAffinityTerm: + labelSelector: + matchLabels: + t2lvLczlk: um + wjQbQIYB: zsr5i + matchLabelKeys: + - "" + - 7H2Kg1N + - NE + namespaceSelector: + matchExpressions: + - key: 2AEBOqKWel + operator: É$íĨ鯖 + values: + - "7" + - S6PWc + - key: c9NGgT2 + operator: Dǥž駗驕咜2 + values: + - WFDcdOBg + - 8akPt + - key: v5V + operator: 苯Dzŏ趘Ɏ蹰ƦȃDz俑I^ģ鄔ĥƁ鲎硹. + values: + - Ro + namespaces: + - rrn + - Gko + - D + topologyKey: 5GfcY + weight: 1374611901 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: 9BEvWF + operator: 箁梄òǣf舢ɉ N + - key: DoJZDVpdUKV + operator: '|痤"纇繁Ơ¹Rnl' + values: + - M1FUy7H + - PmETea + - key: fZB9p + operator: 艨ë寨t^ + values: + - 6SbUQEl9IF + - grOZ + - awRdbXsbbO + matchLabelKeys: + - QbnYiVnjIDt + mismatchLabelKeys: + - dzq3fg + - EHB2 + - E + namespaceSelector: + matchExpressions: + - key: C + operator: 泤煇JĀȅs滚硚ƾĐLJɚ<嗢 + values: + - qweN + - cmGvYLL9 + - key: ftTKd17 + operator: ïǸfǛD + values: + - 3Qp + - 97WXhHH + - QLVxS + - key: X + operator: x Ƙš + values: + - X7mWp + - 4YUDIL + matchLabels: + 2pOyqtJ: X5kt + DqZU: lA7g + yydzgHSxH: mX + namespaces: + - PnB + topologyKey: O2bIu + - labelSelector: + matchExpressions: + - key: lR5v3DP + operator: 8ȈDŽG弪żf[j盠zğ? + values: + - oX28u + - fcVl + - l + matchLabels: + D1CEy: o9m2rVKHK1i + q9TAhY: UxxABL + matchLabelKeys: + - gZSueHOl + mismatchLabelKeys: + - yKwrju + - OmHbxfoV + - p + namespaceSelector: + matchExpressions: + - key: y4jen13nM + operator: '}J;ƴȳ鹓ÿ莂ú' + values: + - 4Fe5y + - BrR + - key: O47QYt11Bl + operator: ıCƾ?9Ìx毧Ƿ + values: + - co + - A7y9 + matchLabels: + "8": 7mV4YD + namespaces: + - vi + topologyKey: sRbXgEn +annotations: + lZ: e +automountServiceAccountToken: true +autoscaling: + enabled: true + maxReplicas: 25 + minReplicas: 20 + targetCPUUtilizationPercentage: 460 + targetMemoryUtilizationPercentage: 169 +commonLabels: + q4ZdG9q: IJWaYu9mhun + sFTTcyl: qVyaa0ULC +configmap: + create: true +console: + roleBindings: + - {} + - {} + roles: + - {} +deployment: + create: false +enterprise: + licenseSecretRef: + key: qYIzRhBP + name: lkd8afL +extraEnv: +- name: 6aAK + value: C + valueFrom: + configMapKeyRef: + key: hSSIqC + name: QPNl + optional: true + fieldRef: + apiVersion: LhfAND6hW + fieldPath: g2J7 + resourceFieldRef: + containerName: BDRH4s + divisor: "0" + resource: "" + secretKeyRef: + key: LfIX + name: vI2UB + optional: true +- name: qUw9kXv + value: WEGTagf + valueFrom: + configMapKeyRef: + key: ejuXsJ1 + name: MYu4 + optional: false + fieldRef: + apiVersion: 9PzuPIkT3 + fieldPath: oa8Oe + resourceFieldRef: + containerName: IuMHr6gt9 + divisor: "0" + resource: dazyeM + secretKeyRef: + key: ludRIp + name: 1RhUa7B + optional: false +- name: UIdv4fEDhnwvUs + value: ZhJ + valueFrom: + configMapKeyRef: + key: 9CIrVsxQ + name: bYh + optional: false + fieldRef: + apiVersion: Fv + fieldPath: W3lmjz5mnuz + resourceFieldRef: + divisor: "0" + resource: 8sULBf + secretKeyRef: + key: mjbYsz + name: ZzZ4TUcp + optional: false +extraVolumeMounts: +- mountPath: TpG9eA0 + mountPropagation: "" + name: XFmsoqjlB + readOnly: true + subPath: rJznnSzpn + subPathExpr: kYhNPw7T1 +- mountPath: rhHVxSG + mountPropagation: Ħɔq + name: zucf + readOnly: true + subPath: rhOyK4f + subPathExpr: dxfS2ISRGUw +extraVolumes: +- name: Py +- name: Wq +- name: "N" +fullnameOverride: 59cQ0qKLI +image: + pullPolicy: 賅5尬Ƕktʈ漻`楾Ő抚@瞹%Ř忞崗Y + registry: gAh7r + repository: VvT9aH5 + tag: "" +imagePullSecrets: +- name: 2Ry3vDGf6 +- name: PE5R +- name: uWsoZ +ingress: + annotations: + Q: 3KXvHleq + YUY: BD + mdCRk: Ilk9wDjAw + className: GuB1VTCp + enabled: true + hosts: + - host: WsTbK7W + paths: + - path: MKCR56 + pathType: hEV + - path: "6" + pathType: pv + - path: rNv + pathType: L0CY1c8 + - host: OxFD + - host: Ojx + tls: + - hosts: + - C + - wxjmQWXDn + secretName: ESgom5IBQR +initContainers: + extraInitContainers: AN4 +livenessProbe: + exec: + command: + - 5m + - 1hj + failureThreshold: 1710421008 + grpc: + port: -1758154628 + service: "" + httpGet: + host: AbGz9Ql + path: 6HPb6FQP + port: 1834140801 + initialDelaySeconds: -1805305530 + periodSeconds: 580837556 + successThreshold: 1568498137 + terminationGracePeriodSeconds: 6055624087283515610 + timeoutSeconds: 1393862090 +nameOverride: xknw +nodeSelector: + "": O +podAnnotations: + IserdW: Y8zC + rKlqh6W: s9dR +podLabels: + 7yc3n: Cmh + bASmPL: XHGF + e1: s0B +podSecurityContext: + fsGroup: -6352604564338413284 + fsGroupChangePolicy: ¥ɬ屛ɀ裕量7ȅLJI/煿I庮\LÌ0 + runAsGroup: -629752081807497066 + runAsNonRoot: false + runAsUser: -7150506011583335552 + supplementalGroups: + - -2079681094590514497 + - 4310353567816636623 + sysctls: + - name: "" + value: 6bg1 + - name: v54yJPXG + value: BNnF0A + - name: DU + value: J +priorityClassName: mFg +readinessProbe: + exec: + command: + - 1A7AuNqZgrO + - 0Dv9uT + - mi + failureThreshold: -1374895470 + grpc: + port: -974870340 + service: rLr6 + httpGet: + host: ZjH9W0Mw2N7wDlEl + path: A1mi + port: VL + scheme: '''Z悁Ţ瘿ª簳Ʀx.ʞ鳃峚5ƫw牑諥ǁ' + initialDelaySeconds: -1507178072 + periodSeconds: 59289443 + successThreshold: 873349641 + terminationGracePeriodSeconds: 3372950661886875571 + timeoutSeconds: -77680726 +replicaCount: 424 +resources: {} +secret: + create: false + enterprise: + licenseSecretRef: + key: 8NBr7XfH + name: UG4to + kafka: + awsMskIamSecretKey: iq3sT9 + protobufGitBasicAuthPassword: TmKaYoY + saslPassword: 41jeqaQ + schemaRegistryPassword: lo1 + schemaRegistryTlsCa: 6ugJXi + schemaRegistryTlsCert: Dfxzy + schemaRegistryTlsKey: s6Wq0 + tlsCa: xiXLxgIB1uY + tlsCert: BoJ + tlsPassphrase: ERo + login: + github: + clientSecret: 6FsPPUCqFaQN9Z + personalAccessToken: mQjpC + google: + clientSecret: zEoO + groupsServiceAccount: sJYwU + jwtSecret: nN8l8K5 + oidc: + clientSecret: t + okta: + clientSecret: uW9S + directoryApiToken: UF7 + redpanda: + adminApi: + password: hkp2 + tlsCa: Hv + tlsCert: YIT6XYEg + tlsKey: gVxUg +secretMounts: +- defaultMode: 217 + name: 84iLClLVXmt + path: z5a16ev9 + secretName: DBNf +securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - Ò4^|wƙJ3ɀªʭ÷齹æc8ǺơG + drop: + - 罩Ɵ + - 凘~蹆縇W偓Ȓ鵇膓咰ɲ俹îS泑 + privileged: true + procMount: 'č #m繰:¿ċY3扙缗_MǮJw' + readOnlyRootFilesystem: true + runAsGroup: -3419647664540135091 + runAsNonRoot: true + runAsUser: -7389132079103631330 +service: + nodePort: 398 + port: 112 + targetPort: 375 + type: N9chrF +serviceAccount: + annotations: + 4Fkdkgg: xGzY0KvisI + WBAEgggZ: v + sCN: cru + automountServiceAccountToken: true + create: false + name: REj +strategy: + rollingUpdate: {} + type: rÂ秘鲊ơ煥ËI5ɠv蜺 +tests: + enabled: true +tolerations: +- effect: Ɍ + key: P5n9NT + operator: hKW塀Bʊ祆aTɋw + tolerationSeconds: 4112555560826291604 + value: WHYsAK +- effect: Ŵ夀D朩儿 + key: QW09kcw + operator: K嗂ɩ + tolerationSeconds: 1977367920031301876 + value: FxI4 +- effect: 虻~ƤɟŪm繒敏嗕?ʅ着é殮领 + key: nkzGJU9 + operator: M鏫ɮ噀屗pq)ɋɎN + tolerationSeconds: 1704904114127412585 + value: AgyEeU +-- case-032 -- +affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: {} + weight: 735732238 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: cFkyLM + operator: 岊B + - key: V3cKSq + operator: ǟ濈1ɑÎ"孲ȀŨFhŲ + values: + - hz + - matchExpressions: + - key: 8N + operator: 9´敤T + values: + - amWROpS + matchFields: + - key: 7hmWbsKS + operator: "" + values: + - lS + - slkOyX + - YlwPcdVh + - matchExpressions: + - key: n5YD + operator: Əüʢ軾ŚũɳnŒ + values: + - 5s4eD6x + - WMkZIzS40rxp + - zCnW + - key: JawyIOLo + operator: 巳c習Gnƛ{ɩ¯Ĭ枺lȜʩ泿趏ǙĊi + values: + - Fvzyw13fUZC + - 4w9T3GeG + - mVj9N + matchFields: + - key: 4amyTWvhx + operator: Ąŵ8雌%ɸ*W褒卒S + values: + - cPr0Nm2WFo1dBq + - a + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: XgsMMBS + operator: ȗ諹 + values: + - foI + - NN1yiUNR + matchLabels: + Qq: VB19aUlI + mismatchLabelKeys: + - hcD + namespaceSelector: + matchLabels: + vMT90cNq3PYf2z: upe + topologyKey: RSVn9W + weight: 603398420 + - podAffinityTerm: + labelSelector: {} + mismatchLabelKeys: + - 4IL0rEe9 + - yY0RMU2 + namespaceSelector: + matchExpressions: + - key: tIka9jS + operator: 7怘xə4ÏɦW + values: + - l + - ajs6c + - hkYj + - key: Qu + operator: ʊ鏀ɑ蒀刹gE + values: + - 2UvY + - hRB1wKXyHi9 + topologyKey: ZKWyn5kI + weight: -1674108352 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: KQfZ4 + operator: ġȁAu盝ȭƈŦ齬{z + values: + - itNS0T + - jL + - key: q0HemjU + operator: e銳ȇ葁õDÏ筃 + values: + - M5yeE + - gJJY + - HInHzXgX + - key: d1LKZ1 + operator: Q + matchLabels: + XElv: QGJ + nD: kNCk5qe + wUtw34v: sCjj5z + matchLabelKeys: + - ej9hOPjp7W + mismatchLabelKeys: + - lhU9gP + - T7rMlvu + namespaceSelector: {} + namespaces: + - ii3aa + topologyKey: 8U7 + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: CkQsu4fS + operator: 鄦&ɲȅ + values: + - RVnwZ + - EVk + - key: yt + operator: 傓N嬅宠H^÷ + values: + - 1L + - rVQPs + - dUHOKQ + - key: hQ1Tl + operator: ɣë筁尻!絜辩^riʨ莠8dƋ + values: + - 4D6Y + - 5TXh + - 8RH + matchLabels: + "9": jb2X + IdL: PQj0N + iB09Upiijt: JpN + matchLabelKeys: + - rKS9p8 + - sK8p + namespaceSelector: + matchExpressions: + - key: KQ6 + operator: '篛I6ÝBŘ F媍/:' + values: + - NXP47Fm + - Z0Qh2Y4 + - JeWX + - key: Yh + operator: '!j3W' + values: + - mTm5dkO58H + - "" + - key: 6q + operator: 景¨Sŝvo/ + values: + - TrgtrP + - zqIsId + matchLabels: + 7E3A1K: "7" + 63IlVL: aSxc + W1hP: 1H9k3O + namespaces: + - "" + - 2Ma + topologyKey: FFqt + - labelSelector: + matchLabels: + "": wklJJ + C8JZ: LP + U1pz: kAE1l4 + matchLabelKeys: + - shj5V + - oU074y + - Ufq2w + mismatchLabelKeys: + - oBzMiOSgd + - iSF + namespaceSelector: + matchExpressions: + - key: fCbLu + operator: 塊衅m鑀ȣ戢ŭ阻蹯ȟ獇ɨ + values: + - B6TgQ75 + - FAHTEOSesQ + - Ms2Kw7XQ + - key: 133fMqId + operator: "" + values: + - pJc0Zu8 + - T1PEuV0uism + matchLabels: + 1rfPa2b4Ny: cemR + Np9l: lcX + SjNYy4: VZX + namespaces: + - 7W + - umFBWrpUDHv + - "" + topologyKey: pPUIqPXo +annotations: + xpNWT: MpOZ +automountServiceAccountToken: true +autoscaling: + enabled: true + maxReplicas: 459 + minReplicas: 198 + targetCPUUtilizationPercentage: 497 + targetMemoryUtilizationPercentage: 146 +commonLabels: + B19ue: 8W + Kxm5R1: R + e3Cx: MIAO +configmap: + create: true +console: + roleBindings: + - K8wnWSD: null + bwYE7: null + y4j: null + - GvFfKdgL: null + enU8G4: null + wvnJcOn: null + - td7: null + roles: + - YQBucbbDX2R: null + - 2UuDKjR: null + IV0Yus9: null + ci20SljQkhw: null +deployment: + create: true +enterprise: + licenseSecretRef: + key: bujGpO7D0C + name: V +extraContainers: +- args: + - T + - Pvf1yAamEa + - jQE8UakuY + env: + - name: 3g + value: JexRP + valueFrom: + configMapKeyRef: + key: QZ + name: QcC + optional: true + fieldRef: + apiVersion: Iv + fieldPath: d7xQ + resourceFieldRef: + containerName: jLpJ + divisor: "0" + resource: m + secretKeyRef: + key: Quhh + name: HUhzPAEo85 + optional: true + - name: ehSBff + value: nHu + valueFrom: + configMapKeyRef: + key: v3Icanu + name: dNPJ8 + optional: false + fieldRef: + apiVersion: xO7UQDq0 + fieldPath: gAyGB6Nj4 + resourceFieldRef: + containerName: Bs2D + divisor: "0" + resource: xJCQsH + secretKeyRef: + key: 3T6tjIQWa0C + name: 8TvRbhP + optional: false + envFrom: + - configMapRef: + name: mf + optional: false + prefix: pZxp + secretRef: + name: v + optional: true + - configMapRef: + name: wosjc9 + optional: true + prefix: ehhmFeLY + secretRef: + name: Ll + optional: false + image: kZ8UUm + imagePullPolicy: Ɓ + lifecycle: + postStart: + exec: {} + httpGet: + host: K29SzZPo + path: y2bQL8 + port: Cr + scheme: 轂Ì蕏ʋ + sleep: + seconds: -3765902632580054640 + preStop: + exec: + command: + - 1pT5X + httpGet: + host: NouEQF + path: WITzSW + port: 1565482371 + scheme: ƒ塒廛鎐藽瀫 + sleep: + seconds: 1831382645860081979 + livenessProbe: + exec: {} + failureThreshold: -1525719681 + grpc: + port: 99688681 + service: xa0sl3k5KM + httpGet: + host: prjHPqf + path: RHwZIE + port: 2UZ7hXI + scheme: 瑀ċ廤ȵ + initialDelaySeconds: -1367665605 + periodSeconds: -1023789296 + successThreshold: 206844073 + terminationGracePeriodSeconds: -3901072071078889022 + timeoutSeconds: 1670691424 + name: t + ports: + - containerPort: 2046398071 + hostIP: pJg + hostPort: -1247541550 + name: DrYeHQ6 + protocol: ²ȑBŸ + readinessProbe: + exec: {} + failureThreshold: 852505381 + grpc: + port: 8093048 + service: "N" + httpGet: + host: uuaPC + path: Mpxk6p + port: -297149767 + scheme: 這伦礗鯪àe]雚腴k£ɂ闧ɦĚH鏰浳 + initialDelaySeconds: 296244720 + periodSeconds: 1237321103 + successThreshold: 722306410 + terminationGracePeriodSeconds: 7739978307238029730 + timeoutSeconds: -2129506856 + resizePolicy: + - resourceName: NBfNOBC + restartPolicy: ƞdWǝi鎠R殩杜Ś晚尒尧ǐ; + - resourceName: oDw8xEb + restartPolicy: ja侬ƕ + resources: + limits: + BJcVkW: "0" + Ub5Spt: "0" + nWi63TNlCyM: "0" + requests: + e5vcw0H: "0" + eKz0z: "0" + gK: "0" + restartPolicy: 嗈ǒɟNǭ臥穥Ť + securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - $拷霒Ø耖} + - ijĸN藬?w粯痵餒薃辕5勅ů + - 幒Ƹʁòĺǂ浼GX + drop: + - 宖 + privileged: true + procMount: 凝 + readOnlyRootFilesystem: false + runAsGroup: -7000080292188880782 + runAsNonRoot: false + runAsUser: 9107304642056618949 + startupProbe: + exec: {} + failureThreshold: -208121509 + grpc: + port: 133215347 + service: pj4Kw + httpGet: + path: hGLW3 + port: -239286046 + scheme: YsÌǮŦʁ¡ē峪3 + initialDelaySeconds: -817672524 + periodSeconds: 1846655614 + successThreshold: -243958761 + terminationGracePeriodSeconds: 4190490525804645179 + timeoutSeconds: -973067987 + terminationMessagePath: 9vMe3Y + terminationMessagePolicy: 雍Wȯ嘷台厃$Țʍ13b霞两e + tty: true + volumeMounts: + - mountPath: yZbL + mountPropagation: 鲫絎Q(銞ÎÕX堙Ľ銃曅注t锋ɮj覧« + name: UFfAqsgd + subPath: wSo + subPathExpr: bIsBP3O + workingDir: DYBcINRq +- command: + - wgBryFN + image: NorbK + imagePullPolicy: 鉓Ĕʠ;兮)Frë + lifecycle: + postStart: + exec: {} + httpGet: + host: Z + path: 3v + port: W1vDkt + scheme: ŷ索gp=ŵāǼ餆嬦Ƹl媓R}豟ɠĖ. + sleep: + seconds: 1583583004300077159 + preStop: + exec: + command: + - XztEol6So + - GveA + - H4aUl + httpGet: + host: 75LDW + path: nu + port: I + scheme: 胛Uȁ¬ + sleep: + seconds: 4617693270470586770 + livenessProbe: + exec: {} + failureThreshold: 1423393786 + grpc: + port: 2097410769 + service: "" + httpGet: + host: W7 + path: PyPprD6 + port: dHwCyz + initialDelaySeconds: -1439644816 + periodSeconds: 182024489 + successThreshold: -1861505070 + terminationGracePeriodSeconds: -4166230023615503394 + timeoutSeconds: -704907360 + name: sFz5 + ports: + - containerPort: 1977465061 + hostIP: kxqRig + hostPort: 393211643 + name: DRO + protocol: ķǔȈ + readinessProbe: + exec: + command: + - mn + - 4TZCjrWPW18 + failureThreshold: 972699487 + grpc: + port: -1384519737 + service: IY5quWWV4JC + httpGet: + host: wq91i + path: Zy + port: -1192576969 + scheme: Á^_ + initialDelaySeconds: 2107832874 + periodSeconds: 1041520026 + successThreshold: -118135340 + terminationGracePeriodSeconds: -4946782594204672541 + timeoutSeconds: -1933961678 + resizePolicy: + - resourceName: MG7PMkMMObJJU + restartPolicy: §觫困Ȏ龝ƃȃɩ芴ÎĽ + resources: + requests: + I4: "0" + zLy: "0" + restartPolicy: 粛醑綇蝙Ɣò犁鶓A + securityContext: + allowPrivilegeEscalation: false + capabilities: + add: + - 掀ǃA颺LnFąɏ動 + drop: + - 输6sĺ宯hĢ + - ĨƨO檔暰z + - Neɬ慿Ȁ0ɳ蠈ǚǦO¸Ğ崔ʂ¢剚 + privileged: false + procMount: 翄怉DžǬ?胉獄ǙƊɚx虉F + readOnlyRootFilesystem: false + runAsGroup: -1943526545280953812 + runAsNonRoot: true + runAsUser: -7089742793545456579 + startupProbe: + exec: + command: + - hDj + - ONyz91fkTFY9t3 + - ynDWkO + failureThreshold: -5561223 + grpc: + port: -1069825885 + service: oQmy + httpGet: + path: l4sWc + port: 53AhP + scheme: ȩ + initialDelaySeconds: -6165070 + periodSeconds: 1844899228 + successThreshold: 903779261 + terminationGracePeriodSeconds: -3909221818854749789 + timeoutSeconds: 746670574 + stdinOnce: true + terminationMessagePath: egr00cLki + terminationMessagePolicy: ɯ2鰌^坪yN蠏Ĵ + tty: true + volumeMounts: + - mountPath: YOyu1MjxN2 + mountPropagation: :鸛o鮓L`<]ơ1b忙n鲃{< + name: dODfVz + subPath: ZknFq + subPathExpr: oX1n + - mountPath: 4TEsoc + mountPropagation: 帺Õ斯剅ƫf鳌麓HƸŘÂ瘖?謾軌 + name: hau + subPath: w24Wq4e + subPathExpr: i2TEix + - mountPath: uuujj + mountPropagation: 氻ʃ2NFJ啼铗"O{À-ŧLJ弟 + name: klnXhhnxKk + subPath: SEx + subPathExpr: CK2FmmyYThL + workingDir: NCvZAa +extraEnvFrom: +- configMapRef: + name: nJXDn + optional: true + prefix: g3ZpAEUJC + secretRef: + name: 5Yin + optional: true +- configMapRef: + name: spYG9o0 + optional: false + prefix: Wv01 + secretRef: + name: BxDbe + optional: true +extraVolumes: +- name: 1zZI6J +- name: D +- name: OUqOnvjvba +fullnameOverride: llK4G +image: + pullPolicy: "" + registry: mU + repository: xY76Tj + tag: AgKh6S1 +ingress: + annotations: + Lhm: f24CRNEJvs + pk6fq: "2" + className: EXqR + enabled: true + tls: + - hosts: + - xEciJGskt + - pBxfBltrqACoat + - INyj + secretName: Qy + - hosts: + - F6sf + - EHuJ + - 95my0 + secretName: XOIr +initContainers: + extraInitContainers: nNSsTt6 +livenessProbe: + exec: + command: + - poXliUr + - PT + failureThreshold: 1396135036 + grpc: + port: -224883306 + service: 3pE97 + httpGet: + host: aUivZn75m + path: ELvTnGaV + port: uLGz4AgHb + scheme: ʟ#ĭ輑槳桓ȡȰ-o廕óʒÉ帇ʗ + initialDelaySeconds: 1526591550 + periodSeconds: -972224922 + successThreshold: -39437670 + terminationGracePeriodSeconds: 2216517890191965292 + timeoutSeconds: -1229662908 +nameOverride: wB +nodeSelector: + ih: xT3Dk3PXT + xhq: vu + zLR9: wFjrfu +podLabels: + So: waKMMvnY + VXPE0: 8ExVsj + ip1RGEzt4t6: "1" +podSecurityContext: + fsGroup: 7101468120327600630 + fsGroupChangePolicy: ȴ鳁ƨ殳h`熡ƍʊ0ŀ擳琗图.AƱX滋 + runAsGroup: 4262945102741076844 + runAsNonRoot: false + runAsUser: -9214274730002703336 + supplementalGroups: + - 4135587743067906306 + - -2908166639165702539 + sysctls: + - name: Yo9 + value: zak2 +priorityClassName: WeB9y8 +readinessProbe: + exec: {} + failureThreshold: 1061708880 + grpc: + port: 241985990 + service: 4id9HdK + httpGet: + host: PcSuBI + path: X5YjgFI2n + port: -1395013021 + scheme: Ȁ/ŚDŽR²庭$ê-d蟄Ä + initialDelaySeconds: 1618839364 + periodSeconds: -2098998213 + successThreshold: -846859522 + terminationGracePeriodSeconds: -4028618433241851907 + timeoutSeconds: 1824930679 +replicaCount: 371 +resources: {} +secret: + create: false + enterprise: + licenseSecretRef: + key: "" + name: be + kafka: + awsMskIamSecretKey: fs + protobufGitBasicAuthPassword: pUSXv + saslPassword: 1tdj + schemaRegistryPassword: iEgQQMH + schemaRegistryTlsCa: TlBV301 + schemaRegistryTlsCert: fRDnVgKC + schemaRegistryTlsKey: 0yblU + tlsCa: 4tIzJcND + tlsCert: NLnN + tlsPassphrase: iI + login: + github: + clientSecret: WHD + personalAccessToken: 9B7Wu + google: + clientSecret: UZnD3r + groupsServiceAccount: 9b + jwtSecret: cdvBine + oidc: + clientSecret: rQyq1alKY + okta: + clientSecret: ED1 + directoryApiToken: p + redpanda: + adminApi: + password: CWqwAXxFtl + tlsCa: gDQRbrAC8l + tlsCert: EDjU6 + tlsKey: Zm +securityContext: + allowPrivilegeEscalation: true + capabilities: + drop: + - 退晦Ţ鲛 + - '}ʄ攏嫫;Mǐ豒ɇf,搅Ð貑ș|Óf' + privileged: false + procMount: D + readOnlyRootFilesystem: false + runAsGroup: 1564095685271138849 + runAsNonRoot: true + runAsUser: -3929576237300142573 +service: + nodePort: 312 + port: 418 + targetPort: 486 + type: aaIqePq +serviceAccount: + annotations: + QHMG: ur9Qr + ZQRGr8gxPSL: BzNE1Ja0avq + yKwL8DJSG: SRC + automountServiceAccountToken: false + create: false + name: zpH +strategy: + rollingUpdate: {} + type: ȁ进辫fu +tests: + enabled: true +-- case-033 -- +affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchFields: + - key: 1O + operator: 拺5ř(Ƅ餕ʟ{鐻Ƈ + weight: -2070567569 + - preference: + matchFields: + - key: JlGR + operator: 脱?ĶA蛜頒ǽGǷ藸 , + values: + - 8zZEVom + - TY + - FSSQQ + - key: w3C + operator: sɯeM^筘褑 + values: + - Q + - i48uKb + weight: -1969968900 + - preference: + matchExpressions: + - key: ZsgVr + operator: Eȗ + - key: RfMZL + operator: "" + - key: r + operator: džɬ毿鵮V町iAÉ橁zy题ʔu7ÆO9 + values: + - uj8h + matchFields: + - key: "" + operator: :止褮Ȃ宸 + values: + - 9h + - Do + weight: 1160212382 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: nmW + operator: '%U<Ȫk7家fƥ降]:' + values: + - e4hDXWb9G8Qi + - SynNDfUn + - C8kz + matchFields: + - key: QO0Q + operator: l!m0ʒbƹ豫ň + values: + - eh + - key: VE5mZtP + operator: ~x蹵#ÂvǗRɩ啭Ö澭肞¤7跜庛Ɍ + values: + - yT + - key: 1Cony + operator: 阃 + values: + - ahj6j + - matchExpressions: + - key: TvhlZutK + operator: 5叹ùz + values: + - rog + - key: qLPNTFw8 + operator: 藘鸘Œé溇ʄsoɷƱǺȾ蹾K混īl軇 + - key: F + operator: 則Yǹ郰饉貓伜ſ0|麊 az襽准 + matchFields: + - key: VcfFwmb + operator: WJMU狰槃žiǶq挿} + values: + - b7G + - "" + - wzxeij27DD + - key: "" + operator: 殀ǥ + values: + - "9" + - 0E3EkrfSX + - vzth + - key: omoz + operator: e´Ģ桇适TŽǤʈ + values: + - TVj0W7 + - 7HjUt2w + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: nN1614M7 + operator: '鰺/堅ý髉铊ɇƴ2友凇3 ' + values: + - D0tt + - sG9E + matchLabelKeys: + - l + mismatchLabelKeys: + - vqTKCL2D + namespaceSelector: + matchLabels: + LIgB: qqC9YL + namespaces: + - BLdVDzfY + - eq + - qB + topologyKey: qwces + weight: 899210618 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: hIz8wo + operator: ĥ\{ė + values: + - ZwYh1 + - 4l9U + - Q5Io + - key: sd3eCUDob + operator: 蒴ǚ<灁Q柷娸颂嘃üĸƢı + values: + - U0 + - "" + - WXJjoBRKrfEY + matchLabels: + QSrEl7t0: hxsiSGCubb + mismatchLabelKeys: + - PiUy + - VhBWFCyx6C + namespaceSelector: + matchLabels: + G: 07tU6 + ZCO1QQK: b + uq: HISLIo9ZC + topologyKey: 87eQuI + weight: 1750437304 + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: nK0RSDE + operator: R(陛m诜ȯơȴ豨躻 + matchLabels: + CE9: u8FukDT + U5N: "y" + matchLabelKeys: + - 5I6wiiY + - JDZsP + - zGyW + mismatchLabelKeys: + - 4WZHZ + namespaceSelector: + matchExpressions: + - key: N9E9 + operator: ȅ)礯占鷨ʫɩfǡnʎə掅Ux曶HŁ遐 + values: + - JdC + - 3NS25HFHxU + - key: "" + operator: ı獗& + - key: q + operator: 髢£Ȋ泽ZwVfc剻Ţ嬊j + topologyKey: "" + - labelSelector: + matchExpressions: + - key: Tof0 + operator: ĥM:ɑȏF叆綯炩藁û漄f + values: + - jTpj + - gYZ8IIq + - key: avL + operator: ɼƌ壟.敾¦ + matchLabels: + P1w: Nb9t3e + matchLabelKeys: + - TkIx94Dmu + - 8KVE + - UEJW + namespaceSelector: + matchExpressions: + - key: gQOOR5Pz + operator: Ȁ蛝畆粔辧殤,ǔžɨʜ + values: + - MiGt + topologyKey: nn1x + - labelSelector: + matchExpressions: + - key: C + operator: 瘎%瑧¹$兤 + values: + - p5TR + matchLabels: + c9PNRTZ: L + matchLabelKeys: + - 9xrNO + - saFgUzTD530EV + namespaceSelector: + matchExpressions: + - key: "" + operator: 琨j貙ŰĤ煾骣ƢƐ肾Q`ĥ?舶 + values: + - "7" + - T4pSI + - key: u0lbHcT + operator: čÉ壶霻*ǻ蠦Źê潡%!Ȱʁr.ň沀痊 + values: + - voUu0X + namespaces: + - tX + - uDgtoDt + topologyKey: "1" +automountServiceAccountToken: true +autoscaling: + enabled: false + maxReplicas: 264 + minReplicas: 267 + targetCPUUtilizationPercentage: 341 + targetMemoryUtilizationPercentage: 404 +commonLabels: + gZ85uw3T: e + qO: F4dqLo67vKYZ +configmap: + create: true +console: + roleBindings: + - 7x: null + Ia1K2tdRuYi: null + j6c9: null + roles: + - {} + - 6Vndf: null + f: null +deployment: + create: true +enterprise: + licenseSecretRef: + key: 9y6KmPZ + name: QM +extraContainers: +- args: + - 3OUsoZkVHy + - Gn3 + command: + - NLtY + env: + - name: 51Xcm68sAs + value: PUTq + valueFrom: + configMapKeyRef: + key: udLx6h9 + name: wSgnPbc + optional: false + fieldRef: + apiVersion: oVPbc + fieldPath: CGK + resourceFieldRef: + containerName: Ind7j + divisor: "0" + resource: 9tlZc + secretKeyRef: + key: z2i + name: aloI0W + optional: true + - name: nGb + value: I91 + valueFrom: + configMapKeyRef: + key: Ft8IZO4DX + name: 7PY9CO1 + optional: false + fieldRef: + apiVersion: DysSUO + fieldPath: M + resourceFieldRef: + containerName: i + divisor: "0" + resource: mbVAnrQ + secretKeyRef: + key: ZVD + name: 4gLX + optional: true + - name: SEd7KC2 + value: I0 + valueFrom: + configMapKeyRef: + key: 71k + name: B + optional: true + fieldRef: + apiVersion: vJE + fieldPath: nvSzEcQ + resourceFieldRef: + divisor: "0" + resource: fYaXGkFYlrz + secretKeyRef: + key: xDT4Uhi + name: a + optional: false + image: NLoqH + imagePullPolicy: U肵銨龋搁}ŗ=;ī篱ɺ頁掆薑 + lifecycle: + postStart: + exec: + command: + - NAmBp8Ijy9vgKS + httpGet: + path: GukCZ + port: umdXEe + scheme: ɭL莒ƠĦZ¢.0tȠȴF梩¯牏GȐ + sleep: + seconds: 2463489515348869616 + preStop: + exec: + command: + - RAP7lxh + - 0WRf37xLvaEE + httpGet: + host: Xi + port: 395093084 + scheme: '}Ä*諓懚泾ıɥ磀>ȃÓ愍瘞5' + sleep: + seconds: -2989387296528249021 + livenessProbe: + exec: + command: + - AondI + - CvX + - X9Dwm + failureThreshold: -1669443788 + grpc: + port: 1602861347 + service: 5dF71q + httpGet: + host: yOYLS + path: m99M + port: 1421693426 + scheme: cǶ嫙x勬´筮 + initialDelaySeconds: -348887387 + periodSeconds: -855526929 + successThreshold: -1868658835 + terminationGracePeriodSeconds: 7220662525875543964 + timeoutSeconds: -893266456 + name: 62y7 + ports: + - containerPort: 41082986 + hostIP: H + hostPort: -671022955 + name: Q + protocol: Ģ + - containerPort: -676585553 + hostIP: jdTqIIXMX + hostPort: 441858691 + name: bam + protocol: ã鯑 + readinessProbe: + exec: {} + failureThreshold: -1607827734 + grpc: + port: -732628448 + service: d + httpGet: + host: q2uSglvPX + path: 5YB9kNfy37 + port: -425352890 + scheme: ZʇįʔÌ玫Ʊ儝$緀ƥǣ鮀 + initialDelaySeconds: 1646541382 + periodSeconds: 597275764 + successThreshold: 1444783765 + terminationGracePeriodSeconds: -4224719974242331571 + timeoutSeconds: 1778484407 + resizePolicy: + - resourceName: YWwAdc + restartPolicy: 蓊ƽqs洊蛀Ƴ澠誉 + resources: + limits: + 9c5: "0" + DJI: "0" + uyw: "0" + requests: + 7livK1: "0" + PWZFD5fFpVA: "0" + restartPolicy: ǐ踊丸y苡汎0塛yM眗酊L攚dzyÚmG + securityContext: + allowPrivilegeEscalation: false + capabilities: + add: + - țƒ摨1娣Q札遢ʌā4魯 + drop: + - W~ + - ȮnLv|麬O稕Ʉ幖0Ţ&揵¸ + - àPĪɉɯ鋹芨ȲƿƛĞx + privileged: false + procMount: ɉq$|ŀ蘨寱彣ɎȈORe]O掓I + readOnlyRootFilesystem: false + runAsGroup: -2438856757446632999 + runAsNonRoot: false + runAsUser: -8511671649189408390 + startupProbe: + exec: + command: + - "" + failureThreshold: 157629836 + grpc: + port: -20533111 + service: vASy4b + httpGet: + host: 94HpH + path: t70 + port: W59mpID + scheme: ħ6琏 + initialDelaySeconds: -146258274 + periodSeconds: 47385732 + successThreshold: -1646222325 + terminationGracePeriodSeconds: -5575789846018254584 + timeoutSeconds: -351943504 + terminationMessagePath: r0ZY2 + terminationMessagePolicy: 傂G嶃a橢抴=Ȃĺ庆ɏ鬹揖絴鹥ɣ¸Ȫs + tty: true + workingDir: XFFilzd +- command: + - VSuU6yfyc8y + - gLgP + env: + - name: PSOr4 + value: m2ujo1f4 + valueFrom: + configMapKeyRef: + key: B9Gc + name: BaR3c + optional: true + fieldRef: + apiVersion: OFu + fieldPath: Pydi + resourceFieldRef: + containerName: jPiF + divisor: "0" + resource: jyp8A7uPD + secretKeyRef: + key: fcGCM + name: Hs + optional: false + - name: Ax9HfRa4p + value: S3R2 + valueFrom: + configMapKeyRef: + key: ZDzzhFD + name: soDgOej + optional: false + fieldRef: + apiVersion: iSfQ + fieldPath: Plzxy53z + resourceFieldRef: + containerName: DfBt3S + divisor: "0" + resource: 757s44h + secretKeyRef: + key: bn2IGjj + name: x8E + optional: false + - name: r + value: PmO + valueFrom: + configMapKeyRef: + key: Htzib1 + name: gfbsiTcDY + optional: true + fieldRef: + apiVersion: Frhab7p2yh + fieldPath: K6XKg + resourceFieldRef: + containerName: CLX + divisor: "0" + resource: cq + secretKeyRef: + key: R + name: zPHkUHXQ + optional: false + image: bSZCow + lifecycle: + postStart: + exec: + command: + - "y" + httpGet: + host: 2cDO + path: L5m + port: yhJI + sleep: + seconds: 6222265361848815058 + preStop: + exec: + command: + - yVT + httpGet: + host: Ibt0C5XF + path: Kf7kW1 + port: Tlj66QW + scheme: 砰僮 + sleep: + seconds: 4926532563180301873 + livenessProbe: + exec: {} + failureThreshold: 982752870 + grpc: + port: -257993986 + service: XKTDj + httpGet: + host: 7vfaAybCd + path: GuTTi + port: 1952486193 + scheme: 馾耼qȩ罔磙ɮƥŴ²叇yēņȮ藺 + initialDelaySeconds: -817095459 + periodSeconds: 603211453 + successThreshold: -1693358568 + terminationGracePeriodSeconds: 3002071779676478929 + timeoutSeconds: 992801771 + name: 9QZX + ports: + - containerPort: -1838828544 + hostIP: cQQMftB + hostPort: -321659395 + name: XBD7a + protocol: '>V>ŝO随;YƁ' + - containerPort: -439290918 + hostIP: Bp0lf + hostPort: 431013681 + name: WQ5qc + protocol: 髄Ĝ估螗ȳ鎷ʫh + readinessProbe: + exec: + command: + - PjwAB3G + - k + failureThreshold: -2015478850 + grpc: + port: 156976837 + service: RSgDfH + httpGet: + host: Yi7aQ + path: 8Ql9 + port: 1150587533 + scheme: C箿i綔ȍȢ ŅŴ娒燸孆5乬瓤Ɛ + initialDelaySeconds: -486757233 + periodSeconds: -994300453 + successThreshold: 2128356439 + terminationGracePeriodSeconds: 4683705418302064343 + timeoutSeconds: 1635565784 + resizePolicy: + - resourceName: deutsepb + restartPolicy: õ崑o¾oɞø°ŮƑ欩Ʋ + - resourceName: WaO + restartPolicy: ±蜊ư蕭材y昍U + resources: + limits: + XiOokB: "0" + gxJ8zn4y: "0" + requests: + "": "0" + RFaH: "0" + restartPolicy: 7岻ðȸɉo熮燍ȉ=n + securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - 迠譚綞撪颫,ʖʃ佞诌Ŧ丞śɧ璯PʥT + privileged: false + procMount: 荞£DS + readOnlyRootFilesystem: true + runAsGroup: 6728166770219183734 + runAsNonRoot: true + runAsUser: 2918288689668335051 + startupProbe: + exec: + command: + - o + failureThreshold: -949081542 + grpc: + port: 220928812 + service: EIuHGNT4 + httpGet: + host: 21BmFcJ50ov + path: WC7WP + port: njQtxPF + scheme: 鲰ʌȱ卹烛橇淃ō雀)缅tb憅棔JǓ*ɒ + initialDelaySeconds: 1631334347 + periodSeconds: -785602818 + successThreshold: -1111896125 + terminationGracePeriodSeconds: -8014749222013301241 + timeoutSeconds: 795835881 + stdinOnce: true + terminationMessagePath: m08AZSt + terminationMessagePolicy: 盛P1砦ǚ瀱#Ʌ穇嘜\Ɍ + volumeDevices: + - devicePath: NdQPZme + name: uHcdGnKv + volumeMounts: + - mountPath: IX + mountPropagation: diȔiN6ļɃƐ釭卬O + name: fPg + subPath: iY + subPathExpr: U + - mountPath: E + mountPropagation: 1ĵ氓ŝ瘛o扬=[蟗 + name: xt + readOnly: true + subPath: 2KRhR + subPathExpr: Vm0HMwn + workingDir: jusEo +- args: + - Ejt + - DYgNM8X + env: + - name: HkwQ + value: fpHbv + valueFrom: + configMapKeyRef: + key: 3e + name: Q + optional: true + fieldRef: + apiVersion: lh + fieldPath: "" + resourceFieldRef: + containerName: E1uEhn3 + divisor: "0" + resource: 0Pa + secretKeyRef: + key: co85cv7H + name: KL1I3G + optional: false + - name: 5MQMJhqUni + value: 34PEKwUkR + valueFrom: + configMapKeyRef: + key: ABhM + name: qq5b + optional: false + fieldRef: + apiVersion: vCLN + fieldPath: tge3Z + resourceFieldRef: + containerName: ST + divisor: "0" + resource: qFS8 + secretKeyRef: + key: Am + name: BLI353a5GI + optional: false + envFrom: + - configMapRef: + name: KBum1 + optional: false + prefix: 56g + secretRef: + name: zt5 + optional: true + image: XgUFG + imagePullPolicy: 锄ģnj[眈例ƚ淍ƁĐ~ + lifecycle: + postStart: + exec: {} + httpGet: + host: Yp7F87b + path: "y" + port: OtElY + scheme: ǐʮŕ + sleep: + seconds: 640752187186511134 + preStop: + exec: + command: + - 4GYkI2pQ + - QB + httpGet: + host: DFjlmWGAFM + path: qLfFaRePdtA + port: GTUH4 + scheme: 罛&ĥ顱Ƌ + sleep: + seconds: -1289822532228205848 + livenessProbe: + exec: + command: + - youyR + - J + - IiK3AJ + failureThreshold: 527043957 + grpc: + port: -1790391516 + service: wFKNeu + httpGet: + host: TjItsuCL + path: Lo07CoiEpmJ + port: 1449812891 + scheme: 聗œdz_x忔8 + initialDelaySeconds: -923296146 + periodSeconds: -920279093 + successThreshold: 1372003156 + terminationGracePeriodSeconds: 4545671926845562588 + timeoutSeconds: -1730135112 + name: ouxZOTiA7 + ports: + - containerPort: 365499724 + hostIP: c3z3 + hostPort: -1622732613 + name: jfpQ + protocol: 鬍匤<ɔɟǜ鼴`ʃ荞ɗ线亮Ô¼ + - containerPort: 387750436 + hostIP: 7OF + hostPort: -922470687 + name: 20ZoNWnefc + - containerPort: -1003650010 + hostIP: yK31 + hostPort: -479225666 + name: 1Up + protocol: 郣-齡^c艃7ɑU牌驀墭:煞 + readinessProbe: + exec: {} + failureThreshold: -189409295 + grpc: + port: -880806937 + service: N1zEO + httpGet: + host: vN9 + path: n8TKqPF + port: -995680865 + initialDelaySeconds: -2090855365 + periodSeconds: 1849358636 + successThreshold: 811072097 + terminationGracePeriodSeconds: -5833095732594202880 + timeoutSeconds: -65186305 + resizePolicy: + - resourceName: 9rUpDkTFnW + restartPolicy: KSʮ1ĩ`乀_Ɠ颩紵 慒¨ƶ挢¸s诡 + resources: + limits: + MYEa: "0" + ngW: "0" + requests: + 174vfq: "0" + restartPolicy: 軵ƿǽ嚢遳E + securityContext: + allowPrivilegeEscalation: true + capabilities: {} + privileged: true + procMount: Ő\烔Z座畄睸zɩCɎx簫S悍a + readOnlyRootFilesystem: false + runAsGroup: -6410700953715650696 + runAsNonRoot: true + runAsUser: -8187102783441071897 + startupProbe: + exec: {} + failureThreshold: 1640672315 + grpc: + port: -799307372 + service: w9KE22PLk + httpGet: + host: e6Zo4rWs + path: tscGwI + port: 2071839677 + scheme: '&ǂȞ<辳)9撆ʚ6&U}P%捸`y' + initialDelaySeconds: 652003075 + periodSeconds: 1077051101 + successThreshold: 1528128815 + terminationGracePeriodSeconds: -2176015428967645191 + timeoutSeconds: -998563216 + stdinOnce: true + terminationMessagePath: P + terminationMessagePolicy: 8痃v7ȱ噣愜Å%Ġ3 + volumeDevices: + - devicePath: k8uvc + name: GL + - devicePath: 31O9l + name: ivY + workingDir: PtgSFsc1GvC +extraEnv: +- name: RTz9f + value: kK5WtZCFpsl + valueFrom: + configMapKeyRef: + key: CB1UV + name: 0pF + optional: false + fieldRef: + apiVersion: xO4s + fieldPath: n2G + resourceFieldRef: + containerName: GmnwMQ + divisor: "0" + resource: yX30Dke4u + secretKeyRef: + key: vPbHh + name: oBAn1EoZmPzN + optional: true +extraEnvFrom: +- configMapRef: + name: lo + optional: false + prefix: mSdySXyKqEkl + secretRef: + name: t4daT3 + optional: true +- configMapRef: + name: IFTvBGq + optional: false + prefix: qKk6o + secretRef: + name: "4" + optional: true +extraVolumeMounts: +- mountPath: gRGvu + mountPropagation: Ŋ4ǔ盍薟惮睌ȿ濍ȯȀüƳ$ + name: oJv65V + readOnly: true + subPath: P20XHtoR + subPathExpr: SzD +- mountPath: xhuwGvn + mountPropagation: 搛悈nj鰣*颵俠Ʀ慫灗岵ȆǴ騔Ė栢č)q + name: ebDa1q2nKt + readOnly: true + subPath: "6" + subPathExpr: N0xOT +- mountPath: xHTM + mountPropagation: 0關ɮUeŪ + name: P8noEsWy3t + subPath: y5E + subPathExpr: oP2A6C +extraVolumes: +- name: MqQb15NA +fullnameOverride: foGC +image: + pullPolicy: 躂Qʢ瞶CǁȮ + registry: JWsGq + repository: JAUpWzFL + tag: 3WF1aV +imagePullSecrets: +- name: s1B +- name: R54rm +ingress: + annotations: + "71": 1aSj + B3N4dn: hsJR8Fl + S9: x8u + className: xm + enabled: false + tls: + - hosts: + - 6PBjnokDE5 + - df + - SMIi + secretName: VVeSdJP + - hosts: + - kY + - VSdS4nZ + secretName: rR5tuP +initContainers: + extraInitContainers: DZkf1 +livenessProbe: + exec: + command: + - b5k + - "8" + - 74zV7hI + failureThreshold: 604102540 + grpc: + port: 1351493068 + service: a + httpGet: + host: pbTe + path: l3E3mpnq + port: nBQsx + scheme: . + initialDelaySeconds: 93396392 + periodSeconds: 1323534907 + successThreshold: 2044410955 + terminationGracePeriodSeconds: -5171571423145940595 + timeoutSeconds: -725304614 +nameOverride: bCPeYVWao +nodeSelector: + TDma3: eGasO + cs6G: CyEFp0L + r: xdylcKb +podLabels: + 1bb6: "" + 3U: mfPv + T: Q +podSecurityContext: + fsGroup: -4412504815274791692 + fsGroupChangePolicy: Ȯƭhjb糯妔ȂǑʜ胴}轣 + runAsGroup: 3860793197532219812 + runAsNonRoot: true + runAsUser: -1963293898483195295 + supplementalGroups: + - 2429921255984048344 + - -2773566751575632894 + - 5629450590441918989 + sysctls: + - name: h + value: zKVw + - name: D5ekUqS2 + value: 5FxU + - name: dgHyyau + value: o +priorityClassName: uHKqx +readinessProbe: + exec: {} + failureThreshold: -1216486926 + grpc: + port: -173591622 + service: CPUt + httpGet: + host: hry + path: KRRaps9O + port: W + scheme: ƈ;黷ç駵P!瘠瘀/ǹ + initialDelaySeconds: -1636119248 + periodSeconds: -1587206371 + successThreshold: 1085720843 + terminationGracePeriodSeconds: 788084162692446331 + timeoutSeconds: 1603673472 +replicaCount: 390 +resources: + limits: + HS: "0" + sspp8OAsyF: "0" +secret: + create: false + enterprise: + licenseSecretRef: + key: enS + name: "" + kafka: + awsMskIamSecretKey: 6Rpozk + protobufGitBasicAuthPassword: b9bAHSr + saslPassword: xFMbXwVAO + schemaRegistryPassword: wMc7l + schemaRegistryTlsCa: Iqy + schemaRegistryTlsCert: B2Y5 + schemaRegistryTlsKey: ooeFo3mZ4 + tlsCa: YCVA9R6f + tlsCert: b5AAaCcgXX + tlsPassphrase: HVdFrCml + login: + github: + clientSecret: JWVOWiL + personalAccessToken: B6DA + google: + clientSecret: lk1l + groupsServiceAccount: KFTHdrXBq + jwtSecret: IfZ3S + oidc: + clientSecret: 33jad4PG + okta: + clientSecret: pEYKMXqE + directoryApiToken: S5N6 + redpanda: + adminApi: + password: cNTmA + tlsCa: Ymp + tlsCert: 5Xquj + tlsKey: f2AsWMK +secretMounts: +- defaultMode: 64 + name: v1bEam0d + path: WfYQ + secretName: FOCtz7x +- defaultMode: 494 + name: 2keqwtlu + path: hpZaUwi + secretName: 1dug +- defaultMode: 354 + name: RAI0g6yvn + path: bCeiaipj + secretName: "2" +securityContext: + allowPrivilegeEscalation: true + capabilities: + drop: + - ɇǎȬ+丰DZ}薞ɎƐ + privileged: false + procMount: Ȧ杖煃a/ɓ<3ő+笽pȗdzSj + readOnlyRootFilesystem: true + runAsGroup: 8336843233603802952 + runAsNonRoot: true + runAsUser: 956863148985923497 +service: + annotations: + lrtdFF: 60R7 + nodePort: 446 + port: 229 + targetPort: 59 + type: 2K35 +serviceAccount: + annotations: + M: 37JLL + TSllzWgI: ZA + gOSHO: 00aEHRLh + automountServiceAccountToken: false + create: false + name: S9Bk +strategy: + rollingUpdate: {} + type: 呇弰$腕煴贔棳軀+œʃǀŖ* +tests: + enabled: false +tolerations: +- effect: 酼駘宁ì<^ʉ逐GM¼韹宅劑圦ȢN鵸; + key: LjdOPUZjJ + operator: 窃銥ɺ嘭t緯ȇw,[t捻S麨vɂ閰 + tolerationSeconds: 1714321621775966634 + value: Uvm9nY3 +topologySpreadConstraints: +- labelSelector: + matchExpressions: + - key: AUro1 + operator: 聘 + values: + - x5E03owNK1 + - 61u06hoBRErcl + matchLabels: + HMA: 7iZSaiF + jCP15v: ksLC1iD + matchLabelKeys: + - cp + - CZpJKgP + maxSkew: 644443933 + minDomains: 1722624609 + nodeAffinityPolicy: ú(ʆɴȾ狍lfĒHȉ嫔7ix壿 + nodeTaintsPolicy: 遡lşř门Ǣl + topologyKey: qP + whenUnsatisfiable: "" +- labelSelector: + matchExpressions: + - key: i8xDfgO + operator: ʖĝ#烕ɋřĊI + values: + - bOA4n + - ByUsK + - key: 6fCdAFtmFF + operator: 靕ƭ錒Ĕ + values: + - JIMC2Pc + - a7wA08 + - key: xMn + operator: "" + values: + - gSa5XT + - 50IS6 + - "8" + matchLabels: + DoGCwvltR: vVXQcZcxdz + JLmhsQlh: L3AY0Pv + X9: U + maxSkew: -2038040013 + minDomains: -1884001920 + nodeAffinityPolicy: 嵋磋ɹ:ɢ慚TA烁.X幰 + nodeTaintsPolicy: 奒)ʅm=矕郔o鬻鴊ȵɯt债CŔ儤 + topologyKey: qkx4gKx7 + whenUnsatisfiable: 匊aO卞肝喚覕Ȭnr說ɉƢ/Æȧ婡賛 +-- case-034 -- +affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: {} + weight: -982889256 + - preference: + matchFields: + - key: XhG + operator: 萎Nc汏帞 + values: + - CY + - key: SQm3as + operator: :g憓痳ʑ^荔ĚE慮ǫ鶉 + values: + - gKNU + - "4" + weight: -2081315042 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchFields: + - key: "" + operator: '[棉' + - matchExpressions: + - key: YgpJq + operator: ës曬¡岹V瀈ȭ岅mK + - key: HKYARp + operator: '完RQ\u穩[憄籎禨 ' + values: + - 2wfWZQ9 + - key: M0 + operator: 酺縿Ȼ慭苾Ʉ6Ʀ + values: + - xr7e9 + matchFields: + - key: O + operator: 笿眷ē睡党ǎf鴋Ɗ給 + values: + - HjtABxYy + - key: TD8D + operator: Ȃ顈筻ůȳM!剢nZÁx.}鯡L颗eĵ + values: + - xDTUGq1 + - 9xI + - key: 2B + operator: ']ţ峝輴{ȳ鬻ŶøU)ŢŤ' + values: + - 8hQz + - BtJ6XJwj8 + - bB1HqX + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: QrP50c0 + operator: 2蕦!#ɺĠȿLy2ǽǃƝFʡ + - key: sh4AX + operator: '"ă粸Ǘ筽齣zƪƭŰ''鴚ǝʠƲy>A' + - key: AyAj1WrXn2nZbf + operator: 郥m,攃 + values: + - xuX0t + mismatchLabelKeys: + - 94CSmERwUUu + - "" + - 3lJqWyss + namespaceSelector: + matchLabels: + XPKK9buQTkk: hK + c6yMPKCuDUW: NaXtSSb31Vtc + topologyKey: 4IWq1 + weight: 1215591736 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: bKgv7w5BLU9 + operator: 佱$Ɛɯȳǚ½ȴk + values: + - Rc6Akw + matchLabelKeys: + - nj2vCk + - GT7VEmkOiP + - D81b9yrN + mismatchLabelKeys: + - xrrln + - "" + namespaceSelector: + matchExpressions: + - key: Okpa0 + operator: ȳɃ互B¸砂霿枹蔪 + - key: bG + operator: "" + values: + - 9Az3OOsKzxT + - qufp1g + - hPp0e + namespaces: + - ia + - wpgLWCg + topologyKey: t9 + weight: 1536631188 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: xCMZF2V + operator: p仯F寃Rm慽財Ū-宩>ɗ呈3嚱Y + values: + - 2IrEZ + - ox + - S1NOR4go + - key: M + operator: ƙ岉 ʛZ3 + values: + - 61kg + - gCY32n2G + - key: z7jqw + operator: '´鋁k透 ' + values: + - 3bI7Mo + - V15M6 + - Elw2un19FO + matchLabels: + "1": jTzLL + E3HVo8p: 8mRx + tHPA: X + mismatchLabelKeys: + - sA + - eKQcaD + - 67tHuF + namespaceSelector: + matchExpressions: + - key: CrZYZ + operator: FWɺŮ + - key: K7SRYb + operator: .ØƣƎ 對猣#倳s7Ǵ栔Ħn4 + - key: k2Bz + operator: "" + matchLabels: + r6: SsE6YhO00w + namespaces: + - bECP + - nZT + topologyKey: ATU + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: T8nB5f + operator: 虁Iɂ飇ě + values: + - bTYBHU + - PWWBtWcP + - key: BJo + operator: 焜Eâ簋@ʘ芮暸UĖ + values: + - DI + - dh9e + - 0hiMkvD + matchLabels: + 7TSrj3: t4aVDF0 + P8L: liB + TkxKc: 4k + matchLabelKeys: + - C + - Uxzu6ju3L0 + mismatchLabelKeys: + - 7JBQmr5 + - K2WwmaMb + - ZGo5q7x + namespaceSelector: + matchExpressions: + - key: "603" + operator: 溝ʫ"zNĂ + values: + - 217W38 + - DjaFqo + - 34Dd6xS + matchLabels: + Le1shqQ: q6Ra + jocxC9: 1wwizZ9OUc3 + t9v: p7 + namespaces: + - tNw7r0z + topologyKey: WB + weight: -695352638 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: Et + operator: "N" + values: + - iXi + - AZpWUZE + - bB + - key: 6e8xewD + operator: 拒D挼霘%Ǧ珕 + values: + - cLLOT + - LzhXzKVG + matchLabelKeys: + - v1hg0Fb0 + mismatchLabelKeys: + - i + - vh3C0ZF + - i694fjp + namespaceSelector: + matchExpressions: + - key: Rt + operator: 4%{ź*妻=舉佸EǩɛW杚察ű + values: + - gx + - x + - M0 + - key: S1J9kEl0 + operator: 湻膴L鮠#桽 + values: + - Lpx + - key: QzUh3 + operator: 閛V;Ĝ棱碗闃{竀%狮闀ʩE腡¹#C + values: + - qh0l + - Jgu1EIM + matchLabels: + tZ: y7 + u7: jkFA4i + namespaces: + - httsx + topologyKey: wNV2 + weight: -441999969 +annotations: + "": kBVzs + JKJQy: g8k + Zcnpm: TWUNV +automountServiceAccountToken: false +autoscaling: + enabled: false + maxReplicas: 23 + minReplicas: 122 + targetCPUUtilizationPercentage: 266 + targetMemoryUtilizationPercentage: 92 +commonLabels: + 0fz: qRhpB + blGSa: Hnim0SflkfpF +configmap: + create: true +console: + roleBindings: + - zktoFv: null + - BnTf: null + N30: null + O: null + - "5": null + up6oELWDxO: null + roles: + - 3vFSt6CV6h: null + - zwoEunAfS: null + - "": null + Kz: null +deployment: + create: false +enterprise: + licenseSecretRef: + key: wTtzVK + name: f +extraContainers: +- command: + - fbGgvGkx + - edBIWrM + env: + - name: 8jJnT7Zj + value: Mq + valueFrom: + configMapKeyRef: + key: JC + name: sVkSiknR2xCa3 + optional: true + fieldRef: + apiVersion: wANryBKXLB + fieldPath: NyZCECkxJ + resourceFieldRef: + containerName: OZ8 + divisor: "0" + resource: cmCxr + secretKeyRef: + key: DwO8j5 + name: B + optional: false + - name: EHh + value: QCji0tC6i + valueFrom: + configMapKeyRef: + key: WAw2dVgj1 + name: Ay + optional: false + fieldRef: + apiVersion: Qi + fieldPath: gpyTLtuoWjh2y + resourceFieldRef: + containerName: lU + divisor: "0" + resource: eblZRy9ULY2IzA + secretKeyRef: + key: mv + name: j + optional: false + - name: aUVmiB + value: kpqOP + valueFrom: + configMapKeyRef: + key: s + name: bQ6 + optional: false + fieldRef: + apiVersion: SdqbUuwjM + fieldPath: 2l + resourceFieldRef: + containerName: tw3t5LDN + divisor: "0" + resource: rwu + secretKeyRef: + key: 4BhlrEVh0 + optional: true + envFrom: + - configMapRef: + name: Hjuj9nlmmK + optional: false + prefix: 1f + secretRef: + name: ZAvqr + optional: true + - configMapRef: + name: xM7XvJNDv + optional: true + prefix: a3u3 + secretRef: + name: cvRqlow + optional: true + - configMapRef: + name: bRyp + optional: false + prefix: 5mEO + secretRef: + name: axWGwhmN + optional: false + image: EszTqv + imagePullPolicy: 輧脙ĭr恐荌ǩ\ȓȫ訷鿍湲瑁u楊禅ɤ& + lifecycle: + postStart: + exec: + command: + - WMJ1Vj + - bt + - UpuoW2L + httpGet: + host: ZQUCS + path: XvmuYh + port: p + scheme: 瘿ā|^k*雗 + sleep: + seconds: -4794985278116558932 + preStop: + exec: + command: + - fNY + - Rk + httpGet: + path: vcHj + port: 94X + scheme: ʕ煤}f + sleep: + seconds: -572101244460663065 + livenessProbe: + exec: + command: + - HoQxW7Nhx + - 1vL7TCk + failureThreshold: 1202856974 + grpc: + port: -177653984 + service: dd + httpGet: + host: cFj8k7 + path: l91YUo + port: -205856494 + scheme: '''朔6嚍¹*¢ɰȯK' + initialDelaySeconds: -1838390355 + periodSeconds: -2089935919 + successThreshold: 745930955 + terminationGracePeriodSeconds: 651854435833106407 + timeoutSeconds: -451727064 + name: LUkN + ports: + - containerPort: 52213129 + hostIP: pBen4iN + hostPort: -1605812710 + name: embL6 + protocol: 隠:ʀǙƴ茝鞝剟蚓遆積ǯ槦黽虼m + - containerPort: -1355336717 + hostIP: Vq9h1OAN6 + hostPort: 1469157628 + name: DgLmxr8 + protocol: ơ阆Ƃ + readinessProbe: + exec: {} + failureThreshold: 1404262379 + grpc: + port: 617847874 + service: wZ + httpGet: + host: 7f + path: 4gU9kDN5 + port: MXWfnK + scheme: 鬮ŵVƉ + initialDelaySeconds: -498539377 + periodSeconds: 1569378042 + successThreshold: 1909376148 + terminationGracePeriodSeconds: -3310812073755566654 + timeoutSeconds: 957960925 + resources: + limits: + 5k: "0" + wIlp6Km9XNo: "0" + requests: + RaT: "0" + restartPolicy: 车WđƜ嚓Ŭ罀ǑȪ + securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - w}ɼ簖#s>腭hWɘnj嗠/ʜ墭呣lj + - dT劍Il捝s+;暷ƻņʖ馺ª贐 + drop: + - '*¢炐96ʑ叛z¢á5ɏeEɢ@Ƨ' + - ƭ樯Ɉ>ƈ@Ɨ + - ńɜʢnij咓ƹ灀}¿\ + privileged: false + procMount: 堲渢)#珯犠ƙYĮ鷝Ƈ蚈_ + readOnlyRootFilesystem: true + runAsGroup: 5272751894835649479 + runAsNonRoot: true + runAsUser: -777021971579066284 + startupProbe: + exec: {} + failureThreshold: 48102716 + grpc: + port: -1093646129 + service: bIKooEs + httpGet: + host: Mv + path: fstI2uQ + port: Qd + scheme: dzLBʖ飐吃ê傧靲dz + initialDelaySeconds: -187921670 + periodSeconds: -217914776 + successThreshold: -664446049 + terminationGracePeriodSeconds: 8083333456613274947 + timeoutSeconds: 399455066 + terminationMessagePath: jqUx + tty: true + volumeDevices: + - devicePath: LLB2W + name: kDDD + - devicePath: 9DhP1 + name: aW0PgFJODCAEF + volumeMounts: + - mountPath: "4" + mountPropagation: ;bŊcN啲;蜩½ǒ朒Q"EƙȌ{甐岊 + name: c + subPath: c + subPathExpr: cXqUzbd + - mountPath: NY + mountPropagation: ʋS溸呖Ä翫ɧȐ{豒lÔș:ľ玠3íw + name: 7nseZUY + readOnly: true + subPath: itHF + subPathExpr: eHexIOW + workingDir: BZZ6 +- args: + - 5cCg + - E7 + - iFP6rZ + env: + - name: qEiC5K + value: HE + valueFrom: + configMapKeyRef: + key: Q4ff + name: c6s + optional: false + fieldRef: + apiVersion: jBI6X + fieldPath: zpTUfYD + resourceFieldRef: + containerName: mzmkl8 + divisor: "0" + resource: 81k8LI + secretKeyRef: + key: "" + name: N9yqj + optional: false + envFrom: + - configMapRef: + optional: false + prefix: WYG + secretRef: + name: DFBRLWb + optional: false + image: Z + imagePullPolicy: ǂAM鳘墊šéDz!迒A + lifecycle: + postStart: + exec: + command: + - r + - RbH + httpGet: + host: FG + path: gzf4kd + port: 813947014 + scheme: '&X垮Ą:S褦慺ʛ竆閃_m鑙òó' + sleep: + seconds: -1141547218815402249 + preStop: + exec: {} + httpGet: + host: ZA8qVd + path: 9ooQ + port: -271801527 + scheme: 鏡稂;ňȓRH愦Ƚ + sleep: + seconds: -8502483422139801966 + livenessProbe: + exec: + command: + - I4WNnF + failureThreshold: -637772395 + grpc: + port: -1513640963 + service: CpWh0e + httpGet: + host: JrZk + path: YCnQ4z + port: 13mIiI + scheme: 鏘 + initialDelaySeconds: -200843985 + periodSeconds: -502259067 + successThreshold: 1719668769 + terminationGracePeriodSeconds: 6044193620909725026 + timeoutSeconds: -388757192 + name: Vem + readinessProbe: + exec: {} + failureThreshold: 1932036046 + grpc: + port: 940655155 + service: h5HN + httpGet: + host: H + path: G1p4WFvGD + port: iMuM + scheme: ŗ颁njNą筵 + initialDelaySeconds: 271733079 + periodSeconds: 1483111043 + successThreshold: -1186732202 + terminationGracePeriodSeconds: 8539189418162863572 + timeoutSeconds: 1565787262 + resources: + limits: + AfrFB6Ne: "0" + UFzEjwa: "0" + regGR: "0" + requests: + 30st: "0" + restartPolicy: Ǫ豥ɗ槻T+Ĕʓȣ+卮Ȱ + securityContext: + allowPrivilegeEscalation: false + capabilities: + add: + - 1蒟顨ƽėȰ + values: + - TGv + - VVtqHApm + - 7Mub + matchLabels: + PI: elzxW + Wd1Q: MYEPScu1su + i: uENdc + topologyKey: QlwUBoDWM +automountServiceAccountToken: true +autoscaling: + enabled: false + maxReplicas: 367 + minReplicas: 105 + targetCPUUtilizationPercentage: 126 + targetMemoryUtilizationPercentage: 500 +commonLabels: + 5NU: UG7t + 6NmZI: QxuTdplvdDdc + BYcISWrd5: YZbXA +configmap: + create: true +console: + roles: + - CSJ: null + - 0hM2tbS5: null + ZhG3M: null +deployment: + create: true +enterprise: + licenseSecretRef: + key: xLO4B2BCZUJ + name: BQR2Y +extraContainers: +- command: + - DlBCuc8xa + - X2hi8Mp + image: 00GQ5 + imagePullPolicy: 賎ʂG}Ƌ煚6ūaĠ腻f + lifecycle: + postStart: + exec: + command: + - mVlE + - cFmlozRTJ + - "" + httpGet: + host: RIzcOYFo + path: eZge9wzJjW + port: ugY08 + scheme: 讣Ɨƶ"ɇǘƓƮ + sleep: + seconds: -5362042555365295319 + preStop: + exec: + command: + - "" + httpGet: + host: hLxRfJhv + path: JA8kOIY + port: tpH1 + scheme: '''k:嘡葊佒ďȏǓɡ毫/视倴ĩ}Ɓ u' + sleep: + seconds: -915316715834475044 + livenessProbe: + exec: {} + failureThreshold: 1628387875 + grpc: + port: -119747124 + service: 3cnWKI + httpGet: + host: 6Wzb9 + path: Af + port: RAzYX + scheme: 嘾Q經f + initialDelaySeconds: 4951530 + periodSeconds: 1309655668 + successThreshold: 918641827 + terminationGracePeriodSeconds: -3073080783253286451 + timeoutSeconds: -1896420637 + name: yML27O + ports: + - containerPort: 509868797 + hostIP: XMFIjyy7MNejY + hostPort: 2083818454 + name: gd + protocol: 槏 R¨ƽT³簑ƤA$<猿.0d + - containerPort: -164866787 + hostIP: eh + hostPort: 1842390272 + name: H7 + protocol: y擫`/洄]ʢÓ7Ā紐ǟ塋 + readinessProbe: + exec: + command: + - 5MrELPMn + - 23x1a + failureThreshold: 1394382122 + grpc: + port: -96138878 + service: DBq + httpGet: + host: 60SrHkgc + path: OwZeja1P + port: 721461548 + scheme: ' `$ħ' + initialDelaySeconds: -2125734502 + periodSeconds: 66441733 + successThreshold: 130216629 + terminationGracePeriodSeconds: -7113768241875088710 + timeoutSeconds: -977567736 + resizePolicy: + - resourceName: 8VNf4C + restartPolicy: Ě} + resources: + limits: + 2TX: "0" + Yd3: "0" + avcFFX: "0" + restartPolicy: Ę<彪6 + securityContext: + allowPrivilegeEscalation: false + capabilities: + add: + - ūW銹fn|óOB¶őǝ:ɛ暙- 嫴 + - 韣噺Ȑ主鋥Ɣ睩熾@Ĥvƈ + - 気ʎɭ愢勈īɔ垆ŀ槌,q儇p顼ǯ歳 + drop: + - EģIJ>筡|n譌ɶd2鍇$X/ȴ偎穾7 + - "赻探ǞiN胂a + name: 79CeZyd + subPath: xMQ + subPathExpr: NvU + - mountPath: smgfnmvP + mountPropagation: ʈ + name: CuKUC + subPath: hZ8KJ3 + subPathExpr: CK4WsX + - mountPath: zm + mountPropagation: 傩骟Ⱥ|尤fŇɓ呣ɘĩŽ + name: wRtUU + readOnly: true + subPath: T1 + subPathExpr: cidBhX8I + workingDir: M0jsi8 +- args: + - rQ7QBmZ4 + - Q32wY3lGUA + - VGeP + command: + - "6" + - 5vVr2Q + - 4YDd + env: + - name: DY1 + value: sge + valueFrom: + configMapKeyRef: + key: O8RUTpJ + name: SCF5ph + optional: true + fieldRef: + apiVersion: NY0hb + fieldPath: ViZ0f + resourceFieldRef: + containerName: "Y" + divisor: "0" + resource: sCX + secretKeyRef: + key: Ma + name: 6s6lc5 + optional: false + - name: m19lk2eiDtcdB7 + value: 0JaB + valueFrom: + configMapKeyRef: + key: VolU + name: jnFjMLIQ19 + optional: true + fieldRef: + apiVersion: "6" + fieldPath: N0wIEnFmQ + resourceFieldRef: + containerName: QwDG86d + divisor: "0" + resource: pda + secretKeyRef: + key: Uc7x1XF + name: efgc + optional: true + - name: 8A + value: 1kUmljHSb + valueFrom: + configMapKeyRef: + key: "" + name: z18yxT + optional: true + fieldRef: + apiVersion: 1qaE + fieldPath: vEzPx + resourceFieldRef: + containerName: GYhSz + divisor: "0" + resource: Ttq + secretKeyRef: + key: aaGRQS + name: C + optional: false + envFrom: + - configMapRef: + name: "0" + optional: false + prefix: 5cqcw + secretRef: + name: O7Gex12 + optional: false + - configMapRef: + name: DHEYwZ + optional: false + prefix: wSbyGx + secretRef: + name: 9nM86dZi + optional: false + image: E + imagePullPolicy: 栧Z + lifecycle: + postStart: + exec: + command: + - 6775E + httpGet: + host: hIoYmpbc + path: qEf + port: rnJpXG69m + scheme: 赙¯6a腚 + sleep: + seconds: 4894208532244895909 + preStop: + exec: + command: + - mHtY + - 0hh1Tr + - "" + httpGet: + host: BuElf + path: fJPDiyG + port: PybmIT + scheme: M*Ķ + sleep: + seconds: 7544543348205057985 + livenessProbe: + exec: + command: + - z7IJ + failureThreshold: -360493877 + grpc: + port: -1395908290 + service: zV1i + httpGet: + host: GLn + port: -279409955 + scheme: ǃU螄骰褃Ʀ诐Ɯ{,ɍb萎Ɲʢ鰪\U + initialDelaySeconds: 1831688310 + periodSeconds: -280461011 + successThreshold: 84363106 + terminationGracePeriodSeconds: 7513815341722354757 + timeoutSeconds: 442815657 + name: pGthpc + readinessProbe: + exec: + command: + - T39QO5 + - "" + - DbSsPel + failureThreshold: -1901163919 + grpc: + port: 1255815597 + service: xeTv + httpGet: + host: bipPJGJ + path: nghEbF + port: uyLPK + scheme: 翁渹牯澖 + initialDelaySeconds: 1295268788 + periodSeconds: 17921235 + successThreshold: -212369586 + terminationGracePeriodSeconds: 1061046207943693656 + timeoutSeconds: -1707711843 + resizePolicy: + - resourceName: RLHi + restartPolicy: 掳?帐(Ǖčĭ纜 + - resourceName: H1Bv + restartPolicy: Ɉ駃愝ɲƁ2*ʍJ蕦ʃĹr}尕5J埉g + - resourceName: f + restartPolicy: ɧ帨y晒ʪäǗ«ǤǞugT埤X澇寿Ù\ + resources: {} + restartPolicy: 7Y熀7rúǬ轘 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - Ǒn%Aʙ]m* + privileged: false + procMount: 鼷R珍沌 + readOnlyRootFilesystem: false + runAsGroup: -287129322294347273 + runAsNonRoot: true + runAsUser: 3942212766283409661 + startupProbe: + exec: + command: + - gN + - zpmlcJ + - DeLJ4s + failureThreshold: 102924404 + grpc: + port: -1304933194 + service: 0iK + httpGet: + host: jbg + path: ZqaSpx8C + port: UPJqfy9dOO + scheme: 韼QY岩沴ì釪儇9ĩN + initialDelaySeconds: -46268668 + periodSeconds: -1126074804 + successThreshold: -2093938118 + terminationGracePeriodSeconds: -3498490773203628311 + timeoutSeconds: -736335366 + terminationMessagePath: "7" + terminationMessagePolicy: 辺OB¯悱楆3Ǫ首傭ɟ鮛ïƇ豙ǁUȵ + tty: true + volumeDevices: + - devicePath: DSh1 + name: 1OMawuQAlZD7 + - devicePath: "Y" + name: liCI2j + volumeMounts: + - mountPath: JPO9Ewk3kgaeuBD + mountPropagation: k釂Żɮ>ɸêW箁B| + name: QGO7HtoR + readOnly: true + subPath: oYudCrOqA + subPathExpr: Z1oG + - mountPath: iH6 + mountPropagation: dP帗俪Ťŷ/6¤þ剛&Ģ趽qi + name: 9Ro4aQU5yby + readOnly: true + subPath: piBl3 + subPathExpr: nfDFn + - mountPath: uU2H4 + mountPropagation: ljQ + name: "" + subPath: rj2 + subPathExpr: E + workingDir: BveK3 +extraEnv: +- name: 14jKCyMC + value: Mb95Ivlchi + valueFrom: + configMapKeyRef: + key: FMRh9 + name: VwME2dRYnb + optional: true + fieldRef: + apiVersion: NlY1uxRPgql + fieldPath: NDrKU5 + resourceFieldRef: + containerName: gPQ1TD3MX + divisor: "0" + resource: r6HOpjj + secretKeyRef: + key: "n" + name: RQLa2rQL7Y + optional: false +extraVolumeMounts: +- mountPath: pqfdKzb + mountPropagation: "" + name: 6btv + subPath: xLjoA + subPathExpr: UseM +- mountPath: EYXxm + mountPropagation: 煊`ś蠶+蓲慅4曌Ƥ4臜.魼簌m缽荈巇 + name: 6ut6g + subPath: 7N + subPathExpr: ypY +extraVolumes: +- name: 00PT1WRWHX +- name: P4 +- name: fn +fullnameOverride: Bv0I +image: + pullPolicy: 垿儣Ƈ#WMƻ + registry: XB9ke7yB + repository: EwU0pzhz + tag: SmZAnO7 +imagePullSecrets: +- name: ygWNP7C0W9 +- name: lo0PU +ingress: + className: vg + enabled: true + hosts: + - host: daRMGxIy7gKoE + paths: + - path: GVhF41Ue + pathType: TeM8 + - path: UontjIzl + pathType: MN + - path: "" + pathType: xN + - host: YCgI + paths: + - path: MPhdfahEcn + pathType: ECPrn + - host: GDOlAVRM + paths: + - path: H5pExfzke + pathType: v8 + tls: + - hosts: + - dQiMWdJ8cYKS + - 35K + - 8Kin + secretName: C + - hosts: + - zPo + - Z7 + secretName: SiZz +initContainers: + extraInitContainers: ITIY +livenessProbe: + exec: {} + failureThreshold: 724782955 + grpc: + port: -2055628426 + service: kYxAdPiz + httpGet: + host: JfFu5eafS + path: S8lsKuv + port: 45830231 + scheme: 嵋6ǞkĤ閾8_Tu鍓 + initialDelaySeconds: 1633166106 + periodSeconds: 2105675880 + successThreshold: 225361138 + terminationGracePeriodSeconds: -5739612377473505352 + timeoutSeconds: -1665363921 +nameOverride: "" +nodeSelector: + LAqpO: N7lh0C2 + RqG8qj: ltTa5 + X3q: F5c +podLabels: + Klzm: we + e: C2swj + s: vw1lrq +podSecurityContext: + fsGroup: -8750452531563962174 + fsGroupChangePolicy: RȗɻÎ + runAsGroup: 3754171381447903160 + runAsNonRoot: false + runAsUser: 2565919490422334632 + supplementalGroups: + - 2907772986244331938 + - -4686580881125536152 + - -7134026849524391427 + sysctls: + - name: 8gezWufB + value: 2Jv + - name: 4nhjhT6P + value: 32ZuT + - name: cQk5tljX + value: Aimzt8kirN +priorityClassName: F +readinessProbe: + exec: {} + failureThreshold: -1128918125 + grpc: + port: -1566880140 + service: wMGGUi + httpGet: + host: EwUYUz5 + path: qC4K0 + port: frlhx + scheme: 2鳳ǿ{ǿN + initialDelaySeconds: -116128728 + periodSeconds: -1936485392 + successThreshold: -1735161598 + terminationGracePeriodSeconds: -4458812029359989949 + timeoutSeconds: -1293939870 +replicaCount: 464 +resources: + limits: + 0PRJ1bi: "0" + JUjtrq: "0" + WN9h: "0" + requests: + TCeGWCB: "0" + x5O0IxuN: "0" +secret: + create: false + enterprise: + licenseSecretRef: + key: Sfb6 + name: Fkoh + kafka: + awsMskIamSecretKey: Bof21IpUS + protobufGitBasicAuthPassword: fIQwt + saslPassword: KBS + schemaRegistryPassword: TehF8FK + schemaRegistryTlsCa: 40HTol + schemaRegistryTlsCert: cgz0Y9o + schemaRegistryTlsKey: QUpyP + tlsCa: naM + tlsCert: cC23TMJ + tlsPassphrase: NxVcNj + login: + github: + clientSecret: IDQ0 + personalAccessToken: "4" + google: + clientSecret: P + groupsServiceAccount: oKbW15 + jwtSecret: "5" + oidc: + clientSecret: YcYiIJm + okta: + clientSecret: CtRNDaLkEFXR + directoryApiToken: pH3E2YC7xP + redpanda: + adminApi: + password: "y" + tlsCa: 4ieHo3L + tlsCert: pQ6AshR + tlsKey: s9 +securityContext: + allowPrivilegeEscalation: false + capabilities: + add: + - '@晏駚T!UɎȉépg鎘Ȉ' + drop: + - ÚơĊ猴渋ĭ8膔櫔ż択ůĦ抹 + privileged: true + procMount: 偖躪 + readOnlyRootFilesystem: false + runAsGroup: -543916493751029755 + runAsNonRoot: false + runAsUser: 7772713475568767829 +service: + annotations: + C3p: uCspVMX + nodePort: 441 + port: 51 + targetPort: 456 + type: ZQQlqx7Np +serviceAccount: + annotations: + 7lpi: QQ + RK: "" + od3x: "3" + automountServiceAccountToken: true + create: true + name: HMyYp +strategy: + rollingUpdate: {} + type: Ʉ>朄崍ʡƥɼ戋\IJĹ +tests: + enabled: true +tolerations: +- effect: aƻƀi + key: 7II7D0fA + operator: 跳<ȴŤƇ梐ȸŷR + tolerationSeconds: -92963183946417046 + value: U +- effect: p鸿xś冣9ɩ揊Ů忁琺ȖP壡o繊堮 + key: 5sC + operator: XɦǨ燖Ż綯逆挤ʦ斝蟏滣ʣ + tolerationSeconds: -6405135249548565002 + value: c2m6hlo +topologySpreadConstraints: +- labelSelector: + matchExpressions: + - key: bsO + operator: Ⱥ8欟慡Ƿţ6氙絿鐘黬聠ç + values: + - hbuLC + - SdAZnchI + - key: b4Pjya + operator: jɀh5湧,Ȳǣ6謉<ɦ + - key: gXEm + operator: ',k涃栏岴g橚甇ȳ0禰餝榖睌ěB縩侾F' + values: + - q9VqX4l + - zoMoc9Vb5 + matchLabels: + B0T: uiIEpLD2 + V: jdhpTcaa + pz: V1dJXS8 + matchLabelKeys: + - yoFhTrxV + - o + maxSkew: -1837539887 + minDomains: 2144009248 + nodeAffinityPolicy: 怓覷環ʤ苷疿ʡB聧!]LJƱĿGť + nodeTaintsPolicy: V~0韾¾Ȣû&嵙纠&ȠVƧ鍌 + topologyKey: GldA + whenUnsatisfiable: Ƀk纩{寍HƋ&庝僟D徼聊 +-- case-036 -- +affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: bkwD5 + operator: B砟摫ʟ]估ȽÓĖ頒ʙǯ + - key: 4n + operator: "" + - key: DDWUTPllaee + operator: ǒ@訹Ðđɤ軗ɲǃZ袓6悔ʙ[x] + values: + - bHwxZg + - iPWF3DQz + - yhiFQZ98w6h + weight: -551427274 + - preference: + matchExpressions: + - key: kZ + operator: "" + values: + - BMfDa + - key: l + operator: unɚʀɂ7Ǩ蘕 + values: + - 1vsAjW + - lEGj0 + matchFields: + - key: EYCyU + operator: 袒雬Ǐ蔡|骐pOĆƍbʌʝl + - key: e9QdJHV + operator: Ɏ鼛鏗擌-悝Ű + values: + - DToToJ + - Gq4 + - key: M4b3wwVy + operator: 煛苅=İ哋ońɢ\Głh斳hɷ韙 + values: + - fMIoNrUiyJdi + - tcNEhOds + - N0 + weight: -906035045 + - preference: + matchExpressions: + - key: 05VafuKQo + operator: ƃèĢC篘 + values: + - McUwm + - oMXVW + matchFields: + - key: "" + operator: 9ȮLǟ3V廉\5膏ɩ袴 + values: + - t + - r8d6G + - FevHe + - key: KeJd9X4 + operator: \Y#uɆɫwĉɎ卲S + weight: -773391374 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: PiRY + operator: 週畯嘰Œ铖'ȸ0Į5k,逊 + values: + - Fo9oE + - KLfm4 + - PiZJC + - key: 6HCuuj + operator: Ȋ!ʈh牅HŹ蓓% + values: + - PU34U + - bZ12kwJ4s1 + matchFields: + - key: CCVSIZH + operator: (铴Njʦ釖Ĩ鎅ƒ獞p)唓u¸::2 + values: + - DjvLD + - key: 9gy6tFM + operator: ø + values: + - lPjPu0 + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: 2oL + operator: Ì溄祤BNjɎ_ )jðZF + - key: Tl1mGP + operator: r0ȨȵeēP眼饾j + - key: 98uL + operator: "" + matchLabels: + "": H0F + IGfr: 8iR8 + pTjU: 2vy5Ol + matchLabelKeys: + - l2d3an + mismatchLabelKeys: + - gomcuJ + - UMhaBnQUuSH4 + namespaceSelector: + matchExpressions: + - key: CyYjfraf + operator: 鸫ʊűoǪĞ3 + values: + - uPW + - key: vuREiHB + operator: ^ĄçȂ挌 + matchLabels: + tlcI6jz: 87JK + namespaces: + - eUszN + topologyKey: yJ + weight: 1657692208 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: 3d3mr + operator: 鿈Ė聭焚歉Ð(币帄Ⱥ + values: + - h + - key: Z5c + operator: ma琓 + values: + - i5Ae6oUo + - EWixIB + - "y" + namespaceSelector: + matchExpressions: + - key: XFYbW + operator: M~ + - key: lWHcsQ + operator: 铿X异~<ÿ缇ī*^ĩ + matchLabels: + s: l6sxM + vFiVA7j: WEOy1jtU + topologyKey: JW85dr45m2G + weight: 444678250 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: bMT + operator: ^)4ɊDZǸDŽ + values: + - CG9Onrt + - key: T + operator: ƞ傏 + values: + - bXs59oj + matchLabels: + 6BRwn: Pdm + Yy: aaoLnp + myN: rwJGrW + mismatchLabelKeys: + - "n" + - c + namespaceSelector: + matchLabels: + 5QMzPp: AP + D: "2" + u: Dca + namespaces: + - 8Af + - NYfxoYf + - R4G + topologyKey: yY + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: 2uhHhqog + operator: Ȧ + values: + - YgsgGf + - key: EaR + operator: 愅YVǵ楔¢4Ʋ + values: + - xaEk + - key: NV5iPi5Kw + operator: ' 軕氡#晉Ʀ筜篧e蹶ʀSɟʂÊʕT' + values: + - BY4 + matchLabelKeys: + - 9fTYFH7s + - aK6HB6 + mismatchLabelKeys: + - 13L + namespaceSelector: + matchExpressions: + - key: 3FT + operator: Tğ枕Ōo*a種JU-ɶƠdz鱓fƑS + values: + - 4ISUCT + - po8yM2L + - T5Q0UARu + - key: RhB + operator: "" + values: + - Re7 + - 7id + - 91GFPdrt + - key: ShRTzNRj + operator: ʬ吇Ȭ?搰Ç + values: + - HiGOGJE + - wOi + - HmllR83Dbvoz + namespaces: + - "" + - TBCPW + topologyKey: 0H + weight: 1493754197 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: CESaz + operator: ŢaæX#暁鲸'媩俛5齗aw'ĥ煆W + values: + - "" + - key: YtpoWP + operator: 瀽LƠ' + values: + - uS13z + - ip0h + - o8m9MWnmr92 + matchLabels: + 7o4tt: QX9gjN + KScJOoR95: Dpu + wfAk1b: rH5Z + matchLabelKeys: + - Yh1S1nZ7hm + - Fwx + - 6mhp + mismatchLabelKeys: + - ihvyNa7 + - m8 + - Q + namespaceSelector: + matchLabels: + 2KH67NR4: Vy8qZyy + topologyKey: w0KJ + weight: 1592497187 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + 1UcAh: h + namespaceSelector: + matchExpressions: + - key: yxz + operator: ',酵ýhȿ鲹芫澥 Ǧ_Ź躄_莯ʊ傡硬M' + values: + - Fof + - key: 8KwNEN + operator: 8炮逴8`M鞵ȍȟ蟷盱 + - key: N0 + operator: Ì崌爷矉&佷* JQȴ躀厇退ƿƍ肙 + values: + - kjlwyKc + - DDz + - Yf8Vf5Ar7w7 + topologyKey: n5cRtvXjK +annotations: + GvX4jkWw: xAyNk + MdtXxfH: "" + WyrWx: 8QO +automountServiceAccountToken: false +autoscaling: + enabled: false + maxReplicas: 213 + minReplicas: 211 + targetCPUUtilizationPercentage: 270 + targetMemoryUtilizationPercentage: 495 +commonLabels: + Nv: YHcp9u + RMi5: o4 + ViLr0: zrEw3 +configmap: + create: false +console: + roleBindings: + - cwSnKnhS: null + mzA9: null + oRCBU: null + - 4VfdtEVC: null + UF: null + - 785va: null + Cmlc: null + NyhDjFL: null +deployment: + create: true +enterprise: + licenseSecretRef: + key: teD + name: fP2IA +extraContainers: +- args: + - gfDaDhh + command: + - Eu + envFrom: + - configMapRef: + name: 9LtiYU + optional: false + prefix: dS5JDbtZJ + secretRef: + name: 3X5 + optional: false + - configMapRef: + name: vpOLCCmA + optional: true + prefix: IJpeUVYk3 + secretRef: + name: TaghAr + optional: true + image: Nw59jHFBw + imagePullPolicy: Eźz购綗映ò#ZuS絇溾^飷 + lifecycle: + postStart: + exec: + command: + - N2F2q + - XKeJn + - CfoVd + httpGet: + host: 0u3Kgf + port: PVA8u + scheme: ȧX[噦摼鎥憈ǴńƘŅ + sleep: + seconds: 9185496374723367536 + preStop: + exec: + command: + - lrWSClt + httpGet: + host: uS + path: 51Gzg9s + port: -1680102290 + scheme: 8涒齃ɠĬ諛鰅jyr塸ȷg× + sleep: + seconds: -302278202696680147 + livenessProbe: + exec: + command: + - fmu + - wJR3 + - 60zV6s4327rKb9 + failureThreshold: 2122798666 + grpc: + port: 1914605377 + service: ES + httpGet: + host: 7LAmwy8 + path: o2XAC + port: S5 + scheme: 犘ßħɚÂ剐*鬰ȇxȺ錎 + initialDelaySeconds: 343978803 + periodSeconds: -1725283583 + successThreshold: 1055506692 + terminationGracePeriodSeconds: -737021961431151273 + timeoutSeconds: 1721351711 + name: r + ports: + - containerPort: -341996687 + hostIP: zR + hostPort: -641414216 + name: AGa7X6lnw + protocol: 阧 + - containerPort: -1616018360 + hostIP: 8q + hostPort: -2060443566 + name: B + protocol: 位ŲȟHbfp餪魹| + - containerPort: -321829785 + hostIP: S + hostPort: 850049722 + protocol: ĢŔ=ɦŊ鳺醩hĂ踻鉀 + readinessProbe: + exec: + command: + - VRq0lZK + - nCUDH3Zgc + - f2h2C + failureThreshold: -444080905 + grpc: + port: -1484737838 + service: UL8hSUw + httpGet: + host: 8DDb + path: Z + port: It67aEO18 + scheme: 蹐疒Į浤 + initialDelaySeconds: -1225398553 + periodSeconds: -1497056806 + successThreshold: -1256842388 + terminationGracePeriodSeconds: -3265344141862786392 + timeoutSeconds: 1127947387 + resources: + limits: + "36": "0" + Oaiu: "0" + v: "0" + requests: + F0olO: "0" + tvGpYtd: "0" + restartPolicy: Ě卿ɫȰLZ懁 + securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - "" + drop: + - Ę螅7O5Ɵ駢Ó宮緂 + privileged: true + procMount: ʤ敠æx漭fƈŸʄ + readOnlyRootFilesystem: true + runAsGroup: -1779689763650765955 + runAsNonRoot: true + runAsUser: -1786517016760367110 + startupProbe: + exec: + command: + - Mcn36l + - "n" + - OMT3J + failureThreshold: 1137002720 + grpc: + port: -2106637755 + service: OYW + httpGet: + path: K + port: STUmUBT + scheme: 貪iɐ巶ɿiɲbɎ;Ŏċ2橺汲ŋ刢g + initialDelaySeconds: -648188998 + periodSeconds: -278768915 + successThreshold: 890955082 + terminationGracePeriodSeconds: 5660177701724482122 + timeoutSeconds: 959596283 + stdin: true + terminationMessagePath: h2a2mAm + terminationMessagePolicy: pjĉ + volumeDevices: + - devicePath: cZ95 + name: wLm + - devicePath: P9RW + name: PjzHR + volumeMounts: + - mountPath: b + mountPropagation: 脣Į + name: bOY + readOnly: true + subPath: mBuB + subPathExpr: 0io + - mountPath: DYp + mountPropagation: 9鹺t"Ĭij(?NB4ɖ鴼B屈桲ȋ噤ǁ + name: O + readOnly: true + subPath: EcI7mF + subPathExpr: HKfaS + - mountPath: NTgHw + mountPropagation: (ńÆ;裉嵀 + name: U6TGXB + subPath: wjpyjQ + subPathExpr: nqq + workingDir: NpjQN3dM +- args: + - m + - fmRfLPl + command: + - okKsRu + env: + - name: y8FxBu + valueFrom: + configMapKeyRef: + key: 1kdTq + name: NGzFHD + optional: false + fieldRef: + apiVersion: WDoDm + fieldPath: HTHz + resourceFieldRef: + containerName: aWk + divisor: "0" + resource: RcTwrpd4PaqW + secretKeyRef: + key: 27uDnW9fM1 + name: diwId6SMC + optional: true + - name: NZ1pEV + value: Xq7fA + valueFrom: + configMapKeyRef: + key: cYo + name: IhK1oKNNr + optional: true + fieldRef: + apiVersion: 0C + fieldPath: "" + resourceFieldRef: + containerName: OywKEud3 + divisor: "0" + resource: E4 + secretKeyRef: + key: gGTl + name: V + optional: false + envFrom: + - configMapRef: + name: fJ + optional: true + prefix: zFUU1PguE + secretRef: + name: S7Jre + optional: false + image: gbZ4mqT + imagePullPolicy: '*罖Ē掙*uĕĥ世û煨o曁ɖ)嬫噩肖Ñ' + lifecycle: + postStart: + exec: + command: + - nxKsxt + - F25ka4x + httpGet: + host: "0" + path: 9k0yMphk + port: GJdG + scheme: 婁箅蝼đ杣Ɗ°VAƭ0ĺ钘1 + sleep: + seconds: 8039264634100238529 + preStop: + exec: + command: + - NuJoJm + - gykEI + - "6" + httpGet: + host: UnkqD3SS + path: BhN + port: 712546393 + scheme: u + sleep: + seconds: 409536667065008471 + livenessProbe: + exec: {} + failureThreshold: 204373937 + grpc: + port: 1803358082 + service: VXsxSeh + httpGet: + host: Ht64jf7Eo + path: u1jjW9Qu + port: 556487018 + scheme: 熖Ű存ŖT磇ɘ外 + initialDelaySeconds: -1152834471 + periodSeconds: -1133396594 + successThreshold: -1385193405 + terminationGracePeriodSeconds: 2915006546098799012 + timeoutSeconds: -1401054296 + name: dfD716 + ports: + - containerPort: 691082006 + hostIP: b + hostPort: 636825973 + name: S5FmEWKv + protocol: g]se墰掀媸晓櫚驟憽hbƥsư° + readinessProbe: + exec: {} + failureThreshold: 152987910 + grpc: + port: 642951905 + service: q2qfom8L + httpGet: + host: GaxyfqlQ + path: Oh0t + port: -766612198 + scheme: UÂ_ + initialDelaySeconds: -1382761032 + periodSeconds: 967018272 + successThreshold: -178373997 + terminationGracePeriodSeconds: 6605400648980208248 + timeoutSeconds: -1404918452 + resources: + limits: + 7cu: "0" + 22n7v: "0" + XsU5mrE: "0" + requests: + kyXuqf: "0" + mBk4P9DWW: "0" + restartPolicy: ʓdT>NȚks_q祈 + securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - ȸŏ脸(Yǃ¯~垇耗A) + - T翱ĥ + drop: + - 商ʏ軒Ƣ厢 + - Ⱥãt\跋þ漙苣ű吡憕鿶0傜om + privileged: false + procMount: Ŷ% + readOnlyRootFilesystem: true + runAsGroup: -1052699124096043871 + runAsNonRoot: false + runAsUser: 3737016357651072730 + startupProbe: + exec: + command: + - jefRNS + failureThreshold: -9144267 + grpc: + port: 642233169 + service: WjvgDkGG + httpGet: + host: 8hzgS0q + path: z + port: -885964296 + scheme: ɸliŵ + initialDelaySeconds: 1014078949 + periodSeconds: 1410148112 + successThreshold: 1164669668 + terminationGracePeriodSeconds: -3385668069040237914 + timeoutSeconds: -1723583731 + stdin: true + terminationMessagePath: zbCh + terminationMessagePolicy: 4攨2õė+軩Ç + tty: true + volumeDevices: + - devicePath: Nx + name: QLHA + - devicePath: 9JAgFLSdSqQ + name: "5" + volumeMounts: + - mountPath: KXG1 + mountPropagation: ȁ捄ɺ絒馢A¥`Èť + name: aghWO + readOnly: true + subPath: el7KEVsV + subPathExpr: tdksniBM + - mountPath: 5nus8 + mountPropagation: N饢杼M7X尅扐ǗÃɱNƞeuĦg儡 + name: TS4kHG + readOnly: true + subPath: i + subPathExpr: ktDaTCGG + - mountPath: CSkt9N0i + mountPropagation: 爕ɐYYȁ<獱椂@椗áʇ憣>\Ɋ筙纉Ë + name: KIKRXUR + readOnly: true + subPath: bWYTiq + subPathExpr: cgxlHqVV + workingDir: F +extraEnv: +- name: 0iCX + value: UfKNkXj6I + valueFrom: + configMapKeyRef: + key: GGYmdb5PBtUx + name: Zl1rWu9 + optional: true + fieldRef: + apiVersion: 1pKgni + fieldPath: 8Zmv + resourceFieldRef: + containerName: nK + divisor: "0" + resource: Yizp + secretKeyRef: + key: Dxqh + name: td + optional: false +- name: bm + value: K06vl + valueFrom: + configMapKeyRef: + key: dOTjzfwtRPzX + name: YleYOzRS + optional: true + fieldRef: + apiVersion: xl + fieldPath: 6NM2 + resourceFieldRef: + containerName: jreT + divisor: "0" + resource: "" + secretKeyRef: + key: B7 + name: cu + optional: true +- name: F4Vp + value: 9q + valueFrom: + configMapKeyRef: + key: dAPalKT0 + name: UXC7S + optional: false + fieldRef: + apiVersion: bTxwQmS + fieldPath: XW + resourceFieldRef: + containerName: iqnl + divisor: "0" + resource: e9 + secretKeyRef: + key: c1WJ + name: sg2TuPSW + optional: false +extraEnvFrom: +- configMapRef: + name: 3PT + optional: true + prefix: l + secretRef: + name: zakko + optional: false +- configMapRef: + name: RdxlkV + optional: false + prefix: 9Ae4W + secretRef: + name: UiJ + optional: true +- configMapRef: + name: bp + optional: true + prefix: SU + secretRef: + name: fy + optional: true +extraVolumeMounts: +- mountPath: Oly + mountPropagation: ƈįlñ + name: QuM + readOnly: true + subPath: NPJ + subPathExpr: vn +- mountPath: xsiqpcicm + mountPropagation: Ŝȃ燩čƃʤǸ儼 + name: blYv + readOnly: true + subPath: 8f + subPathExpr: I +- mountPath: "" + mountPropagation: 犒k洐ɨ3UʓďȏUm8/x艂" + name: i2 + readOnly: true + subPath: G + subPathExpr: Wo47OrA +extraVolumes: +- name: HUa7xM +fullnameOverride: AumW +image: + pullPolicy: ǫtŖŮƘ瓧ù¹勍u + registry: ai + repository: f54I + tag: iO +imagePullSecrets: +- name: bbjdn +- name: VI +ingress: + annotations: + RX47S: lb0 + Ton: ukp + className: R3Ykmr + enabled: false + hosts: + - host: bybyr6XsLFPDg + paths: + - path: c9F + pathType: TyYv +initContainers: + extraInitContainers: q +livenessProbe: + exec: + command: + - dRbj + failureThreshold: 864346345 + grpc: + port: -568790446 + service: 9WyiSW + httpGet: + host: EbFlYW + path: HC + port: C1Fv7 + scheme: 軔ǷʧP + initialDelaySeconds: -1341055636 + periodSeconds: 2055603833 + successThreshold: -175204389 + terminationGracePeriodSeconds: -2333626465204273709 + timeoutSeconds: -589897727 +nameOverride: 9mG8n4Wu4 +nodeSelector: + U3Rfg9: WSTvjvP + hODw: LSv + iwleZ: fD +podAnnotations: + jLE31lUP: LWc +podLabels: + 6W: FQvOa + YwkBSNWK: 0qqd + jP3: iNkD +podSecurityContext: + fsGroup: 8205502301244812774 + fsGroupChangePolicy: "" + runAsGroup: -8440674019915815616 + runAsNonRoot: true + runAsUser: 4432310384984167581 + supplementalGroups: + - 7965846110903121951 + - -9174375158887062481 + sysctls: + - name: OkeQ + value: A + - name: 24y + value: fIPA + - name: "" + value: b3 +priorityClassName: gPB +readinessProbe: + exec: + command: + - NjJ7Lit5 + - 29odviV2mnb + failureThreshold: 1075627654 + grpc: + port: 364618769 + service: g1wc + httpGet: + host: 40i + path: OTDO + port: -2089902693 + scheme: $Gȇ表匾ʞG絁娚彰ŝê<ĭ + initialDelaySeconds: 333726894 + periodSeconds: 1376975278 + successThreshold: 112483424 + terminationGracePeriodSeconds: 1389336444380098948 + timeoutSeconds: 669945326 +replicaCount: 24 +resources: + limits: + 7VHN3: "0" +secret: + create: true + enterprise: + licenseSecretRef: + key: jPpQY + name: uRkzw + kafka: + awsMskIamSecretKey: B + protobufGitBasicAuthPassword: EfQbyB + saslPassword: w + schemaRegistryPassword: qiltVq + schemaRegistryTlsCa: kyT4j + schemaRegistryTlsCert: Tu4varJ + schemaRegistryTlsKey: bmT + tlsCa: UyskLmDZ + tlsCert: "" + tlsPassphrase: IdsCzt + login: + github: + clientSecret: hPt + personalAccessToken: vRbRqD0 + google: + clientSecret: "" + groupsServiceAccount: lcc9 + jwtSecret: tf0x + oidc: + clientSecret: A9RDbO6GzTtHYG + okta: + clientSecret: HktzleLAg + directoryApiToken: qX + redpanda: + adminApi: + password: 5imX8ztdqjU + tlsCa: opQQ + tlsCert: PGcfJC3zH + tlsKey: IhqyTvQn4T +securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - '*·戌ɳKõʚK(懷ë蟅ȣg' + - vOpɔm&ɞ法槪ųf + drop: + - l¤0ɖK樌ŕDĪ箰ɬȓũ梫h揼 + - 躟OBZş互鹫Íʨƶ`ã + privileged: false + procMount: 9®俠ɳ屑ŏO'pe,Q+膿麣 + readOnlyRootFilesystem: false + runAsGroup: -289823929905824069 + runAsNonRoot: true + runAsUser: -4392330066259666500 +service: + nodePort: 249 + port: 113 + targetPort: 414 + type: XHYb2qmrk +serviceAccount: + automountServiceAccountToken: true + create: false + name: Jg +strategy: + rollingUpdate: {} + type: LJėwǮ甧 +tests: + enabled: false +-- case-037 -- +affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: IPWU1 + operator: 魡燸"趵p砮ƘċÈ3ljDŽ + values: + - i + matchFields: + - key: "" + operator: 廋46齄aā[傡ŤXjğ@ɫ聱昣ȞA + values: + - hrjhAJC + - RGJEJ + - key: 9XRD + operator: 鏖Ų姓萲1蜓舆 + - key: nmlhnezDL + operator: =WF»圻礼鍕4u-瘸]NJ + values: + - MlE9xcsLb + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: vxH0 + operator: kűŐ鄴 + matchLabels: + YR: ZYyx + matchLabelKeys: + - lrfi + - 9s + - "2" + mismatchLabelKeys: + - "" + - vc + - rz4SvG + namespaceSelector: + matchExpressions: + - key: ybBiR8Fm + operator: UlƜ寻眅崈O+聁ȴ + values: + - xxao + - key: UpNi + operator: v韠Ʀ.Ɓ氩諑ʊ0ɔ凹 + values: + - ECPGYavF2 + matchLabels: + 7qRB: 56MM + tcHg1: kpR + topologyKey: "7" + weight: 212582037 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + 6PJt: OILe3j + mismatchLabelKeys: + - PB + namespaceSelector: + matchExpressions: + - key: "1" + operator: ǯVɳCĬ鷹儉ïXǐʐ楏ċŇǽ + - key: aFA + operator: ƣ諔&ȵ%ǼQ傠ûQ& + values: + - tdkCJmsLj + - 2WF + - nlO + matchLabels: + "": JgBcTwL + gUx2lrPlU: 2MEiay0i + namespaces: + - iUHz + - F + - C + topologyKey: 0DqLIsLvEJ + - labelSelector: + matchLabels: + D65k: m + v: Wf73pl + namespaceSelector: + matchExpressions: + - key: Mql8T + operator: Ȳ + values: + - kiCXA + matchLabels: + QJPP2Wmbc: MGiu + tm: POZGk072F + v: OdyUJaKz8sW + topologyKey: CaAJ + - labelSelector: + matchExpressions: + - key: kJFGWDPIX + operator: '`園bsN唲幈ùÄ!鑢' + values: + - x + - key: PQktimeqK + operator: Í Ho亜q毂EɌ39蓷 + values: + - rYZ + - key: L6Wp + operator: '&去鉼晆Äě菉' + values: + - BPX5 + - 7Ows + matchLabelKeys: + - PhOMWnct + - 4Iar + mismatchLabelKeys: + - SfvAwYYqtwPc + - w9 + namespaceSelector: + matchExpressions: + - key: VmRQ2 + operator: 錛ȋʤ`搲ZL婨ƅ\鴃m闬ǿ戺ƨĤs@ + values: + - Ah8tj + matchLabels: + JBFf5vLf4: q2X6daLRz + VuZT: gmluiWbT + p64cMTP: B9 + namespaces: + - Ri6BSDl1 + topologyKey: nACF7H8 + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: ZZaxS + operator: 黦ƒ©瀂 + values: + - "" + - 20OCN + - IZ86eI1 + - key: RXLfn + operator: .惊ŝ4ni`ræseȕƌ筬NJ@pŻ + values: + - Fuy + - 6ZIkwShr + matchLabels: + RJHcF0aLL9: avVll8hJB + Spsji: hW + mismatchLabelKeys: + - RDiUdFmoEZ + namespaceSelector: + matchExpressions: + - key: RmcZbbc + operator: uŒ¶鱸K + values: + - 90lQUM5B + - J07lI + matchLabels: + 6hQX9h: Sr5NoqB + L0vc: i + iJ6hIS: yLkpjBIU + namespaces: + - i1uGAcY9Xxf + - DO5c + topologyKey: uVcRZ + weight: 608820709 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: Mgdm + operator: 惋¯ʢÝǒ=h佅茆接 + - key: "n" + operator: 系¦澜C2騗ā穩 + values: + - yelaWfaB + - Cq + - Va + - key: Ymvr + operator: 7 ^»ðq> + values: + - GES + - gPThP + matchLabels: + zj9Ud7LvFtg: trcgDo5 + matchLabelKeys: + - X + mismatchLabelKeys: + - peo1 + - zVPvCpJUM + - "" + namespaceSelector: + matchLabels: + "1": qRCy + namespaces: + - Eczjbhs + - F8 + topologyKey: Az + weight: -470853400 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: {} + matchLabelKeys: + - VWM7 + namespaceSelector: + matchLabels: + Q4BC: BojBLo + Vz06Yne: "" + namespaces: + - yEEmKNg + - iGJzcn + - G1bhP4 + topologyKey: pcOSh + - labelSelector: + matchExpressions: + - key: lCW5OK2A6HKOaC7 + operator: 蚿~2婈 ʝ似矉k + values: + - 5IOGWj + - UwmQ + - Ser + matchLabels: + "4": PB0Pb9 + Ykh3k: oX8w + matchLabelKeys: + - SfZ9pUjA + mismatchLabelKeys: + - i16lOT + - 8iU + namespaceSelector: + matchExpressions: + - key: ZxE + operator: 恇3 + values: + - "" + - 43TqLr + - key: ikCzWLGa + operator: E + values: + - W1 + - ZqA + matchLabels: + "": YJaQ + 7h: dybADQ + topologyKey: "" + - labelSelector: + matchExpressions: + - key: 0bZO + operator: '[ ' + values: + - DPm + matchLabelKeys: + - "" + namespaceSelector: + matchExpressions: + - key: b8XGJRAsiP7 + operator: ']眆寜眴z' + values: + - MsgI + - dhrJF0b + - key: SMx + operator: JɦĈ + values: + - o + - yknE + - key: rfxn3qvEK + operator: 綐岮~2熗昕Ñ占Wm员Ƴ橝灃Ɗ + values: + - "" + - K + matchLabels: + 2Jd: g3du2W + ZHju0: u7DvsT5e + zUssA7: ZKAL + namespaces: + - Qpqer2VPQ6oA + - zR0okqL + - nuH + topologyKey: i +annotations: + 1B8qie: FSPYCLoT + I: hpwL4TH + Z: 0LFy +automountServiceAccountToken: false +autoscaling: + enabled: false + maxReplicas: 370 + minReplicas: 221 + targetCPUUtilizationPercentage: 463 + targetMemoryUtilizationPercentage: 49 +commonLabels: + BJ: Gq0Rw + FPcPYvmbB7dAZe: Cy7WaeI + uEVMkDkYRvnn: zvptNai +configmap: + create: true +console: + roleBindings: + - 2m: null + VNrY1fwY: null + eaGm2c: null + - Ng0sM: null + Txhv6: null + e2uo: null + roles: + - Dd: null + H0QLXtA: null +deployment: + create: false +enterprise: + licenseSecretRef: + key: HqS5hb + name: 3sA8DqHdr +extraContainers: +- args: + - UaqwQ7 + image: 9gJVF + imagePullPolicy: 5傅c諹ɕ ƅƬDr1鰹瀣n怌ʡ + lifecycle: + postStart: + exec: + command: + - EJfXoz + - pxAl7T7 + httpGet: + host: 4dtyQHxp + path: 9i + port: BmGAi + scheme: ¼ů + sleep: + seconds: 2333336810403167963 + preStop: + exec: + command: + - EF + httpGet: + host: gc + path: 5IcdjR2 + port: Ln1 + scheme: Ȱʛ{`Ɓʛ劽Ŋ劧Yǥ + sleep: + seconds: -8338094784810815040 + livenessProbe: + exec: {} + failureThreshold: -1009316117 + grpc: + port: 434468004 + service: hOHaw7yL5 + httpGet: + host: r0OfO9Tjf + path: rvqaH + port: 1861701721 + scheme: 蓫AȚ%Țx痷 + initialDelaySeconds: -1210592458 + periodSeconds: -1685889023 + successThreshold: -1513585658 + terminationGracePeriodSeconds: -2039599439532369874 + timeoutSeconds: 615837494 + name: 0z + ports: + - containerPort: 920384597 + hostIP: amIbTg + hostPort: -1446796645 + name: H + protocol: tsė歟ū$B,qʐ医枝 + - containerPort: 533680030 + hostIP: AQrcm57h + hostPort: 436553418 + name: zI + protocol: mĖ}ʘá~滬 + - containerPort: -88474612 + hostIP: 5Q7z7DzPSmu1KQ + hostPort: -894572877 + name: Ie31rl + protocol: Z尤汸 + readinessProbe: + exec: + command: + - Ig53IR5s + - X + - MD + failureThreshold: -697650972 + grpc: + port: -1408023460 + service: q3NQW + httpGet: + host: NClmq + path: "y" + port: 4KJj4nVotN + scheme: ®顫jV/懔e + initialDelaySeconds: 1925202911 + periodSeconds: 1008375062 + successThreshold: -1515262628 + terminationGracePeriodSeconds: -9135279372752511888 + timeoutSeconds: -757546061 + resizePolicy: + - resourceName: BhTx + restartPolicy: O憢%ȔnjŸƓx汮$ + resources: + limits: + 0R8h7mczbiK0u: "0" + ngcoDm: "0" + requests: + FvPC8: "0" + restartPolicy: 竴xJ飊µ + securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - eF + drop: + - '#泪<1饤ǯȲ78狎外龬郄晛頯6汐嫏' + privileged: true + procMount: bűƍȓ2C޵舕秗騛^ĪĪ溫Nȇ + readOnlyRootFilesystem: true + runAsGroup: -3343110605261139689 + runAsNonRoot: true + runAsUser: 7479178344552716344 + startupProbe: + exec: + command: + - 4mbBa0iSAgQ + - 9Vb + - B5u + failureThreshold: 753806032 + grpc: + port: 1382157718 + service: Sbk + httpGet: + host: bVoIiYzvoi0B2 + path: H7pGt3 + port: TTVi + scheme: 厪$dıQǵ_ƀÁ釔ɵ徣 + initialDelaySeconds: 849023271 + periodSeconds: -1908074475 + successThreshold: 328769480 + terminationGracePeriodSeconds: 5149904224053969297 + timeoutSeconds: 1277324377 + terminationMessagePath: 00uJXyD + terminationMessagePolicy: 禣儛x~靰ɿ`šŀǼŋP^n + tty: true + volumeDevices: + - devicePath: TMbZU + name: hFJz + - devicePath: yr + name: O0NQRcuq + - devicePath: UHqeq + name: Ydaqo + workingDir: TzR +- args: + - 1EEFNaNA + - U2l + command: + - CsMZk + - 4HgTHX + - Sqt9at + envFrom: + - configMapRef: + name: RRMDeJ + optional: false + secretRef: + name: lcA + optional: false + image: GQ69 + imagePullPolicy: Ɉǥ + lifecycle: + postStart: + exec: + command: + - 3YpG + - vZTzHN + httpGet: + host: cPtKCkyO + path: "4" + port: -1049236742 + scheme: 硺=ɸǖɵ恆Žd0 + sleep: + seconds: -7566729856608460688 + preStop: + exec: + command: + - y2fpvM + - VG + - hhX3m + httpGet: + host: o + path: "7" + port: nl5CZNKB + scheme: Ȉ + sleep: + seconds: -9000479934802388409 + livenessProbe: + exec: {} + failureThreshold: 115197733 + grpc: + port: 418872789 + service: mK04M1 + httpGet: + host: tYy4jqPpZ + path: om7u1 + port: 6vYh + scheme: 鬧ĕ,b嫲ʞÈȅɼ瑀\-ŤÔĞ{ + initialDelaySeconds: -1996330627 + periodSeconds: -2123682197 + successThreshold: -274102072 + terminationGracePeriodSeconds: -4086669261853017280 + timeoutSeconds: 1671175282 + name: MN + ports: + - containerPort: -581773322 + hostIP: w + hostPort: -1918799357 + name: NUQc5 + protocol: lɡFàW6ǼC7騰僮氁繸{Ȏ + readinessProbe: + exec: + command: + - IYC3M + failureThreshold: 178025639 + grpc: + port: -205038391 + service: EGqI + httpGet: + host: oGjb56 + path: mnq + port: pb9x + initialDelaySeconds: -1053907742 + periodSeconds: -777502604 + successThreshold: -350871959 + terminationGracePeriodSeconds: -6813701492426236069 + timeoutSeconds: -1712603807 + resources: + limits: + TwWe: "0" + requests: + 4FGQT: "0" + 57DEge: "0" + zBEzXaq: "0" + restartPolicy: 焂ś(Z緌挄ǥȪȑq*刾 + securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - Ư#æ9NF犔帙錈 + - N範3>ȖlǖɥöS竾ƾÔŸ烠dk弸 + privileged: false + procMount: ı.ĔtQ+p銍/盂pJr替àŽ + readOnlyRootFilesystem: true + runAsGroup: -9023516459602390407 + runAsNonRoot: false + runAsUser: 2513546243926544067 + startupProbe: + exec: + command: + - C + - 9o + failureThreshold: -1595663358 + grpc: + port: 879782754 + service: E3 + httpGet: + host: j + path: ZwGu + port: -1183682475 + scheme: ȉʬ|Ȗ-胨\GǴ酥âïŀ + initialDelaySeconds: -320635887 + periodSeconds: -1762048755 + successThreshold: -1206942688 + terminationGracePeriodSeconds: 2874889772540953352 + timeoutSeconds: 201190682 + terminationMessagePath: D5nhSA2KK + terminationMessagePolicy: '|Áʊv~' + tty: true + volumeDevices: + - devicePath: fl + name: "" + - devicePath: Pivii + name: SAJBTs + volumeMounts: + - mountPath: os + mountPropagation: 霤ņd碤 + name: Wma3F + readOnly: true + subPath: J + subPathExpr: rp + - mountPath: 7p + mountPropagation: ʜ塖ɥw阒ɠ·閐駔址遥铣C龂ȵ槂瑷 + name: EKv9jGIV + readOnly: true + subPath: YjGj1 + subPathExpr: goeN5mMZVyE + workingDir: 9pZ +- env: + - name: jUF3n5Y + value: 5Oas + valueFrom: + configMapKeyRef: + key: NjvBzcrV9 + name: kjnqdL + optional: true + fieldRef: + apiVersion: EKxzT + fieldPath: keiWEt + resourceFieldRef: + containerName: 6ei + divisor: "0" + resource: 5SYJ0LG + secretKeyRef: + key: khTsQnn + name: R22Yc + optional: true + - name: Eqsqk + value: ZbUl8L + valueFrom: + configMapKeyRef: + key: LBJ9Co8gX + name: 5F + optional: false + fieldRef: + apiVersion: BBXJwlU6ov + fieldPath: tR7Z2 + resourceFieldRef: + divisor: "0" + resource: Kw7UxsTdNB + secretKeyRef: + key: x1Ijg6T + name: qqT6Y + optional: true + - name: 7zUt + value: 92wkXugDh + valueFrom: + configMapKeyRef: + key: JfY0lIp0Jdtpv + name: nYzr + optional: false + fieldRef: + apiVersion: IDhOF + fieldPath: aTWd + resourceFieldRef: + containerName: m4s0LUsO + divisor: "0" + resource: jJSLfi + secretKeyRef: + key: KzYvK2KKl0 + name: sR + optional: true + envFrom: + - configMapRef: + name: LuhmK + optional: true + prefix: z3 + secretRef: + name: bhwKfwEMY + optional: true + - configMapRef: + name: ZLn6PrNZ + optional: true + prefix: CZK + secretRef: + name: ln + optional: false + image: 40twCh1 + lifecycle: + postStart: + exec: + command: + - "" + - 4qZLs + - OKN + httpGet: + host: L1rE + path: zDyVFyy + port: kQZa + scheme: l + sleep: + seconds: -7109845505283004784 + preStop: + exec: + command: + - HBLUwI5qG + httpGet: + host: vM5bd + path: "y" + port: 1065237668 + scheme: 働ı愊GƜǻo4qtHŢ*獊K[w + sleep: + seconds: -1099871671561452384 + livenessProbe: + exec: + command: + - K1 + - O5Tdq + failureThreshold: 1326476911 + grpc: + port: 1266228568 + service: 0yovH + httpGet: + host: feV + path: HDTE + port: "1" + scheme: '!@ȄKh8淫~ǿ%硬睇鵤嵤' + initialDelaySeconds: 1175577649 + periodSeconds: 1877040036 + successThreshold: -1354358221 + terminationGracePeriodSeconds: -925123122471881643 + timeoutSeconds: 1464454545 + name: W8b6OOS + readinessProbe: + exec: + command: + - i + failureThreshold: 1781656452 + grpc: + port: -1606887908 + service: RrbvDP + httpGet: + host: mKx + path: HD + port: hiq5RvT05 + scheme: 鱑Ȍ¾ĵ覓{>鿼钇 + initialDelaySeconds: -1803086365 + periodSeconds: 450703172 + successThreshold: -1624696013 + terminationGracePeriodSeconds: -5286538260023923986 + timeoutSeconds: -528162423 + resizePolicy: + - resourceName: um0g1naPII7 + restartPolicy: ¹俞Wƌ甝 + resources: + limits: + EDhQ2V: "0" + OQ: "0" + WtnTV: "0" + requests: + jQaF: "0" + restartPolicy: '{鉪蟏E喧t庛Þa¦ʕ' + securityContext: + allowPrivilegeEscalation: false + capabilities: + add: + - Ň鰍坸Ñ霰ʁ攽$Ơ + - 蟒磁砈Z芥EDZ + drop: + - ċ6洌扼雚nj墣l睧奟*躾ƛƌ秡t + privileged: true + procMount: 蜵5>MU + readOnlyRootFilesystem: true + runAsGroup: -7704085956113873818 + runAsNonRoot: false + runAsUser: 5730999299228810722 + startupProbe: + exec: + command: + - ImPt + - cIB + - e58MzW + failureThreshold: 310737712 + grpc: + port: 1849024783 + service: B1W + httpGet: + host: 1nU5qLkMA + path: Oo7nHt + port: hxGSeC + scheme: ƇĒɔmĦɦ齋貢 + initialDelaySeconds: -1797908483 + periodSeconds: -761708273 + successThreshold: -1316915468 + terminationGracePeriodSeconds: 8128903938581944374 + timeoutSeconds: -1573011089 + terminationMessagePath: FYPtlxf + terminationMessagePolicy: Pʏɉ{ů囏Ì4鰸曘Ʃ氕峵 + tty: true + volumeDevices: + - devicePath: "93" + name: t3A + workingDir: w +extraEnv: +- name: fXB4uyH + value: GPmKm1YgQuvB8 + valueFrom: + configMapKeyRef: + key: BYyG6 + name: Kr8iKZ + optional: true + fieldRef: + apiVersion: sSt + fieldPath: 7r3LBO + resourceFieldRef: + containerName: B8G + divisor: "0" + resource: 3cRQ + secretKeyRef: + key: nQtb + name: B8Snqwl0U0 + optional: true +extraEnvFrom: +- configMapRef: + name: C1P + optional: true + prefix: KcZH45pd2 + secretRef: + name: N7Yt + optional: true +extraVolumeMounts: +- mountPath: twfjF9 + mountPropagation: ȶ唗蠤S柋ɖȈƻ + name: MMcC8 + subPath: UwT0sYVo + subPathExpr: 9ugOBQ +- mountPath: 6cj + mountPropagation: "" + name: 3iQ + subPath: SaQ + subPathExpr: QQI +extraVolumes: +- name: xbuLqNQHFY +fullnameOverride: ADIhC +image: + pullPolicy: '|í' + registry: CIzpk + repository: O + tag: F +imagePullSecrets: +- name: Yi +- name: 6XnEhUN +- name: oeoW +ingress: + annotations: + "8": SeJ + className: PHr + enabled: true + hosts: + - host: PXAcFs520n + paths: + - path: 1uGP0 + pathType: dWpX + - path: hAH + pathType: LjzFf + - path: 7Qy + pathType: vjB + - host: z9QAJ5 + - host: "" + paths: + - path: Hc0IpaX + pathType: bc0T + - path: dzn1ldJ5h + pathType: M +initContainers: + extraInitContainers: 7DdMwNg +livenessProbe: + exec: + command: + - XRPuLpEO + - nplEP2IP3 + - 9jrKdj2 + failureThreshold: 1516033986 + grpc: + port: -531236004 + service: 11bsOMf + httpGet: + host: 9PMyxMco + path: RI3zx + port: -2029405965 + scheme: G隠Ī:ŁuƠ禲oŇO鿈Ⱥȡ + initialDelaySeconds: 1774510914 + periodSeconds: 1308551645 + successThreshold: 752675362 + terminationGracePeriodSeconds: 8661862683503969755 + timeoutSeconds: 437106483 +nameOverride: u2r6 +nodeSelector: + CrYMUu1pg: "" + ftZ: dKqEwc + pNPla: Cc +podAnnotations: + dApB5noz: fJm84 +podLabels: + 9c2: 3fwyB6m1 + MyocWENxGGa: TrRadg +podSecurityContext: + fsGroup: 5618615494228351604 + fsGroupChangePolicy: ʩrXù济延唇ė袡 ʊ + runAsGroup: -3861060047548570674 + runAsNonRoot: false + runAsUser: 3602747950735365650 + supplementalGroups: + - -5665823160677538937 + - 2942720231280319982 + - -7811581565559124250 + sysctls: + - name: X + value: sWo + - name: MI521Dolo + value: ETgcRWsr + - name: 4gVCXpSch + value: csKV +priorityClassName: U7wS +readinessProbe: + exec: + command: + - cYKp + - vP + failureThreshold: 670800660 + grpc: + port: 1721771977 + service: y69H + httpGet: + host: mtLvsm + path: hd4c + port: 326683785 + scheme: X½鼅餕嚶渭闬脮ƧŗŠ#7êk.] + initialDelaySeconds: 713201976 + periodSeconds: 1611391820 + successThreshold: 604905966 + terminationGracePeriodSeconds: 8452879830155323173 + timeoutSeconds: 981065048 +replicaCount: 471 +resources: + limits: + avG: "0" + q: "0" + w8p: "0" + requests: + AZ: "0" + fGW: "0" + vom84xUd0: "0" +secret: + create: false + enterprise: + licenseSecretRef: + key: 41x + name: HHI4WeIS + kafka: + awsMskIamSecretKey: vvbXmwn + protobufGitBasicAuthPassword: uJNU2 + saslPassword: 1wgp7riu8 + schemaRegistryPassword: nKfA7t + schemaRegistryTlsCa: dsi + schemaRegistryTlsCert: 85xiT + schemaRegistryTlsKey: "1e0" + tlsCa: hEe0gyNOx + tlsCert: "" + tlsPassphrase: Jktiu0 + login: + github: + clientSecret: BDnf + personalAccessToken: MrWfu + google: + clientSecret: tkAac + groupsServiceAccount: w6hg3 + jwtSecret: zpS + oidc: + clientSecret: d + okta: + clientSecret: "" + directoryApiToken: a + redpanda: + adminApi: + password: raQeh15W + tlsCa: Ax453qH + tlsCert: 5cvfDAz7XB + tlsKey: ve +securityContext: + allowPrivilegeEscalation: false + capabilities: + add: + - Ȏ煣+ȗ爸詤rȱoCö:踕v;D'茈% + - 斉 + - 劝 + drop: + - 6儌 + privileged: false + procMount: G + readOnlyRootFilesystem: true + runAsGroup: 6433461052261949548 + runAsNonRoot: false + runAsUser: -8726272423258831483 +service: + nodePort: 150 + port: 226 + targetPort: 87 + type: At +serviceAccount: + automountServiceAccountToken: true + create: true + name: ItYso +strategy: + rollingUpdate: {} + type: 匏ǛǢ²Ƴ屣EǙ9Gʡy +tests: + enabled: true +topologySpreadConstraints: +- labelSelector: {} + matchLabelKeys: + - ImKkR6l + - oUu1w + maxSkew: 373901521 + minDomains: -938191316 + nodeAffinityPolicy: "" + nodeTaintsPolicy: 梄焑ȅƗH + topologyKey: Mh1K + whenUnsatisfiable: CǑ庬Kf鄊珪t忒訾Ɗ壚pv餲(ɯŕT铈藘SȂ臏閏@ȗ云Ȧ + weight: -1530606902 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: [] + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: R8 + operator: 茔íȟÁ嗮敚S顕DZ躨ijȱ厎ɬɏl蜶拼 + values: + - PRc + - svCs + - key: LBaaOWdWW + operator: 0ŧĸ荕fR焌禗#ȰȶŁA + values: + - G0FXBn + - IpnG + - NM8oL + matchLabels: + lrB: NtdoEuXoTr2r + y1BSzp: ivK7CU + matchLabelKeys: + - 6ZNJrk5JxOHW + - B9Q + mismatchLabelKeys: + - "48" + - nm1WD5nM + - vLqhDh + namespaceSelector: + matchExpressions: + - key: GF6EQ8mKus + operator: B"(ň枣<吰檰戱R&狅Ɍ鋋Ļ飮 + values: + - f0plBpNy + - Gzl + - key: x4 + operator: Dz謶ʮ_ūKNdv· 壼×z朤 + values: + - zo + namespaces: + - QMv + topologyKey: r1z + weight: 1950038583 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: x3pdwI + operator: ǿLȴ8涣ÎƶǛ醌Õ纺網(đ倠樓纗Ǯg + values: + - xJlJ3H5 + - iza5 + - 4rszgB8v9aH + - key: 9j5f + operator: ǘ賊ƾA迌磡m摾烊 + values: + - EMECS8f + - oveu + - He + matchLabelKeys: + - 33y4E5v + - 5XIM + - "" + mismatchLabelKeys: + - 37I + - a02Re + - GVqKNcGgl + namespaceSelector: + matchExpressions: + - key: Rtiwm + operator: 萱J矻軚fC + matchLabels: + 8ipw: G + JwDA: 8EVkJ + oiQ2p: mYGgaz + topologyKey: 5l6PI + weight: -1824427504 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: "" + operator: 晑2%·QHVJTM錈 + values: + - CTU + - X5a + matchLabels: + WdJU6: I + bN: "" + uoTcuu: w1Y3yLW2rz + matchLabelKeys: + - O80Pf1RfMp + - WRJOT6B + mismatchLabelKeys: + - "" + - "6" + - nwQikpclV + namespaceSelector: + matchExpressions: + - key: CNaHfk + operator: 蕵Qmƀʁ6鲿)żȯ+ɩ玙9 + values: + - OuxZv + - key: dS + operator: 炧踮P-.壨ġ + values: + - 6ZJp7y + - key: jiLGGAQ + operator: 蟾Ɵ餌|ƨ綁訲bǝɋ圼 + values: + - mQ + - Fk3eA81t + - YR3WT + topologyKey: "5" + weight: 1634860618 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: "" + operator: (冁粄Ƴ\Ē4ǀ9峖樾t燠熂鷸ȿź蛼* + values: + - fnrA + - g + - gptz8 + - key: 4Hue + operator: oğ魀Ʌ¦榴 + values: + - InPtpb + - rxTpo + - HXnghAhWU1 + - key: EE2p + operator: á儬倏qȼ療ƚ + matchLabels: + YvCi: 1Tg + oLQ9OhyY: pFYpYKV + matchLabelKeys: + - J7 + - VR5 + namespaceSelector: + matchExpressions: + - key: cwgATYQvdj + operator: ÷Zá磋舫棹瑗-神ĕ嘟泦猵 + matchLabels: + Inz: BpiLQXOvEh + topologyKey: 5sHov5x + - labelSelector: + matchExpressions: + - key: vLI2 + operator: 歑ūĿɒ + values: + - FiQIMCFX2 + - vqhAaV5N7 + matchLabels: + 6DNwSiVsen: 1fRK + V: 3L49A8YEn + matchLabelKeys: + - K0sPcZWy + - fqn0luLnrF + - "" + namespaceSelector: + matchLabels: + O9bMG: CvBa11UI9OL + cm56v: Z83nkLc + gLJIEvg5: tUJq + namespaces: + - yP + topologyKey: 3RN + - labelSelector: {} + matchLabelKeys: + - vMX6FV1t + - vP + - TU8VLc + mismatchLabelKeys: + - ZAaEBYk + - Y0F4V0C + namespaceSelector: {} + namespaces: + - LwoHgQ + - qAJ + topologyKey: "0" + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: afwQ + operator: X(^Ȓ蘘}例 + values: + - 2ak8Yfa6P + - key: T4 + operator: ȵë_-Òŝ/c諒M攕窸 + values: + - Vktm + - trH51Z3 + - key: in74thKl + operator: HþČ謼ijƉË + values: + - NK2D3 + - NUsncshnv + - YDiqn6 + matchLabels: + T1: "" + nQFxJe: tdqf + matchLabelKeys: + - KI + - 6LjhIKmlnlhpI + - 88DArl53wb + mismatchLabelKeys: + - Bn30p + - zjq + namespaceSelector: {} + topologyKey: LrLYm2oYCgO + weight: -1318876164 + - podAffinityTerm: + labelSelector: + matchLabels: + T837hItO1qv: mCNMYnPq + gDh4Dxx2O: JUZxy4z + matchLabelKeys: + - sTn + - 4nu + - CSgSC + namespaceSelector: + matchExpressions: + - key: A5z + operator: "" + values: + - PJ6Zh + - S + - key: VufLBVvFECvIW + operator: ʝcƘʣ]筍ġ0Ğ鎏£<艻錯瀢 + values: + - tz64EN + - i + - key: 8Q2s + operator: E1戠天:ɺ勎sȸɾ + matchLabels: + XTI: 7cIZ + jpH49wkR: D5u5c + namespaces: + - XyGPkW + - CERSWYSVu + - Ms80R + topologyKey: 57PFRYX + weight: -1558645933 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: ZGO5iRhr + operator: 堭ŷz + values: + - IfLuRt6FZf7 + - 03fn3j1 + - key: HL + operator: M螎õ}shƏ檅葜0<瘼Ɗț夡J偦ʆ + values: + - "96" + - 4uInca + - KsWaAE + - key: nKr + operator: ʋƲ~uè蟪ʗƁʬȌ势ȃVÄ穵Ą + matchLabels: + DVRktk1U: 1XFlhcXH + matchLabelKeys: + - kJMI + - Js8qeQ + mismatchLabelKeys: + - lnn1G + - A4nlWqCrE3 + - BzU + namespaceSelector: + matchExpressions: + - key: "" + operator: ɍįmŐ冹?E蹣ƋH肥=ɭuR訷$ + values: + - faDMJv + - b0VUPX + - lOsWCl + - key: 7iy + operator: 0:H碼\b黵禧鐃 + - key: nbn + operator: 疬厼掚Ƿ蛬ƞÜ9懎拖ų洜 + values: + - byjrbi + - RqfcIc + - dLaAUt + topologyKey: BUfQ +annotations: + He: OemFaO9 + QE5O: 6CBP +automountServiceAccountToken: false +autoscaling: + enabled: false + maxReplicas: 400 + minReplicas: 455 + targetCPUUtilizationPercentage: 64 + targetMemoryUtilizationPercentage: 472 +configmap: + create: true +console: + roleBindings: + - zn: null + - WCQKaiaj: null + py: null + roles: + - {} +deployment: + create: false +enterprise: + licenseSecretRef: + key: 4F + name: k +extraEnv: +- name: fqLRMsbtI + value: VzzHe + valueFrom: + configMapKeyRef: + key: "" + name: 1au8QkGsYcK + optional: true + fieldRef: + apiVersion: "38" + fieldPath: rM + resourceFieldRef: + containerName: Moz + divisor: "0" + resource: V + secretKeyRef: + key: IQ7AC3i60u + name: BCb + optional: false +extraEnvFrom: +- configMapRef: + name: twq36B + optional: false + secretRef: + name: OLKXh + optional: true +- configMapRef: + name: Pyr + optional: true + prefix: nyu + secretRef: + name: HDmfly7EP + optional: true +- configMapRef: + name: 2TmUL8GD + optional: false + prefix: R5 + secretRef: + name: TyS + optional: false +extraVolumeMounts: +- mountPath: 4zQSAo1Lj + mountPropagation: 檛ȂWg + name: eeS + subPath: iaw3G + subPathExpr: N02q4 +extraVolumes: +- name: "" +fullnameOverride: j1dUk8TGy8Np +image: + pullPolicy: 谝鞛榜ɸ暐ɸ刀x喋 + registry: zi + repository: MTSoVvJ + tag: a25lJOfGpG +imagePullSecrets: +- name: OlRQO +- name: Hkuk3 +- name: fP +ingress: + annotations: + ADJxl: n5EK4WzM0 + M: Zoud6 + eWXUqq: "" + className: "27" + enabled: false + hosts: + - host: 6PclZ7Q + paths: + - path: RqbF29XX + pathType: WB + - path: npV1GL + pathType: zxvm + tls: + - secretName: Q + - hosts: + - EvjYI + secretName: gRDta + - hosts: + - zlgJP1 + - g367Bgr1 + secretName: eQ +initContainers: + extraInitContainers: d5lM +livenessProbe: + exec: + command: + - S + - eqi + failureThreshold: -574948042 + grpc: + port: -653621031 + service: ir + httpGet: + host: qboin0qudh2Y + path: 4jFbHK + port: 9APWoaII + scheme: ćdž埭]KU + initialDelaySeconds: 1217073146 + periodSeconds: 2084735603 + successThreshold: -1091703574 + terminationGracePeriodSeconds: -4975007928507132892 + timeoutSeconds: -203727359 +nameOverride: ld +podAnnotations: + Scdn: fLH1yCm + lCp: Hi +podLabels: + 6AmpBMD: yDh + lPb: vi6tx4 + u: Vai7 +podSecurityContext: + fsGroup: -4268923634359973318 + fsGroupChangePolicy: 椶'ɏ4Ŝʘþf¸ǚļţRď0 + runAsGroup: -5513988494785819878 + runAsNonRoot: true + runAsUser: 3348050323720255791 + supplementalGroups: + - -9211346208910065015 +priorityClassName: 89gnK9rXyDXui +readinessProbe: + exec: + command: + - WCCn1 + failureThreshold: 1866953941 + grpc: + port: -978078521 + service: Gk8q + httpGet: + host: 4aDbYIp + path: sFssnZ8D + port: b9TEE2n + scheme: n8鞘呷2ef嫰髡箩棔螇džNj雤 + initialDelaySeconds: -1624688782 + periodSeconds: -231284043 + successThreshold: 1609785496 + terminationGracePeriodSeconds: -564252460349465292 + timeoutSeconds: 767134266 +replicaCount: 444 +resources: + limits: + wjrESvfqh: "0" + requests: + fSPJBFEwK58: "0" + j: "0" +secret: + create: false + enterprise: + licenseSecretRef: + key: iKQ6Nz + name: OD68lA + kafka: + awsMskIamSecretKey: "" + protobufGitBasicAuthPassword: GKaL + saslPassword: J6S + schemaRegistryPassword: 8PuilRN + schemaRegistryTlsCa: "" + schemaRegistryTlsCert: "" + schemaRegistryTlsKey: LsoxQcg + tlsCa: rGkjDT + tlsCert: gzs + tlsPassphrase: "70" + login: + github: + clientSecret: BGgKCBXeA + personalAccessToken: S + google: + clientSecret: KQXew + groupsServiceAccount: Ll + jwtSecret: 95jKDcdtX + oidc: + clientSecret: "" + okta: + clientSecret: b + directoryApiToken: "" + redpanda: + adminApi: + password: y2jU08n6KI + tlsCa: 6YyBT + tlsCert: ZkxE + tlsKey: MpUTYb4y +securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - Ƹłš硇¹,9菧ȉŪ転Ǹï7ĭɜ + privileged: false + procMount: 榷ŋĦƨÈ俟ţUȫ桊fLŊƐbƼɤ襐 + readOnlyRootFilesystem: true + runAsGroup: 2134851813508950156 + runAsNonRoot: false + runAsUser: 1677623433130194771 +service: + nodePort: 470 + port: 46 + targetPort: 43 + type: uqFB +serviceAccount: + automountServiceAccountToken: true + create: true + name: fP77cJ3T +strategy: + rollingUpdate: {} + type: '>Ƒ梚ǩ' +tests: + enabled: true +topologySpreadConstraints: +- labelSelector: + matchLabels: + IoAy: C6rMwI0 + eM8D7JD5PJ: "n" + lFmG: gJ3l + maxSkew: 839777044 + minDomains: -1438737093 + nodeAffinityPolicy: Ƭ氄ɿ[閾pʙ9 + nodeTaintsPolicy: j珙%!溌BN + topologyKey: 2GZ + whenUnsatisfiable: 屄ɧȄ +- labelSelector: + matchExpressions: + - key: UQkB4Vn + operator: D86i溨F'>亖÷ + values: + - pH + - LHgYM1W9 + - gO + matchLabels: + bw52WaG7: 5zm31oU + t99k: AF0 + matchLabelKeys: + - lkYaHo + - 4tzd + maxSkew: -1948819142 + minDomains: -1754532325 + nodeAffinityPolicy: 酝ʪ+彨緱Y塞雾}捋嗭0]ȰʤĖé横 + nodeTaintsPolicy: '#騅Ɵ$F圃拱鿎鵅xq' + topologyKey: z2NL + whenUnsatisfiable: uȤÝ酑 +-- case-039 -- +affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: OiH + operator: Eʤ#/7諨 + values: + - iYzfGpa4 + - PaMqxj5fj8 + - sWaI + - key: Pw + operator: Kw[o0鿚 + values: + - Gnm + matchFields: + - key: YO9QL + operator: ȏ网牙鍩橷潗D9騭ŗʈ求U縷讒Ƴ漏哟 + values: + - XV65fSG5o + weight: 144962453 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: [] + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: p2uqgWn7p + operator: ǙmX窀ʄʙ婘m.Ƈ谱qŴĆ揿 + values: + - IQGwhE + - Hiut + - key: mrN9GbREak + operator: oʟ + values: + - GZkF1BV + matchLabels: + 8bOT0: pvv + VYd3OWm: 0gW5 + matchLabelKeys: + - thrYIp + namespaceSelector: + matchExpressions: + - key: sonam3I + operator: "" + values: + - a9M + - bM + - key: ZFAy + operator: yW揚ɻʖî床哲ɯǮ^DzǓ + - key: ZwHE + operator: sǍ逘璿Ǧ5u軟DZ鞏綇鏑Ɲ` + values: + - 1D6 + matchLabels: + MoK3: j4Rw + namespaces: + - yS + - F2VMFv + topologyKey: wNv3 + weight: -1334539094 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: Hp + operator: QɃ蒜§Ɩ5SyǸ鎧ȝ)ɒ獬v氮n兡Ĝ + values: + - "" + - y3ufRu75J + matchLabels: + Sbhb4LC: p + U1NMpjoLa: BC1D + eIgw: tBbWDRZ7j + mismatchLabelKeys: + - iWKlUgr + namespaceSelector: + matchExpressions: + - key: 9HkK + operator: ȃĕ送 + - key: P9rh1yxLN + operator: ŋľ&謮稠Ÿ珀胔俨ʎŰ + values: + - 16yHoCooS + - r3ym6YAoy + matchLabels: + PrnS8: K2h + namespaces: + - s + - US2hE + topologyKey: 5SbLzS + weight: 1219402233 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: 082AGo10x + operator: pȁij~搣ɢDĝ偩ʣȘ'oIʓ?憏圽U + - key: CXjEgRK + operator: 颭镃Ș蠮S闬耧涐²ǒ圡窽ǹ(ǁ + values: + - zIVWI7jXh + - HE8UDiZnhVG + - "" + matchLabels: + FRgh: MUBtKVc + iu: K3 + jV: 5jM + mismatchLabelKeys: + - h2 + namespaceSelector: + matchExpressions: + - key: "" + operator: mHɻȐĪ$ + values: + - GFueB + - 5prw02 + matchLabels: + KgBnfc: t9Hb4 + SxGw: 4qCJppj + h3m2: gRc + namespaces: + - 1maI + topologyKey: UCy + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: 08Q + operator: $鏪轟ſ俨+嬯呦ĄȕɓJp + matchLabels: + kSy3s8nE: Q0 + matchLabelKeys: + - bf0Tpn + - I + mismatchLabelKeys: + - 0Bm09lf + - P7 + - lyb2 + namespaceSelector: + matchExpressions: + - key: 6zTBp0G7 + operator: 氯¥+Dz睧勪娳Ƨ伮慒{ąɫ`瑛稃5绨 + values: + - 1YVGovQ + - bJ + - key: Cxm + operator: 芼 + topologyKey: f + - labelSelector: + matchExpressions: + - key: jNrAref + operator: 接ʼnĎ + values: + - N0 + - ZNwtHjxR + - key: 33k8BGf + operator: rĴr+qȩȃ休3Ȳȅ + values: + - "" + - E8yL4W + - 9anWnm + matchLabels: + WyV0Ct: 6BVL + vLUV: mvMLwn + matchLabelKeys: + - 9O + mismatchLabelKeys: + - CO + namespaceSelector: + matchExpressions: + - key: Jiyaq + operator: ɯ唺饓9 + values: + - qogYf + - key: UXg6 + operator: à! + values: + - phW2 + - BItew + - c09DZ9v + - key: hPhLpBwJ + operator: g«疻:糄Ś$q + namespaces: + - jAvA + - 0V6Uv6PU + - AOoh3 + topologyKey: d2QYa +annotations: + IJC774: 5hK + P1Py: YYAic7jN + REyW: 7LdLtJYMz +automountServiceAccountToken: false +autoscaling: + enabled: false + maxReplicas: 461 + minReplicas: 403 + targetCPUUtilizationPercentage: 297 + targetMemoryUtilizationPercentage: 161 +configmap: + create: true +console: + roleBindings: + - 6O4d: null + EY: null + oPTMvYGp: null +deployment: + create: false +enterprise: + licenseSecretRef: + key: KvJNskb5ptO + name: vVsE +extraContainers: +- args: + - fajfbgt + - 1XG4cARu + envFrom: + - configMapRef: + name: F5n + optional: false + prefix: Prg + secretRef: + name: vq2FHcobO + optional: false + - configMapRef: + name: Mfdidfx + optional: false + prefix: eggfGpU + secretRef: + name: gX5GT + optional: false + image: H + imagePullPolicy: 玣ɟ踣 + lifecycle: + postStart: + exec: + command: + - 5ABG2Ao + httpGet: + host: D4S2dPB + path: QCCIL6 + port: wu + scheme: eSÉĝ嶤ʮ牑 + sleep: + seconds: -6736232898620818377 + preStop: + exec: + command: + - "" + - 9oy + httpGet: + host: vIPKpEbM + path: l4HaTS9 + port: -180983347 + scheme: h儷#PX盩ʋÈ + sleep: + seconds: -3654571329064470871 + livenessProbe: + exec: + command: + - zGWiFCpvJyG + - 2A + failureThreshold: 130427535 + grpc: + port: -458689504 + service: keBJI3 + httpGet: + host: fkJ + path: MFy2 + port: 1638404838 + scheme: ƵĜRóM螻作仄ĨgŋƷ蔶慅Ƹ + initialDelaySeconds: -1024094942 + periodSeconds: -1045387639 + successThreshold: 966241980 + terminationGracePeriodSeconds: 43907789703605006 + timeoutSeconds: -2115548430 + name: n65z1Le + ports: + - containerPort: -496460005 + hostIP: m9e0LZZ + hostPort: 557092727 + name: hG + protocol: 奀x儋韖ȃ嶍射擋- + readinessProbe: + exec: {} + failureThreshold: 1620135876 + grpc: + port: -1149097195 + service: 7KtLa + httpGet: + host: Mel9pu + path: J + port: Bl + scheme: 臹欔 + initialDelaySeconds: -750113074 + periodSeconds: 820678693 + successThreshold: 1708685033 + terminationGracePeriodSeconds: 6351250062493105403 + timeoutSeconds: -89282235 + resizePolicy: + - resourceName: Cm2W + restartPolicy: o^Cǐɬ醒ÛQȌ帧圷孩Ą + - resourceName: jhEz4gNWQKP + restartPolicy: DV庴 + - resourceName: EgwUKXikbg + restartPolicy: 瑚 + resources: + limits: + 2jSTU8: "0" + 7OI: "0" + FIfseL: "0" + requests: + EPF86: "0" + GcwO1SNT: "0" + restartPolicy: '>Ǥ摔ȶ蘭ɘʜɩ' + securityContext: + allowPrivilegeEscalation: false + capabilities: + add: + - J + - 8垺ŭihȸ£gJĠǐ!İ0 + - ƶ害Ƈ§孶邸 + drop: + - 龈PeęIJ傮ȅ溣E忬鮷蜆GÊ霌 + - þƢ^ + - RTmī07ý謐ɩ噎 + privileged: true + procMount: (朴頲碞!0¿搻ź)磑[哈YǓěNG$ + readOnlyRootFilesystem: false + runAsGroup: 3606686082741296584 + runAsNonRoot: true + runAsUser: -9076124251416402294 + startupProbe: + exec: {} + failureThreshold: -2038237600 + grpc: + port: -992723564 + service: bMQIm4Y6fY + httpGet: + host: w0Z6WQWwn + path: Kw + port: KdZFUIvpm + scheme: L媰 + initialDelaySeconds: 266050830 + periodSeconds: -879749840 + successThreshold: 1098563171 + terminationGracePeriodSeconds: -3577990655544091297 + timeoutSeconds: -838391922 + stdinOnce: true + terminationMessagePath: bh7 + terminationMessagePolicy: 餔Ŵ婜 + tty: true + volumeDevices: + - devicePath: 5EA9lR0y + name: wCP0dl2Uf + - devicePath: IKOQwmn + name: connmB4Ve + - devicePath: hssHEiwb + name: vP68uD + volumeMounts: + - mountPath: 9Yvkg + mountPropagation: Q众XM娪08菫 + name: XP + readOnly: true + subPath: Mk + subPathExpr: LV + - mountPath: 381fE + mountPropagation: ǚ钍jǍŏh濢n1ŕǼ姕ŗđċCʏ(漇 + name: 4prce + subPath: tvkrRPN + subPathExpr: Otc + workingDir: D4 +extraEnvFrom: +- configMapRef: + name: zdN8iNs1e + optional: true + prefix: z + secretRef: + name: tGw + optional: false +- configMapRef: + name: qRSvRtA6 + optional: false + prefix: dE0dDLvy + secretRef: + name: m + optional: false +extraVolumeMounts: +- mountPath: nTxUyaL + mountPropagation: "" + name: cwkJrEER + readOnly: true + subPath: FKU9h + subPathExpr: 12vLerk +- mountPath: DuUpWysEh2r + mountPropagation: IƏ + name: YlcuH + readOnly: true + subPath: 1faJ4ypp7 + subPathExpr: ZDct +extraVolumes: +- name: bdnliW +- name: Tr +- name: cd +fullnameOverride: bbshm +image: + pullPolicy: ɴ烚庻阐狘:ŭ(M$tY炜ī崞Ž + registry: QxUvz + repository: Gr + tag: hrAYj1i +imagePullSecrets: +- name: MTOK84IL +- name: YAl +ingress: + className: qyKUEOUT4u + enabled: true + tls: + - hosts: + - F7m23 + - "7" + secretName: M +initContainers: + extraInitContainers: aSeq42klM +livenessProbe: + exec: + command: + - ajpIBjdV + failureThreshold: -1650923727 + grpc: + port: -598400902 + service: NoUl1T + httpGet: + host: "1" + path: T + port: -1011339684 + initialDelaySeconds: -1047122153 + periodSeconds: 300714247 + successThreshold: 1660165948 + terminationGracePeriodSeconds: -6817463041894309382 + timeoutSeconds: 497385152 +nameOverride: o2F37Lr +nodeSelector: + Md8w5MD: cTipUm6 + Y31W: uQ5xyo +podAnnotations: + 5oGD5: wKq + Qi815eSQdI7wJ: SwgPh + vAJU: z +podSecurityContext: + fsGroup: -1210907643611065698 + fsGroupChangePolicy: IJ鄔ȫ荪癓椥%k矜椒ʊ0宻lƑɜIɇ + runAsGroup: -4059110951032458810 + runAsNonRoot: false + runAsUser: -6169453912741831517 + supplementalGroups: + - 5292690601828357137 + sysctls: + - name: xY9WN + value: JL + - name: v7R + value: q1nexB5KTD3SE + - name: PN + value: neE5ismaY +priorityClassName: aDlP +readinessProbe: + exec: + command: + - 2xO + - BlUV + failureThreshold: -2130189853 + grpc: + port: 996585883 + service: qWavRHqQOBBP + httpGet: + host: U + path: MJdmT7Y + port: aujUU + scheme: ¹Ť碏譽> + initialDelaySeconds: -781516024 + periodSeconds: 241739148 + successThreshold: 912206192 + terminationGracePeriodSeconds: 1472699093368179429 + timeoutSeconds: -1948646722 +replicaCount: 122 +resources: + limits: + g51: "0" + requests: + Wd: "0" +secret: + create: false + enterprise: + licenseSecretRef: + key: PXlML + name: 1ZXP + kafka: + awsMskIamSecretKey: Q8ZB + protobufGitBasicAuthPassword: 6x8Cv + saslPassword: kPhPSQWJJ + schemaRegistryPassword: JK + schemaRegistryTlsCa: SnQ + schemaRegistryTlsCert: nrxxx8 + schemaRegistryTlsKey: aizaszl + tlsCa: tKnCvE97 + tlsCert: XQGOjdnSY + tlsPassphrase: UIS + login: + github: + clientSecret: RAo + personalAccessToken: YJtxt19kpv + google: + clientSecret: V0kmwLq + groupsServiceAccount: AaiW + jwtSecret: FGWF3nXjDA4 + oidc: + clientSecret: rnv + okta: + clientSecret: ZE5mxhO6s + directoryApiToken: 7z + redpanda: + adminApi: + password: YwKgntj3 + tlsCa: ywmMdJU + tlsCert: OK6C5sNI0 + tlsKey: eNdF9knNN +secretMounts: +- defaultMode: 368 + name: GaEvNh0Ifo + path: 8c1 + secretName: "" +- defaultMode: 412 + name: Dy8Ef + path: X2Ct + secretName: QRQFk +- defaultMode: 211 + name: cLEkHy + path: alMc11eGER + secretName: 8miR +securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - ƕE仍腽ʨLJ甴Z´:涟 + - mŠ'菴h饘ǦŃ2 + privileged: false + procMount: 麤绊噃ȳ{ɚƪ秥ȧG + readOnlyRootFilesystem: false + runAsGroup: -8188439767627968973 + runAsNonRoot: true + runAsUser: 2990782549155496077 +service: + annotations: + 4yhZo: zLVEslN + Amz4VM: QAvK + IPCS: b1R + nodePort: 233 + port: 400 + targetPort: 329 + type: dPOD9Kzb +serviceAccount: + annotations: + PPZDrdmxKV: UBjiSx + automountServiceAccountToken: false + create: true + name: 8s2qVhKEW +strategy: + rollingUpdate: {} + type: '!蘃«2狺čH' +tests: + enabled: false +topologySpreadConstraints: +- labelSelector: + matchExpressions: + - key: K98063hAMXd + operator: 閃ŘDZƳwųA旰C汔§挦塳¹@ē + matchLabels: + y9: GJEjaj + matchLabelKeys: + - 4xZpqk + maxSkew: -659297182 + minDomains: 1124395321 + nodeAffinityPolicy: ʬC8 + nodeTaintsPolicy: 鱯禓瞝 + topologyKey: mq + whenUnsatisfiable: A´ʕɭNÀȜ龎q擞u貒槂轌v +- labelSelector: + matchExpressions: + - key: Yd + operator: "" + values: + - dCWo2pjVuA + - hl8G3Kp + - M + - key: VYxo + operator: _k?Ř + matchLabels: + 3kRK: xOzJ6 + KUwsC: FN5bAqvV + QPay: w0lIH + matchLabelKeys: + - gkJFY + maxSkew: 501038978 + minDomains: -2011840701 + nodeAffinityPolicy: Łdz倾僚ʒ屆9ÐE釤Ŏo + nodeTaintsPolicy: Ǩʖ#Ŭǧ¦Ûũ°啑 + topologyKey: JCJYk4 + whenUnsatisfiable: 暛ūZɆǗ絜皼bȇĀ簁搿WXƪçɗÁ +- labelSelector: + matchExpressions: + - key: gyZMV + operator: ƲƬ釒橙ȋ齸鑝鷳ĔǸɊZ聻趁õÈc + matchLabels: + T1YT: SJYt + W: ZaF + WdGxif: 3EKPjb9 + matchLabelKeys: + - ukD8HM + - mD + - Z + maxSkew: 1774410820 + minDomains: 36391976 + nodeAffinityPolicy: "" + nodeTaintsPolicy: ŵɎļ%鋏[ʞô + topologyKey: oGrtNcnUje + whenUnsatisfiable: ƓǪĈɏ荥蟗Ș鉢A +-- case-040 -- +affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: 7RRFnuao + operator: 鑿梞e璺瀧敢tȱ + - key: 3qz030r9N4 + operator: 脟óȨq駥Ƽx垤R$L + - key: 4egJ + operator: 敕ƒ洀ņ+Ō轲C丼Ʒij.ƾ蚯ƺ痻3皆咒 + values: + - "" + - J66saNw8 + - xBRUfDKhiA + matchFields: + - key: Kgp4qFm + operator: 桋iz<ïŃǃ襶D齿 + - key: 7F + operator: "" + values: + - iquNT + - aFPIw + - lYMJn4Un3 + weight: -954635927 + - preference: + matchExpressions: + - key: ePHgEs + operator: 撹ł + weight: -2109244754 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: gK + operator: 垭ʮȌ)"彛 + values: + - Vvo + - "" + - key: n0 + operator: 挪VɱȒ + values: + - 595ST + - sHQoTQgQ + - ZyYxnGB + matchFields: + - key: "8" + operator: 餒ơ鋦r)锟壃m汇 + values: + - H8 + - matchExpressions: + - key: nErJm + operator: Ûɟ敀淽 + values: + - sbjW + - 1l + - go + matchFields: + - key: ozzkD4D + operator: Ʌ\h崭蠒ȓ旉蹖楚_掁S5 + values: + - NrN0Id15O + - VrahPz + - YJfhO + - {} + podAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: qiGNj + operator: jƯȨ穞ɿPȧ + - key: HPRR + operator: ž8ƃKKDz蠽ƚ0ƻ + values: + - NAx + - Pr2F + matchLabels: + LY: ZRjD + matchLabelKeys: + - ikCO + - n25 + - IY0AqNStYm + mismatchLabelKeys: + - uO6G + - EFKfLOM0 + namespaceSelector: + matchExpressions: + - key: frBwUGG + operator: ǧ啯ʖ6džȡ衺Z莋æȘzv + values: + - 68q + - PrId4k5Nk + - 1Izg6c + - key: H5neR + operator: "" + values: + - gf2 + - "" + - key: LTEiVQV + operator: ʅďl$y韙bO儺e籾吕ŃV + values: + - LccIflVn3 + - QX + - kRZLtn + matchLabels: + lccn5: lx6 + topologyKey: AE + - labelSelector: + matchExpressions: + - key: ljGag0 + operator: "" + values: + - 3AlcF9eOiK + - key: XPoIj + operator: ĻĵN稙²x鸴ʊ + - key: "" + operator: m[ɻD«ʯĢĥɖHÃú锺N蓍!f + values: + - cwRFs + - wJtpMgyV1I + matchLabels: + 6gzmw2BW: v1eC + QI6Gl: Ckzyw0v + uRw21: 36kl + mismatchLabelKeys: + - XiX9Mrhv + - Xk2Ri + namespaceSelector: + matchExpressions: + - key: Roq9G + operator: 槓G{? + values: + - YCBJEhS + matchLabels: + 9X5C: TU1y + PG1k: 8j76iX8R + iYq9QLUSh3bk: Mvl2WRQ + namespaces: + - Pp + - z1O9mW5rB + topologyKey: U + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: pqtCgWlk + operator: eŭñZ) + values: + - 6eUrtsX + - GmGeP7 + - pBhe0 + - key: gctw + operator: L?岤紎!蠾黅誽帯÷Ʉ坏q + values: + - G + - "" + - "" + matchLabelKeys: + - IGYc + mismatchLabelKeys: + - C + - XlxD2Y5h + - Eut + namespaceSelector: + matchExpressions: + - key: QNvJq6Uc + operator: Ǔƀ閝遨垛簙UdĢ7ȍ騽¹DŽ + values: + - m4wq + - TmuqVB1 + - key: PTVC + operator: 珙'ɀɒ虃龓楼ƺ譄êǿ + values: + - w + - K + matchLabels: + GQp: tw + namespaces: + - t + topologyKey: I9Ng7D + weight: -278680619 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: IaZiqfV6 + operator: 幋x:Ȗ + values: + - XmaYG80 + - aaEScB + - DxB + matchLabels: + J3Ny9zUJ2DOTKO: eiUL0RR + lt: bqOs + matchLabelKeys: + - XYHp1S + - JKj1 + namespaceSelector: + matchLabels: + WopugltEP1J: eaGpkiS + namespaces: + - H9w9Q + - A8D + topologyKey: pvkKW + weight: 252280673 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: lSi + operator: 襚ǫAŇþ腦W[ĕ嘱ʌſœɃ槏Z岪 + matchLabels: + OzmceOBQ: F2mtk + QcoH: qt3OR6ZcjY + t5Cqg1: 1x9WW8EUyyn + matchLabelKeys: + - 0XGJ + mismatchLabelKeys: + - K6T + namespaceSelector: + matchExpressions: + - key: KoofEA + operator: ' íɀ馩Ȭɫġo娤螗暴Û漷ʦO腔' + values: + - nj + - U + - onkfJ4 + - key: 0aO + operator: Ŷű輖+¶)罩ƌ×螂 + matchLabels: + 2hf: GeFfROs4 + pA23: kqkG + rZ: DH6cT + namespaces: + - yvfsu + - L3Pu + topologyKey: BBBCjZel + weight: 392487334 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + 0hp: sd9 + mwTeR: D3HlJbmoK8 + matchLabelKeys: + - MwDkniC + - "" + mismatchLabelKeys: + - VuQB + namespaceSelector: + matchLabels: + 1x: Pj + D3J: 4gFps + bQU: weT0tI + namespaces: + - y9zrYKWApO + - rq0K3 + - 5XUeP7 + topologyKey: P7V + - labelSelector: + matchExpressions: + - key: Jv + operator: 啽ŃŐø + matchLabelKeys: + - s + namespaceSelector: + matchExpressions: + - key: Fy5Deb + operator: 旉錛!荕Ɂ! + values: + - nbiy + - "" + - 6QORDbd6zn + matchLabels: + bba0KJ: NE1j + nYif5xu0Hy9XW: 0s + qAoT: "46" + namespaces: + - 4JHyx + topologyKey: 7621t +automountServiceAccountToken: false +autoscaling: + enabled: false + maxReplicas: 470 + minReplicas: 361 + targetCPUUtilizationPercentage: 160 + targetMemoryUtilizationPercentage: 475 +commonLabels: + X: zjmrl + "Y": yG0 +configmap: + create: true +console: {} +deployment: + create: true +enterprise: + licenseSecretRef: + key: a7Ph + name: zsHNWVcS9 +extraContainers: +- args: + - jlI16Xnnb0 + - x0Z + - Tv6z + command: + - 3MnkZe0L + - OK + - cKvaGI + env: + - name: 7RtgX9 + value: TQH + valueFrom: + configMapKeyRef: + key: "" + name: GE2 + optional: false + fieldRef: + apiVersion: x2H + fieldPath: iVYVzT + resourceFieldRef: + containerName: 3QSG + divisor: "0" + resource: AgMtPE + secretKeyRef: + key: BhGA6 + name: LKemd3Cs9 + optional: false + - name: 9dFxchX + value: huoZj + valueFrom: + configMapKeyRef: + key: skdmo + name: gSEkUx + optional: true + fieldRef: + apiVersion: ymAcwLzaJ00G + fieldPath: de9Q + resourceFieldRef: + containerName: ZgwwQvA + divisor: "0" + resource: OTraA + secretKeyRef: + key: Pe8 + name: 39mCZV7ERv + optional: true + envFrom: + - configMapRef: + name: l + optional: false + prefix: kGdnbCakM + secretRef: + name: JrDM + optional: true + - configMapRef: + name: 0iH67 + optional: true + prefix: 3JVMhcII7 + secretRef: + name: PS1J + optional: true + image: Bx3IW17kjF7 + imagePullPolicy: È8秏糇 + lifecycle: + postStart: + exec: {} + httpGet: + host: EeLx + path: JC + port: 638412697 + scheme: 翔ĩñɁɬj局³喪Eů磘Ʒ唡嬤 + sleep: + seconds: -2739564842418698030 + preStop: + exec: + command: + - zjNyV + - 3i + httpGet: + host: RxhMCXQN + path: Dq + port: -821303664 + scheme: 髒xD>?ǠĆ踃w¬ + sleep: + seconds: 8925361607851382825 + livenessProbe: + exec: {} + failureThreshold: -2015695369 + grpc: + port: 102189788 + service: VG2k6Atq + httpGet: + host: 0dxm + path: Pix7SytH + port: 284583441 + scheme: 畝ǂƬƜ聞|b + initialDelaySeconds: 1150668189 + periodSeconds: 1279412097 + successThreshold: 337444728 + terminationGracePeriodSeconds: -665826210809930777 + timeoutSeconds: -802810999 + name: 1KSo0a + readinessProbe: + exec: + command: + - 3cCL4 + - en + - VN0 + failureThreshold: 448729232 + grpc: + port: -174942651 + service: paUcCUtV8A6 + httpGet: + host: tSEChhvGgDsf + path: Jrr + port: 516172996 + scheme: c{Ƭ臾斡:Ɣ?Í + initialDelaySeconds: -714126900 + periodSeconds: -88316167 + successThreshold: -1820867160 + terminationGracePeriodSeconds: 272130190949654337 + timeoutSeconds: 1803351679 + resources: + limits: + f9GQWFTKPFP: "0" + g5: "0" + requests: + 4A89zLoFG: "0" + SmOBH: "0" + restartPolicy: Ű高ǙG%7BČCaďʥyď + securityContext: + allowPrivilegeEscalation: false + capabilities: + add: + - H鞕ă鶅镀秀 + - Ŏ昮0yƤɯ斺R妕Je芓BɜCĵ + privileged: false + procMount: ÿʑ鎆乭cŇ陛ǼȠn + readOnlyRootFilesystem: true + runAsGroup: 5591360478943231672 + runAsNonRoot: false + runAsUser: 6381588597473822835 + startupProbe: + exec: + command: + - rV83LKQ + - 87Vc + failureThreshold: -2022114361 + grpc: + port: 1348736621 + service: Gx8f9phR + httpGet: + host: fWnW4CGV + path: yQl0PNEE3g + port: TYi + scheme: 絅xn,ȵ6ʎ癙 + initialDelaySeconds: 205090742 + periodSeconds: -1401542741 + successThreshold: -2130268569 + terminationGracePeriodSeconds: 4104437343850793050 + timeoutSeconds: 604054255 + terminationMessagePath: ec8kHaD + terminationMessagePolicy: 甎i + tty: true + volumeDevices: + - devicePath: NFjF + name: AH + - devicePath: "" + name: u + - devicePath: 0q6A + name: nFe3FY4 + volumeMounts: + - mountPath: ad7JXhGN + mountPropagation: =廄殞+ + name: qVHWCUHp + readOnly: true + subPath: m3RBekA0 + subPathExpr: 7F0F8Ge + workingDir: LmnqIVV +- args: + - 3g94Jb + - "n" + - HxatWli7Qe + env: + - name: yKfn + value: fni0 + valueFrom: + configMapKeyRef: + key: cQjxg02ud + name: DqLUCO + optional: false + fieldRef: + apiVersion: dS + fieldPath: aH + resourceFieldRef: + containerName: BVSH2Bxu + divisor: "0" + resource: ZLW3 + secretKeyRef: + key: J + name: APYyG5qY + optional: false + - name: b4i9WEf + value: Ru + valueFrom: + configMapKeyRef: + key: mzxgZ + name: XgDd + optional: false + fieldRef: + apiVersion: U1l + fieldPath: sG2pcjz + resourceFieldRef: + containerName: Vlc1Ru + divisor: "0" + resource: hZpqB + secretKeyRef: + key: X0W3QpdAhux + name: I3L + optional: true + envFrom: + - configMapRef: + name: DJjN7Phe + optional: true + prefix: 4K2MBzNl + secretRef: + name: s4GF + optional: true + - configMapRef: + name: td0aZ + optional: true + prefix: CYvFW + secretRef: + name: WaBWGCRa8 + optional: true + - configMapRef: + name: ehHs9m + optional: false + prefix: n1x + secretRef: + name: TdUJ + optional: true + image: UNJ6E6 + imagePullPolicy: 砓³绔丬A + lifecycle: + postStart: + exec: + command: + - Qs8Sd + - JGX4Qj + - eCw00uq + httpGet: + host: NNLSd + path: y4tS + port: QzOfwe3a + scheme: º猗ĥɮƅLɘ隮术ƒ赥;,ǝ髳Ĝ7Ĭ嬳 + sleep: + seconds: 1170469124057922158 + preStop: + exec: + command: + - TN62uDLAuIx + - ndI + httpGet: + host: t7H6l2 + port: RHeYpAvJ8 + scheme: KǠɀƴ杔¸Ɉ$毕削peýfv! + sleep: + seconds: -5232306180460338099 + livenessProbe: + exec: {} + failureThreshold: -1900233123 + grpc: + port: -1323381498 + service: wJ + httpGet: + host: pAHsn3 + path: k31zW1 + port: 2elbrK + scheme: 痯秿丌 + initialDelaySeconds: 537756270 + periodSeconds: 1139432456 + successThreshold: -289377675 + terminationGracePeriodSeconds: -709025030374540888 + timeoutSeconds: 254134433 + name: zWs + readinessProbe: + exec: + command: + - x093a + - v1 + - Ef + failureThreshold: 75768089 + grpc: + port: -237977747 + service: "y" + httpGet: + host: EBEth + path: C + port: 790399211 + scheme: ær堹mhʢ + initialDelaySeconds: -157687184 + periodSeconds: 1071897332 + successThreshold: 824432298 + terminationGracePeriodSeconds: -54575953702939670 + timeoutSeconds: -1190752843 + resizePolicy: + - resourceName: R9fM + restartPolicy: ?ʖȒƅƀ逎v鐰wģ籫 + - resourceName: 7C + restartPolicy: óʌF鿯薸k} + - resourceName: Bqy + restartPolicy: E吻X秤} + resources: + limits: + UMJnobyO: "0" + qJmAwr: "0" + requests: + ZktW7e51vRUG: "0" + restartPolicy: '>ŀ鎙莸鼔茷蝼薼Ƽƅ°3貦罌臣洴軟處姼' + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - 儜vƝ¾ + - 輝Ġ$琑+檂 + - 飂 + privileged: false + procMount: ɓĎʙʗG0瑑娄K坢Ö&Ù + readOnlyRootFilesystem: true + runAsGroup: 2234167178876811137 + runAsNonRoot: true + runAsUser: -1191472066985646967 + startupProbe: + exec: + command: + - KGi9U + - D6 + - HZ3aC1 + failureThreshold: -2057203764 + grpc: + port: -1203229903 + service: Xd + httpGet: + host: tTW + path: oWk + port: -1347841801 + scheme: 檸`sȝBULj懄 + initialDelaySeconds: 1386184157 + periodSeconds: 2110004457 + successThreshold: -692279219 + terminationGracePeriodSeconds: -7060466210747559086 + timeoutSeconds: -905577521 + terminationMessagePath: g + terminationMessagePolicy: 頨Ĥ° òȯǤū暓坐ƚă杋鍄 + volumeMounts: + - mountPath: FmQht + mountPropagation: 饌^ǩ朳ųW磀ĥAijƨ+= + name: j5 + subPath: aoEWb7k + subPathExpr: 0ra + workingDir: zmwmt +- command: + - oFEaN2U1 + - HuBj9vk17eCjI + - "" + env: + - name: n3JVvVY + value: U14PEXs + valueFrom: + configMapKeyRef: + key: Ai0Xg3owIe7XlG + name: U4 + optional: false + fieldRef: + apiVersion: ZyO4Jpwkp2hV + fieldPath: roNil + resourceFieldRef: + containerName: gx + divisor: "0" + resource: Z + secretKeyRef: + key: AcP + name: qMy + optional: false + - name: oSWakHA + value: eR + valueFrom: + configMapKeyRef: + key: qsSVOr + name: o + optional: false + fieldRef: + apiVersion: SeP3aPXfjLIcfE + fieldPath: 091i + resourceFieldRef: + containerName: T5hI + divisor: "0" + resource: KxGi43CVGe + secretKeyRef: + key: "" + name: 5uI + optional: true + envFrom: + - configMapRef: + name: MujT + optional: false + prefix: cVRH + secretRef: + name: mpF + optional: true + - configMapRef: + name: MeO3F + optional: false + prefix: w3C4 + secretRef: + name: hnYx + optional: false + - configMapRef: + name: NT5MFmC65 + optional: true + prefix: "7" + secretRef: + name: yl2ze1 + optional: false + image: A8o + imagePullPolicy: ?晐T鴭Xp + lifecycle: + postStart: + exec: + command: + - zaLOG2 + httpGet: + host: kA51kbv + path: LMnFclIJczBo + port: 402299955 + scheme: :踖坯(Iȷ碨劅 + sleep: + seconds: 245674034851902981 + preStop: + exec: + command: + - Tz87qO + httpGet: + host: Xr6sP + path: xxE + port: 1901089000 + scheme: 3媧ş>La芸`Lzuŀɽ坤¦.痻Jǻ + sleep: + seconds: 6906639179439192094 + livenessProbe: + exec: + command: + - yxk0313sz + failureThreshold: 385001414 + grpc: + port: 1589713469 + service: UA + httpGet: + host: ZWfT + path: vTNYug5RZh + port: -192111662 + scheme: e¢dYÜdz + initialDelaySeconds: 1708942834 + periodSeconds: 1356452566 + successThreshold: 1750780088 + terminationGracePeriodSeconds: -1272770054640188829 + timeoutSeconds: 1656218869 + name: FxzTg + ports: + - containerPort: 63673829 + hostIP: 4xjED0VKV0G + hostPort: 2007665826 + name: xbwJ + protocol: ¼vb皪螯ʉwʒR玔È覦劙 + readinessProbe: + exec: + command: + - 0S + - "" + - GkPj + failureThreshold: 1405674719 + grpc: + port: -1659132742 + service: gIFP + httpGet: + host: jYnI3ins7 + path: bIEaFAc1 + port: UHfz + scheme: ʼn + initialDelaySeconds: 1531278754 + periodSeconds: -238235402 + successThreshold: -1690388514 + terminationGracePeriodSeconds: -2788228502880198888 + timeoutSeconds: -567709755 + resizePolicy: + - resourceName: nxpzTS + restartPolicy: ƫŀMs+,ǼƞȒ + - resourceName: 61uCVQ1 + restartPolicy: /澰ɍ½鑀a帷[鞺鏨攬姟壃F$R犬 + resources: + requests: + YfM: "0" + restartPolicy: œ|F彟S崘Ȑ貸1Ũȷ+齳 + securityContext: + allowPrivilegeEscalation: true + capabilities: + drop: + - 鸎dĉç荧 + privileged: true + procMount: "" + readOnlyRootFilesystem: false + runAsGroup: 5795239965908151493 + runAsNonRoot: true + runAsUser: 2409160731771391054 + startupProbe: + exec: + command: + - D6j2Q + failureThreshold: 975103738 + grpc: + port: -2081980063 + service: Nh + httpGet: + host: vdLm3FUXIs + path: jqCqF + port: "" + scheme: Ű"ƆĩNÙ襔冠ʈ + initialDelaySeconds: 524220215 + periodSeconds: 923596095 + successThreshold: 547119693 + terminationGracePeriodSeconds: 7382309226647739877 + timeoutSeconds: -1902082444 + terminationMessagePath: 2i5 + terminationMessagePolicy: 踑ĆĦ荷ýA/ǎ桫 + tty: true + volumeDevices: + - devicePath: KlUUX + name: NWO + - devicePath: W1JLM + name: qNw + - devicePath: BVE + name: c + volumeMounts: + - mountPath: yCztpht + mountPropagation: 巧苄;钽肇謌ʭɿw刄wɰM迵. + name: Mv9 + subPath: RWmlw + subPathExpr: Oy + - mountPath: Gf + mountPropagation: ɩ + name: On78O + readOnly: true + subPath: s7p + subPathExpr: 57aJIvpEm + - mountPath: m + mountPropagation: 崌蠿Ƣ湺 + name: CXSu + subPath: F8oe + subPathExpr: S +extraEnv: +- name: cD + value: JW + valueFrom: + configMapKeyRef: + key: "" + name: 8Ri7OfQ + optional: false + fieldRef: + apiVersion: Qc + fieldPath: 6ZYFg + resourceFieldRef: + containerName: qkUV + divisor: "0" + resource: yEf5zz13U + secretKeyRef: + key: xozuxs + name: z + optional: true +- name: "" + value: gea3 + valueFrom: + configMapKeyRef: + key: hwe3l3k2h + name: QX + optional: true + fieldRef: + apiVersion: kx + fieldPath: m7f + resourceFieldRef: + containerName: 0XEGE + divisor: "0" + resource: y4ce5 + secretKeyRef: + key: hmvX + name: 18Z + optional: true +extraEnvFrom: +- configMapRef: + name: DR3hdrvZIv + optional: true + prefix: kGV4HZ8 + secretRef: + name: tR3Yu1G + optional: true +- configMapRef: + name: 6pMd0VA0 + optional: true + prefix: Csp + secretRef: + name: ceqZBJ7fdqP + optional: true +extraVolumes: +- name: iPeR +- name: ZgdCb2kUB +fullnameOverride: KchYZFsbB3 +image: + pullPolicy: -0Ź桛ɼ訚Ņ;秵ňĝ苒9麡ñà臸ʫ + registry: cwfXN2KlU + repository: qYQHJ + tag: RIG +imagePullSecrets: +- name: V1 +- name: AyLzRkaGE +- name: 3pZ8 +ingress: + annotations: + 7KBv: R6qBYfCa + aBRf1: ygsbc + yL0ht8k8h: e + className: N8nne2Adwe5AYa + enabled: false + hosts: + - host: FyKy + paths: + - path: Cgcwa4F + pathType: pcConNItFmo +initContainers: + extraInitContainers: uND1 +livenessProbe: + exec: + command: + - 6VSzmxYwHC + failureThreshold: -1894321442 + grpc: + port: 487517384 + service: INsH + httpGet: + host: JNW + path: QZgsr + port: 228553774 + scheme: 躀廗裲繄鄸爖ž + initialDelaySeconds: 1986051838 + periodSeconds: 541607099 + successThreshold: -1968479306 + terminationGracePeriodSeconds: -7878496327638757142 + timeoutSeconds: 1374945691 +nameOverride: 6sW +nodeSelector: + y63G: wNiNvOMv +podSecurityContext: + fsGroup: 2302511509023017096 + fsGroupChangePolicy: 闦ñ禢`J鉤 + runAsGroup: -2347956389924856743 + runAsNonRoot: true + runAsUser: 1720952380350228641 + supplementalGroups: + - -621944387099711210 + sysctls: + - name: CvGz + value: "" + - name: dO + value: qwZyE +priorityClassName: 3A +readinessProbe: + exec: + command: + - "" + - KEndqzRiV + failureThreshold: 467513555 + grpc: + port: -1573796455 + service: ErWB + httpGet: + host: lLC + path: HH5gzp + port: -1970119534 + scheme: 酥梕ʄE訳 + initialDelaySeconds: -6410364 + periodSeconds: -623380707 + successThreshold: 1641270972 + terminationGracePeriodSeconds: -4383611239728405989 + timeoutSeconds: 1203716236 +replicaCount: 291 +resources: + limits: + "1": "0" + MrwIP: "0" + hgaW: "0" + requests: + 1lF: "0" +secret: + create: false + enterprise: + licenseSecretRef: + key: yoQYDK + name: xU86MHgk + kafka: + awsMskIamSecretKey: b1dpxuu + protobufGitBasicAuthPassword: bNLttpx0UHrQ + saslPassword: WLiPGk4IafDZkx8 + schemaRegistryPassword: d7In271W + schemaRegistryTlsCa: JYJZN + schemaRegistryTlsCert: muZOO19 + schemaRegistryTlsKey: 7cUIM + tlsCa: NWid + tlsCert: v843II + tlsPassphrase: ks1QSKsS + login: + github: + clientSecret: Bh26we + personalAccessToken: yKlBsX + google: + clientSecret: luzCc89Wm0 + groupsServiceAccount: qpX + jwtSecret: ojb + oidc: + clientSecret: cze + okta: + clientSecret: uuUR + directoryApiToken: WOW1d + redpanda: + adminApi: + password: rVI + tlsCa: yMec + tlsCert: YYHCeTg + tlsKey: 4Qv3y5Dl +secretMounts: +- defaultMode: 83 + name: ieSo8V + path: d + secretName: mD0jl +securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - 阊 + - DIȜO吽解诎-曅 + drop: + - 贎秨Ůɭ懾Ù盾| + privileged: true + procMount: ʪ勪įOew\Ǡ礓 + readOnlyRootFilesystem: true + runAsGroup: -6230225082797374618 + runAsNonRoot: true + runAsUser: -2569068293811684873 +service: + nodePort: 314 + port: 424 + targetPort: 17 + type: oZi +serviceAccount: + automountServiceAccountToken: true + create: false + name: Cj +strategy: + rollingUpdate: {} + type: G阏发6s +tests: + enabled: true +topologySpreadConstraints: +- labelSelector: + matchExpressions: + - key: pPoL + operator: ǭȉćŴ讶Y + values: + - "69" + - UC9 + - "7" + - key: 6toZoG + operator: Ġ+kʫȸ颷ʅÓ欽V譵; + values: + - go8adRXrn + - key: S + operator: ĕȻ*Gɝ靿暛_洳瑼Ĩ + matchLabelKeys: + - "" + - V7xIs1 + - eqq + maxSkew: 983843814 + minDomains: 854272231 + nodeAffinityPolicy: '>S篐ö抏茄(6' + nodeTaintsPolicy: e3äTȦ硷B捕萑Ǵ吷Ǿ邂Ǝièø + topologyKey: NoEcMWkg + whenUnsatisfiable: 幗鞲&渶Ÿɪ`鹵N +-- case-041 -- +affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: gRchHJ + operator: g>騿b鈐ʃB¾偡医選ȍ恋 + values: + - I + - Ei + - "" + - key: hyf + operator: 斒ʃǜƆƲ + values: + - QUyyD + - key: Bkmx + operator: ư酰姺醪芄堑 + weight: 751548356 + - preference: + matchExpressions: + - key: oLam + operator: 蟹 + values: + - ouUaVpYnKDUI + - key: vjw6GPYYTKt + operator: 竣iN¸嚿×ɮib + values: + - ZTaqp + - key: d8VuBX6qV + operator: 脼Ȩ + values: + - a8aOe1 + matchFields: + - key: twbeCR + operator: óçøG靼Ɏȸ­乷ɍ + values: + - fJAm6rm + - 2h8IU + - zE9 + weight: 291395585 + - preference: + matchExpressions: + - key: qC6uf99en + operator: 鼢犖龆醑喐蠿鯌ʛB契p + initialDelaySeconds: -879591831 + periodSeconds: 1110714898 + successThreshold: -1301180826 + terminationGracePeriodSeconds: 3872467306429462875 + timeoutSeconds: 674947774 + terminationMessagePath: bm28lY3K2pwh + terminationMessagePolicy: Ȇƍ@¦Ț'±0ž + tty: true + volumeDevices: + - devicePath: o8dr + name: XmhFb + workingDir: 5wQN +- args: + - o0cO9clz7 + - HMSb + - 6uV0c + env: + - name: M3V9WePpx + value: ysO25 + valueFrom: + configMapKeyRef: + key: UqaJg4r + name: RfxtXP + optional: true + fieldRef: + apiVersion: lwe4YmNPx + fieldPath: tQj57vj + resourceFieldRef: + containerName: ZQ + divisor: "0" + resource: T + secretKeyRef: + key: x + name: ny4NEtt3z + optional: false + - name: cc2 + value: L0hw + valueFrom: + configMapKeyRef: + key: 385Ue36 + name: mmjoQw + optional: false + fieldRef: + apiVersion: 6oECJJ + fieldPath: viT + resourceFieldRef: + containerName: gwdJxK + divisor: "0" + resource: ck7 + secretKeyRef: + key: UuNsYAQvXJ0 + name: 1NAqDCU3 + optional: true + envFrom: + - configMapRef: + name: ZFk + optional: true + prefix: bXa4IzYR + secretRef: + name: aAJU + optional: false + image: JPgUP + imagePullPolicy: Q ¶ + lifecycle: + postStart: + exec: + command: + - r1uMNf + - M + - 8G + httpGet: + host: cuhhh + path: lXMriYoe + port: -988033465 + scheme: ',轄kzĒfť' + sleep: + seconds: -8820103652541681769 + preStop: + exec: + command: + - bElmX + httpGet: + host: bCNS + path: A0F + port: "" + scheme: 砘ɁA甜猷14ʣ)ǨƿŊ\ + sleep: + seconds: 821413986956195833 + livenessProbe: + exec: + command: + - M9y + - ay + - sRaY + failureThreshold: 600887441 + grpc: + port: 1597779369 + service: ua8K + httpGet: + host: 0XuF + path: V3 + port: -703127215 + scheme: 舷$趺É螳P阁]嚂驶钋琦袳$ƸO侎 + initialDelaySeconds: -1230549565 + periodSeconds: -335663932 + successThreshold: -1184112514 + terminationGracePeriodSeconds: 9077275487127832448 + timeoutSeconds: 1992088322 + name: pz + readinessProbe: + exec: + command: + - lVaA + - E9DNIWT7reP + - NW1Cc5O2 + failureThreshold: 1119300491 + grpc: + port: 2061347792 + service: fUXdOYJ9On + httpGet: + host: "0" + path: Us3pM3OkquAEW2 + port: -1693856749 + scheme: 鞡|鬟扝}肾~ + initialDelaySeconds: 1307857751 + periodSeconds: 1903760018 + successThreshold: 612917619 + terminationGracePeriodSeconds: -4296518247806248606 + timeoutSeconds: 1025631498 + resizePolicy: + - resourceName: "8" + restartPolicy: ȯy髚ʦ=ǰɮ瓿b:劀ǴáiO3IĮ + - resourceName: 8mFXK1FTs + restartPolicy: ėv|冿瀱Ƥ鐻D[ƼŮ/ + resources: + limits: + TVwPaoBqGL: "0" + juxQS6V3mr: "0" + requests: + igiG: "0" + restartPolicy: 皷ƴȿOvJ郦'欝 + securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - ǐ缠]館ʚƾó|őɤ + - 6 銨dN_ZɻǦ絛顆麓 + - u鹍u鼓练gʘɍK]痰痁鶄Ȼ咶嚅俊ǙǕ + drop: + - 沎闸埲dz + privileged: false + procMount: "" + readOnlyRootFilesystem: false + runAsGroup: -265773045457612130 + runAsNonRoot: true + runAsUser: -6489119899323828796 + startupProbe: + exec: + command: + - 95NULc + - cCLaGfz + failureThreshold: -414102461 + grpc: + port: 339886942 + service: 7hdbpU + httpGet: + host: bN6EBrngIW + path: Luv09 + port: plsGDEJ + scheme: ʔ垃桪抴痺MM温ǹ + initialDelaySeconds: 2135898388 + periodSeconds: 1107416140 + successThreshold: -648919802 + terminationGracePeriodSeconds: 4653203112295127978 + timeoutSeconds: 1294917615 + terminationMessagePath: C + terminationMessagePolicy: 擎:Ȓ + volumeDevices: + - devicePath: TGjb8dLs + name: QN5Dj50Kuoc + - devicePath: aRIfAur + name: wQ47Fq7W3WPNDG + - devicePath: 2Smu + name: 1Q3d5wRJf6 + volumeMounts: + - mountPath: 5Trbk9 + mountPropagation: 秮驇穁 + name: YvM + readOnly: true + subPath: pFKsUV + subPathExpr: mhIjzA + - mountPath: F3lqb + mountPropagation: 窆f + name: NJXDvoxv + subPath: zVGgP + subPathExpr: H + workingDir: IEObw8N +extraEnv: +- name: 4R567pw + value: mWumx + valueFrom: + configMapKeyRef: + key: zDKgXG8 + name: Murbi95HW + optional: false + fieldRef: + apiVersion: FE + fieldPath: WAoZL + resourceFieldRef: + containerName: KyYyulloT + divisor: "0" + resource: fqVTn + secretKeyRef: + key: "2" + name: MHnd7TscnRWwYy + optional: false +- name: fm + value: 8fbdsVIUd + valueFrom: + configMapKeyRef: + key: "" + name: 6dU18hENH + optional: false + fieldRef: + apiVersion: Z + fieldPath: yt6csyy + resourceFieldRef: + containerName: c1WXMV + divisor: "0" + resource: NJVUoKSuC7pJDm + secretKeyRef: + key: "" + name: JptOa + optional: false +- name: WjWJX + value: 9VpkkQa + valueFrom: + configMapKeyRef: + key: Rpe79 + name: os5FYjLzS + optional: true + fieldRef: + apiVersion: "0" + fieldPath: j + resourceFieldRef: + containerName: NYuP + divisor: "0" + resource: EWUuGe739oa + secretKeyRef: + key: CFh + name: 8zez51Q + optional: true +extraVolumeMounts: +- mountPath: cIK + mountPropagation: 爂 YLƝ«煘?沀#朚ń鮾+ğÔ + name: orwvhF0 + subPath: ivP1ha4I + subPathExpr: VPCFJYVRHf +- mountPath: s + mountPropagation: m椥扶ȟqÈ倕{峙刷} + name: O35 + subPath: AN + subPathExpr: vm7 +- mountPath: 7P72D19W + mountPropagation: 堂窜B,Ś贃腔Ʈ£顽ąfYR + name: 6Z + readOnly: true + subPath: d7MJ + subPathExpr: LF +extraVolumes: +- name: "4" +- name: Kry +fullnameOverride: eHZ +image: + pullPolicy: ź,Î斎殉媰Fƅ + registry: l0qIdHu + repository: 5OO0wF5p + tag: i +ingress: + annotations: + fDuBFTYK9Q: 5XXu + wYD: 6p + "y": "" + className: Zp11 + enabled: false + tls: + - hosts: + - "" + - I + secretName: yCke +initContainers: + extraInitContainers: GXh2uupW81kt +livenessProbe: + exec: {} + failureThreshold: 1618833311 + grpc: + port: -1505397275 + service: IUgXOa3 + httpGet: + host: 99a94 + path: YFX41J + port: -636645896 + scheme: ƣ[ɐ虪ǸI + initialDelaySeconds: -1510068452 + periodSeconds: -1728837159 + successThreshold: -1832841689 + terminationGracePeriodSeconds: -2499091687248362302 + timeoutSeconds: 254335269 +nameOverride: 84QIe +nodeSelector: + JDRn7n: tOGfx + lKq0V88a: uR3S + vXzm2Hny: tURxvlp +podAnnotations: + JkW1: feghYA7 + okSVM8H: 7Pau + yYrmYn: uT +podLabels: + b4I: j707zvg + eyn1: gqdp7 + sWR: MV07t +podSecurityContext: + fsGroup: 3426922926776119440 + fsGroupChangePolicy: 橣 + runAsGroup: 8316915980597683441 + runAsNonRoot: false + runAsUser: 6270039107728700969 + supplementalGroups: + - -2399342924686736516 + - 620655430084388100 +priorityClassName: 6ZbHC +readinessProbe: + exec: + command: + - u4wSt + failureThreshold: -992972964 + grpc: + port: -940292781 + service: zh5 + httpGet: + host: 1Tg + path: FfFHRfo + port: -94900838 + scheme: țcPÞ + initialDelaySeconds: 2051362912 + periodSeconds: -288287188 + successThreshold: -404266702 + terminationGracePeriodSeconds: -123318567100123885 + timeoutSeconds: 31934256 +replicaCount: 378 +resources: + limits: + 0Yl63: "0" + BUorG9: "0" + requests: + JNdWuFZf5nnT: "0" + aszsvHn: "0" + qC76cU: "0" +secret: + create: false + enterprise: + licenseSecretRef: + key: "5" + name: X2lLLdu + kafka: + awsMskIamSecretKey: RoyDigH4v7A0 + protobufGitBasicAuthPassword: 3m + saslPassword: 5E + schemaRegistryPassword: "2" + schemaRegistryTlsCa: DSr2uQnBZ2 + schemaRegistryTlsCert: mji + schemaRegistryTlsKey: EcukHN + tlsCa: HwarCHVf + tlsCert: tsx + tlsPassphrase: owRWr + login: + github: + clientSecret: 3QP + personalAccessToken: RFXhu + google: + clientSecret: KbrHoAQ + groupsServiceAccount: tSLR4 + jwtSecret: gQSZ8AC + oidc: + clientSecret: O + okta: + clientSecret: tv58V + directoryApiToken: C3j + redpanda: + adminApi: + password: OZVk + tlsCa: F4wK + tlsCert: nkKfJ + tlsKey: ewWdsq +secretMounts: +- defaultMode: 210 + name: gcTdF + path: ctE5Qa + secretName: MPU +- defaultMode: 186 + name: "4" + path: n8KpOJZ + secretName: s6 +- defaultMode: 412 + name: lBE0nAE + path: 3Ka7 + secretName: RG +securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - 憑 + - 贁 + - cÝ琦ŝʛD緪娥t諰ɤɼʠßʏ + drop: + - Hē粙 S綽ESFľĞóǂ + privileged: false + procMount: '>IÐ肣ɚòĺIGʖƟ穿ź' + readOnlyRootFilesystem: true + runAsGroup: -6867300864246942363 + runAsNonRoot: true + runAsUser: 972586500223089794 +service: + nodePort: 310 + port: 190 + targetPort: 396 + type: uTyclgj9tVV +serviceAccount: + annotations: + 1vh4t: 2P6FHr47JPz + JPV: tx0p + automountServiceAccountToken: true + create: false + name: gIkiPRSc53Eb4w +strategy: + rollingUpdate: {} + type: ĸ鍽3ɨ勍Ȱ¦T搟 +tests: + enabled: true +tolerations: +- effect: ć`湇Ȏ2篤螕巴蛬>@ø£鞌q + key: E7p + operator: 畁鼄瓈貔Ĕ釲ĸȚ貺|ǴĄl蔺İɽ糹 + tolerationSeconds: 3092681449541780742 + value: Zmrz8 +-- case-043 -- +affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: [] + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: x2q + operator: B肖HOʀ + values: + - "" + - Ys3JeXs5q + - key: kTV1 + operator: ɑɸ&楥ÃFŎł + values: + - UQJ1b + - PSnF + matchLabels: + x3: OyQXZWg + matchLabelKeys: + - c7l + - QL52 + mismatchLabelKeys: + - upadP + namespaceSelector: + matchExpressions: + - key: ve00EK + operator: 'ɗY莶ʥV蔈ƀ廜ȶƹŀLjÓ%õɽ ' + values: + - KsFwEq9un + matchLabels: + pZaTZ4dEyKe: Zr + y2udi: nOeICOHiSN + namespaces: + - eh3 + - Tk + topologyKey: sDRodPzb + weight: 950808176 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: "5" + operator: 豗ŵǕ + values: + - CXc + - lamtTG39Nn + - key: PAiD + operator: 靑 + values: + - Xc2 + - 0vCS1b + - MsAd + - key: V5SqAAs0jK + operator: tŇ + values: + - "" + matchLabels: + sN: eS9 + zyhZtMI: vk + mismatchLabelKeys: + - "9" + - 8kmgYkR + namespaceSelector: {} + namespaces: + - rttEi + - LsPL05A + - vt + topologyKey: RI9Fz + weight: 735869102 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: 3wYP8eoC3 + operator: Ĭ囁缯盦鍎Șe宧冸'Pțl諷鵣 + values: + - tjW4s6vTm + - dAFd + matchLabels: + MYd: Xsox8 + vdIPmBzGHW: u + vtRD: cJZSpnJ + mismatchLabelKeys: + - ysVrZBCS + namespaceSelector: + matchLabels: + LLN: an + zhG0GzF: ebgXWsq + namespaces: + - Tc7JW + - l5 + topologyKey: XvVTKe + weight: 284965413 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: snHS61E + operator: ŁjĈ偔Ĵgä缬ɏ魜竿Ȍ匊ȡf + - key: GF64H + operator: N?+痱+龟嗙糨(;籄µ_ȤP榡Ȁ + values: + - sBC5mout + - gLNrAHCql + matchLabelKeys: + - I6T + - cfQ + - bj1O + mismatchLabelKeys: + - DOsKcbZ + namespaceSelector: + matchExpressions: + - key: wabhpRnnMK + operator: 昶Ǝ傪Ȃß + values: + - 6A + matchLabels: + AWV: wH5n597Z5ZD + MO5x: gCiuzkb + namespaces: + - SE6wLN + topologyKey: i + - labelSelector: + matchExpressions: + - key: hyV52PjMCdDTPM3Xj + operator: t.卆痘惠Ú皙駼ɥ飑蝪 + values: + - df + - QinuCr3k + matchLabels: + "4": xjs7u + 26YT8Kwl: 6Fn7QaX + IyQVKh: FT + matchLabelKeys: + - 43p + - 7wOCOZltU + mismatchLabelKeys: + - 69P + - KGelm4KjR + namespaceSelector: + matchExpressions: + - key: lc1l + operator: 圼酭蟶ƿʕNȎ褷K0¢戜ŰĨ矤磓 + values: + - F5sJcyG + - gSLP4 + - key: VUC9 + operator: 伂Nxŧ}_Ť + values: + - fdEFxj + - key: TtWF1erkH + operator: 鿐ȖP薈廰ǿÅʋ + values: + - 8fCxCdw018mnN + namespaces: + - MI7v + - 4d + topologyKey: t6NgG + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: D + operator: 棎 + values: + - 20fifD + - FrMdPhx9xo + - key: UGNn3lb + operator: 佛Ǥ3 + - key: Z2RLUvJbK + operator: "" + values: + - FdkgDft + - TefWIg2 + - bpqycNdCB + matchLabels: + HS3J6YWoEqk: Z6wgyP + doC4E: kBDLOXELx + matchLabelKeys: + - AcWh + - wz1OjMAc + mismatchLabelKeys: + - TzAtxmFj + namespaceSelector: + matchExpressions: + - key: 0PcmdJ + operator: h + values: + - cUMRXCqpYKF + - key: CNiL1smGnM + operator: cSŦ胪ǟ婟魳!M + values: + - nn + - J + - DT + namespaces: + - 115aP7 + - NIr + topologyKey: pAC + - labelSelector: + matchExpressions: + - key: N5YJ + operator: '`ȺDŽ窿U澩Û' + values: + - c6b9k + - kBiQmy4m0 + matchLabels: + I7ZhU9r: mVYody9U + kY71: tu + r0veMW: zYM + matchLabelKeys: + - iswu + mismatchLabelKeys: + - CANmp649B + namespaceSelector: + matchExpressions: + - key: 9dVeM + operator: "" + values: + - j4ohdLhch + - l + - "" + - key: Dg0F + operator: wŴǂ&;计DzP.觰髬uþ + values: + - gaIEZk1 + - W + - ox3 + - key: eem + operator: F铃ø睤榺蠯ƺDZ2s瘨澌秠%晸 + values: + - gQvNAvyI + - oime + - 4Sq9 + matchLabels: + J9W: R8 + o3EOEfEW: doLp + namespaces: + - kkkj1owvoXiU0 + - yfKU6aK + - LAx8rxmN8 + topologyKey: Z +automountServiceAccountToken: true +autoscaling: + enabled: false + maxReplicas: 400 + minReplicas: 207 + targetCPUUtilizationPercentage: 127 + targetMemoryUtilizationPercentage: 234 +configmap: + create: false +console: + roles: + - Ei: null + v4ACJLz: null + - isAtO9ew4: null + yruh: null + - 51fb5in: null + ILAz4wr: null + l90: null +deployment: + create: false +enterprise: + licenseSecretRef: + key: lN0R + name: Is29uweE +extraContainers: +- args: + - lXv3W4h + command: + - 0hlaE + env: + - name: 2R4HDOw + value: Ow63m2 + valueFrom: + configMapKeyRef: + key: W + name: K4xi + optional: true + fieldRef: + apiVersion: Jky + fieldPath: 53aQO + resourceFieldRef: + containerName: FnyzXcJW0Y + divisor: "0" + resource: CEeuoM3B + secretKeyRef: + key: d1k + name: gqHwwuuW7YCi + optional: false + - name: ixNGgU + value: zzCXF + valueFrom: + configMapKeyRef: + key: pAT30it + name: t + optional: false + fieldRef: + apiVersion: yp + fieldPath: Mh1WcPCbP + resourceFieldRef: + containerName: IswD1IBE9 + divisor: "0" + resource: Ro + secretKeyRef: + key: yFZxBVZdODt + name: X + optional: true + - name: WTnCxkS + value: pEk + valueFrom: + configMapKeyRef: + key: 11H + name: QATfCX3IsDv + optional: true + fieldRef: + apiVersion: vN4 + fieldPath: qMFch + resourceFieldRef: + containerName: uO0O + divisor: "0" + resource: N0cJGosw + secretKeyRef: + key: fDMU + name: hps + optional: true + envFrom: + - configMapRef: + name: 0OJJ5YVIX03 + optional: true + prefix: qMb + secretRef: + name: Q + optional: true + - configMapRef: + name: xbFZU + optional: false + prefix: a1 + secretRef: + name: x + optional: false + - configMapRef: + name: k37 + optional: false + prefix: YoFy + secretRef: + name: ogUiKqk + optional: true + image: 0pe + imagePullPolicy: 娒菐皎X噴粗嘍»ƪ~ + lifecycle: + postStart: + exec: {} + httpGet: + host: lO6z + path: Ocry6h + port: ZXfKF + scheme: ə朕IH尹ğ殤鍻O艚Ʃj"羈 + sleep: + seconds: 5751106255636900299 + preStop: + exec: {} + httpGet: + host: 7QkaR + path: F + port: 1848101873 + scheme: 7Õ嚎c煣擢?ǙȬžREWƿY#¡DZ + sleep: + seconds: -6692990274650219794 + livenessProbe: + exec: + command: + - uNT + failureThreshold: -829813283 + grpc: + port: -567104846 + service: LDcJp + httpGet: + host: g20utb + path: SiqR + port: hDMLQykO + scheme: Ŧ螵n^ʑ柁ɼĥh韁傧厬džƑ + initialDelaySeconds: -564429238 + periodSeconds: -1564220228 + successThreshold: 358143040 + terminationGracePeriodSeconds: -3271131206023471117 + timeoutSeconds: 1743016683 + name: 0dQgH + ports: + - containerPort: 1592798281 + hostIP: Ob6i + hostPort: 1226080714 + name: owTN2e7 + - containerPort: -909719890 + hostIP: LU4ibkw2 + hostPort: -291412037 + protocol: ț榌餬<孋蔣熰瘞;癘, + - containerPort: -1320944614 + hostIP: FALEX24mB + hostPort: -2067901656 + name: 3x2T + protocol: 鑴桄ɵ珧Ū + readinessProbe: + exec: + command: + - oc + failureThreshold: -784903530 + grpc: + port: -2046315075 + service: OUsbY + httpGet: + host: s50gn + path: gPyB + port: -2077437763 + scheme: 撫ƄǥǞ + initialDelaySeconds: 1983356613 + periodSeconds: 1988783141 + successThreshold: 2066305810 + terminationGracePeriodSeconds: 2348593211159662414 + timeoutSeconds: -418402994 + resizePolicy: + - resourceName: yW + restartPolicy: 9從O9籿c绉ȠýH + - resourceName: 9WLZ + restartPolicy: 酎!8 + - resourceName: ISSu7K + restartPolicy: RǷ巫錬$e幅"Ȅ + resources: + requests: + ZAHXO: "0" + cT: "0" + ftA: "0" + restartPolicy: 箕赳箨J顏 + securityContext: + allowPrivilegeEscalation: false + capabilities: + add: + - 厍F>%甾灵讝 dɌ撑礙Oo_ʦ + - ǮI埁艏:řŴi/隰6Ň + privileged: false + procMount: 籟ɔ矎C趶椰ʓ + readOnlyRootFilesystem: true + runAsGroup: -1819068651107678420 + runAsNonRoot: true + runAsUser: -4446960001037568719 + startupProbe: + exec: {} + failureThreshold: 1529697760 + grpc: + port: 2086810289 + service: LFhs + httpGet: + host: y7 + path: 7Q5PcVes + port: i + scheme: 阀ÿ¼+砵S麦ƺ'nǥ恪qżZǹ + initialDelaySeconds: -2048008543 + periodSeconds: -1559576850 + successThreshold: -655600930 + terminationGracePeriodSeconds: -8913842277118830912 + timeoutSeconds: -857654009 + terminationMessagePath: 9TOoj + terminationMessagePolicy: ¦ƫʇȬ儤f^_U躭 + tty: true + workingDir: cGeaEyJc6A9 +extraEnv: +- name: 1qcxFe + value: CddCzg + valueFrom: + configMapKeyRef: + key: uetPc0pnjv + name: CvmkK + optional: true + fieldRef: + apiVersion: FHMfGqk + fieldPath: 2P + resourceFieldRef: + containerName: bD1 + divisor: "0" + resource: kcSi + secretKeyRef: + key: pUu0 + name: 31uIu28D + optional: false +extraEnvFrom: +- configMapRef: + name: sJl8l + optional: false + secretRef: + name: ULPPuBUveK + optional: false +- configMapRef: + name: r4KbQIM + optional: true + prefix: vFNhdrDV + secretRef: + name: b + optional: false +extraVolumeMounts: +- mountPath: BsnW + mountPropagation: 撾<¥燩Uáb魩2wdz携W駟c韀羸â閹 + name: kS + readOnly: true + subPath: MQkyaubVs + subPathExpr: Bc +extraVolumes: +- name: FK5aYrlt +- name: BuMd +fullnameOverride: y0pa6pm83 +image: + pullPolicy: ā + registry: frvkIce + repository: Eyf5QN + tag: NF +imagePullSecrets: +- name: kBoh0Lyd +ingress: + annotations: + GOF: Fk7wcu + J2: ViiBwn6 + WODaheluZ: jCoFdBnr + className: 4Z1r6JSTY + enabled: true + tls: + - hosts: + - hAi45 + - N3wGXf + - 2Og0 + secretName: 11BdzGx + - hosts: + - MPqkMom + - mBwetJrK + - PcEKgK + secretName: HtA + - secretName: jRYKg +initContainers: + extraInitContainers: "" +livenessProbe: + exec: + command: + - 5l + - TPa5xuR1 + - pL3 + failureThreshold: -665161597 + grpc: + port: -1993107785 + service: u6KPs + httpGet: + host: R4Get + path: 0V + port: 1160926320 + scheme: ǨĄBW躼uQ劢Z + initialDelaySeconds: -958442622 + periodSeconds: 1883059027 + successThreshold: 1933410843 + terminationGracePeriodSeconds: 6283661173054068495 + timeoutSeconds: -1835273944 +nameOverride: "" +podLabels: + ZUMXq: 1paitbyR + o5jSmwn: "1" +podSecurityContext: + fsGroup: -2194962218839547968 + fsGroupChangePolicy: Ƃ搵Ņů羁nʇ雵Ri摿TǛø!ʣa饪詹 + runAsGroup: -8349123147211058668 + runAsNonRoot: false + runAsUser: -7634316416044162316 + supplementalGroups: + - -8005115528631553908 + - 3338610853164048033 + sysctls: + - name: KolWq + value: HzqTwBK4G4 + - name: rWyCA7 + value: DXY + - name: ukO43edoA + value: EVLsuF +priorityClassName: vW +readinessProbe: + exec: + command: + - 0X8tCVJI + - Sm4 + failureThreshold: -1604827341 + grpc: + port: 42051403 + service: H + httpGet: + host: 0gB9WjO + path: 0sPD + port: -849836679 + initialDelaySeconds: -1237987229 + periodSeconds: -2089146286 + successThreshold: 1944965466 + terminationGracePeriodSeconds: 6313366685724995629 + timeoutSeconds: -421565232 +replicaCount: 180 +resources: + limits: + pWciOVB3: "0" + requests: + CokuM: "0" +secret: + create: false + enterprise: + licenseSecretRef: + key: KGprr + name: w + kafka: + awsMskIamSecretKey: "" + protobufGitBasicAuthPassword: SerI + saslPassword: GKTX + schemaRegistryPassword: 4e + schemaRegistryTlsCa: "" + schemaRegistryTlsCert: 5V + schemaRegistryTlsKey: WFfrAH2a + tlsCa: kdCuX + tlsCert: j8Y2S + tlsPassphrase: jzecZl + login: + github: + clientSecret: cRkCl + personalAccessToken: 7XzR7g4 + google: + clientSecret: 1h + groupsServiceAccount: PpzN + jwtSecret: "" + oidc: + clientSecret: r + okta: + clientSecret: om + directoryApiToken: vYqev5 + redpanda: + adminApi: + password: X0 + tlsCa: MadMnzee10AL + tlsCert: SXxHZ + tlsKey: HYAn +secretMounts: +- defaultMode: 257 + name: mbhBeHK + path: 4B + secretName: "3" +securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - ɓ秈Ǽ霏*苇ȋɇ燡ƲɔċɈx + - 畼#QȲȬ懹脆俼[葓箘Ⱥ¿ + - ƭ + drop: + - 鉉C餱芕鳧ǥƔʚŰ + - ǖ瞱祈)售歜ŃȀƖ厀Ʃ9茡ɥq + privileged: false + procMount: '''³編Ź~莽WS2孲j禺' + readOnlyRootFilesystem: false + runAsGroup: -7898786566866618408 + runAsNonRoot: false + runAsUser: 5048177807031045156 +service: + nodePort: 402 + port: 11 + targetPort: 465 + type: 9TsjJQkJZ +serviceAccount: + automountServiceAccountToken: true + create: true + name: Gma +strategy: + rollingUpdate: {} + type: I讗烉Ð-Ǵ +tests: + enabled: false +topologySpreadConstraints: +- labelSelector: + matchExpressions: + - key: 8oHl6iWalV + operator: 嗌ƕþ]eěk歄兠惴5]nj鿵ų|暫\ + matchLabelKeys: + - n2lT + - nr + maxSkew: 565546972 + minDomains: 1026506021 + nodeAffinityPolicy: _攊v + nodeTaintsPolicy: 踠~Ë?¶嘬 + topologyKey: OZKwm9I + whenUnsatisfiable: 艽ʧj +- labelSelector: + matchExpressions: + - key: e + operator: 貙wɡȗ扊l橠,ȶ^ + values: + - "2" + - 1aeU + - X1mzNz + matchLabels: + Kw: L0rDwe + hFD: 9Kbm7CtaSg + matchLabelKeys: + - lw1gZ + maxSkew: 131623139 + minDomains: 1034504401 + nodeAffinityPolicy: NƎ乮+却ŷƑIf.L焚 + nodeTaintsPolicy: "" + topologyKey: dpa7OA + whenUnsatisfiable: 貧uƻläʯlÓʐȮ竇dʐ疮儾 +-- case-044 -- +affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: AFOKvXU + operator: ¸藬 + values: + - vIFxLM + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + ZpWVx: agTJ2kP3DWNYN + matchLabelKeys: + - "4" + mismatchLabelKeys: + - 0qG + namespaceSelector: + matchExpressions: + - key: D8 + operator: d|ɬ曖 + values: + - p3iQYi6Y + - key: c + operator: ǵmV逛鲳鈐譮稹ÚȾČXú + values: + - a + - 3C55L6S7 + - SQaxr + matchLabels: + "5": jC + namespaces: + - oDKjy + - "" + topologyKey: C9jgFk + weight: 1276231314 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: lGp2 + operator: "" + matchLabels: + "": sKP1q2 + 44krG: UrYUSMsisV + unYZqLh67: tMKQ + matchLabelKeys: + - orDt3ZdEA + - LIBJK3 + mismatchLabelKeys: + - bgz2i + - CNqlQJ + namespaceSelector: + matchExpressions: + - key: 35CZTXLY + operator: 掟0笝润ɲDGĪ1Ɋ乧鴹ǥ + values: + - OOB1s + - o4H + - key: f21 + operator: nȿqh + namespaces: + - L0w7 + - DB9 + - T1mom4CrS + topologyKey: OWKJz + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: WaOHp + operator: Ƥ熅ǒe²敹Ņ0ľ(Ȯɩ6ÿ + - key: 0X + operator: be3蚛鷿_鴈y+圚ʀF虹D + values: + - ZIZDTnyfwD + - B4NWO9ffPz + - 1jsu + matchLabelKeys: + - mXhYg + mismatchLabelKeys: + - mp6 + namespaceSelector: + matchExpressions: + - key: xE + operator: ʩ畕 + values: + - uc7IZ + - Hxl1 + - key: Xb41Q + operator: cʓʁ卡嵷韻 + values: + - pA + namespaces: + - edcrY + topologyKey: sP2BdI + - labelSelector: + matchExpressions: + - key: U0 + operator: 卢ʩ + values: + - OBtefl + - yMIZlx + - key: X + operator: Ǔ%é鵔:ß侙鞅 + values: + - s1qg3meB + - e6J6ZH89 + - key: dhFO + operator: ƋŎ頖,é襺枣Ť卩骏ɰ抟篧JɂǛȝȵ + values: + - R9sJoCz + matchLabels: + 2T: 84ZhksfB + matchLabelKeys: + - Yc41 + mismatchLabelKeys: + - zgncb + - pCwXYOK + - hViR + namespaceSelector: + matchExpressions: + - key: 3hWtuB6Y + operator: ʪ+ʜǻ拎奜跁ª4鶒鲒[ʒJi\ʝ)皡 + values: + - s + - key: xGSn + operator: 羥/Br=Z擧Ŀ泀Ą舨cïŕɘʡȽIJ鉽 + values: + - lOZtQ2cI + - Vk6 + - Ri3t + - key: Z6UDhR9VLqSA + operator: 淸c欨pɝo腛ı廓齩鄬檏繑郭>Ö呡 + values: + - s6hp + topologyKey: wZZTf + - labelSelector: {} + matchLabelKeys: + - afDo + mismatchLabelKeys: + - S + namespaceSelector: + matchExpressions: + - key: AWObA + operator: ĝf表OS厅啬児0~L槩华L稙訐\Tȼ + values: + - M39 + matchLabels: + 0D9: u5 + T1: xiLiZn + v6: nSQp5 + topologyKey: mr +annotations: + 4i: zwiMMKf + ZTKUDg2t: qHc7 + fGsx: dIpd +automountServiceAccountToken: false +autoscaling: + enabled: false + maxReplicas: 220 + minReplicas: 54 + targetCPUUtilizationPercentage: 269 + targetMemoryUtilizationPercentage: 205 +commonLabels: + BvJq2xZ: jY6O0 +configmap: + create: true +console: + roleBindings: + - UiHg9: null + - "": null + mAYLjAybA: null + roles: + - 0NpG04j: null + UxtPt: null + l5dMdK: null + - J9: null + MzWfEl: null + yNu: null + - "": null + Pv: null + tGJIDyXG: null +deployment: + create: true +enterprise: + licenseSecretRef: + key: x8ik3q + name: K7c7oe +extraContainers: +- args: + - CCdc + - xnWsPf + - K9Lp8whZH + envFrom: + - configMapRef: + name: eRd + optional: true + prefix: jF9v + secretRef: + name: QS0dQM4 + optional: false + image: UEbFmY + imagePullPolicy: ɂǖ耒ȯ+Ǎ妸ÄĊ wʠB堯¥ƿɤp + lifecycle: + postStart: + exec: + command: + - 89MtW + - LOaqkcP + - JzjyxNZS + httpGet: + host: "3" + path: V + port: RUOELw + scheme: u*暪÷鰦ʭ,0噱D #干 + sleep: + seconds: 7312334685976474890 + preStop: + exec: + command: + - Cmo91luAq + - DTCwI + - d3Q8xly + httpGet: + host: e + port: -1761554680 + scheme: '|' + sleep: + seconds: -8572473558022233717 + livenessProbe: + exec: + command: + - 1K0Fir + - Ws + - jWym + failureThreshold: 1492079208 + grpc: + port: -1612320137 + service: wk3AYU + httpGet: + host: U + path: yLWf + port: dE + scheme: (魠ʫ倳|岺溻IJħu|æ粅 + initialDelaySeconds: -1551121242 + periodSeconds: 101556636 + successThreshold: -690762638 + terminationGracePeriodSeconds: -7606489989577612357 + timeoutSeconds: -947750725 + name: GKPhj2 + ports: + - containerPort: 690563670 + hostIP: mVXvug29A + hostPort: -1389446008 + name: pcUz3a8NWF + protocol: o& + readinessProbe: + exec: {} + failureThreshold: 816403475 + grpc: + port: 2090385753 + service: pp5W00 + httpGet: + host: sP9DV + path: cpLL + port: TNUIzm + scheme: '!敓GĜƝ塀ȏ@{8嶤ɍ|' + initialDelaySeconds: 911169006 + periodSeconds: 257542772 + successThreshold: 1702435185 + terminationGracePeriodSeconds: -4557510245814657403 + timeoutSeconds: -581799810 + resources: + limits: + 5UdZ91O: "0" + TXdC: "0" + bK0pEj0Mb: "0" + requests: + s8hZFXOGF: "0" + tCP: "0" + restartPolicy: Ǩ轡´@ǂȟ + securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - 鿞;P粜鬌)Ǭ郑&鑉k!f] + - Ċ + drop: + - ?孡渄:Ơ廔晞!ē8瞅@rDZ_ + - cfdú¯'ƱơÅś祏侪 + privileged: true + procMount: ȝ?A@û2蝓撕%o摤絡) + readOnlyRootFilesystem: true + runAsGroup: -2314751572399378702 + runAsNonRoot: true + runAsUser: 989961539055775316 + startupProbe: + exec: {} + failureThreshold: 971752114 + grpc: + port: -1594677871 + service: O + httpGet: + host: EIXRs + path: EA1CukJtUZ + port: g9g0 + scheme: 遱O靑課淁hɕ怡ņ鲥 + initialDelaySeconds: -1020857297 + periodSeconds: 1332161137 + successThreshold: -1412285197 + terminationGracePeriodSeconds: -7087737322486666596 + timeoutSeconds: 563432789 + stdin: true + terminationMessagePath: S + terminationMessagePolicy: =ɑ_èʊâ錯Ɛ窾O亇_ + tty: true + volumeDevices: + - devicePath: 2EtZS + name: "" + - devicePath: glBRF4 + name: e8K + volumeMounts: + - mountPath: L4U + mountPropagation: '}6ʓ蓱9峖3疖售Ʉ朞' + name: 4oVeDs + subPath: RoA + subPathExpr: b + - mountPath: b3TFcP + mountPropagation: ʘʟ| + name: jg4Ya + subPath: F + subPathExpr: flS + workingDir: VZi6ElPHw +- command: + - 3xxCjTRw + env: + - name: 1n + value: cHl + valueFrom: + configMapKeyRef: + key: "95" + name: gi + optional: true + fieldRef: + apiVersion: sQA8hZeZu + fieldPath: xgpJlFJ2 + resourceFieldRef: + containerName: fLR0HyM + divisor: "0" + resource: Sanx4 + secretKeyRef: + key: XgKm5 + name: gvoS9jB + optional: false + - name: s2cwze + value: hu + valueFrom: + configMapKeyRef: + key: fDoUz3 + name: XKG + optional: true + fieldRef: + apiVersion: q0CUy1W + fieldPath: B3Lkh + resourceFieldRef: + containerName: V1gnkr8hpTmU + divisor: "0" + resource: 7PEJNYX + secretKeyRef: + key: IiBIw + name: kiXa5 + optional: false + envFrom: + - configMapRef: + name: JayMLn + optional: true + prefix: Iyk + secretRef: + name: I8 + optional: true + image: uuJKCAGoiYb + imagePullPolicy: '&mɈ{DC鹪ŘƖ暢C镯VĪɮJ樟' + lifecycle: + postStart: + exec: {} + httpGet: + host: TlUl + path: v9nd + port: Khf + scheme: 雦G'獲ɕ垑Ɠ奚 + sleep: + seconds: 3204757101293724426 + preStop: + exec: + command: + - s8505Cg5U + httpGet: + host: hAMBGK + port: LNxGid + scheme: 9?Ɉ + sleep: + seconds: -7512312074000843110 + livenessProbe: + exec: {} + failureThreshold: -1252597876 + grpc: + port: -544919593 + service: "N" + httpGet: + host: xfP + path: ByIZxFF1w + port: 465839308 + scheme: ôȔʄǽȕ$Ɨ嫸% + initialDelaySeconds: 1827740835 + periodSeconds: 1434348082 + successThreshold: 1145653124 + terminationGracePeriodSeconds: -9056662989967493169 + timeoutSeconds: -741454610 + name: pkN5 + readinessProbe: + exec: + command: + - pmJ6cF + failureThreshold: -182850181 + grpc: + port: -30654612 + service: q + httpGet: + host: Vra + path: tovB7 + port: -934938952 + scheme: Ⱥǵ1茆鯨ț]ų1ơñ澂 + initialDelaySeconds: -1966697414 + periodSeconds: -1866944455 + successThreshold: -259752087 + terminationGracePeriodSeconds: -4535014313385885341 + timeoutSeconds: -1545912021 + resizePolicy: + - resourceName: RxDBqX + restartPolicy: 韌ʮ濅& + - resourceName: spCee + restartPolicy: 腋+桯PɆ誎z4µ&ȁou-囈鵼夵v| + resources: + limits: + rElH: "0" + requests: + "": "0" + restartPolicy: 7GK¦碦ǒ抩Z芍緜 + securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - NjǗA窇ţ + - 逈%Ǵ7QǚƶƜr + drop: + - 鹭Iv0蠤'Ɵ皝ƨ=¨ + privileged: false + procMount: èįƤ;L虥u籖ʄƎ}橃V炖 + readOnlyRootFilesystem: false + runAsGroup: -1041723617216276814 + runAsNonRoot: false + runAsUser: -3933065726531016441 + startupProbe: + exec: {} + failureThreshold: -983644738 + grpc: + port: 1827183629 + service: X7oC1 + httpGet: + host: vGk + path: ohKaYc + port: l1rVsh9 + initialDelaySeconds: -648569392 + periodSeconds: 873065120 + successThreshold: -612441773 + terminationGracePeriodSeconds: 6808330544454597158 + timeoutSeconds: 1534439066 + terminationMessagePath: VYh + terminationMessagePolicy: 唌Üi+ + volumeDevices: + - devicePath: DGsn + name: Ia + volumeMounts: + - mountPath: "14" + mountPropagation: 渉seǝ蕟厪ë嵎ǥ墮@ + name: "" + readOnly: true + subPath: C1G4VS1 + subPathExpr: eU + workingDir: odPxO +extraEnv: +- name: Ahlf + value: UEv + valueFrom: + configMapKeyRef: + key: uwaRvb + name: M8Iklu7qx + optional: true + fieldRef: + apiVersion: H + fieldPath: 43xb + resourceFieldRef: + containerName: t8wgC87mO + divisor: "0" + resource: Z + secretKeyRef: + key: "" + name: EQfJ3z7tv + optional: false +- name: xj + value: lwmxmxP + valueFrom: + configMapKeyRef: + key: "" + name: cdBhO + optional: true + fieldRef: + apiVersion: U + fieldPath: Dj1sswKP + resourceFieldRef: + containerName: 1p3yUdrvd + divisor: "0" + resource: 5A + secretKeyRef: + key: DDcgdcu + name: oD38 + optional: true +extraEnvFrom: +- configMapRef: + name: 2ECaB + optional: true + prefix: bao + secretRef: + name: CA5S95 + optional: false +extraVolumeMounts: +- mountPath: v + mountPropagation: ?IJ純ʈxɧʅ + name: 9AiRaE35OlCv + readOnly: true + subPath: 2dv5RZ + subPathExpr: H7f +- mountPath: "4" + mountPropagation: 涾頴tOĜʥ朤 + name: ePEz + readOnly: true + subPath: BY + subPathExpr: w +- mountPath: n5FPgiJmk + mountPropagation: Ǵ棢__@ŗɆ4瞑5ŗ­L/ķ{篦ǯ + name: NryERK9Q + readOnly: true + subPath: tINFMAR5 + subPathExpr: VrBKy +extraVolumes: +- name: Kt6NIoVzEY +- name: O +fullnameOverride: resP +image: + pullPolicy: 讘ɂȴɩF壜î栒p + registry: UqWwteW0x + repository: TZqk + tag: 0fpMB +ingress: + annotations: + 7CEw: nk8 + bqg: H5 + x1S7: Pu + className: 6IuECM + enabled: false + hosts: + - host: gDc + paths: + - path: len9tdPYcpq + pathType: XETm5mmK3Es + - path: zn5u + pathType: p5jlQul + - host: "" + tls: + - hosts: + - Th5w + - xssK + - xFW9 + secretName: wA + - hosts: + - bR + - U73RtLKOI + secretName: jEnKU +initContainers: + extraInitContainers: 0VCU +livenessProbe: + exec: + command: + - wV + - eooUnSLpW + failureThreshold: 1147871047 + grpc: + port: 483952618 + service: Ca + httpGet: + host: pXrlUHltqchNl + path: kMP5 + port: -1823407150 + scheme: Ò壻«Ƭ魠?ǣ×Ç + initialDelaySeconds: -470682176 + periodSeconds: 842863336 + successThreshold: 2078067842 + terminationGracePeriodSeconds: 8174922400865091455 + timeoutSeconds: 1252398573 +nameOverride: tvDI +nodeSelector: + 2i: dRi6btw6 + R4: UsW + fFNJXGk: XBkx +podAnnotations: + N0F: vSjZxkjW +podLabels: + K1uahi: UMygEU2O2 + ecdKkB: "1" +podSecurityContext: + fsGroup: -3027126285888130862 + fsGroupChangePolicy: 袺芥ŵ罋o郘渢e堫柝dž + runAsGroup: -3172565869747057973 + runAsNonRoot: true + runAsUser: 5739747577453985710 + supplementalGroups: + - -1289730562709624524 + - 2918948066534341347 + - 8836988143915675306 + sysctls: + - name: ZSspAgrV + value: ES11 +priorityClassName: 8KMLup9vb +readinessProbe: + exec: + command: + - 50jwjhoUN3n + failureThreshold: 1026367217 + grpc: + port: -238173978 + service: Ju + httpGet: + host: wDDq9i + path: w7hRVdP6kmTaLN + port: -919313657 + scheme: 闡ś + initialDelaySeconds: -233395254 + periodSeconds: -96619339 + successThreshold: -2083481091 + terminationGracePeriodSeconds: -7352799244112409845 + timeoutSeconds: 1827269276 +replicaCount: 410 +resources: + limits: + eYVLCq: "0" + requests: + P: "0" + VsuQcjg: "0" + jwq: "0" +secret: + create: false + enterprise: + licenseSecretRef: + key: zvbci + name: W0 + kafka: + awsMskIamSecretKey: SFtL8nb + protobufGitBasicAuthPassword: "" + saslPassword: "" + schemaRegistryPassword: p + schemaRegistryTlsCa: 0m5L + schemaRegistryTlsCert: fqb + schemaRegistryTlsKey: whFm7 + tlsCa: 2Ir + tlsCert: JBVRtfzSurH + tlsPassphrase: OSDd + login: + github: + clientSecret: mCF8qeqhA + personalAccessToken: 7MnYqfh + google: + clientSecret: uo83GiVX2X + groupsServiceAccount: LCEQJi + jwtSecret: cmCx + oidc: + clientSecret: jW3Syrm + okta: + clientSecret: RDyL5FTb + directoryApiToken: BmJgmq2h + redpanda: + adminApi: + password: 6pe + tlsCa: gzJP1h + tlsCert: GRhBENFNa + tlsKey: qKQ +securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - ɐ毻sǨ斩麀|髦 + - (波F= + - 2鱶ɥǚ蘃齯ʃE桹蹝Ȓ畸蘋桙0 + drop: + - c掁轖e9\Ǟ¦ + - ȽT下Zź%賂蕄3 + - 乯`ŤĊŸ眸ʞ缔Ň妌嵳楕ǐwč*ǩ妩ɴ + privileged: true + procMount: ŃE诩Ŗś僆 + readOnlyRootFilesystem: true + runAsGroup: 6580465723841053659 + runAsNonRoot: true + runAsUser: -56006153890553620 +service: + annotations: + CRHNsVY: Nl04 + nodePort: 437 + port: 103 + targetPort: 329 + type: "" +serviceAccount: + automountServiceAccountToken: true + create: true + name: W9k +strategy: + rollingUpdate: {} + type: ɬdW5f +tests: + enabled: true +topologySpreadConstraints: +- labelSelector: + matchLabels: + 435gSB: cXqM + XuT: nA + sKWX6pPX: YyYe + maxSkew: -1347306472 + minDomains: 1890499147 + nodeAffinityPolicy: 扒Ŕ + nodeTaintsPolicy: 諹uɔM_灢ʫ6ªWŢ庿ɛ + topologyKey: 34nlpPe2Tl + whenUnsatisfiable: šĉ鎨嶕鯖Ťȯ蝲萤ɪeCŒ5ő3|押 +-- case-045 -- +affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchFields: + - key: MyOwAD1 + operator: 啜0Ȕ + values: + - ZGn4YX + - key: jDkjMmXqE + operator: NŤ~鷚ȃÐ醩@鿘.礡PdL + values: + - N3K + - ow + - PzPEWA + weight: -72104605 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: JvUcVrA7 + operator: Žx"ơ + - key: xqi + operator: 1匹层舕ƒ僜ʓ + values: + - e + - key: eLiG + operator: '[r-!"ĻŻ艂酁嵍鏺]髠' + values: + - EKgA + - 2tR + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + 7EKjs: lal36 + matchLabelKeys: + - DsNc + - EF + - MxSx7 + namespaceSelector: + matchExpressions: + - key: AJRciio + operator: I鎴 3ɡƞK慳hĉ + values: + - dh + - key: O8 + operator: ʤ喜牅ƫ]Ȉʚ廆Ƨ椬訐儹9ȡ趿 + values: + - QIR + - 4QIg3r + - key: xEKeM + operator: 嬕 + values: + - R0qm21j + topologyKey: yN7rFb + weight: 371178507 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: 6m + operator: "" + values: + - sEP + - r + - 916oARGpag + - key: YtLdy2vWFRG + operator: "" + values: + - NbAvpL8G + - 0a3vqv + - key: TOiWxWC + operator: ǝ椦誄ȟ2沾ʩɁǢɶ攧Ţ胑< + values: + - BDKh + - NFb9UYct3p + - TFdQLF + matchLabelKeys: + - TACd + - RFCD1IMt + mismatchLabelKeys: + - CLaySswMot + - S3sEweRaY + - tC6pZ + namespaceSelector: + matchExpressions: + - key: pDz + operator: "" + - key: iRP7TsiyE + operator: 8šiƛPċŞ貲I轒ĮÜ + matchLabels: + 4IVb55JZf: "" + XokO: FntMc + namespaces: + - BOohC67i + - tv + topologyKey: Wc36G + - labelSelector: + matchExpressions: + - key: 2swiyf9 + operator: X + values: + - "2" + - Mmu6iYl3 + - XsZhnelID + matchLabels: + zf: IJlhUxrQg + namespaceSelector: + matchExpressions: + - key: RMLd0ptomdzoSd + operator: ƋŲǯ-'Dð獿礘ĘQ蕲螙x + values: + - rz5QKfx + - key: smO + operator: DɴK*4瘢齮 + matchLabels: + "": crZm + R7TX: 7hcjy + Yh: dyM1 + namespaces: + - PqubN + - elFz + - 5Iah6Cz + topologyKey: QE + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: faWSc + operator: ʚʉŝwʊ寭跼Z + values: + - dgKap + matchLabelKeys: + - sEXCWO + mismatchLabelKeys: + - BqB + - QSJQOy + namespaceSelector: + matchExpressions: + - key: 9zT + operator: 锂遼9ɎVn嵕缰~ + - key: bJi68gZ + operator: 己樚僚%隓馦d + values: + - LT + - "" + matchLabels: + yt: Z + zMv4Ez: NSxkcn + namespaces: + - bfc + topologyKey: pUFg7ZP + weight: -962989660 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: {} + matchLabelKeys: + - "" + mismatchLabelKeys: + - Mfh + namespaceSelector: + matchExpressions: + - key: 6Ax1cf + operator: ʆ骜ʣ蘧F栮,C + values: + - 1WljmgAmSY + matchLabels: + 174k: 7or9Mr + F4YETWGCg: Rt46e + cMQyYT: RTaOOxz3Li + topologyKey: 9j +annotations: + 12kkcHLZdTIn: FQ4am + LQDfr: q +automountServiceAccountToken: false +autoscaling: + enabled: true + maxReplicas: 305 + minReplicas: 326 + targetCPUUtilizationPercentage: 344 + targetMemoryUtilizationPercentage: 186 +commonLabels: + M1diW: PVb +configmap: + create: false +console: + roles: + - tvT4mf0wFe: null +deployment: + create: false +enterprise: + licenseSecretRef: + key: kMfu2CiNvgC34 + name: oa9a +extraContainers: +- args: + - HP10TO + - kuCNcTLL + command: + - m + - Nww8 + - 98Rn + env: + - name: SSO + value: dOiVAD + valueFrom: + configMapKeyRef: + key: rG6s + name: ZIOGFg7 + optional: true + fieldRef: + apiVersion: 5QpSAgTC + fieldPath: wvXbuBkn + resourceFieldRef: + containerName: ZRxTJ6p + divisor: "0" + resource: lxXIfgo + secretKeyRef: + key: a4I + name: fdAC + optional: true + - name: t + value: lhJB5Gu + valueFrom: + configMapKeyRef: + key: 9sIY7ap56C + name: jxSPO + optional: true + fieldRef: + apiVersion: 7y + fieldPath: TVs + resourceFieldRef: + containerName: Bk7GMS + divisor: "0" + resource: KghhcLY + secretKeyRef: + key: "4" + name: Q0xn + optional: true + envFrom: + - configMapRef: + name: xkM + optional: false + prefix: 6Hmq + secretRef: + name: 2W7 + optional: false + - configMapRef: + name: nw + optional: true + prefix: ZF8q + secretRef: + name: Hazz + optional: true + - configMapRef: + name: C0TBIATG + optional: true + prefix: Wm + secretRef: + name: Yg2 + optional: true + image: vXSldD9 + imagePullPolicy: .Ś.l庥抁臚蚋巸_ȧʟ[R榶E + lifecycle: + postStart: + exec: + command: + - oN + - eEYgTnILd + httpGet: + host: mg7llOt105m + path: dtlR4G + port: wD90f + scheme: ʖ两ĕ¤¬瞮U? + sleep: + seconds: -2237517267526569736 + preStop: + exec: + command: + - GMjypvCI + httpGet: + host: T8pa05 + path: u9bCqIg + port: M9zgB + scheme: '*蛬ŻĈ' + sleep: + seconds: 475574192596548942 + livenessProbe: + exec: + command: + - dUJeULUg + failureThreshold: 1485223326 + grpc: + port: 701458966 + service: CQKKuIS4d + httpGet: + host: E2fjZ + path: XvuU + port: NoCTx + scheme: 蜼烀ȏǓɦMDn糆ƥHʼn/瓏ìȢŷ + initialDelaySeconds: -1475170089 + periodSeconds: 1989433587 + successThreshold: 1386111224 + terminationGracePeriodSeconds: 5430499533574282933 + timeoutSeconds: 1740226413 + name: wG4ZxvZMuJ + readinessProbe: + exec: + command: + - "6" + - obo + failureThreshold: 2126666969 + grpc: + port: 521888256 + service: z + httpGet: + host: Fpq + path: ghrc2 + port: -314576227 + scheme: 瓰vp烫ǁĴŰDȐ插研Ǽʜ + initialDelaySeconds: 1330937719 + periodSeconds: 78230226 + successThreshold: -351220698 + terminationGracePeriodSeconds: 6147801770047971409 + timeoutSeconds: 1906635539 + resizePolicy: + - resourceName: Waf + restartPolicy: ʑ艜ɾ蘩Ƈ`7ɫ坓弎Ȗƈ + resources: + limits: + WfxZ: "0" + gZ: "0" + oup1P0j: "0" + requests: + D0AyOZ87h: "0" + Wmp9uU8: "0" + mowWvEm: "0" + restartPolicy: ǔ輋篐棶耏īʡm0Ñ!ř$曤Qʢ瞪Ļ + securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - Ì酃`sŬ硪W#鿻Gƃu + - 先ĜtàX + privileged: false + procMount: Ĕʤj螹țȞVa + readOnlyRootFilesystem: true + runAsGroup: 5877071704122825347 + runAsNonRoot: true + runAsUser: 607897543692979281 + startupProbe: + exec: + command: + - 1R1GIynL2u + failureThreshold: 197417586 + grpc: + port: 581882770 + service: jrlDhPYYcBk + httpGet: + host: btMskta + path: iy + port: -1405181644 + scheme: ­劲襇板ƶ2豣Ă輒" + initialDelaySeconds: -317632223 + periodSeconds: 1128778719 + successThreshold: -878681442 + terminationGracePeriodSeconds: -5809012571377279815 + timeoutSeconds: 326998121 + stdin: true + terminationMessagePath: vlSz + tty: true + volumeDevices: + - devicePath: jpSm + name: A1S8F + volumeMounts: + - mountPath: zH + mountPropagation: Œib抪黠wƱ軭 + name: vY1XOHYYy + subPath: Tui26JLZyP + subPathExpr: 2T0bhLFBv + - mountPath: qLd4 + mountPropagation: = + name: MlJNiuK + subPath: Gt + subPathExpr: 1br + workingDir: qaJz +extraEnv: +- name: "" + value: 8qqxpUmb + valueFrom: + configMapKeyRef: + key: nyn + name: 2a6 + optional: true + fieldRef: + apiVersion: 4VL + fieldPath: mLkq5SaY + resourceFieldRef: + containerName: q58NCY4 + divisor: "0" + resource: iTwPTz + secretKeyRef: + key: fymwKG2di + name: jP + optional: false +extraEnvFrom: +- configMapRef: + name: kjk + optional: true + prefix: bXXh + secretRef: + name: ksMoUzjV + optional: true +- configMapRef: + name: 8AWI + optional: false + prefix: hqwWp6 + secretRef: + name: a + optional: false +extraVolumeMounts: +- mountPath: g + mountPropagation: ƎÀ虰|墫} + name: izh4Kt + subPath: l3Jx + subPathExpr: bgpu9UdSPr4CF +extraVolumes: +- name: UQKug +- name: giK +fullnameOverride: 9gCm5xz +image: + pullPolicy: "" + registry: I + repository: utUA + tag: 3NaFJMnq7cwb +imagePullSecrets: +- name: rTO7I +- {} +ingress: + className: y6u9o + enabled: true + hosts: + - host: V + paths: + - path: VRp3 + pathType: WX + - path: ZXqa + pathType: LXDjotJK + - path: b + pathType: 6l3svu + tls: + - hosts: + - SzMunki + secretName: OT +initContainers: + extraInitContainers: Gaa +livenessProbe: + exec: + command: + - w + - 4y0unO7q + - fUMv46yk + failureThreshold: 564680295 + grpc: + port: -274686900 + service: SZ + httpGet: + host: "97" + path: R + port: sw2f4 + scheme: ǖe灻膃爌|rQʮ` + initialDelaySeconds: -1623540175 + periodSeconds: 2083875877 + successThreshold: 1467697726 + terminationGracePeriodSeconds: 1240720412315600394 + timeoutSeconds: 514813622 +nameOverride: tOoxEiwdVpT +nodeSelector: + 4X: PJ6v +podAnnotations: + TImM2rpn: ixT +podLabels: + jAyDz: vW2 +podSecurityContext: + fsGroup: 8841428564051369991 + fsGroupChangePolicy: '''諢憭捽鉚ƾ邓鈽6M_s' + runAsGroup: 5877981406957979012 + runAsNonRoot: false + runAsUser: -2714811370596686768 + supplementalGroups: + - 3627757755693767927 + - 3933990106793080427 +priorityClassName: Op +readinessProbe: + exec: + command: + - Rvxle1 + failureThreshold: -1544911058 + grpc: + port: 1480625343 + service: iUWGjn1Yq + httpGet: + host: 0Wg8b + path: qrDi3 + port: -689203177 + scheme: 馨PƆȣdfTNʫ*ɀLɐ3} + initialDelaySeconds: -386708604 + periodSeconds: -1196967535 + successThreshold: -658970667 + terminationGracePeriodSeconds: -8534050677682835111 + timeoutSeconds: 1352482566 +replicaCount: 218 +resources: + requests: + Nh6YX: "0" + z: "0" +secret: + create: true + enterprise: + licenseSecretRef: + key: "9" + name: Pd + kafka: + awsMskIamSecretKey: "" + protobufGitBasicAuthPassword: naFpMBw + saslPassword: nKEzr + schemaRegistryPassword: xU + schemaRegistryTlsCa: pc + schemaRegistryTlsCert: fF1z9FE + schemaRegistryTlsKey: tx + tlsCa: bhhbwypQ + tlsCert: Dw1477 + tlsPassphrase: zRD + login: + github: + clientSecret: 1UD4N + personalAccessToken: LmFkP6BgmLQ + google: + clientSecret: m + groupsServiceAccount: "" + jwtSecret: 9ejQZ6 + oidc: + clientSecret: cXdjG + okta: + clientSecret: eF90RohF + directoryApiToken: 1zXLSJEQ + redpanda: + adminApi: + password: rr4c4 + tlsCa: Eonnpq + tlsCert: aPCNgYI + tlsKey: vlrLQ9I9 +secretMounts: +- defaultMode: 266 + name: omIzst + path: "" + secretName: Pn +- defaultMode: 133 + name: "1" + path: gIWg + secretName: gi4zM +- defaultMode: 451 + name: lrUYguc + path: D9pR + secretName: 3FH +securityContext: + allowPrivilegeEscalation: false + capabilities: + add: + - m优ķNJ噓+Pð + - 橯O燁 + drop: + - 褈墄ȃ杵 + - 娨Î + - rƴ}Ɇ橮ʕ*m敼ʎhǰ.ʔcZ + privileged: true + procMount: 攏O婑 + readOnlyRootFilesystem: true + runAsGroup: 8829730151763757512 + runAsNonRoot: false + runAsUser: 64441908715087607 +service: + nodePort: 325 + port: 314 + targetPort: 398 + type: C +serviceAccount: + annotations: + "": zL + EANkzh: rmy + automountServiceAccountToken: false + create: true + name: nX5G +strategy: + rollingUpdate: {} + type: ɬ(ìɅ +tests: + enabled: true +tolerations: +- effect: ɥ)藖朡YȖɌGǼRŗ迼@醹F6鎚 + key: 7Nq + operator: "4" + tolerationSeconds: 3766411560743927749 + value: TCksEtpTf +- effect: ȷ^?3HʉɚŢȾL + key: mj5pit + operator: 隱瀆J纝ɽÄ:憹欓 + tolerationSeconds: -3549323835306297633 + value: CN0gSHK7T +topologySpreadConstraints: +- labelSelector: + matchLabels: + N5pfvDQM4ZnP: "" + ZDk6ppZLAO: nn + f1Z: 2Molvtunvm + matchLabelKeys: + - cUf4VG + maxSkew: 2039905438 + minDomains: -1795353257 + nodeAffinityPolicy: 啚FLjʐəǪɠ梎Ň沮<^Zæ + nodeTaintsPolicy: Å扯R + topologyKey: qVloCmz + whenUnsatisfiable: ūh挕ŀ靕土伔澍鄓 +- labelSelector: + matchExpressions: + - key: sgB0Jx + operator: "y" + matchLabels: + Dhp: chzEB + matchLabelKeys: + - TBO + - g5M + - h + maxSkew: -825758940 + minDomains: 1383227075 + nodeAffinityPolicy: 婬ȴ羉Ā蕲k<ǯŘ`貉ì攘窼ȶ{黺( + nodeTaintsPolicy: 晓}從磹砛鬀D + topologyKey: MXei + whenUnsatisfiable: Ē舐ɒ'Q|ȃ#Y\厾h +-- case-046 -- +affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: 2Nsqe + operator: 阴闤Bǘ尚僞熐蘐槄TČ鉇拍Ɣ唉f钡 + values: + - EQslZWcPKU3 + - key: clrdH7j + operator: 鹓ī郖漖8ĬwƓ + values: + - zsB2 + - HGN2A + matchFields: + - key: Is7w3FDS5zse + operator: -ĉYd + values: + - U4nF56qPTw + - mm38x0AQL5c + weight: -1981921933 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: mRa + operator: ȥǮĬʩɄeƩ蟤确= + values: + - ooR1 + - QIho6keUV5fIUe + - jrOsTe + matchFields: + - key: miXl + operator: ʯ5yɶȁ/z>Ǡb_Ȉ撿÷đ湕ǭ + - matchFields: + - key: yXFe + operator: ȁ!Ńǩ浉F蕊ƕ倉輴Q¬ß巩ɿ + - key: qEUUleUJCe + operator: dz楥Qɗ鎽嚬t轮黑<ƻ眄 + values: + - pXk + - l22 + - l6 + - key: DiInxf + operator: lťõ祟X鬀ò嬬uġ + values: + - CtW2vs2 + - x + - rT + podAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: 0oFNd + operator: 喯z芡I钷)bę%匾蟨 + values: + - i6xl9Mn + - "Y" + - Dnn1nA + matchLabels: + ACWAVtod: 5MsAi + W7L46x: Iohx + matchLabelKeys: + - tZcagyiX + - 5w + - SMP + mismatchLabelKeys: + - b + - f + - bqCBIIfcdw + namespaceSelector: + matchLabels: + H3qd: 6DBRkuQvCde + namespaces: + - Y3j7k + - 8i2rf + topologyKey: 290Z + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: j8OASVi + operator: Ų驐Ĥ>Ȳ`1)o}嵊袀d + values: + - DE + - key: Iir + operator: WqȊ晝ɛ唊ɵk抩Ǟ紅銫Ş秠Ś~ą + matchLabels: + 8RiTX5m: lU1nenIq2B + B1: gskcNQo6g + D1kq67: "" + matchLabelKeys: + - ii9Ab3 + mismatchLabelKeys: + - 4X2zohLQD + namespaceSelector: + matchExpressions: + - key: HyU35bXzWF + operator: 尽ǰ + values: + - "" + - sB3pY + - 4r + namespaces: + - vW + - LYI + - mhQ0 + topologyKey: pjisw + weight: 1962236401 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: 9GtVGXjE + operator: 镭鱆ʁ;崽DȔ3Ĭ鐓敝 + values: + - igW0 + - Qiyx + - zMm24In + matchLabels: + AWiVWW: gPF0Yh + matchLabelKeys: + - 01T9Mphw + - qcecz73o + - o6bBrV + mismatchLabelKeys: + - uJJWe + - 8On4IIB31 + - p4t46HL8K + namespaceSelector: + matchLabels: + h: iExiiF + topologyKey: ZhTV + weight: -2130387111 +annotations: + cflWrdcz: jJe +automountServiceAccountToken: false +autoscaling: + enabled: false + maxReplicas: 451 + minReplicas: 241 + targetCPUUtilizationPercentage: 434 + targetMemoryUtilizationPercentage: 89 +commonLabels: + "": WcYTY + rHtDM6k: ZY6Kw +configmap: + create: false +console: + roleBindings: + - 0RZs: null + 3MoL: null + DS: null +deployment: + create: false +enterprise: + licenseSecretRef: + key: "" + name: mP +extraContainers: +- args: + - TLL + command: + - "" + - kyr + envFrom: + - configMapRef: + name: cGxJkM382 + optional: false + prefix: 8ZYix + secretRef: + name: sptdX + optional: true + - configMapRef: + name: sv + optional: true + prefix: juf4E1 + secretRef: + name: WrvN + optional: true + - configMapRef: + name: stixRM6Z1c + optional: false + prefix: eHg4 + secretRef: + name: kJK + optional: false + image: Q + imagePullPolicy: 榲µʪ + lifecycle: + postStart: + exec: + command: + - AHw4N6lX4 + httpGet: + host: CuJ + path: kY9OI68 + port: I6fEdljwf7WI + scheme: 0Tæ + sleep: + seconds: 8747859025599270243 + preStop: + exec: + command: + - SAiYloe + - rxrb8 + - U1 + httpGet: + host: D + path: Ck4D + port: 1235678776 + scheme: 讅º頼 + sleep: + seconds: 2255567287221174216 + livenessProbe: + exec: + command: + - rlPo + - TpvecI + - c + failureThreshold: -1194959675 + grpc: + port: 1286950474 + service: l03Ttx + httpGet: + host: iZbpkGTG + port: -104521289 + scheme: ǘɚƃŊ1_蛺ƥ篯 + initialDelaySeconds: -1041934050 + periodSeconds: 1858129919 + successThreshold: 812913269 + terminationGracePeriodSeconds: -6125486107996409317 + timeoutSeconds: -1767574186 + name: "5" + readinessProbe: + exec: {} + failureThreshold: 596482569 + grpc: + port: 1150156757 + service: qaPYsPWRM + httpGet: + host: iNasZ6 + path: CpVj + port: GC + scheme: 謭¤GȫȇƄ聭Dłʬ + initialDelaySeconds: -1604058483 + periodSeconds: -603768209 + successThreshold: 1589218932 + terminationGracePeriodSeconds: 4819160591653315271 + timeoutSeconds: 2047446198 + resizePolicy: + - resourceName: Or + restartPolicy: OȜ)漢ɨ酳h + - resourceName: i6roWBCG + restartPolicy: Ćʊ赆ʒ + resources: + limits: + ZTOf: "0" + requests: + "5": "0" + restartPolicy: ȱTǣıN飿 + securityContext: + allowPrivilegeEscalation: false + capabilities: + add: + - c + - Ɛ絜-Ȭ狆ǚƫȼ)ɦȗ欌3Z + drop: + - '*`N}柁番贝鍝陂±Ǖ弊' + privileged: true + procMount: 湅ʨɩƗ吞硩Ǘɵ櫜5 + readOnlyRootFilesystem: true + runAsGroup: 2454233763446715277 + runAsNonRoot: true + runAsUser: 1349777568495231591 + startupProbe: + exec: + command: + - tEiO0Gf + failureThreshold: 1955219951 + grpc: + port: -4890683 + service: 4tTWT + httpGet: + host: 5h5p4Uk + path: JX2HU + port: b6yI + scheme: 娂儯庬Xǿƫ + initialDelaySeconds: 1159427409 + periodSeconds: -1534574298 + successThreshold: 1143094739 + terminationGracePeriodSeconds: -2223019815025430450 + timeoutSeconds: -1544667872 + stdin: true + stdinOnce: true + terminationMessagePath: 1FuR + volumeDevices: + - devicePath: "Y" + name: EahA503T0 + volumeMounts: + - mountPath: QxOZw9E + mountPropagation: N"賬 + name: k4sw3lfzmj4 + subPath: 9a + subPathExpr: q5p0 + - mountPath: 9FHN + mountPropagation: o~ʆ容Ĺkjɋ5cȔcƼ诔楞 + name: wmkq + subPath: M1UIiHV + subPathExpr: IhSh2 + - mountPath: KTgxDgARv + mountPropagation: 篪k矲PƊ$ʇ謞šS婝耻遄 + name: nvW2 + readOnly: true + subPath: u6 + subPathExpr: C3n82 + workingDir: F2B +extraEnvFrom: +- configMapRef: + name: s4S + optional: true + prefix: g8JM + secretRef: + name: Km8n + optional: false +extraVolumeMounts: +- mountPath: VW + mountPropagation: gjɲi呒>[ɻ + name: HRTFVpU6YN + readOnly: true + subPath: J + subPathExpr: Zx9CYV +extraVolumes: +- name: ldO +fullnameOverride: fB6TF +image: + pullPolicy: '&Q眫' + registry: HjNl + repository: z9WL9QV + tag: jKgmVjE +imagePullSecrets: +- name: DL1OBpd0 +- name: jM +ingress: + annotations: + A4M6T: IUmZ9 + AHN: gcT00IU6 + S: lzi1Q + className: aU0xOzsFN + enabled: true + tls: + - hosts: + - PV + secretName: aHG1 + - hosts: + - bX + - Cu + - xuscoJ + secretName: fBCynrlb +initContainers: + extraInitContainers: aF +livenessProbe: + exec: + command: + - mWA8 + failureThreshold: -2111746605 + grpc: + port: -159496093 + service: 5BzT + httpGet: + host: Pgb + path: W + port: FTodWK + scheme: '@ĝȗɰ*8Eȑ' + initialDelaySeconds: 1224736641 + periodSeconds: 1490424943 + successThreshold: 2012886943 + terminationGracePeriodSeconds: 1140281843739171103 + timeoutSeconds: 1910690397 +nameOverride: "" +podAnnotations: + P10bx: 4As + RWk: E + e: rh7XI +podLabels: + SnZ: mnX + aL0TsomY: aVv4hsuMJ7Aiq + luPi3E6: iCt +podSecurityContext: + fsGroup: -137977092678744094 + fsGroupChangePolicy: ʅ翄ąIJU÷[Ɉ<Ǧ兰巒鄂 + runAsGroup: 2453672470118860 + runAsNonRoot: false + runAsUser: -2867620198524252040 + sysctls: + - name: p + value: "" +priorityClassName: wQ +readinessProbe: + exec: + command: + - bmfgcwd + failureThreshold: -1418487663 + grpc: + port: -468793496 + service: MhQm3 + httpGet: + host: nQSr0S + path: M8 + port: 1657726276 + scheme: 鶉阑 $ý + initialDelaySeconds: 1895968402 + periodSeconds: -1686229865 + successThreshold: 1934722351 + terminationGracePeriodSeconds: 2537915062001973026 + timeoutSeconds: 1366589097 +replicaCount: 376 +resources: + limits: + 87w5tBp: "0" + AmXXE: "0" + QH55ZH: "0" + requests: + EbalAlq: "0" + RpvkPX: "0" +secret: + create: true + enterprise: + licenseSecretRef: + key: ellF2F + name: K3 + kafka: + awsMskIamSecretKey: Xs8UvJPyL + protobufGitBasicAuthPassword: BKbdr + saslPassword: xW3EDKA + schemaRegistryPassword: Vewx + schemaRegistryTlsCa: te + schemaRegistryTlsCert: JxH + schemaRegistryTlsKey: jhxioPhQ + tlsCa: eP + tlsCert: H9 + tlsPassphrase: Gz + login: + github: + clientSecret: Q + personalAccessToken: akEcq + google: + clientSecret: vj6 + groupsServiceAccount: pJ8NQ + jwtSecret: jUc4rQpG + oidc: + clientSecret: 8SCyi + okta: + clientSecret: Yd + directoryApiToken: q1rSa + redpanda: + adminApi: + password: mON + tlsCa: rNzsp + tlsCert: UStA + tlsKey: 3E +secretMounts: +- defaultMode: 305 + name: smBrE0cI + path: "2" + secretName: zeb +securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - pij*fƤ + privileged: false + procMount: 罽İ耲,衧駕R=k{ŝ{躈瑮L + readOnlyRootFilesystem: true + runAsGroup: 3478202026348193011 + runAsNonRoot: false + runAsUser: -5521479784565460908 +service: + annotations: + aDeGG7F9S: 5d + nodePort: 439 + port: 271 + targetPort: 481 + type: PK7oH1pcU3 +serviceAccount: + automountServiceAccountToken: false + create: false + name: "" +strategy: + rollingUpdate: {} + type: żb給ū裬M +tests: + enabled: false +tolerations: +- effect: 瑟bĕʫFuěG盲ÿ + key: d + operator: 秸ƿ + tolerationSeconds: -7614909558910242428 + value: h2U4 +topologySpreadConstraints: +- labelSelector: + matchExpressions: + - key: 60k + operator: ʉ赳Ɇǂt硴煟讒ib + values: + - M755avF + - He6fTmtHDXC + matchLabels: + c4BN5BiYtjB: tyUmvwGkL + matchLabelKeys: + - E4G8mM3 + - G1C9Cjj + maxSkew: -1527756346 + minDomains: 432090734 + nodeAffinityPolicy: qǗ阵W&喁CE®ņpPȂ\Ç苗ĈȄ + nodeTaintsPolicy: ȉ珉@:x凝謽Q釀ļn适c顦 + topologyKey: V + whenUnsatisfiable: 瀥 +-- case-047 -- +affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: {} + weight: 182966451 + - preference: {} + weight: -2028220392 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: [] + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: 5a5MXO + operator: kƎǦƙ«嚄ƭr騥邜Fċʐ叧F& + values: + - BRA + - Ywt7JHE + - key: TjE3wFb6 + operator: O`6ƥ縈L:Ckʄ鹟瑧 + values: + - "" + - dxDLfiL + - 0IgsneLlLo + - key: tuBbSOMR + operator: 桛ʫ褛ʒɩWkv濱瘛#Ěi邱CNǖ4孳 + values: + - 9zJ + - 7T3iJAwX + matchLabelKeys: + - ZYcvinlq + - PwQO9 + - M3gb + mismatchLabelKeys: + - e + - K1XrVh + - D1CkR8 + namespaceSelector: + matchExpressions: + - key: uqnyV6k + operator: rĮ'示嶠ĵ攛Ņ + - key: 0ONfMVB + operator: n梷E8ʟ菛晉 + values: + - Q + matchLabels: + IqH8n: pCJ16S + mUE: HyxdirX0F + namespaces: + - gptVP + - L + - 7CmPHtA + topologyKey: XDhewcrvK + weight: 2033587292 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: jcAfZ5VF + operator: 饀re + - key: sj + operator: U姑R° + values: + - p8zbO + - key: 2LmP5 + operator: ŸȢ庾塁BƖ + values: + - NN + matchLabels: + ApvKyKe: kHE9lIIleR + mismatchLabelKeys: + - n3VRcT5qX + - zGNqgUGNX + - hDZ + namespaceSelector: + matchExpressions: + - key: "7" + operator: 砃=G墈赞飍鵝7d + values: + - Uiz9BnY + - key: hd76 + operator: '{緶ɡnW' + values: + - vc1yj10y + - Je + - eg + - key: 06pjmB + operator: =帛胏 + values: + - RQ10 + - Z5WWhGqt + namespaces: + - seMTT1 + topologyKey: E + - labelSelector: + matchLabels: + oplIL: 67Fs0Yu4 + mismatchLabelKeys: + - T1 + namespaceSelector: + matchExpressions: + - key: hOQWYMD + operator: vǑ壞2â飿"Xʝ簮倏c + values: + - "0" + - key: WWGKqAgL + operator: '''OƼŪ祰ǑŗiU嘏ɮ?Ī語' + values: + - yU5IOsL + - koP + namespaces: + - lDs + - xQZsD + - J + topologyKey: j0k4ds + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: 9nDdXGQwP + operator: '[痵lǝ,ǶÜÂD' + values: + - th + - u8xZ + - ucr3vqZeG + - key: QWVrK8k + operator: ʀăɼy耯#運+3坽« + values: + - 2lcZKn + - G2IQ + - YbYwv + - key: N4bc7Wn + operator: '%7`iɊȑ槦醒}' + values: + - NiSH90 + - 98iHVkt + - 0r3Yu9i + matchLabelKeys: + - zrV + - Ey + - R + namespaceSelector: + matchExpressions: + - key: gEbVS1wo + operator: z + matchLabels: + 2YURuF: "" + CJTjm6: nOFN + oUtlWUD: 0k14ag + topologyKey: M1yF5YA + weight: 477520510 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: mdjoxbr + operator: V2SŨǰ8嫟淦 + values: + - 3ww0Ei + - 2PjudE + - pmpvETB0n + - key: NFqQGo + operator: 处;Ƕk鎹û絹褡Sy + values: + - V + - key: HuZ + operator: ȓő&ś>S怭ť]E榕 + values: + - sUume + matchLabels: + ef2q: 4ZL0O9b + r8xqG: MJ + matchLabelKeys: + - "" + - "Y" + mismatchLabelKeys: + - djn6fDf + - ukZi8 + namespaceSelector: {} + namespaces: + - dOU1F + - 1ygQdj3xZ3YIf + - wvpeJx + topologyKey: Rq4K6z6 + weight: -1277100698 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: b + operator: "" + values: + - tmuB5 + - 9qE9GM + - oJpaRDn2 + - key: WY + operator: u酘b + values: + - RhO + - Cs2rDIRrPlii + - nG4bqoAkQU + - key: eMae + operator: ǟĕȴnjI覿9¥H艞ɋ + matchLabels: + ToIBbWL: 4k8X + i2qGkWjvF7QJ: pb0sZq + u12o4B4: Ybz + matchLabelKeys: + - HCKtJC7hm + mismatchLabelKeys: + - 21r0Z + - "" + namespaceSelector: + matchLabels: + 2BNgnKr7Ob: 5RffK5NB3ghhfO + bJC: WTOgH + uA: bxdRwsU + topologyKey: 2CsbupZ + - labelSelector: + matchExpressions: + - key: RIP + operator: Oȝ(氧罻 + values: + - 1bx3Fix9 + - key: eqQoi + operator: 68+ʈĘ + values: + - FgfwmYrR + - mznlyr2aLTGF + - GfAoC8M + matchLabels: + FKwNoJ: aJZxa + cEeo8ix: 3dHunLjp5 + ihSd: qG7x + matchLabelKeys: + - F6LQK + mismatchLabelKeys: + - ULcGW + - RYv + - fF + namespaceSelector: + matchExpressions: + - key: Tkp5 + operator: ȴ潺谡Ƣh躈ŮâÿȒũĔ + values: + - fY9NuWB + - O84 + matchLabels: + 09fI: EDSEVi + Dl: 4u38aD4O + vZCciR: neqAXd7k + namespaces: + - ozziI6FZ + - URQlLJF + topologyKey: SeSq4K +annotations: + Bx5i3M: s + svlaTGpSHD: 7P9k +automountServiceAccountToken: true +autoscaling: + enabled: true + maxReplicas: 122 + minReplicas: 449 + targetCPUUtilizationPercentage: 218 + targetMemoryUtilizationPercentage: 488 +configmap: + create: false +console: + roleBindings: + - eaLPMN8qOPT: null + xb: null + xnt: null + - 3Mgk: null + roHIFBN: null + - TtzrP: null +deployment: + create: true +enterprise: + licenseSecretRef: + key: nj + name: rl +extraContainers: +- args: + - lW + - lpUVzUh + command: + - 3mEGtoKbEWE2Jw5T + - b1GBFA + env: + - name: hsiWF93 + value: zBco + valueFrom: + configMapKeyRef: + key: 8hvvaoHB + name: "y" + optional: false + fieldRef: + apiVersion: WPT5J + fieldPath: sc + resourceFieldRef: + containerName: 0xbTU4O + divisor: "0" + resource: tPBV2ObG + secretKeyRef: + key: YEKZukl + name: px + optional: false + - name: PM0MyyH3R6R + value: yOzX + valueFrom: + configMapKeyRef: + key: I3pi + name: DC + optional: true + fieldRef: + apiVersion: "25" + fieldPath: "" + resourceFieldRef: + containerName: aZj1E7LU + divisor: "0" + resource: sxs0nE31 + secretKeyRef: + key: Ktb3c4 + name: g98T + optional: true + - name: 6kDq8UgFIS8 + value: L0i4 + valueFrom: + configMapKeyRef: + key: 9WUe9 + name: tZrRUK + optional: false + fieldRef: + apiVersion: GIc + fieldPath: AXTmU + resourceFieldRef: + containerName: E2 + divisor: "0" + resource: a63tq + secretKeyRef: + key: luWp + name: lPdowo + optional: true + envFrom: + - configMapRef: + name: vzVk + optional: true + prefix: DONFyRd + secretRef: + name: 9uct + optional: false + - configMapRef: + name: z5nC9D + optional: true + prefix: 5epUyS1iy5m8 + secretRef: + name: zqRFC + optional: true + - configMapRef: + name: awjfJlZxN + optional: true + prefix: LhArOQgbq1OCR2L + secretRef: + name: mb5axzX5 + optional: true + image: qPLiX + imagePullPolicy: '{Ĩ檽]ĻĹňɋ偌Ȏ.阛魉' + lifecycle: + postStart: + exec: + command: + - yAeOM + - s53um + - 3m + httpGet: + host: GJWsJm + path: iDQ + port: 1781170742 + scheme: 皐ű葺ȝĬ麐&ʉ執dz0娸叹 + sleep: + seconds: -4230531115544534394 + preStop: + exec: + command: + - sIGb5 + httpGet: + host: AbxhPKar + path: 3ZZ5 + port: 88852320 + scheme: 砨Ĝ_筀¤痟氻劊űI俼员z幛F + sleep: + seconds: -4758564920159898567 + livenessProbe: + exec: + command: + - ty6JMTW6vA + failureThreshold: -1459976999 + grpc: + port: -1689493187 + service: ihsDMVYd + httpGet: + host: e9NNlO5d + path: iBo4 + port: 334788778 + scheme: ƿ:ħȠL$ + initialDelaySeconds: 1625633184 + periodSeconds: 1327859251 + successThreshold: 1766792721 + terminationGracePeriodSeconds: -3971501657411371216 + timeoutSeconds: 557348614 + name: U3U + readinessProbe: + exec: + command: + - "Y" + failureThreshold: 391027623 + grpc: + port: -1858356724 + service: hnqm + httpGet: + host: g + path: C48 + port: F + scheme: 苎lɲÁ频×ȊDžȀ9Ď"昽 + initialDelaySeconds: -1404160881 + periodSeconds: 521131323 + successThreshold: 2005094455 + terminationGracePeriodSeconds: -5942417190535485186 + timeoutSeconds: 2118365394 + resources: + limits: + Ms1A: "0" + WkWhM: "0" + requests: + b4kR9nm9BfQZy: "0" + eLg: "0" + huME: "0" + restartPolicy: ľ慔/PpǏ銢9滖ɝ韍I鍌$ʪ辫Uz + securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - wą&嘪研Z`ȧȢfʘ*ō + drop: + - ƿ`ĉĎ苦Ǧ蘈NJ她笻Ƞ + - 磨3踦煨1JƸc錚捁 ĊZe)ám \ + privileged: true + procMount: 鋶XJm/覹ɋ¶ȉĒȤ瀶|ƻŒ(咡 + readOnlyRootFilesystem: false + runAsGroup: -8452021579348253718 + runAsNonRoot: true + runAsUser: 5983932912975749110 + startupProbe: + exec: + command: + - sZhTLr + - GK + - kqL9aDDm + failureThreshold: 1004086477 + grpc: + port: 1266077274 + service: l1ji1IW1ic + httpGet: + host: rJI + path: H731Dr + port: 1333462733 + scheme: 项鰚ɽ洍êƳ + initialDelaySeconds: 1806670133 + periodSeconds: 1290098703 + successThreshold: -490255445 + terminationGracePeriodSeconds: -206080146769410314 + timeoutSeconds: 270060590 + terminationMessagePath: P1HCGJEbJiD4 + terminationMessagePolicy: ʇ鞯BC鸼樁÷ǹ楺 + tty: true + volumeDevices: + - devicePath: a4 + name: 0bA + - devicePath: VeRXU9 + name: A0XbFJhG + - devicePath: fdim + name: RJf + workingDir: ZoDFb +extraEnv: +- name: "" + value: YbKo + valueFrom: + configMapKeyRef: + key: bIruuA + name: x8 + optional: true + fieldRef: + apiVersion: EqX + fieldPath: ZOh + resourceFieldRef: + containerName: IDJTm5lv + divisor: "0" + resource: QDC8v + secretKeyRef: + key: "8" + name: LcSdNiKff4 + optional: false +- name: RZHq9C + value: m + valueFrom: + configMapKeyRef: + key: PZVqf + name: x + optional: true + fieldRef: + apiVersion: xQi + fieldPath: vxeo + resourceFieldRef: + divisor: "0" + resource: l7 + secretKeyRef: + key: i3lK + optional: true +extraVolumeMounts: +- mountPath: OO0aO6h + mountPropagation: "" + name: kDKM + readOnly: true + subPath: AlRCH + subPathExpr: 7UemLsIe +- mountPath: Z8zdlU + mountPropagation: 醗¡°v:胡 + name: aedAMG + subPath: zo5P1xa + subPathExpr: WmuiME +- mountPath: ufiUx + mountPropagation: '`ʡÔ关Ľ?' + name: PWBh + subPath: 2hslJ + subPathExpr: pUtN3 +fullnameOverride: YUi5JpG +image: + pullPolicy: ȕ蚧竔/´苅oC + registry: zUsK + repository: lQjo + tag: p +ingress: + annotations: + CImW98Gx2v: otj + fP: SRGkm + className: lM + enabled: false + hosts: + - host: AYT + - host: oulge + paths: + - path: 3bi + pathType: ixqeQz + - path: nG + pathType: 5LwYGxvMr + - host: "" + paths: + - path: jJrUpe + pathType: 72AAc + - path: B0K + pathType: kxnm8kN + - path: tQDn + pathType: IxAmHD + tls: + - hosts: + - n9Np8ftRtFhzi + - g + secretName: C + - hosts: + - CMhuwA + - wYA0tSvo + secretName: z + - hosts: + - 34mbP + secretName: 80Z +initContainers: + extraInitContainers: PRtnaAy8 +livenessProbe: + exec: {} + failureThreshold: -1392926461 + grpc: + port: 257623603 + service: us + httpGet: + port: L9CrR58RHnS + scheme: ʅ²7kp + initialDelaySeconds: -1384385388 + periodSeconds: -1660079876 + successThreshold: 680842396 + terminationGracePeriodSeconds: 6050526356201491316 + timeoutSeconds: 213455290 +nameOverride: nEojiMtRc +podAnnotations: + Mfsd: hmi +podLabels: + 6dZAs: xJPaLHKS1Y2 +podSecurityContext: + fsGroup: -6567182940167159103 + fsGroupChangePolicy: 6iɰ堂:齐ǪÈ + runAsGroup: -1787219330993537800 + runAsNonRoot: true + runAsUser: -5627543087390804845 + supplementalGroups: + - -3306962996817147613 + - 975882030005456556 + - -5263492609498468245 + sysctls: + - name: YC + value: 7JlDTCP6hs +priorityClassName: 0P6RnoBeb5 +readinessProbe: + exec: {} + failureThreshold: 1689894479 + grpc: + port: 222105741 + service: D + httpGet: + host: vyj + path: JoV4VZMz2Bv + port: vRf9ZHgc4j + scheme: 条om競娷Njʑ + initialDelaySeconds: -1753994274 + periodSeconds: -1189421015 + successThreshold: 1278527365 + terminationGracePeriodSeconds: -6266260075166332402 + timeoutSeconds: -209775227 +replicaCount: 391 +resources: + limits: + 8ycM: "0" + requests: + CvglPI: "0" + s5: "0" + uiHB: "0" +secret: + create: false + enterprise: + licenseSecretRef: + key: Iq + name: Tb8RGi + kafka: + awsMskIamSecretKey: gj + protobufGitBasicAuthPassword: kO + saslPassword: IB3qNjrV + schemaRegistryPassword: 4wnp6Qi + schemaRegistryTlsCa: gFBJq + schemaRegistryTlsCert: LUubckiv + schemaRegistryTlsKey: 9Op + tlsCa: 94x0v + tlsCert: h4lSMbv + tlsPassphrase: CVT4wjw + login: + github: + clientSecret: YaYETggo1hi + personalAccessToken: d + google: + clientSecret: tDqsIg + groupsServiceAccount: FSUAkU004n0k + jwtSecret: 2dWKNqarwb + oidc: + clientSecret: i2n + okta: + clientSecret: XytR0yn + directoryApiToken: m3WEq4zKv + redpanda: + adminApi: + password: ozo + tlsCa: 0g + tlsCert: hQ + tlsKey: xfpkmy +secretMounts: +- defaultMode: 184 + name: L8dbWip + path: g + secretName: LF0O +securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - «Ƙz损 + - ɟE鄱Į惪Y桦ŗɘoȍ蠣4ƪ呀R> + - "" + drop: + - 娤b + privileged: false + procMount: ʍ曏(ƶæ + readOnlyRootFilesystem: true + runAsGroup: -406748533537085799 + runAsNonRoot: false + runAsUser: 3238073083343117470 +service: + annotations: + 8v2: JbH + 95cxbjjD7C: JBMaJ + VY: yRV7d + nodePort: 18 + port: 168 + targetPort: 227 + type: WAAXkZY +serviceAccount: + annotations: + DQxrtk8: buiWLPbYq + HHbP: sAY + Y0DKOcTa: D82Nfh + automountServiceAccountToken: true + create: true + name: DSw7 +strategy: + rollingUpdate: {} + type: żʧȟ +tests: + enabled: false +-- case-048 -- +affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchFields: + - key: v + operator: ė + values: + - ln + - lU4zX8iz + - t0Xc + - key: s3fpu + operator: ɥ娿ăʄĠ mʓ銈E'袭ĵ + values: + - ljJlhx + - matchExpressions: + - key: qPBvuBghor + operator: 泱诅ʫt + values: + - a05XZwN + - SiAvFWs + - FhW1 + - key: MVFTcW + operator: º囜N赧0索d + values: + - c + - ghZI + - AjB0J + matchFields: + - key: QzMSpLW + operator: :ɉùȪÇzǥC货°ÕV? + - matchExpressions: + - key: pA7a1gYdV + operator: '[ĪtOK' + values: + - 2bE4Bw + - fyMOYi + - key: wshbw7Ix + operator: J槭~撑MS=ÑƎ薽饵a緗 + values: + - 9jt6 + matchFields: + - key: s1 + operator: 犫茬睶ňv + values: + - XhyH + - Ng1r1 + - nqis + - key: mHLiT + operator: ȁ佝L郗s稷tŻ+f舭拳鰵2e{a + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: jdvk + operator: ƶ + values: + - NV + - y4 + - V2XRZS + - key: 9VvAl5 + operator: <坎陸$§¤_ã檠奙Å饉J夗ɓ翩锸辸 + values: + - x26kYkJ + matchLabels: + DziixIJYd: yCXzPc + matchLabelKeys: + - XNuk + - RGLu + mismatchLabelKeys: + - aF3 + - R + - Tnj6SmTq + namespaceSelector: + matchExpressions: + - key: e1XR + operator: Kɞ窏ǿ,鸣ŰcNc + values: + - Yrq + matchLabels: + F2Pe7J: dlwTdhs + lK: nolQ + ys9z: euXWPiaJ3Bv + namespaces: + - tAzvw4OH1G + topologyKey: 6y + weight: -1640008169 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: XbjQvP + operator: V嶙NZ谡筩ǒ抂 + - key: i + operator: ɔŃ旓Ɍ鬺X + values: + - Zvx + - 7HWJ + - e4ucTP + matchLabelKeys: + - 0LSTZ + - ESk2r + mismatchLabelKeys: + - CKhfvR0Sg + namespaceSelector: + matchExpressions: + - key: A0tc + operator: 辛§ʢ垝V矋n握匞~嶯筪溆¸ + values: + - ML + matchLabels: + K1pr: ROFIwZhJYYo + ODc: 48WQ + namespaces: + - Wv7 + - zenLPw + topologyKey: tIVDde5U + weight: 1977587462 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: 3YyUamlR + operator: 橯F + values: + - dHitre + - 90jUjk + - key: NtnSL + operator: 臰sR=坵Ěcñ黪:ɻ寊â9dƎ\V + values: + - qqzycK + - key: ICXJGRFS + operator: $貕^eėǭD鳅ʇ + values: + - txX + - SFrkJ9r + - 3jOnwEW1 + matchLabels: + Uwj1kpV: oUXOYkF + o: ts5wRqjTyCy + matchLabelKeys: + - V2DNNCORe7ZRA + - pglXe4D + - w3881 + mismatchLabelKeys: + - xbi5KtUmR + - eZenitLdd + namespaceSelector: + matchExpressions: + - key: fxd5Y + operator: 頣R熗!A麳Ƚ6r爤暓 + values: + - oe46YF + - rT30v + matchLabels: + 4WA: EH + nRhlLLx1yHy: 5UFrj + namespaces: + - 7j92oP + - 2hf + topologyKey: "" + weight: 92207265 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: wBvol + operator: Ɂüɯ + values: + - eKmyok + - key: B2uj69 + operator: "" + - key: hLrZlh + operator: ȕ嵠味 ɼ_ + mismatchLabelKeys: + - W + namespaceSelector: + matchExpressions: + - key: Qu + operator: 亣i拴ÿ + values: + - OeiUsmYu + - oGXa6Ma + matchLabels: + "": Li + oDV7yR: NP + namespaces: + - PQjQb3LP + topologyKey: Gs1 + - labelSelector: + matchLabels: + "": nF + mismatchLabelKeys: + - YG6aQj + namespaceSelector: + matchExpressions: + - key: HpxPVtw + operator: z畘ŠƽǢ蘟\ɡ忕ɋ蜹5B + values: + - EQ + - RP3fBi + - key: Lv60cZut + operator: 裰ƈ + values: + - I9JbN + - dt + - Cya + - key: 0MGm8N + operator: 遍Ż + matchLabels: + nELvnrAFr: DClM + topologyKey: N57yxG + - labelSelector: + matchExpressions: + - key: "" + operator: KǞ}ɣȿ嚶宗荝«Dž + values: + - CGw32z4JHya + - E + - u5CDtdc + matchLabels: + J5LzcLei: kBwTCGZ + iLpqu: j4bqBNDjAK + jN: jUZ0u + matchLabelKeys: + - lNM + - K3nOO5 + - 9norFQpMiC + namespaceSelector: + matchExpressions: + - key: y4teb + operator: 蚯 + values: + - P + - O0 + - MvxOu + - key: v8w1Ok + operator: 8ƴņŨƊ¹艗胲ƦpYƿ9d脙~Ë + values: + - "4" + - "66" + namespaces: + - OtWsVW + - p + topologyKey: GeF + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: GRLHy + operator: Ä椶 + - key: Z + operator: ė牫ȃ汥Ƈ娍q\桕ɄNǴ + values: + - S1hMkP + - K + - x5coDg + - key: kJzBQ + operator: ʉĻ孺bɧɬʬ柿娤e¯]每) + values: + - DbD1 + - C5dyvNew + matchLabelKeys: + - 8G + - 7cCVU + - lN + mismatchLabelKeys: + - xJ5l + namespaceSelector: + matchExpressions: + - key: U89y + operator: ȓ2浿澰V缐厧钎wň莁願菶ʈ杈 + values: + - 9m6ydjpHu + - CatqpZmUCL + - dJz + - key: SIePbOJc6H + operator: ljR2qɟ$s櫮c雕Ů幔莁沥ʫľƙŝ + values: + - 75tj75r + - XiO + - key: "" + operator: 舄或崙Ĭɐ耼Ī弋禽$ + values: + - HWwXVr4o + - WEkwi8ZNDQ + - f + matchLabels: + fi8w0BX: Z48LRdXmkJ + namespaces: + - Yaw2NnfJ + topologyKey: ElKfd7Eo + weight: 1078166465 +annotations: + Dgw3Wl: 7aofTp +automountServiceAccountToken: true +autoscaling: + enabled: true + maxReplicas: 1 + minReplicas: 224 + targetCPUUtilizationPercentage: 468 + targetMemoryUtilizationPercentage: 256 +commonLabels: + 4kU: mkn8 + Ro: NFx1P + Z1p: WE +configmap: + create: true +console: + roleBindings: + - FZ5NQS6: null + - 0ToI: null + RTwav: null + mWwdgyM: null + - {} +deployment: + create: true +enterprise: + licenseSecretRef: + key: "" + name: 3VGefRh +extraContainers: +- args: + - 3QF + - k1BJBm + command: + - PMW + - j + - V7MAcfomz + env: + - name: rAzI53 + value: WlHlq + valueFrom: + configMapKeyRef: + key: zzIBsb + name: Bh261F + optional: false + fieldRef: + apiVersion: SlA + fieldPath: "6" + resourceFieldRef: + containerName: q0BBEv + divisor: "0" + resource: JE + secretKeyRef: + key: FvrZgBz + name: ZTBeic + optional: false + - name: uPptX + value: i9 + valueFrom: + configMapKeyRef: + key: JeHwi + name: TiQHOG1EsFUgIE + optional: true + fieldRef: + apiVersion: i7dd + fieldPath: Tu + resourceFieldRef: + containerName: ChdvA + divisor: "0" + resource: Eq1V33RTZQSJRJFg3V + secretKeyRef: + key: ojxn54r + name: L + optional: false + - name: Sl9Py25FX + value: e9 + valueFrom: + configMapKeyRef: + key: Zq80J9tyR0opcz + name: gy00dyvHFa + optional: true + fieldRef: + apiVersion: UJLSQy7zL + fieldPath: Xm4sg5H + resourceFieldRef: + containerName: ZmY7Fno6Fcop3 + divisor: "0" + resource: gqZwW + secretKeyRef: + key: v + name: hJDoWtjkfL + optional: true + envFrom: + - configMapRef: + name: RdWA + optional: true + prefix: Dq + secretRef: + name: BOBOO0sLIWw0e + optional: false + - configMapRef: + name: MoMnWNTC + optional: false + prefix: "3" + secretRef: + name: B58Vvj3 + optional: false + image: Vn5V + imagePullPolicy: 筥ǏŤČ癳嶧GĒH挕ÄHɡ + lifecycle: + postStart: + exec: + command: + - hTIx + - lslygl + - lSgx5G2IfU + httpGet: + host: GNVKz7 + path: d0Y + port: Igi + scheme: 莵łEǐ嫖ʒʔvŊ>ry5贛 + sleep: + seconds: -184172880642712439 + preStop: + exec: {} + httpGet: + host: tD1TkKV0ES + path: s6 + port: OpK5riOe96 + scheme: 琊*i#欱E唂ȧ鐄膶詃7 + sleep: + seconds: -4889549574266894064 + livenessProbe: + exec: {} + failureThreshold: 1591130939 + grpc: + port: -540029946 + service: aoAN2Lx03 + httpGet: + host: vWu + path: Lo + port: 1468671948 + scheme: ȯ煐IŢ + initialDelaySeconds: -1879733088 + periodSeconds: 1106663448 + successThreshold: 240850805 + terminationGracePeriodSeconds: -7405296717602935730 + timeoutSeconds: 524743651 + name: AInfx2Rak + readinessProbe: + exec: + command: + - oIA3 + - H + - 96Uj2 + failureThreshold: -1855887857 + grpc: + port: -495541010 + service: X + httpGet: + host: ZplmMg + path: tAAr + port: 1950182935 + scheme: ʂ綽oa;n轮ęB觼Z=G泇跢揌韇锶 + initialDelaySeconds: 1057136331 + periodSeconds: -2025421367 + successThreshold: -812558156 + terminationGracePeriodSeconds: 4314843605692522234 + timeoutSeconds: -1609986779 + resizePolicy: + - resourceName: EvmpG + restartPolicy: 4ɱ + - resourceName: hTB20ObO1 + restartPolicy: ½ŏ伐Q蔏ʝ噙漃袩J]Ɣ蒘岇 + resources: + limits: + KWlx2c: "0" + O: "0" + requests: + ZCJwGBL: "0" + restartPolicy: 1nĔ:蹮>s蹬ÍǺ + securityContext: + allowPrivilegeEscalation: false + capabilities: + add: + - 迠寈搣弝渎İ- + drop: + - 檹Ɩ + - ɧ麧ç2ā兛杧蔙團载^P蚡5缿ʒU襩 + - cLD|ƶ虌Ȗ + privileged: false + procMount: ïƋ圏滜ľ転謀ĤP蹥ȅ|髃蒃Q癎æ + readOnlyRootFilesystem: false + runAsGroup: -4850605470374303682 + runAsNonRoot: false + runAsUser: 7731251064648990624 + startupProbe: + exec: + command: + - LqYoUQy3c4BE + - 5N + - Ug + failureThreshold: -1290004088 + grpc: + port: -1721281251 + service: H2p + httpGet: + host: 02CP5 + path: F609y + port: JjwFH + scheme: 珑 + initialDelaySeconds: -402608647 + periodSeconds: -1520214127 + successThreshold: 209058699 + terminationGracePeriodSeconds: -1900030585542850396 + timeoutSeconds: 1686394545 + terminationMessagePath: qixKzKz + terminationMessagePolicy: Ǥ衚蔁ʙ剠Ǡɭf~ + volumeDevices: + - devicePath: zM1 + name: jmc + - devicePath: IZ + name: PS + - devicePath: kN24U + name: Apu0r1U2 + workingDir: WgB +- args: + - 2Z37 + - 75kO + - TjvjkZTrc8s + command: + - M0NtzJ + env: + - name: 2EH + value: O + valueFrom: + configMapKeyRef: + key: J1ozKsuji + name: glLvAIHP7i + optional: true + fieldRef: + apiVersion: 3gAjGu + fieldPath: sNpuR8m + resourceFieldRef: + containerName: oxx + divisor: "0" + resource: PuKq + secretKeyRef: + key: Iua2L1LoCWMs2 + name: YfKwS8s + optional: true + image: PKNM + imagePullPolicy: ÍĪ0魣Ŋʒ + lifecycle: + postStart: + exec: {} + httpGet: + host: fsZ + path: EGnu + port: 765491661 + scheme: ?ğ叆ɂ&pʠ溶Ǚu + sleep: + seconds: 4688626474961012693 + preStop: + exec: {} + httpGet: + host: TB + path: "6" + port: -50369560 + scheme: ~Ǚɇ>ƃ\7]歉sh羘y4 + sleep: + seconds: -5293607398165581925 + livenessProbe: + exec: + command: + - 1g8dewdj + - lRmD + failureThreshold: -125369558 + grpc: + port: -1490211482 + service: R + httpGet: + host: CSGThzhG + path: 9NBKzoiFzs + port: -272474300 + scheme: ŀ + initialDelaySeconds: -1094670881 + periodSeconds: 1768141210 + successThreshold: -985604418 + terminationGracePeriodSeconds: -1297054466922920616 + timeoutSeconds: -1289231356 + name: KtKv6dg + ports: + - containerPort: -632764671 + hostIP: 8CU + hostPort: 917138107 + name: 1VgOx + protocol: 典ȫ窃ÛǪ3m患 + - containerPort: 739656218 + hostIP: dQQ3 + hostPort: -1348301133 + name: "3" + protocol: '?Ū慾ŘLº桒J:茦扰絥ǗȑĎ:' + readinessProbe: + exec: + command: + - qZ2J + failureThreshold: 293719665 + grpc: + port: 1235836411 + service: ig3 + httpGet: + host: Ws + path: FVnJhZq7I + port: -1075951148 + initialDelaySeconds: 321800409 + periodSeconds: -556535717 + successThreshold: -625124830 + terminationGracePeriodSeconds: -4084380722124342213 + timeoutSeconds: -904900305 + resizePolicy: + - resourceName: GKINnuJx + restartPolicy: Řl©=嬈牍]佧& + resources: + requests: + omO: "0" + uga5: "0" + xnRsp6C: "0" + restartPolicy: ʝdŌİ蒘傥>晑|癶x&ĭmŭƙŵ + securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - 約nɤưHĞ4WƳǤȣ糥蠇t + - ¾ʃŔ冻楟?¿揈h嘼œ + drop: + - 7忭譺屩嫕ƞʅ袬/氼Xg养ȸ陣萓 + - 胨`鯵ƪĽ藹 + privileged: true + procMount: Ulƙxȿƌ乜溬噕瀆储铐\纬 + readOnlyRootFilesystem: true + runAsGroup: 4589112012742886931 + runAsNonRoot: true + runAsUser: 3204614620414442288 + startupProbe: + exec: + command: + - TFJ + failureThreshold: -585814509 + grpc: + port: 178002023 + service: lAuHCrE + httpGet: + host: "88" + path: Th + port: In + scheme: 鷵菭g顲Ⱦ穪 + initialDelaySeconds: -1856697198 + periodSeconds: 1469578394 + successThreshold: 160563852 + terminationGracePeriodSeconds: -4442318275257517382 + timeoutSeconds: -16211809 + terminationMessagePath: 513sVbgA + terminationMessagePolicy: 隓Ǽ屼Å7嗟Ʈ麝0{ȦDžĐ! + tty: true + volumeDevices: + - devicePath: ugQAJ + name: Jf + - devicePath: BFfnTD + name: kfF6CZ + volumeMounts: + - mountPath: C3 + mountPropagation: 呍婻厦ǒ絶偂蠛ƺ蠖蕍v貰Ė + name: DQvHajhHx + subPath: aYHGugq + subPathExpr: MSs + workingDir: OE +extraEnv: +- name: rd10f1l + value: GtUE + valueFrom: + configMapKeyRef: + key: C1N + name: bi + optional: true + fieldRef: + apiVersion: 9GWlMsB + fieldPath: l2 + resourceFieldRef: + containerName: 4t + divisor: "0" + resource: eyjvzsf + secretKeyRef: + key: xBMOaej + name: O8AG + optional: false +- name: C + value: fYlde + valueFrom: + configMapKeyRef: + key: 4HvhDAkW + name: 5bgA7leE7 + optional: false + fieldRef: + fieldPath: zY6rf + resourceFieldRef: + containerName: S3 + divisor: "0" + resource: 3sD + secretKeyRef: + key: s43 + name: LpaQ + optional: true +extraVolumeMounts: +- mountPath: M5 + mountPropagation: 稤Bơ觓Ð琋 + name: yQHj49RtdzN + subPath: GdQkAKF + subPathExpr: Gvswh +- mountPath: QRg + mountPropagation: 搚Kƕ欕K貵蠜d旓ĀÝ虩釓 + name: qCEH27RF + readOnly: true + subPath: nHB05RuTZ + subPathExpr: K0yH +fullnameOverride: 3um +image: + pullPolicy: Ƀşb?師Ğ`3H觉趟糯襖 + registry: VHbf77MFq + repository: 9Gz + tag: Tg +ingress: + className: ob + enabled: false + hosts: + - host: gH + paths: + - path: Ts + pathType: CGb + - path: "" + pathType: zZQ + - host: iiV3 + tls: + - hosts: + - tHQ4 + secretName: fnmcizOYm + - hosts: + - iPP + - 6ESVwf0d + - ziZck0N + secretName: O7mKv7 + - hosts: + - 8YGvchGJ + - wN + - XtvjzH0 + secretName: VlbaTuVK +initContainers: + extraInitContainers: thAoOYwQDaAt +livenessProbe: + exec: + command: + - nCg + - T6fzKjCjD + failureThreshold: 279778022 + grpc: + port: -995356959 + service: 9yOO2 + httpGet: + host: PYJSaHej + path: fr7 + port: 8Ij + scheme: QɄ揆ѧ鶹i骡l僴Ǎ植烤ĕǘqɦ + initialDelaySeconds: 1098820524 + periodSeconds: 414174316 + successThreshold: 1178515566 + terminationGracePeriodSeconds: -5729352865043664628 + timeoutSeconds: 873461419 +nameOverride: W7q3X +nodeSelector: + Bm9U: oTYglG6dh +podAnnotations: + eG: vxInc0 + g: BI6yk + xCtSP: rQ +podLabels: + ZEXh: zufy +podSecurityContext: + fsGroup: -3794452885502571644 + fsGroupChangePolicy: 欲飹Rɦ薕µL<Ĕ + runAsGroup: -3171560656159467191 + runAsNonRoot: true + runAsUser: -4412205905842408558 + supplementalGroups: + - -7215185124091152595 + - 5139656417921062736 + - 600742233156257714 + sysctls: + - name: Te + value: cKzihj +priorityClassName: l4Mowg +readinessProbe: + exec: + command: + - "" + - c8G + failureThreshold: 37001950 + grpc: + port: 1211428387 + service: UUKg3TJGP2 + httpGet: + host: eznD + path: aBohoOMPU + port: -2044766681 + scheme: 讻;Ǩ办鈁癃靟èʣ¾fǖ^Ǟ + initialDelaySeconds: -396024246 + periodSeconds: -1467409206 + successThreshold: -1328773613 + terminationGracePeriodSeconds: -8721653473984246810 + timeoutSeconds: -1781454259 +replicaCount: 46 +resources: + limits: + 8cdWaeK7jVrR: "0" + HYBi6o: "0" + requests: + NOz: "0" + gH: "0" +secret: + create: false + enterprise: + licenseSecretRef: + key: wNZRnHu3m + name: ULOBG + kafka: + awsMskIamSecretKey: RfMF + protobufGitBasicAuthPassword: julgURa4B + saslPassword: uuq + schemaRegistryPassword: "54" + schemaRegistryTlsCa: 0rjT0gsnw3 + schemaRegistryTlsCert: kpA9ZJQgp1 + schemaRegistryTlsKey: 4rfN + tlsCa: NhTEC0A + tlsCert: iN0W + tlsPassphrase: Id1ovgK + login: + github: + clientSecret: LWyKxwgV + personalAccessToken: Nkq1DyJixsC + google: + clientSecret: tJv + groupsServiceAccount: 9jqz4h + jwtSecret: PWdr6CcxS + oidc: + clientSecret: RMxiMIY + okta: + clientSecret: SJ6I + directoryApiToken: 1wIf + redpanda: + adminApi: + password: C9I2x + tlsCa: Qpp + tlsCert: "" + tlsKey: 7uh28L +secretMounts: +- defaultMode: 80 + name: Mt1 + path: WsSL4vxNxCkXP + secretName: ZxXI0Hhv +securityContext: + allowPrivilegeEscalation: false + capabilities: + add: + - Ɋ闻ǃɗʀd撪 + - 蘑ǪY桼ɮǚɳ爥ňB + drop: + - 乄}ñ0詘蛾牪坣缰ƩǏ薷©瓚`Ʋ虯r + - ǓJğ&ĊƯʝbǠCŪzgì + - ńǜ[ɪ判Uʋ]泘狔 + privileged: false + procMount: 媹:堏_ɟ榧禙Ɲ'瞟 + readOnlyRootFilesystem: false + runAsGroup: 2759228957449300312 + runAsNonRoot: true + runAsUser: -812867783664200775 +service: + annotations: + c: DNy + kDPtPpnL: kFmmx + nodePort: 377 + port: 311 + targetPort: 29 + type: l5gj +serviceAccount: + automountServiceAccountToken: true + create: true + name: sKa +strategy: + rollingUpdate: {} + type: 顓ǝSm +tests: + enabled: false +tolerations: +- effect: 嫜ʎ愤wßj硭 + key: JO1 + operator: ȼ¾Pȇ挮ƶȋ'蹑鶚嗵ïG + tolerationSeconds: -6027642013843151183 + value: a3XbyS +-- case-049 -- +affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: L + operator: 域%Ɠ礇!ʘl.ǷŠ该貹&N + values: + - oAk8rvkey + - Fb08GpumY + - key: YJGr + operator: '|4\i事!ų藦x鳜Ǫ' + values: + - 63Yvc + - key: j + operator: ¸瀖čņ!彅搀 + values: + - RnzdW + - Nxs + - unZuno + matchFields: + - key: wLP0QqdHBmd9e + operator: ȑwȼ嶢vC`ȖĜƐ桡牆ēIa,謧ŗ + - key: mdgmMZ + operator: Ō§ȶƔ>#Z骻5S洝岛Ċ啞. + values: + - Fvf6 + - key: GQsV + operator: 涥ȕêȩȋ婍0毙舺糩\DŽŅ饒 + values: + - XccQkxG + weight: -1172839714 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: JpS0BkW + operator: 聣耥ʒ昼|Ȏ)ß瞖a癨櫒缮{v + - key: HLL3gv + operator: 铡ÞC腢z蟒Á + - key: iDGQV8Bjyu5Q + operator: 舢脛歛ƻ68 + values: + - eLCH7Nc + - QQqPUN + - "" + matchFields: + - key: AY2q9fnL + operator: ȏ伌鎩5桀ʁ + values: + - Uac + - K0q + - bY71A + - key: rBwZz + operator: '*ĴȉǼ矼SN]ʛ源' + values: + - 5yMkn + - key: S1C + operator: ÿƙ彋,嘲樦 + values: + - OXH + - vl1 + - uCYaO8Cn + - {} + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: mZ3rAF9 + operator: yŲĺȫ阁笵W®詃Œ + values: + - bhvFz + - key: uiaNXZcXT + operator: "" + - key: AAM + operator: 閸鬼駝洁c奊(Ƅ謍MǍ辰T堍癩)丗 + values: + - "9" + - ESiN3 + matchLabels: + kCSDZtsm5: vVk + oBlyCq: jlh + matchLabelKeys: + - BCZ8FFbh + - A + namespaceSelector: + matchExpressions: + - key: Lsf + operator: L + values: + - a0HB + - C + - key: eoj6ic3 + operator: ż伌oA汄俔ɿ7巪娻% + matchLabels: + Cx: wwPPM + namespaces: + - 9xhG + - JAutZqe4gGeuf + - "" + topologyKey: 1a + weight: 223935020 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: LtGRhs + operator: 棺ǔ'ɘ砒Æ擑Ɵģ + values: + - GhM4BSJqNOf + matchLabels: + "": 7Ni + matchLabelKeys: + - yxF4 + - 22RoWr + - etRteovEh9 + mismatchLabelKeys: + - 7NOfe + namespaceSelector: + matchExpressions: + - key: 3KCX2 + operator: 臞ʀ¯弄Ɨ橎琜ġ鍳¶ȣ2墛.ɮ濎ɕ磞 + values: + - 5YiE0xEC + - 4spxMd + - vUPA + matchLabels: + YHIq: nS + topologyKey: F4 + weight: 716052627 + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: "9" + operator: ĠƑȥ兾3ŶJ + - key: pPvuyWZ + operator: ;bļo刲+圊}MǏŅ惤ć + values: + - 9pMXT + - Ezwo11 + matchLabels: + 66347W: ccFxZoF9 + X: VrN5kt + mismatchLabelKeys: + - u4LyY1 + - zT + namespaceSelector: + matchExpressions: + - key: qwhutJo + operator: 垴ǞƼ + matchLabels: + OFxMkYx: lhxtM + topologyKey: WN8qbUgigF + weight: -1609734055 + - podAffinityTerm: + labelSelector: {} + matchLabelKeys: + - "" + mismatchLabelKeys: + - XnhP + - "" + - Bk + namespaceSelector: + matchExpressions: + - key: M + operator: Ǽ糨ʡ毺Ɇw + values: + - ntvI + - vs + matchLabels: + "4": 2Y2FBpcbg + namespaces: + - 1S8c + topologyKey: jxiZ4d + weight: 1993833508 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: EpKkdimp + operator: 额ƀ箰L禼aÅ顙)C舉 + - key: e2Zu7Kb + operator: t潱髦pö鵺b澁6銹 + values: + - z9n + - LdMQ + - r + matchLabels: + F: Nc + Qa2h5toVwd: GGxZ3BQ + l: Z6Rh + matchLabelKeys: + - LsCC + - dgmxxZW + mismatchLabelKeys: + - e + - Cb + - e0DAEluN + namespaceSelector: + matchLabels: + oJ56D: 33m + tkP8tO: mIkfyE6E + namespaces: + - VxN + - hbwB9 + - t + topologyKey: qag0unul +annotations: + BceQMZiOm: E1uakdHPkLNL +automountServiceAccountToken: true +autoscaling: + enabled: true + maxReplicas: 292 + minReplicas: 381 + targetCPUUtilizationPercentage: 255 + targetMemoryUtilizationPercentage: 99 +commonLabels: + 0HYkOrz: JCwpSW + 0TgDztQSY: P + ztm: qegfb80 +configmap: + create: false +console: + roleBindings: + - K: null + nGSYV: null + roles: + - {} +deployment: + create: true +enterprise: + licenseSecretRef: + key: yAo51i + name: blNvk6O7Urx +extraContainers: +- args: + - kn0F9 + command: + - M + - Hph3 + - lZfWKF + env: + - name: HBWtNh10A + value: 8guE + valueFrom: + configMapKeyRef: + key: Chnm + name: UlwzEQ + optional: false + fieldRef: + apiVersion: 8pq9 + fieldPath: qpnfP4p + resourceFieldRef: + divisor: "0" + resource: L0tn + secretKeyRef: + key: J + name: gbfgF + optional: true + envFrom: + - configMapRef: + name: n32MM + optional: true + prefix: cp3 + secretRef: + name: Uc + optional: true + - configMapRef: + name: VGBL + optional: true + prefix: NTMU + secretRef: + name: CEg + optional: true + image: zIWYBi7 + imagePullPolicy: 蘂ȱʃ& + lifecycle: + postStart: + exec: + command: + - QpTcv + - MS0T0N + - wiE + httpGet: + host: ZCUJOIH + path: UsXT + port: 8nExSP2u + scheme: 'uŊ6熀: 焆 烷ʫ-Ŗ亾ɣʖ氝"肰' + sleep: + seconds: -2519616411083819638 + preStop: + exec: + command: + - rmQ7 + - GxRXQk + httpGet: + host: UIVpXMrzW + path: 4tHQ + port: 8xLK1VyM + scheme: ƳǃóɃȊ{回żz闓葊G嚥 + sleep: + seconds: 3595323074300269449 + livenessProbe: + exec: {} + failureThreshold: -882825879 + grpc: + port: 503069299 + service: W + httpGet: + host: FilCCd + path: NPZrCEq + port: 6NoPho8wIsxe + scheme: āȹ顺悩錣Xƕ灄ĿG乒 + initialDelaySeconds: 781680731 + periodSeconds: 205458 + successThreshold: 1115648780 + terminationGracePeriodSeconds: 4579765768791485272 + timeoutSeconds: -676867842 + name: 2tf + readinessProbe: + exec: + command: + - edKf + - 0U + - MFr2Oh + failureThreshold: 1812906550 + grpc: + port: -791379232 + service: IAqADBco + httpGet: + host: 55GZ + path: AQC + port: sxTXcp + scheme: ƷMg靚珨嘸ȗʒ鑉Ȝ梒ŗǐkōĕĵ鞍 + initialDelaySeconds: -130429301 + periodSeconds: 876742351 + successThreshold: -1424043483 + terminationGracePeriodSeconds: -1574530902871555383 + timeoutSeconds: 764935409 + resources: + limits: + 9eHi: "0" + rO52puR: "0" + requests: + UF8LV7N: "0" + ao: "0" + cRVsAz8v: "0" + restartPolicy: ɥ]×璳 + securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - ɖ膵7&ʞíXĦx-ǰİɾ榩聨ŗ% + - DŽ熲鴼玜覲杷ȆƠ沺伤{拢 + - ɉȋʠRÂo霾噜奩ƻv$Áő + drop: + - ɑ摿愻J«ʘA宜ƹ¶ + - 餫aJ矐sǁ隑z36渢X赼 + - )ǜ鄰挺溒ŒV栜Ù涸JH-_d + privileged: false + procMount: Ito縎 + readOnlyRootFilesystem: false + runAsGroup: 2484782727894659713 + runAsNonRoot: false + runAsUser: -6936271037843914749 + startupProbe: + exec: + command: + - X + failureThreshold: -256045507 + grpc: + port: 376282302 + service: wdQrDn0 + httpGet: + host: teaO6 + path: DBHpGkYdgAJ + port: -1625640156 + scheme: Ʌ + initialDelaySeconds: 673272264 + periodSeconds: -1050905915 + successThreshold: 282500457 + terminationGracePeriodSeconds: 5768805478519709604 + timeoutSeconds: -601307290 + stdinOnce: true + terminationMessagePath: POO + terminationMessagePolicy: '#d鿂Hk閎=ɰ蜐ġOʡ蠁żǖ' + tty: true + workingDir: Z3pdGL +- args: + - a7Tqs + - UuID5t + - gRCnbjyp + env: + - name: ZV1KP + value: WrT0 + valueFrom: + configMapKeyRef: + key: zZzTgax + name: 3z3eoets + optional: true + fieldRef: + apiVersion: 88zo + fieldPath: z0vE72 + resourceFieldRef: + containerName: DF4t + divisor: "0" + resource: hfVfYFW4 + secretKeyRef: + key: I6JwpO5 + name: I88w22gsx3 + optional: true + - name: z8 + value: sgj8UHZ + valueFrom: + configMapKeyRef: + key: Q85vN + name: lYGl4 + optional: true + fieldRef: + apiVersion: oQu7 + fieldPath: TYd + resourceFieldRef: + containerName: "Y" + divisor: "0" + resource: Yx + secretKeyRef: + key: f + name: 0Pjf9YBj + optional: false + envFrom: + - configMapRef: + name: fAH + optional: false + prefix: vjjU + secretRef: + name: 9A8OgEQ9 + optional: false + image: R7L + imagePullPolicy: '}m6铤<豎ŵ,#M狥ʬo' + lifecycle: + postStart: + exec: + command: + - 2E + - gzntg + httpGet: + host: BOoVI + path: ns7ZMdNwQC + port: XF + scheme: ky咊ʅ ʂ娼ȟƐ橽ǿ唔ARɨ罙 + sleep: + seconds: -3978858376823543730 + preStop: + exec: + command: + - Hns + httpGet: + host: Lw8 + path: wdo + port: -239095421 + scheme: ƹ禍OÇ + sleep: + seconds: 3838288160382433952 + livenessProbe: + exec: + command: + - 8E + failureThreshold: -1052479375 + grpc: + port: 82058135 + service: S3UA2HwQaN + httpGet: + host: T0 + path: wYV6 + port: cEf + scheme: 斡1{嘫b葎剜屙唯皎図Ǜ錮ơxȒt駦Ƨ + initialDelaySeconds: -1976610733 + periodSeconds: 436460884 + successThreshold: -949159248 + terminationGracePeriodSeconds: 1786907735670591108 + timeoutSeconds: -2035324376 + name: 0ygO + readinessProbe: + exec: + command: + - "" + - YQ + failureThreshold: 1469514474 + grpc: + port: -1835111333 + service: 5WmTypZfT + httpGet: + host: BDf + path: ZY + port: tyrBXIqhX + scheme: 趬扬鉰昵 + initialDelaySeconds: -683847692 + periodSeconds: -95594828 + successThreshold: -1707399501 + terminationGracePeriodSeconds: 3256417681193515380 + timeoutSeconds: -2088454060 + resources: + limits: + zVX: "0" + restartPolicy: 晄d塮@ʥO%驮ÆgǍô + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ' 吓zǘa畷' + - 鲃ʍ瑘ƴɛjV艑ǔpMK杣Ġ + privileged: true + procMount: zɱÙŭǫäƿ诧聉ń醽Ƥ裩5 + readOnlyRootFilesystem: true + runAsGroup: -2381715627246700598 + runAsNonRoot: false + runAsUser: 6590063474480015904 + startupProbe: + exec: + command: + - "9" + - oRMM2F + - "" + failureThreshold: -1711876939 + grpc: + port: 1138187974 + service: OvdS + httpGet: + host: GZWJ + path: vzJeBCvGMHn7 + port: h9p1Pak + initialDelaySeconds: 447733263 + periodSeconds: 1805541821 + successThreshold: -1114184264 + terminationGracePeriodSeconds: 2730048172651207780 + timeoutSeconds: -1850805595 + terminationMessagePath: GK8 + terminationMessagePolicy: ɾDŽ÷郃ɻ玗璺,4 + volumeDevices: + - devicePath: bLf + name: UVN1o + - devicePath: fIT + name: Qiswb + - devicePath: 9b8i + name: h1 + workingDir: 1IOT +extraEnvFrom: +- configMapRef: + name: GTjM + optional: true + prefix: GSbKp + secretRef: + name: vhsV8Pl5 + optional: true +- configMapRef: + name: cvXs + optional: false + prefix: cBFtb + secretRef: + name: x9N + optional: false +- configMapRef: + name: rDSrOmdL + optional: false + prefix: 0u3 + secretRef: + name: A6PG37zBJfwNR + optional: false +extraVolumeMounts: +- mountPath: De7 + mountPropagation: 1k噟霞ƁĹ + name: 1Z2WnghTc + subPath: Ts5Ful + subPathExpr: YyidD +- mountPath: onM7c3 + mountPropagation: m=Cɬ + name: GC5ZsY07Mr + readOnly: true + subPath: Xt + subPathExpr: r6gZk +- mountPath: 8gPjX7hc + mountPropagation: ƃ柅珚ȭ能 + name: oN + subPath: auYcD + subPathExpr: aheb25w +fullnameOverride: 0BIfuN +image: + pullPolicy: õ鴀铑û + registry: RCYS61Exfql + repository: 8ZLfmymq + tag: 4BSL9iL +imagePullSecrets: +- name: h5x +ingress: + annotations: + q5IN: ehJ3uPo + zL3YTK: "3" + className: aflhQOHWYOXuZ3 + enabled: false + hosts: + - host: obOeJZKpH + - host: u1ac0 + paths: + - path: Riz + pathType: Oa0rGRl + - path: w2xzu + pathType: n2bXr + - path: a68 + pathType: S + tls: + - hosts: + - pgmng + - hosts: + - rxpJYOgPS + secretName: dMa7jxJF +initContainers: + extraInitContainers: N4zG +livenessProbe: + exec: + command: + - "8" + - hRb + - cFB + failureThreshold: -567921134 + grpc: + port: -512457609 + service: F01OY6OLj + httpGet: + host: C04PqGy + path: lMqUJbF + port: 381786117 + scheme: c隢ƖȂ賒Q'd{X旝ĤɪI,k4Ú + initialDelaySeconds: -507660572 + periodSeconds: 1912372611 + successThreshold: -232304560 + terminationGracePeriodSeconds: -4579383330955987300 + timeoutSeconds: 582403024 +nameOverride: 8dJzE +nodeSelector: + ra78: fJ +podAnnotations: + "": cuRn + qBdeU: EQv +podLabels: + O2n4u: kpFpu + g1c: XEOMg +podSecurityContext: + fsGroup: 6449559755791185949 + fsGroupChangePolicy: 慩梱ʂcƎƱ\火ɘ²ɉ_ + runAsGroup: 841256803887707704 + runAsNonRoot: true + runAsUser: -2824253868920734938 + supplementalGroups: + - 8145086042470336086 + - -5005570809576723279 +priorityClassName: JhGfjGXQ +readinessProbe: + exec: {} + failureThreshold: 1010917423 + grpc: + port: 1307350058 + service: TfOG + httpGet: + host: dKWY + path: Qr + port: -837347685 + scheme: C_ + initialDelaySeconds: -986314779 + periodSeconds: 1763110639 + successThreshold: 1473932979 + terminationGracePeriodSeconds: -4633283219964217670 + timeoutSeconds: 1291669389 +replicaCount: 308 +resources: + limits: + x6: "0" + requests: + eeR: "0" + l: "0" + xppI8xB: "0" +secret: + create: true + enterprise: + licenseSecretRef: + key: 6LDJ8t + name: 4n4q72vaO + kafka: + awsMskIamSecretKey: INqD5 + protobufGitBasicAuthPassword: SBJl + saslPassword: 78E + schemaRegistryPassword: YMuFCG7qR + schemaRegistryTlsCa: 1y5yRb6O2b + schemaRegistryTlsCert: NuhkhpMV7b + schemaRegistryTlsKey: 9zcrFj + tlsCa: 0PF + tlsCert: wArD + tlsPassphrase: bj3xqz + login: + github: + clientSecret: jdPGF7 + personalAccessToken: y6xqv + google: + clientSecret: m6FeI + groupsServiceAccount: xi1j27Lipj8 + jwtSecret: pg + oidc: + clientSecret: zbsTootC + okta: + clientSecret: rHSfT + directoryApiToken: rOXaN + redpanda: + adminApi: + password: 8c + tlsCa: CJbHIM + tlsCert: uO + tlsKey: uhB0L +secretMounts: +- defaultMode: 500 + name: 99SgdOsZD + path: AQpWvptFEk7y + secretName: B6Fq +- defaultMode: 337 + name: U + path: p44 + secretName: DddF02 +- defaultMode: 246 + name: WFd + path: UiI + secretName: tz +securityContext: + allowPrivilegeEscalation: false + capabilities: + add: + - 趩燡º嗂{踦 + - CƮ + drop: + - 殟kĔ=ņŧɋ] + privileged: false + procMount: aŻ釯fȠ埱ɺȚ + readOnlyRootFilesystem: true + runAsGroup: 4284419790643993066 + runAsNonRoot: true + runAsUser: -4828746969388386674 +service: + annotations: + L: CP + Yf: K4waOjMg + tIYLLgy: d1szIPW6xt + nodePort: 291 + port: 269 + targetPort: 479 + type: IfYfRoHRG +serviceAccount: + annotations: + 5bpPp: ponDVyZ + Ml1: "" + lt: 6VN8BRlJd + automountServiceAccountToken: true + create: true + name: z12W +strategy: + rollingUpdate: {} + type: 擺m鷾DžPĨ +tests: + enabled: true +tolerations: +- key: ka + tolerationSeconds: 2857628758439265098 + value: Ohni9QGx +topologySpreadConstraints: +- labelSelector: + matchLabels: + 3Ym: o2h5aVp + yR4PPZO: 3X + matchLabelKeys: + - vCKujB + - UqCFKCN + - Xnjfai + maxSkew: -943395897 + minDomains: 1955399000 + nodeAffinityPolicy: 噙撢馥櫱m>Q脕擏w梪 + nodeTaintsPolicy: 蝚溄鑝刉=歱Mr踄 + topologyKey: cHyq + whenUnsatisfiable: Q輒ƗȈʑǯƐ| +- labelSelector: + matchLabels: + E: lyK5b9t + UuSjduy: NcK4 + fty: iP6ai + maxSkew: 1881677866 + minDomains: -561571142 + nodeAffinityPolicy: ȫ寴ī嘌.樥'ǹs + nodeTaintsPolicy: ɇ剀ǨUǜ!俛dz餂~匹呃 + topologyKey: pCHj + whenUnsatisfiable: 尘I:Ƒ匌,騸 diff --git a/charts/redpanda/redpanda/5.9.2/charts/console/testdata/template-cases.golden.txtar b/charts/redpanda/redpanda/5.9.2/charts/console/testdata/template-cases.golden.txtar new file mode 100644 index 0000000000..cf65330d4f --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/console/testdata/template-cases.golden.txtar @@ -0,0 +1,24705 @@ +-- testdata/autoscaling-cpu.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +--- +# Source: console/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console +stringData: + enterprise-license: "" + kafka-protobuf-git-basicauth-password: "" + kafka-sasl-aws-msk-iam-secret-key: "" + kafka-sasl-password: "" + kafka-schema-registry-password: "" + kafka-schemaregistry-tls-ca: "" + kafka-schemaregistry-tls-cert: "" + kafka-schemaregistry-tls-key: "" + kafka-tls-ca: "" + kafka-tls-cert: "" + kafka-tls-key: "" + login-github-oauth-client-secret: "" + login-github-personal-access-token: "" + login-google-groups-service-account.json: "" + login-google-oauth-client-secret: "" + login-jwt-secret: SECRETKEY + login-oidc-client-secret: "" + login-okta-client-secret: "" + login-okta-directory-api-token: "" + redpanda-admin-api-password: "" + redpanda-admin-api-tls-ca: "" + redpanda-admin-api-tls-cert: "" + redpanda-admin-api-tls-key: "" +type: Opaque +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +spec: + ports: + - name: http + port: 8080 + protocol: TCP + targetPort: 0 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + type: ClusterIP +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +spec: + replicas: null + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + strategy: {} + template: + metadata: + annotations: + checksum/config: 4f717eb67ef3f4c7e8737af0264bfe0922c76494c9ee31f7f52c63a13b02de86 + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + spec: + affinity: {} + automountServiceAccountToken: true + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: LOGIN_JWTSECRET + valueFrom: + secretKeyRef: + key: login-jwt-secret + name: console + envFrom: [] + image: docker.redpanda.com/redpandadata/console:v2.7.0 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 0 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: console + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: {} + securityContext: + runAsNonRoot: true + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: /etc/console/secrets + name: secrets + readOnly: true + imagePullSecrets: [] + initContainers: [] + nodeSelector: {} + priorityClassName: "" + securityContext: + fsGroup: 99 + runAsUser: 99 + serviceAccountName: console + tolerations: [] + topologySpreadConstraints: [] + volumes: + - configMap: + name: console + name: configs + - name: secrets + secret: + secretName: console +--- +# Source: console/templates/hpa.yaml +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console +spec: + maxReplicas: 100 + metrics: + - resource: + name: cpu + target: + averageUtilization: 80 + type: Utilization + type: Resource + - resource: + name: memory + target: + averageUtilization: 10 + type: Utilization + type: Resource + minReplicas: 1 + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: console +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "console-test-connection" + namespace: "default" + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['console:8080'] + restartPolicy: Never + priorityClassName: +-- testdata/autoscaling-memory.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +--- +# Source: console/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console +stringData: + enterprise-license: "" + kafka-protobuf-git-basicauth-password: "" + kafka-sasl-aws-msk-iam-secret-key: "" + kafka-sasl-password: "" + kafka-schema-registry-password: "" + kafka-schemaregistry-tls-ca: "" + kafka-schemaregistry-tls-cert: "" + kafka-schemaregistry-tls-key: "" + kafka-tls-ca: "" + kafka-tls-cert: "" + kafka-tls-key: "" + login-github-oauth-client-secret: "" + login-github-personal-access-token: "" + login-google-groups-service-account.json: "" + login-google-oauth-client-secret: "" + login-jwt-secret: SECRETKEY + login-oidc-client-secret: "" + login-okta-client-secret: "" + login-okta-directory-api-token: "" + redpanda-admin-api-password: "" + redpanda-admin-api-tls-ca: "" + redpanda-admin-api-tls-cert: "" + redpanda-admin-api-tls-key: "" +type: Opaque +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +spec: + ports: + - name: http + port: 8080 + protocol: TCP + targetPort: 0 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + type: ClusterIP +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +spec: + replicas: null + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + strategy: {} + template: + metadata: + annotations: + checksum/config: 4f717eb67ef3f4c7e8737af0264bfe0922c76494c9ee31f7f52c63a13b02de86 + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + spec: + affinity: {} + automountServiceAccountToken: true + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: LOGIN_JWTSECRET + valueFrom: + secretKeyRef: + key: login-jwt-secret + name: console + envFrom: [] + image: docker.redpanda.com/redpandadata/console:v2.7.0 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 0 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: console + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: {} + securityContext: + runAsNonRoot: true + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: /etc/console/secrets + name: secrets + readOnly: true + imagePullSecrets: [] + initContainers: [] + nodeSelector: {} + priorityClassName: "" + securityContext: + fsGroup: 99 + runAsUser: 99 + serviceAccountName: console + tolerations: [] + topologySpreadConstraints: [] + volumes: + - configMap: + name: console + name: configs + - name: secrets + secret: + secretName: console +--- +# Source: console/templates/hpa.yaml +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console +spec: + maxReplicas: 100 + metrics: + - resource: + name: cpu + target: + averageUtilization: 14 + type: Utilization + type: Resource + minReplicas: 1 + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: console +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "console-test-connection" + namespace: "default" + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['console:8080'] + restartPolicy: Never + priorityClassName: +-- testdata/autoscaling-nulls.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +--- +# Source: console/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console +stringData: + enterprise-license: "" + kafka-protobuf-git-basicauth-password: "" + kafka-sasl-aws-msk-iam-secret-key: "" + kafka-sasl-password: "" + kafka-schema-registry-password: "" + kafka-schemaregistry-tls-ca: "" + kafka-schemaregistry-tls-cert: "" + kafka-schemaregistry-tls-key: "" + kafka-tls-ca: "" + kafka-tls-cert: "" + kafka-tls-key: "" + login-github-oauth-client-secret: "" + login-github-personal-access-token: "" + login-google-groups-service-account.json: "" + login-google-oauth-client-secret: "" + login-jwt-secret: SECRETKEY + login-oidc-client-secret: "" + login-okta-client-secret: "" + login-okta-directory-api-token: "" + redpanda-admin-api-password: "" + redpanda-admin-api-tls-ca: "" + redpanda-admin-api-tls-cert: "" + redpanda-admin-api-tls-key: "" +type: Opaque +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +spec: + ports: + - name: http + port: 8080 + protocol: TCP + targetPort: 0 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + type: ClusterIP +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +spec: + replicas: null + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + strategy: {} + template: + metadata: + annotations: + checksum/config: 4f717eb67ef3f4c7e8737af0264bfe0922c76494c9ee31f7f52c63a13b02de86 + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + spec: + affinity: {} + automountServiceAccountToken: true + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: LOGIN_JWTSECRET + valueFrom: + secretKeyRef: + key: login-jwt-secret + name: console + envFrom: [] + image: docker.redpanda.com/redpandadata/console:v2.7.0 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 0 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: console + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: {} + securityContext: + runAsNonRoot: true + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: /etc/console/secrets + name: secrets + readOnly: true + imagePullSecrets: [] + initContainers: [] + nodeSelector: {} + priorityClassName: "" + securityContext: + fsGroup: 99 + runAsUser: 99 + serviceAccountName: console + tolerations: [] + topologySpreadConstraints: [] + volumes: + - configMap: + name: console + name: configs + - name: secrets + secret: + secretName: console +--- +# Source: console/templates/hpa.yaml +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console +spec: + maxReplicas: 100 + metrics: + - resource: + name: cpu + target: + averageUtilization: 80 + type: Utilization + type: Resource + minReplicas: 1 + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: console +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "console-test-connection" + namespace: "default" + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['console:8080'] + restartPolicy: Never + priorityClassName: +-- testdata/case-000.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: false +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + "": 31q1Pbz + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: "n" + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: HRoLg + namespace: default +--- +# Source: console/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + labels: + "": 31q1Pbz + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: "n" + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: hvGoJL +stringData: + enterprise-license: "" + kafka-protobuf-git-basicauth-password: "" + kafka-sasl-aws-msk-iam-secret-key: "" + kafka-sasl-password: "" + kafka-schema-registry-password: "" + kafka-schemaregistry-tls-ca: "" + kafka-schemaregistry-tls-cert: "" + kafka-schemaregistry-tls-key: "" + kafka-tls-ca: "" + kafka-tls-cert: "" + kafka-tls-key: "" + login-github-oauth-client-secret: "" + login-github-personal-access-token: "" + login-google-groups-service-account.json: "" + login-google-oauth-client-secret: "" + login-jwt-secret: SECRETKEY + login-oidc-client-secret: "" + login-okta-client-secret: "" + login-okta-directory-api-token: "" + redpanda-admin-api-password: "" + redpanda-admin-api-tls-ca: "" + redpanda-admin-api-tls-cert: "" + redpanda-admin-api-tls-key: "" +type: Opaque +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + "": 31q1Pbz + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: "n" + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: hvGoJL +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + "": 31q1Pbz + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: "n" + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: hvGoJL + namespace: default +spec: + ports: + - name: http + port: 8080 + protocol: TCP + targetPort: 0 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: "n" + type: ClusterIP +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + Q9AVJD4: G9TEnp + creationTimestamp: null + labels: + "": 31q1Pbz + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: "n" + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: hvGoJL + namespace: default +spec: + replicas: 387 + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: "n" + strategy: + type: Ò泆A + template: + metadata: + annotations: + checksum/config: a2b60d22337ad49c09f2108d08f05fc6590bc4b45c804adc901467f348d564e1 + lyW: mn + pjq6fDr: YA2w301 + uXvFB: VQ5gP9 + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: "n" + spec: + affinity: {} + automountServiceAccountToken: true + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: Z2BpO + value: 0ggF3ha7D + - name: LOGIN_JWTSECRET + valueFrom: + secretKeyRef: + key: login-jwt-secret + name: hvGoJL + envFrom: [] + image: docker.redpanda.com/redpandadata/console:v2.7.0 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 1028486626 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 1713123405 + periodSeconds: -1411200119 + successThreshold: -1362510905 + timeoutSeconds: 1375594715 + name: console + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + limits: + x0StjCjt: "0" + securityContext: + runAsNonRoot: true + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: /etc/console/secrets + name: secrets + readOnly: true + imagePullSecrets: [] + initContainers: [] + nodeSelector: {} + priorityClassName: vQhDS + securityContext: + fsGroup: 99 + runAsUser: 99 + serviceAccountName: HRoLg + tolerations: [] + topologySpreadConstraints: [] + volumes: + - configMap: + name: hvGoJL + name: configs + - name: secrets + secret: + secretName: hvGoJL + - name: 7iCCax + - name: meEH + - name: xYVSV +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "hvGoJL-test-connection" + namespace: "default" + labels: + "": 31q1Pbz + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: "n" + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['hvGoJL:8080'] + restartPolicy: Never + priorityClassName: vQhDS +-- testdata/case-001.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: Sh + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: T50cZi + namespace: default +--- +# Source: console/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: Sh + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: T50cZi +stringData: + enterprise-license: "" + kafka-protobuf-git-basicauth-password: "" + kafka-sasl-aws-msk-iam-secret-key: "" + kafka-sasl-password: "" + kafka-schema-registry-password: "" + kafka-schemaregistry-tls-ca: "" + kafka-schemaregistry-tls-cert: "" + kafka-schemaregistry-tls-key: "" + kafka-tls-ca: "" + kafka-tls-cert: "" + kafka-tls-key: "" + login-github-oauth-client-secret: "" + login-github-personal-access-token: "" + login-google-groups-service-account.json: "" + login-google-oauth-client-secret: "" + login-jwt-secret: SECRETKEY + login-oidc-client-secret: "" + login-okta-client-secret: "" + login-okta-directory-api-token: "" + redpanda-admin-api-password: "" + redpanda-admin-api-tls-ca: "" + redpanda-admin-api-tls-cert: "" + redpanda-admin-api-tls-key: "" +type: Opaque +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: Sh + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: T50cZi +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: Sh + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: T50cZi + namespace: default +spec: + ports: + - name: http + port: 8080 + protocol: TCP + targetPort: 0 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: Sh + type: ClusterIP +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: Sh + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: T50cZi + namespace: default +spec: + replicas: 414 + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: Sh + strategy: {} + template: + metadata: + annotations: + checksum/config: 6eb5d8456a652d5006051c8425191238a1a7d39e93a9336b0cc8ca98963c2dbd + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: Sh + spec: + affinity: {} + automountServiceAccountToken: true + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: 3Nf + value: vATdo0CH + valueFrom: + configMapKeyRef: + key: IRw5 + name: fa + fieldRef: + apiVersion: 93Fjhay + fieldPath: LRa2I + - name: T0 + value: trXO4 + - name: P9hPooVH + value: yii5lolb + valueFrom: + configMapKeyRef: + key: spAKa + name: U0EYAAe0 + - name: LOGIN_JWTSECRET + valueFrom: + secretKeyRef: + key: login-jwt-secret + name: T50cZi + envFrom: [] + image: docker.redpanda.com/redpandadata/console:v2.7.0 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 0 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: console + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: {} + securityContext: + runAsNonRoot: true + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: /etc/console/secrets + name: secrets + readOnly: true + - image: LlCU3if + imagePullPolicy: RɷVȄ×ʤǫĠ侻Ɏźx跻Å榜 + lifecycle: {} + name: l0 + resources: {} + securityContext: + allowPrivilegeEscalation: true + privileged: true + startupProbe: + exec: {} + failureThreshold: -1510490758 + initialDelaySeconds: 112782468 + periodSeconds: -738545847 + successThreshold: -1801864225 + timeoutSeconds: 1026753125 + terminationMessagePath: gCG + terminationMessagePolicy: hmƂÚÕʏ疅耪鯉瓉Ɏ煐8qĺ + tty: true + workingDir: ixD7Jq + imagePullSecrets: [] + initContainers: + - 'error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string + into Go value of type []interface {}' + nodeSelector: {} + priorityClassName: NyOpfr + securityContext: + fsGroup: 99 + runAsUser: 99 + serviceAccountName: T50cZi + tolerations: + - effect: Mǣ鍙x奬Ø裗Ʈ唿踣ʘ)ɒâÄ + key: AWx + operator: yīÄLJʑʢ避 + value: cO + - effect: ï楡ɜƐf鱖À夹ǙȤK + key: Gk23T + operator: è6槈$_ȋ6}rvĕ曉¸顋ŀÓ + value: DCkzy + - effect: 蠯u牰ŇɔnÜȎĤ原H + key: qSC + operator: "n" + tolerationSeconds: -7696192156323826000 + value: z + topologySpreadConstraints: [] + volumes: + - configMap: + name: T50cZi + name: configs + - name: secrets + secret: + secretName: T50cZi +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "T50cZi-test-connection" + namespace: "default" + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: Sh + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['T50cZi:8080'] + restartPolicy: Never + priorityClassName: NyOpfr +-- testdata/case-002.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: vN4yH7I + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: R1Yar8 + namespace: default +--- +# Source: console/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: vN4yH7I + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: xZty +stringData: + enterprise-license: "" + kafka-protobuf-git-basicauth-password: "" + kafka-sasl-aws-msk-iam-secret-key: "" + kafka-sasl-password: "" + kafka-schema-registry-password: "" + kafka-schemaregistry-tls-ca: "" + kafka-schemaregistry-tls-cert: "" + kafka-schemaregistry-tls-key: "" + kafka-tls-ca: "" + kafka-tls-cert: "" + kafka-tls-key: "" + login-github-oauth-client-secret: "" + login-github-personal-access-token: "" + login-google-groups-service-account.json: "" + login-google-oauth-client-secret: "" + login-jwt-secret: SECRETKEY + login-oidc-client-secret: "" + login-okta-client-secret: "" + login-okta-directory-api-token: "" + redpanda-admin-api-password: "" + redpanda-admin-api-tls-ca: "" + redpanda-admin-api-tls-cert: "" + redpanda-admin-api-tls-key: "" +type: Opaque +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: vN4yH7I + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: xZty +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: vN4yH7I + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: xZty + namespace: default +spec: + ports: + - name: http + port: 413 + protocol: TCP + targetPort: 267 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: vN4yH7I + type: ILpSX2Cy +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: vN4yH7I + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: xZty + namespace: default +spec: + replicas: 417 + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: vN4yH7I + strategy: {} + template: + metadata: + annotations: + 8vRMfVroYC2: QXbUbLea + VV4w: s4sL + checksum/config: 69703ab54946efe744831224dacdb980663f666d8fa5be794fb800135f91d11f + upwTMuIqflmD: 9J0H45zXX + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: vN4yH7I + spec: + affinity: {} + automountServiceAccountToken: true + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: LOGIN_JWTSECRET + valueFrom: + secretKeyRef: + key: login-jwt-secret + name: xZty + envFrom: + - prefix: cfVf + secretRef: + name: ha + - prefix: i2E2Jvnc + image: docker.redpanda.com/redpandadata/console:v2.7.0 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 0 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: console + ports: + - containerPort: 267 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + limits: + 27ywV: "0" + nMnjjF4kM: "0" + xar2JX: "0" + securityContext: + runAsNonRoot: true + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: /etc/console/secrets + name: secrets + readOnly: true + - mountPath: Y40 + mountPropagation: $寕洦敬苖ēRõøȀ + name: vn5hd + readOnly: true + subPath: oXCY9 + subPathExpr: p + imagePullSecrets: + - {} + - name: YPVBzxvx + initContainers: [] + nodeSelector: {} + priorityClassName: TeCy + securityContext: + fsGroup: 99 + runAsUser: 99 + serviceAccountName: R1Yar8 + tolerations: + - effect: ǩ趥螏|F8ǻĬ嵍Ğ错ʂĺƠǷ俆峻噸 + key: b + operator: wąȹV{İ刡嚮ȜJ + value: ZuTw + - effect: D稕栥[Ǟ$焫昲 + key: NnhmxYy + operator: Xʀ + value: v65W + - effect: 岂bĤ晏#DĢº + key: MOgT + operator: 礩懜蹻ǍBȟvɸ堊 + value: 3iXh + topologySpreadConstraints: [] + volumes: + - configMap: + name: xZty + name: configs + - name: secrets + secret: + secretName: xZty +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "xZty-test-connection" + namespace: "default" + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: vN4yH7I + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + imagePullSecrets: + - {} + - name: YPVBzxvx + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['xZty:413'] + restartPolicy: Never + priorityClassName: TeCy +-- testdata/case-003.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: w6 + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: 8nE + namespace: default +--- +# Source: console/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: w6 + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: 8nE +stringData: + enterprise-license: "" + kafka-protobuf-git-basicauth-password: Fb + kafka-sasl-aws-msk-iam-secret-key: SrYY84t + kafka-sasl-password: xCc3TeVY + kafka-schema-registry-password: ovCqxwz9Bf + kafka-schemaregistry-tls-ca: JL + kafka-schemaregistry-tls-cert: cS + kafka-schemaregistry-tls-key: UMwYx4F + kafka-tls-ca: HFpsnPdw + kafka-tls-cert: hseIt + kafka-tls-key: "" + login-github-oauth-client-secret: "" + login-github-personal-access-token: "" + login-google-groups-service-account.json: "" + login-google-oauth-client-secret: "" + login-jwt-secret: SECRETKEY + login-oidc-client-secret: "" + login-okta-client-secret: "" + login-okta-directory-api-token: "" + redpanda-admin-api-password: "" + redpanda-admin-api-tls-ca: "" + redpanda-admin-api-tls-cert: "" + redpanda-admin-api-tls-key: "" +type: Opaque +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: w6 + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: 8nE + namespace: default +spec: + ports: + - name: http + port: 8080 + protocol: TCP + targetPort: 0 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: w6 + type: ClusterIP +--- +# Source: console/templates/ingress.yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: w6 + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: 8nE +spec: + ingressClassName: EqUYi + rules: + - host: bKQCmfZ + http: + paths: null + - host: djItx5GtejC6 + http: + paths: null + - host: 2wLaQU8 + http: + paths: null + tls: + - hosts: + - V8BpuMCig + - 7LqG4w92 + - el3u4v + secretName: nUlu5bMwB8 + - hosts: + - 4HLzq + - 2i4g + secretName: lSgQIKwj5 +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "8nE-test-connection" + namespace: "default" + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: w6 + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['8nE:8080'] + restartPolicy: Never + priorityClassName: HNqN9h2 +-- testdata/case-004.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + "": PtQ7JxIAdPjt + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: YMl + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console-YMl + namespace: default +--- +# Source: console/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + labels: + "": PtQ7JxIAdPjt + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: YMl + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console-YMl +stringData: + enterprise-license: "" + kafka-protobuf-git-basicauth-password: "" + kafka-sasl-aws-msk-iam-secret-key: "" + kafka-sasl-password: "" + kafka-schema-registry-password: "" + kafka-schemaregistry-tls-ca: "" + kafka-schemaregistry-tls-cert: "" + kafka-schemaregistry-tls-key: "" + kafka-tls-ca: "" + kafka-tls-cert: "" + kafka-tls-key: "" + login-github-oauth-client-secret: "" + login-github-personal-access-token: "" + login-google-groups-service-account.json: "" + login-google-oauth-client-secret: "" + login-jwt-secret: SECRETKEY + login-oidc-client-secret: "" + login-okta-client-secret: "" + login-okta-directory-api-token: "" + redpanda-admin-api-password: "" + redpanda-admin-api-tls-ca: "" + redpanda-admin-api-tls-cert: "" + redpanda-admin-api-tls-key: "" +type: Opaque +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + "": PtQ7JxIAdPjt + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: YMl + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console-YMl +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + "": PtQ7JxIAdPjt + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: YMl + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console-YMl + namespace: default +spec: + ports: + - name: http + port: 112 + protocol: TCP + targetPort: 173 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: YMl + type: dO7eovC +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: {} + creationTimestamp: null + labels: + "": PtQ7JxIAdPjt + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: YMl + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console-YMl + namespace: default +spec: + replicas: 261 + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: YMl + strategy: + type: ɡv?ĨJ姯ɚƟć匪cb + template: + metadata: + annotations: + 1iK8Ic: Qo3FCg9qi + 63SsVxDT: v + A1Q4J4: U9jygY2t1F + checksum/config: 5f83295c905c2d3c9fea06172a38428a89334248aea9df0ebd8b589a29afeb4f + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: YMl + spec: + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: {} + weight: -1713447377 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: null + podAntiAffinity: {} + automountServiceAccountToken: true + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: LOGIN_JWTSECRET + valueFrom: + secretKeyRef: + key: login-jwt-secret + name: console-YMl + envFrom: [] + image: docker.redpanda.com/redpandadata/console:v2.7.0 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 0 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: console + ports: + - containerPort: 173 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: {} + securityContext: + runAsNonRoot: true + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: /etc/console/secrets + name: secrets + readOnly: true + - mountPath: Oj + name: QmzFlXE + subPath: "" + imagePullSecrets: [] + initContainers: [] + nodeSelector: {} + priorityClassName: JT0MK + securityContext: + fsGroup: 99 + runAsUser: 99 + serviceAccountName: console-YMl + tolerations: [] + topologySpreadConstraints: [] + volumes: + - configMap: + name: console-YMl + name: configs + - name: secrets + secret: + secretName: console-YMl + - name: QmzFlXE + secret: + defaultMode: 197 + secretName: 7gi +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "console-YMl-test-connection" + namespace: "default" + labels: + "": PtQ7JxIAdPjt + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: YMl + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['console-YMl:112'] + restartPolicy: Never + priorityClassName: JT0MK +-- testdata/case-005.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: MW + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: pN + namespace: default +--- +# Source: console/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: MW + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: pN +stringData: + enterprise-license: "" + kafka-protobuf-git-basicauth-password: "" + kafka-sasl-aws-msk-iam-secret-key: "" + kafka-sasl-password: "" + kafka-schema-registry-password: "" + kafka-schemaregistry-tls-ca: "" + kafka-schemaregistry-tls-cert: "" + kafka-schemaregistry-tls-key: "" + kafka-tls-ca: "" + kafka-tls-cert: "" + kafka-tls-key: "" + login-github-oauth-client-secret: R4Zj + login-github-personal-access-token: N85av + login-google-groups-service-account.json: "" + login-google-oauth-client-secret: "" + login-jwt-secret: SECRETKEY + login-oidc-client-secret: enei1WIcV + login-okta-client-secret: "" + login-okta-directory-api-token: "" + redpanda-admin-api-password: "" + redpanda-admin-api-tls-ca: "" + redpanda-admin-api-tls-cert: "" + redpanda-admin-api-tls-key: "" +type: Opaque +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: MW + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: pN + namespace: default +spec: + ports: + - name: http + port: 8080 + protocol: TCP + targetPort: 0 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: MW + type: ClusterIP +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: MW + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: pN + namespace: default +spec: + replicas: 396 + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: MW + strategy: {} + template: + metadata: + annotations: + checksum/config: 74234e98afe7498fb5daf1f36ac2d78acc339464f950703b8c019892f982b90b + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: MW + spec: + affinity: {} + automountServiceAccountToken: true + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: LOGIN_JWTSECRET + valueFrom: + secretKeyRef: + key: login-jwt-secret + name: pN + - name: LOGIN_GITHUB_CLIENTSECRET + valueFrom: + secretKeyRef: + key: login-github-oauth-client-secret + name: pN + - name: LOGIN_GITHUB_DIRECTORY_PERSONALACCESSTOKEN + valueFrom: + secretKeyRef: + key: login-github-personal-access-token + name: pN + - name: LOGIN_OIDC_CLIENTSECRET + valueFrom: + secretKeyRef: + key: login-oidc-client-secret + name: pN + envFrom: [] + image: 7iw15D/RnJFs0:OQDirE + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: -1921365096 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: -1548958176 + periodSeconds: -1952555242 + successThreshold: -1289242499 + timeoutSeconds: -265051013 + name: console + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: {} + securityContext: + runAsNonRoot: true + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: /etc/console/secrets + name: secrets + readOnly: true + - mountPath: JU4z + name: QEJyD + subPath: ZBEy2m0m + subPathExpr: S1Kk + - mountPath: RjUw5sX7NP + name: ett1n + subPath: NmZKwz + subPathExpr: QOMT + imagePullSecrets: + - name: ATcT6Hd + - name: l15Hhw + initContainers: + - 'error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string + into Go value of type []interface {}' + nodeSelector: {} + priorityClassName: KnLhcy2cw + securityContext: + fsGroup: 99 + runAsUser: 99 + serviceAccountName: pN + tolerations: [] + topologySpreadConstraints: [] + volumes: + - configMap: + name: pN + name: configs + - name: secrets + secret: + secretName: pN +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "pN-test-connection" + namespace: "default" + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: MW + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + imagePullSecrets: + - name: ATcT6Hd + - name: l15Hhw + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['pN:8080'] + restartPolicy: Never + priorityClassName: KnLhcy2cw +-- testdata/case-006.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: false +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: gCH15URsJZr + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: nd7TSb2mNTS + namespace: default +--- +# Source: console/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: gCH15URsJZr + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: rzd +stringData: + enterprise-license: "" + kafka-protobuf-git-basicauth-password: G + kafka-sasl-aws-msk-iam-secret-key: 1tq + kafka-sasl-password: K8kPgIp6 + kafka-schema-registry-password: "" + kafka-schemaregistry-tls-ca: Zr + kafka-schemaregistry-tls-cert: KN + kafka-schemaregistry-tls-key: t + kafka-tls-ca: CQ + kafka-tls-cert: 6xZ8 + kafka-tls-key: "" + login-github-oauth-client-secret: "" + login-github-personal-access-token: "" + login-google-groups-service-account.json: "" + login-google-oauth-client-secret: "" + login-jwt-secret: SECRETKEY + login-oidc-client-secret: "" + login-okta-client-secret: "" + login-okta-directory-api-token: "" + redpanda-admin-api-password: "" + redpanda-admin-api-tls-ca: "" + redpanda-admin-api-tls-cert: "" + redpanda-admin-api-tls-key: "" +type: Opaque +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: gCH15URsJZr + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: rzd +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: gCH15URsJZr + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: rzd + namespace: default +spec: + ports: + - name: http + port: 8080 + protocol: TCP + targetPort: 0 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: gCH15URsJZr + type: ClusterIP +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: gCH15URsJZr + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: rzd + namespace: default +spec: + replicas: 176 + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: gCH15URsJZr + strategy: {} + template: + metadata: + annotations: + checksum/config: f55f3fdc49a4774db4d2377ea9b69fd8da2a190ef99f7fb31aeb393215f878cc + s2D: DMU7 + creationTimestamp: null + labels: + CoBI: 20aOZaZvs + app.kubernetes.io/instance: console + app.kubernetes.io/name: gCH15URsJZr + e0xqmoOD: Nb5V + ylGQE: p + spec: + affinity: + podAffinity: {} + podAntiAffinity: {} + automountServiceAccountToken: true + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: KAFKA_SASL_PASSWORD + valueFrom: + secretKeyRef: + key: kafka-sasl-password + name: rzd + - name: KAFKA_PROTOBUF_GIT_BASICAUTH_PASSWORD + valueFrom: + secretKeyRef: + key: kafka-protobuf-git-basicauth-password + name: rzd + - name: KAFKA_SASL_AWSMSKIAM_SECRETKEY + valueFrom: + secretKeyRef: + key: kafka-sasl-aws-msk-iam-secret-key + name: rzd + - name: KAFKA_TLS_CAFILEPATH + value: /etc/console/secrets/kafka-tls-ca + - name: KAFKA_TLS_CERTFILEPATH + value: /etc/console/secrets/kafka-tls-cert + - name: KAFKA_SCHEMAREGISTRY_TLS_CAFILEPATH + value: /etc/console/secrets/kafka-schemaregistry-tls-ca + - name: KAFKA_SCHEMAREGISTRY_TLS_CERTFILEPATH + value: /etc/console/secrets/kafka-schemaregistry-tls-cert + - name: KAFKA_SCHEMAREGISTRY_TLS_KEYFILEPATH + value: /etc/console/secrets/kafka-schemaregistry-tls-key + - name: LOGIN_JWTSECRET + valueFrom: + secretKeyRef: + key: login-jwt-secret + name: rzd + envFrom: [] + image: zT38Q/V:iSGm6MT1 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 0 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: console + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + requests: + PY: "0" + securityContext: + runAsNonRoot: true + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: /etc/console/secrets + name: secrets + readOnly: true + - mountPath: 5uhd1qMX + mountPropagation: ȵS鈛ZQì暗 + name: "N" + readOnly: true + subPath: lbeciOZZ + subPathExpr: Pd88cwE + - mountPath: yVo + mountPropagation: ÑƇ[嫨ĸŁ幵鿯它(ȡ~嘶ƌO情=į臺 + name: Z + readOnly: true + subPath: Nrqx + subPathExpr: Q4ChfT + imagePullSecrets: [] + initContainers: + - 'error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string + into Go value of type []interface {}' + nodeSelector: {} + priorityClassName: 1x11c0q + securityContext: + fsGroup: 99 + runAsUser: 99 + serviceAccountName: nd7TSb2mNTS + tolerations: [] + topologySpreadConstraints: [] + volumes: + - configMap: + name: rzd + name: configs + - name: secrets + secret: + secretName: rzd +-- testdata/case-007.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: false +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: HWL + app.kubernetes.io/version: v2.7.0 + cV05TKdtF: 55lItpeJD + h: 1Y7dqm4wZL + helm.sh/chart: console-0.7.29 + name: RFjc7 + namespace: default +--- +# Source: console/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: HWL + app.kubernetes.io/version: v2.7.0 + cV05TKdtF: 55lItpeJD + h: 1Y7dqm4wZL + helm.sh/chart: console-0.7.29 + name: "y" +stringData: + enterprise-license: "" + kafka-protobuf-git-basicauth-password: "" + kafka-sasl-aws-msk-iam-secret-key: "" + kafka-sasl-password: "" + kafka-schema-registry-password: "" + kafka-schemaregistry-tls-ca: "" + kafka-schemaregistry-tls-cert: "" + kafka-schemaregistry-tls-key: "" + kafka-tls-ca: "" + kafka-tls-cert: "" + kafka-tls-key: "" + login-github-oauth-client-secret: "" + login-github-personal-access-token: "" + login-google-groups-service-account.json: gp + login-google-oauth-client-secret: Ln0 + login-jwt-secret: SECRETKEY + login-oidc-client-secret: "" + login-okta-client-secret: 3A593BjCuu + login-okta-directory-api-token: mSSz8MZ + redpanda-admin-api-password: t + redpanda-admin-api-tls-ca: QD1x71f + redpanda-admin-api-tls-cert: 744Ysvi + redpanda-admin-api-tls-key: 56VaHh +type: Opaque +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} + role-bindings.yaml: |- + roleBindings: + - "": null + 5w1YcAu: null +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: HWL + app.kubernetes.io/version: v2.7.0 + cV05TKdtF: 55lItpeJD + h: 1Y7dqm4wZL + helm.sh/chart: console-0.7.29 + name: "y" +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: HWL + app.kubernetes.io/version: v2.7.0 + cV05TKdtF: 55lItpeJD + h: 1Y7dqm4wZL + helm.sh/chart: console-0.7.29 + name: "y" + namespace: default +spec: + ports: + - name: http + port: 286 + protocol: TCP + targetPort: 404 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: HWL + type: Vvrvx +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: HWL + app.kubernetes.io/version: v2.7.0 + cV05TKdtF: 55lItpeJD + h: 1Y7dqm4wZL + helm.sh/chart: console-0.7.29 + name: "y" + namespace: default +spec: + replicas: 103 + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: HWL + strategy: {} + template: + metadata: + annotations: + checksum/config: 37ddb9195e66f6743cc901bea8e2e2db0492fbf3e78355ffe8c7f2395ece1e90 + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: HWL + spec: + affinity: {} + automountServiceAccountToken: true + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: qY0f + value: Wu + - name: 9zVp + value: g + - name: LOGIN_JWTSECRET + valueFrom: + secretKeyRef: + key: login-jwt-secret + name: "y" + - name: LOGIN_GOOGLE_CLIENTSECRET + valueFrom: + secretKeyRef: + key: login-google-oauth-client-secret + name: "y" + - name: LOGIN_GOOGLE_DIRECTORY_SERVICEACCOUNTFILEPATH + value: /etc/console/secrets/login-google-groups-service-account.json + - name: LOGIN_OKTA_CLIENTSECRET + valueFrom: + secretKeyRef: + key: login-okta-client-secret + name: "y" + - name: LOGIN_OKTA_DIRECTORY_APITOKEN + valueFrom: + secretKeyRef: + key: login-okta-directory-api-token + name: "y" + - name: REDPANDA_ADMINAPI_PASSWORD + valueFrom: + secretKeyRef: + key: redpanda-admin-api-password + name: "y" + - name: REDPANDA_ADMINAPI_TLS_CAFILEPATH + value: /etc/console/secrets/redpanda-admin-api-tls-ca + - name: REDPANDA_ADMINAPI_TLS_KEYFILEPATH + value: /etc/console/secrets/redpanda-admin-api-tls-key + - name: REDPANDA_ADMINAPI_TLS_CERTFILEPATH + value: /etc/console/secrets/redpanda-admin-api-tls-cert + envFrom: + - configMapRef: + name: OUS + optional: true + prefix: YWvtgT + - configMapRef: + name: 4xZZ + prefix: Djbp99U + image: docker.redpanda.com/redpandadata/console:v2.7.0 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 1105213631 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: -1727299217 + periodSeconds: -579129147 + successThreshold: -1278687101 + timeoutSeconds: -603846855 + name: console + ports: + - containerPort: 404 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 114758306 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 457836757 + periodSeconds: -1914503008 + successThreshold: 1926018786 + timeoutSeconds: 458769630 + resources: + requests: + 4P1f3: "0" + DmuY: "0" + securityContext: + runAsNonRoot: true + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: /etc/console/secrets + name: secrets + readOnly: true + imagePullSecrets: [] + initContainers: + - 'error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string + into Go value of type []interface {}' + nodeSelector: + CAy: 19kW + R2z: OpcDywz9x + priorityClassName: rs + securityContext: + fsGroup: 99 + fsGroupChangePolicy: 驸Ǩiµ慷泱世 + runAsGroup: 6873387834465682000 + runAsUser: 7937848737866681000 + sysctls: + - name: mp + value: SkIvFN + - name: E + value: RknyuPB + - name: kcY + value: us1 + serviceAccountName: RFjc7 + tolerations: [] + topologySpreadConstraints: [] + volumes: + - configMap: + name: "y" + name: configs + - name: secrets + secret: + secretName: "y" + - name: dCz +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "y-test-connection" + namespace: "default" + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: HWL + app.kubernetes.io/version: v2.7.0 + cV05TKdtF: 55lItpeJD + h: 1Y7dqm4wZL + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['y:286'] + restartPolicy: Never + priorityClassName: rs +-- testdata/case-008.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: RW + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: YcV5zP8 + namespace: default +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: RW + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: GbgHqD +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: RW + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: GbgHqD + namespace: default +spec: + ports: + - name: http + port: 8080 + protocol: TCP + targetPort: 0 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: RW + type: ClusterIP +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + hfXF: v4uLEC6f8m + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: RW + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: GbgHqD + namespace: default +spec: + replicas: 475 + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: RW + strategy: + rollingUpdate: {} + type: 堯飉J侚桤 合w犌ŝ|#è:(蹝Ƀy輐 + template: + metadata: + annotations: + BTlN: z8t + a: Pqjhw + checksum/config: 1ba99bb938e262d91c73069e0caf6c1ce45d5e92491a50db9d1af5d59db59aed + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: RW + spec: + affinity: {} + automountServiceAccountToken: false + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: [] + envFrom: [] + image: docker.redpanda.com/redpandadata/console:v2.7.0 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 1421249778 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 1194618095 + periodSeconds: 1245060237 + successThreshold: -641096828 + timeoutSeconds: -617099936 + name: console + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + failureThreshold: -10750427 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 208988771 + periodSeconds: -2096658971 + successThreshold: -233405863 + timeoutSeconds: 2042765580 + resources: {} + securityContext: + procMount: ȃ蘗ʮǺ踰蒐佛桸gɋ + readOnlyRootFilesystem: false + runAsGroup: 5367218369967094000 + runAsNonRoot: true + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + imagePullSecrets: [] + initContainers: [] + nodeSelector: {} + priorityClassName: 0fXQqWA96 + securityContext: + fsGroup: 99 + fsGroupChangePolicy: ǶȚ/廻 + runAsGroup: 3241750191956122000 + runAsNonRoot: false + runAsUser: 2693812519144067600 + supplementalGroups: + - -7558357415363805000 + - -9152494874115652000 + - -906805565867492900 + sysctls: + - name: CBe8XsS + value: bh + - name: pUYyG9c + value: xPm1 + serviceAccountName: YcV5zP8 + tolerations: [] + topologySpreadConstraints: + - maxSkew: -722842418 + nodeTaintsPolicy: uã链掎ŏȅ噘籥邟澶N3-昃嗽(七|犘 + topologyKey: vq + whenUnsatisfiable: Ȭť'Ùt苷ŲĤ蘝 + - labelSelector: {} + maxSkew: 1436245353 + nodeAffinityPolicy: 0ʠƃ氁ʆZ + topologyKey: t + whenUnsatisfiable: x叾džʜƽ耨 + - labelSelector: {} + matchLabelKeys: + - 6T2 + - FqrwFd + maxSkew: -172720268 + nodeAffinityPolicy: 觏败TʙȎ喧5婬ȑªgȢ'!ÅWp襎 + nodeTaintsPolicy: ÛB¹]ʐ梳Ě + topologyKey: VyU9 + whenUnsatisfiable: 烹wɹȐN坿¨叻ʊ鴥/Ŭ屎釽C欼 + volumes: + - configMap: + name: GbgHqD + name: configs +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "GbgHqD-test-connection" + namespace: "default" + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: RW + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['GbgHqD:8080'] + restartPolicy: Never + priorityClassName: 0fXQqWA96 +-- testdata/case-009.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: BKV + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: l1Bnpx + namespace: default +--- +# Source: console/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: BKV + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: l1Bnpx +stringData: + enterprise-license: "" + kafka-protobuf-git-basicauth-password: "" + kafka-sasl-aws-msk-iam-secret-key: "" + kafka-sasl-password: "" + kafka-schema-registry-password: "" + kafka-schemaregistry-tls-ca: "" + kafka-schemaregistry-tls-cert: "" + kafka-schemaregistry-tls-key: "" + kafka-tls-ca: "" + kafka-tls-cert: "" + kafka-tls-key: "" + login-github-oauth-client-secret: "" + login-github-personal-access-token: "" + login-google-groups-service-account.json: "" + login-google-oauth-client-secret: "" + login-jwt-secret: SECRETKEY + login-oidc-client-secret: "" + login-okta-client-secret: "" + login-okta-directory-api-token: "" + redpanda-admin-api-password: "" + redpanda-admin-api-tls-ca: "" + redpanda-admin-api-tls-cert: "" + redpanda-admin-api-tls-key: "" +type: Opaque +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: + efgehQaV5UI0y: GymqDudh + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: BKV + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: l1Bnpx + namespace: default +spec: + ports: + - name: http + port: 229 + protocol: TCP + targetPort: 85 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: BKV + type: yZy +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: BKV + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: l1Bnpx + namespace: default +spec: + replicas: 315 + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: BKV + strategy: {} + template: + metadata: + annotations: + checksum/config: 74234e98afe7498fb5daf1f36ac2d78acc339464f950703b8c019892f982b90b + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: BKV + spec: + affinity: + nodeAffinity: {} + podAffinity: {} + podAntiAffinity: {} + automountServiceAccountToken: true + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: LOGIN_JWTSECRET + valueFrom: + secretKeyRef: + key: login-jwt-secret + name: l1Bnpx + envFrom: [] + image: docker.redpanda.com/redpandadata/console:v2.7.0 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: -1420734522 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 753838163 + periodSeconds: -444344576 + successThreshold: -1003403229 + timeoutSeconds: -172453343 + name: console + ports: + - containerPort: 85 + name: http + protocol: TCP + readinessProbe: + failureThreshold: -286281002 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 138566964 + periodSeconds: -361700659 + successThreshold: 422528479 + timeoutSeconds: 352721839 + resources: {} + securityContext: + runAsNonRoot: true + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: /etc/console/secrets + name: secrets + readOnly: true + - mountPath: xShE + name: yWBr98zs1 + subPath: "" + - mountPath: Wnbf + name: qUQ5 + subPath: "" + - mountPath: fgV + name: hpqapQJQ + subPath: "" + imagePullSecrets: + - name: x42RbB4KLm + initContainers: [] + nodeSelector: + OBRBvRK: hMXDLGN5 + ky: sv + priorityClassName: p0ShP6Yru + securityContext: + fsGroup: 99 + fsGroupChangePolicy: 灆Zeɪ霅ǭɒ<ǖ韆 + runAsGroup: -2394155475284911600 + runAsNonRoot: true + runAsUser: 99 + supplementalGroups: + - 802667379359895800 + - 8316082600801372000 + serviceAccountName: l1Bnpx + tolerations: [] + topologySpreadConstraints: + - maxSkew: -73453467 + minDomains: 326628755 + nodeAffinityPolicy: "" + topologyKey: zWgGRC + whenUnsatisfiable: 黚堳ʈ¡ + volumes: + - configMap: + name: l1Bnpx + name: configs + - name: secrets + secret: + secretName: l1Bnpx + - name: yWBr98zs1 + secret: + defaultMode: 414 + secretName: YMpib3J + - name: qUQ5 + secret: + defaultMode: 402 + secretName: Pw8 + - name: hpqapQJQ + secret: + defaultMode: 410 + secretName: 1JLIOjZI8 +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "l1Bnpx-test-connection" + namespace: "default" + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: BKV + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + imagePullSecrets: + - name: x42RbB4KLm + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['l1Bnpx:229'] + restartPolicy: Never + priorityClassName: p0ShP6Yru +-- testdata/case-010.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: + TTsn5: s3xEhO + tZiUN: CtjX + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: JFcK + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: kIzbDF + namespace: default +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: JFcK + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: ivK + namespace: default +spec: + ports: + - name: http + port: 8080 + protocol: TCP + targetPort: 0 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: JFcK + type: ClusterIP +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: JFcK + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: ivK + namespace: default +spec: + replicas: 250 + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: JFcK + strategy: {} + template: + metadata: + annotations: + checksum/config: 74234e98afe7498fb5daf1f36ac2d78acc339464f950703b8c019892f982b90b + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: JFcK + spec: + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: hu5a9Q0m + operator: Ʊ飁Ɲŗʫf + values: + - fDVpOP + - fUBu2Zhz + matchFields: + - key: zOA + operator: 豔|Ĺ霱鑕yȮM錕陰蔆 + - key: uqlr1 + operator: ʏ + weight: -157546286 + - preference: + matchExpressions: + - key: yI2tB1c6Om + operator: 槼湝@)萢=\Ɇ剋Ś>(.aC俥?蔔 + values: + - 5QB3 + - C + - key: IhL2k3 + operator: "" + matchFields: + - key: Kn1 + operator: q'ʏC効L¶ƋMʐģƥƝnĤe + weight: -1818860211 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - {} + podAffinity: {} + automountServiceAccountToken: true + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: LICENSE + valueFrom: + secretKeyRef: + key: 6Y + name: juyv + envFrom: [] + image: 4A/0YeLdES:1a4iH + imagePullPolicy: "" + livenessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 0 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: console + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 1992527736 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 1233698472 + periodSeconds: 1177961840 + successThreshold: -1634725396 + timeoutSeconds: -1493252430 + resources: {} + securityContext: + runAsNonRoot: true + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: C3nMA + name: 0sxSVsP + readOnly: true + subPath: V + subPathExpr: 1E5cYdMw + - env: + - name: nE8 + value: hFfGzdv + valueFrom: + configMapKeyRef: + key: 9Sc + name: kviW + fieldRef: + fieldPath: bzL + resourceFieldRef: + containerName: ky9X6 + divisor: "0" + resource: RgwF + image: mEMnGhDi + imagePullPolicy: <Ǐ(嬘箓閁1_Y.脯鮉娇腾1 + name: ZyDivTyKOX + readinessProbe: + failureThreshold: 368214623 + initialDelaySeconds: 1711545214 + periodSeconds: -1669571514 + successThreshold: 830602444 + timeoutSeconds: -1406663042 + resources: + requests: + Ta: "0" + restartPolicy: M#L粓Ojw+ĸɊcƗ镃聆琮ǘ滂W + stdin: true + terminationMessagePath: 7hyobl + terminationMessagePolicy: gŜĶ蔓林驲%嶄ʚ轿竷 + volumeDevices: + - devicePath: zlgauG + name: Uy7Ds5N + - devicePath: pturCrgNMxS + name: "1" + volumeMounts: + - mountPath: 2ftw3U97pI + mountPropagation: ǮmW + name: NeLq9zvIQ + subPath: 5XYnpNAb + subPathExpr: rAeHuQk + - mountPath: aOj5TCBKn + name: DWFR + subPath: G + - mountPath: ovoJMYcQZ7 + mountPropagation: ɷ&娈瘱 + name: o6QaPD8 + subPath: rIo + subPathExpr: j0F1wa + workingDir: tj + - env: + - name: KO7zek + value: AE8r + valueFrom: {} + envFrom: + - prefix: T4nvtH0yCoJCx + - prefix: KaMGNcK + image: m + imagePullPolicy: 牀 + lifecycle: + preStop: + exec: {} + sleep: + seconds: -1229802121654850600 + livenessProbe: + failureThreshold: 1036399450 + grpc: + port: 1383801223 + service: nm0jd39Ta + httpGet: + host: VhafGy + path: CP9 + port: BnhNd + scheme: hxu崚奵Y + initialDelaySeconds: 141265356 + periodSeconds: 251484282 + successThreshold: 257415096 + terminationGracePeriodSeconds: 3476093234934520000 + timeoutSeconds: -1657896181 + name: UCZJ + ports: + - containerPort: 574867450 + hostPort: 156179933 + name: 0re + protocol: 頶韜»釟ţKFƂƄp錴畗~[禬B琡9 + - containerPort: -374880824 + hostPort: 1342282100 + name: OeyfSkg3EJIuD + protocol: 佃ŦŬ穷唂&2ŌĜ,gF躊貀j寝ô + readinessProbe: + failureThreshold: 978947885 + httpGet: + host: A + path: Ngfyt + port: "" + scheme: Í蠕窩獙 + initialDelaySeconds: 60101484 + periodSeconds: 1102760384 + successThreshold: 1260060937 + terminationGracePeriodSeconds: 1157546254675437000 + timeoutSeconds: -465800822 + resizePolicy: + - resourceName: P6b56 + restartPolicy: 冿÷Ý萦{[P貍ȕ,Sɕ錼 + - resourceName: azLsfqbuYlr + restartPolicy: 蒃Ký阹ǒ1T獽蛍峸伦ƨ(Ƭ-央á + - resourceName: skOpL + restartPolicy: 鸿dŶ徥w^ȏ嘳Ƙ唓Ęɸ-ɫ鷠C + resources: {} + terminationMessagePath: vmp + terminationMessagePolicy: Ƒh庛ʘ$8L藑奾ń4說 + workingDir: rgrA + imagePullSecrets: [] + initContainers: [] + nodeSelector: {} + priorityClassName: x0ISc2 + securityContext: + fsGroup: 99 + runAsUser: 99 + serviceAccountName: kIzbDF + tolerations: [] + topologySpreadConstraints: [] + volumes: + - configMap: + name: ivK + name: configs +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "ivK-test-connection" + namespace: "default" + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: JFcK + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['ivK:8080'] + restartPolicy: Never + priorityClassName: x0ISc2 +-- testdata/case-011.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + JwK5MKTa: WW + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: Cy9eHCiP + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + v7E: 1g6JB + name: hbe + namespace: default +--- +# Source: console/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + labels: + JwK5MKTa: WW + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: Cy9eHCiP + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + v7E: 1g6JB + name: hbe +stringData: + enterprise-license: "" + kafka-protobuf-git-basicauth-password: "" + kafka-sasl-aws-msk-iam-secret-key: "" + kafka-sasl-password: "" + kafka-schema-registry-password: "" + kafka-schemaregistry-tls-ca: "" + kafka-schemaregistry-tls-cert: "" + kafka-schemaregistry-tls-key: "" + kafka-tls-ca: "" + kafka-tls-cert: "" + kafka-tls-key: "" + login-github-oauth-client-secret: "" + login-github-personal-access-token: "" + login-google-groups-service-account.json: "" + login-google-oauth-client-secret: "" + login-jwt-secret: SECRETKEY + login-oidc-client-secret: "" + login-okta-client-secret: "" + login-okta-directory-api-token: "" + redpanda-admin-api-password: "" + redpanda-admin-api-tls-ca: "" + redpanda-admin-api-tls-cert: "" + redpanda-admin-api-tls-key: "" +type: Opaque +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + JwK5MKTa: WW + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: Cy9eHCiP + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + v7E: 1g6JB + name: hbe +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: + "": NbuyvXjW + 2CTz: vRGLHMO53rD + yLzpKqz: uBjXvD + creationTimestamp: null + labels: + JwK5MKTa: WW + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: Cy9eHCiP + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + v7E: 1g6JB + name: hbe + namespace: default +spec: + ports: + - name: http + port: 478 + protocol: TCP + targetPort: 90 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: Cy9eHCiP + type: sl +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + pJ: f0brcnhV + creationTimestamp: null + labels: + JwK5MKTa: WW + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: Cy9eHCiP + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + v7E: 1g6JB + name: hbe + namespace: default +spec: + replicas: 65 + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: Cy9eHCiP + strategy: {} + template: + metadata: + annotations: + checksum/config: 0ebeace369c9c96d75109609694bd464d6c28c2e8d1fcbd96529ef96d4ba0ec5 + creationTimestamp: null + labels: + "2": RgUAFm + D2V: V80aQ + app.kubernetes.io/instance: console + app.kubernetes.io/name: Cy9eHCiP + spec: + affinity: + podAffinity: {} + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: {} + matchLabelKeys: + - E9nCu6aLM + topologyKey: PfPCGvStt + weight: -1379963896 + - podAffinityTerm: + namespaceSelector: {} + topologyKey: CgA4 + weight: -726546395 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: ijh1hJb + operator: ƏŧD續筚朊 + values: + - BOfF5xB + - 3iu4 + - key: "93" + operator: Dij%{欬ɽ + - key: NEd + operator: ÿD + values: + - r + - B7E1BoYQ4Njb + - BTV + matchLabelKeys: + - FuyLvc + - Lh60qi + namespaceSelector: + matchExpressions: + - key: w + operator: 嘑 + - key: eQ6nY99xw + operator: H辄萟蘎Ÿ塪²;暃 + - key: 8JrCFA + operator: "" + values: + - wVO + topologyKey: ByO + - namespaceSelector: {} + topologyKey: b21 + - namespaces: + - Ifv + topologyKey: F9j5 + automountServiceAccountToken: true + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: XW + value: PCPsJt + valueFrom: + configMapKeyRef: + key: Zk0vTu6kC + name: d9zm3 + optional: false + secretKeyRef: + key: mRF + name: CW + optional: false + - name: loir2K + value: Ti0q + - name: lAxIKF7cbLlc + value: 1ksS + valueFrom: + fieldRef: + apiVersion: 8i2Z + fieldPath: vD7H + resourceFieldRef: + containerName: yqY + divisor: "0" + resource: ebRDAl + secretKeyRef: + key: E9514U + name: g3Rbzs + optional: false + - name: LOGIN_JWTSECRET + valueFrom: + secretKeyRef: + key: login-jwt-secret + name: hbe + envFrom: + - configMapRef: + name: d + prefix: Fl1 + secretRef: + name: X8xDu + optional: true + - prefix: M + secretRef: + name: 10or1C2m + optional: false + - configMapRef: + name: BBj + optional: false + prefix: Xy + secretRef: + name: ZA3 + image: gjR/U:Tl0EP + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 653767212 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 832425522 + periodSeconds: -1810991482 + successThreshold: 1954581711 + timeoutSeconds: -574178850 + name: console + ports: + - containerPort: 90 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 1745353710 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 1504484890 + periodSeconds: -846859037 + successThreshold: -1564014824 + timeoutSeconds: 888372342 + resources: + requests: + "Y": "0" + securityContext: + runAsNonRoot: true + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: /etc/console/secrets + name: secrets + readOnly: true + - mountPath: 2Qy8k + name: n4BPeF + subPath: "" + - mountPath: O + mountPropagation: ŜQLhlkU穒´宕Ïůŝƪ + name: JeSPIB + readOnly: true + subPath: RTiJ + subPathExpr: wad + - mountPath: QV6Kf + name: Pj7R + subPath: qBOd + subPathExpr: kN3Uujt + imagePullSecrets: [] + initContainers: + - 'error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string + into Go value of type []interface {}' + nodeSelector: + HC7: EI8 + priorityClassName: sJXoA3V + securityContext: + fsGroup: 4103142176308445000 + fsGroupChangePolicy: Ő6­撱悤ÅC`碸 + runAsUser: 9170579519391071000 + sysctls: + - name: 4OKA + value: P7ouRq + - name: iD9Oz + value: gL6ARE + serviceAccountName: hbe + tolerations: [] + topologySpreadConstraints: [] + volumes: + - configMap: + name: hbe + name: configs + - name: secrets + secret: + secretName: hbe + - name: n4BPeF + secret: + defaultMode: 12 + secretName: auIr +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "hbe-test-connection" + namespace: "default" + labels: + JwK5MKTa: WW + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: Cy9eHCiP + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + v7E: 1g6JB + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['hbe:478'] + restartPolicy: Never + priorityClassName: sJXoA3V +-- testdata/case-012.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: Qr03ts + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: tmn2Kt + namespace: default +--- +# Source: console/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: Qr03ts + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: tmn2Kt +stringData: + enterprise-license: "" + kafka-protobuf-git-basicauth-password: "" + kafka-sasl-aws-msk-iam-secret-key: "" + kafka-sasl-password: "" + kafka-schema-registry-password: "" + kafka-schemaregistry-tls-ca: "" + kafka-schemaregistry-tls-cert: "" + kafka-schemaregistry-tls-key: "" + kafka-tls-ca: "" + kafka-tls-cert: "" + kafka-tls-key: "" + login-github-oauth-client-secret: "" + login-github-personal-access-token: "" + login-google-groups-service-account.json: "" + login-google-oauth-client-secret: "" + login-jwt-secret: SECRETKEY + login-oidc-client-secret: "" + login-okta-client-secret: "" + login-okta-directory-api-token: "" + redpanda-admin-api-password: "" + redpanda-admin-api-tls-ca: "" + redpanda-admin-api-tls-cert: "" + redpanda-admin-api-tls-key: "" +type: Opaque +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: Qr03ts + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: tmn2Kt +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: Qr03ts + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: tmn2Kt + namespace: default +spec: + ports: + - name: http + port: 8080 + protocol: TCP + targetPort: 0 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: Qr03ts + type: ClusterIP +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + v: D + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: Qr03ts + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: tmn2Kt + namespace: default +spec: + replicas: 407 + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: Qr03ts + strategy: + rollingUpdate: {} + type: 9Cɠ+餌µ骽O惠LƬɇɦ鉍挶 + template: + metadata: + annotations: + checksum/config: f03a44f92485e3dfb6772dc84dec7c868a151f08fa5c04332bebe63251290ce5 + creationTimestamp: null + labels: + "": S7BNyT + app.kubernetes.io/instance: console + app.kubernetes.io/name: Qr03ts + r1F: Fsc + yeY4LjT: MRlwtd + spec: + affinity: {} + automountServiceAccountToken: true + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: LOGIN_JWTSECRET + valueFrom: + secretKeyRef: + key: login-jwt-secret + name: tmn2Kt + envFrom: + - prefix: RyT9JuZ + image: docker.redpanda.com/redpandadata/console:v2.7.0 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 666524470 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 1841184951 + periodSeconds: 465079780 + successThreshold: -1928046688 + timeoutSeconds: 1377323766 + name: console + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: {} + securityContext: + allowPrivilegeEscalation: false + privileged: true + readOnlyRootFilesystem: false + runAsGroup: -6536894786619940000 + runAsNonRoot: false + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: /etc/console/secrets + name: secrets + readOnly: true + - command: + - "" + - 7yJE + envFrom: + - prefix: kRXk + secretRef: + name: TJsCapqoxl + - prefix: ucUEP + secretRef: + name: 1zCfpPiVt9o + optional: true + image: hwJ + imagePullPolicy: dh + name: Ody4zqt + readinessProbe: + exec: {} + failureThreshold: 1607990521 + grpc: + port: 2033135747 + service: "" + initialDelaySeconds: -889776869 + periodSeconds: -35190825 + successThreshold: -958310065 + terminationGracePeriodSeconds: 3166888730011246600 + timeoutSeconds: 806015074 + resources: + requests: + mg2KyOVo97: "0" + restartPolicy: 档媘řĖ焘傐Yʮ,+Ƽ梽讫ƭ焇 + securityContext: + readOnlyRootFilesystem: true + runAsGroup: -2035296945120192500 + stdinOnce: true + terminationMessagePolicy: '*.Q' + workingDir: 0g9 + - command: + - ktel2 + - 2gO + image: Kq1K2HexLL + imagePullPolicy: 蟫黳jª0狫ĝ| + lifecycle: + postStart: + exec: + command: + - I + name: XmcrosJ9Art + resizePolicy: + - resourceName: 8dOXgKMh + restartPolicy: T@罞 + resources: + limits: + Qf424: "0" + UkBWyCgR: "0" + yS9FH: "0" + securityContext: + allowPrivilegeEscalation: true + capabilities: + drop: + - Ǐ蟯ƛU賊稁uv/u讎胗< + - 1湹 + privileged: false + readOnlyRootFilesystem: false + runAsGroup: -281571585037868400 + runAsUser: 8469885005475494000 + stdin: true + stdinOnce: true + terminationMessagePath: 6ii28 + terminationMessagePolicy: ȊGī3慺Ŏ + volumeDevices: + - devicePath: "" + name: lqvpF + - devicePath: 3vTez + name: pD6EOo + workingDir: QEqnPlY6YE + - args: + - eiyTiCxBp + envFrom: + - configMapRef: + name: uxUzs + prefix: 0Oq + secretRef: + name: ahghhjB + - configMapRef: + name: yjx + prefix: cOCr6ajjpSTT + - configMapRef: + name: "4" + prefix: 0XtWv + secretRef: + name: oKDQ + image: PV + imagePullPolicy: d?遼gŜT纬ɷšǧ餝Ƨ + livenessProbe: + exec: {} + failureThreshold: 746140291 + grpc: + port: 1197495917 + service: "" + httpGet: + host: x78yAB + path: P5mSLs + port: Cb2 + scheme: 儰试9ȷǴ燀ǃ¦籇射,ǠöcƲ伙 + initialDelaySeconds: 1418617842 + periodSeconds: 187037501 + successThreshold: -1821323321 + timeoutSeconds: -894994792 + name: ToH + resizePolicy: + - resourceName: 7Ut8kM + restartPolicy: gěǏ* + - resourceName: gvoJz7 + restartPolicy: ł0Iɷ»u诎żȋ貏C炭 + - resourceName: VpTvtNnJOw + restartPolicy: 阠eR'k.Ơ糦啮ŋ睷N譺 + resources: + limits: + cYhO6a: "0" + startupProbe: + exec: {} + failureThreshold: -1040244189 + grpc: + port: 1921669257 + service: Me + httpGet: + host: 5fL4Z + path: BwLac + port: SKrb2z + scheme: ľ<Ƽ浳s剪ɍ + initialDelaySeconds: -1064995957 + periodSeconds: 230643461 + successThreshold: -1865926881 + timeoutSeconds: 1102271416 + terminationMessagePath: ZbnnI + terminationMessagePolicy: 阳壀ɀS强pŇȆDž鹩 + tty: true + volumeDevices: + - devicePath: pP2eHwth + name: S9Sy + workingDir: Z + imagePullSecrets: [] + initContainers: + - 'error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string + into Go value of type []interface {}' + nodeSelector: {} + priorityClassName: vMcB + securityContext: + fsGroup: 99 + runAsUser: 99 + serviceAccountName: tmn2Kt + tolerations: [] + topologySpreadConstraints: [] + volumes: + - configMap: + name: tmn2Kt + name: configs + - name: secrets + secret: + secretName: tmn2Kt +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "tmn2Kt-test-connection" + namespace: "default" + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: Qr03ts + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['tmn2Kt:8080'] + restartPolicy: Never + priorityClassName: vMcB +-- testdata/case-013.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: dDkIKgMwXv + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: RttlJN + namespace: default +--- +# Source: console/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: dDkIKgMwXv + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: RttlJN +stringData: + enterprise-license: "" + kafka-protobuf-git-basicauth-password: "" + kafka-sasl-aws-msk-iam-secret-key: "" + kafka-sasl-password: "" + kafka-schema-registry-password: "" + kafka-schemaregistry-tls-ca: "" + kafka-schemaregistry-tls-cert: "" + kafka-schemaregistry-tls-key: "" + kafka-tls-ca: "" + kafka-tls-cert: "" + kafka-tls-key: "" + login-github-oauth-client-secret: "" + login-github-personal-access-token: "" + login-google-groups-service-account.json: "" + login-google-oauth-client-secret: "" + login-jwt-secret: SECRETKEY + login-oidc-client-secret: "" + login-okta-client-secret: "" + login-okta-directory-api-token: "" + redpanda-admin-api-password: "" + redpanda-admin-api-tls-ca: "" + redpanda-admin-api-tls-cert: "" + redpanda-admin-api-tls-key: "" +type: Opaque +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: dDkIKgMwXv + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: RttlJN +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: dDkIKgMwXv + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: RttlJN + namespace: default +spec: + ports: + - name: http + port: 8080 + protocol: TCP + targetPort: 0 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: dDkIKgMwXv + type: ClusterIP +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: dDkIKgMwXv + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: RttlJN + namespace: default +spec: + replicas: 412 + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: dDkIKgMwXv + strategy: {} + template: + metadata: + annotations: + checksum/config: 80fd97b611d09c692bd5e12a12d43f51c7486213c5798a4f57bb8f0866119572 + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: dDkIKgMwXv + spec: + affinity: {} + automountServiceAccountToken: true + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: LOGIN_JWTSECRET + valueFrom: + secretKeyRef: + key: login-jwt-secret + name: RttlJN + envFrom: [] + image: docker.redpanda.com/redpandadata/console:v2.7.0 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 0 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: console + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + failureThreshold: -225696508 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 1573121125 + periodSeconds: -1561542711 + successThreshold: 1804677264 + timeoutSeconds: -1540252725 + resources: + limits: + f7Jr: "0" + fl: "0" + requests: + Q4O7nA: "0" + securityContext: + privileged: true + readOnlyRootFilesystem: false + runAsNonRoot: true + runAsUser: -8804799239371185000 + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: /etc/console/secrets + name: secrets + readOnly: true + - mountPath: DVlVa1jiDIh5G + name: zaV + subPath: lXnque8 + subPathExpr: aFzzfyzr + - mountPath: 7VmD + name: bNuYmK + readOnly: true + subPath: zsTvmtU0 + subPathExpr: uNyQSZ + - mountPath: p + name: q3 + readOnly: true + subPathExpr: k4yfc0H + - env: + - name: bNyX + value: DpJ + valueFrom: + secretKeyRef: + key: r3ZL + name: GM2zRN8 + optional: false + - name: dS + value: u2CpI14PZ + - name: JVoNndPj + value: eCfRy + image: 9nkfM + imagePullPolicy: v洓p褾NJ翛Y/笸i洞偀fX綤鰐 + livenessProbe: + exec: + command: + - TzQ + - 5tBBhynsjV + failureThreshold: -1613952147 + httpGet: + host: gYV + path: 9qC2GovT + port: Gh + initialDelaySeconds: 1651935443 + periodSeconds: -1307313312 + successThreshold: 1553368137 + terminationGracePeriodSeconds: -4575724788805099000 + timeoutSeconds: -499895377 + name: aOBSLF + readinessProbe: + failureThreshold: 687754614 + initialDelaySeconds: -1880005074 + periodSeconds: 794268536 + successThreshold: -1510519942 + terminationGracePeriodSeconds: 3334702514671978000 + timeoutSeconds: -178867660 + resources: + requests: + hiWTQ: "0" + m7CDU: "0" + stdin: true + terminationMessagePath: Yj9V + terminationMessagePolicy: js$昦夁糎fț + tty: true + volumeMounts: + - mountPath: Xaoy + name: XuLXzMm + readOnly: true + subPath: NI8v + subPathExpr: nPRuyC + - mountPath: S + mountPropagation: ĜX鴮璫ȓĢ + name: c2o + readOnly: true + subPath: DEcziG + subPathExpr: 7UjF6H + workingDir: yPE + imagePullSecrets: [] + initContainers: + - 'error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string + into Go value of type []interface {}' + nodeSelector: {} + priorityClassName: BDUfm1wSRDI + securityContext: + fsGroup: 99 + runAsUser: 99 + serviceAccountName: RttlJN + tolerations: + - effect: ƞ嬂 + key: wnH + operator: Ā蔥ąʏƅȑǚ缗'r~熐{Ǎ楯&鑫咂] + value: LYZYjeFUmK29wdL + - effect: 硞撤幅娰tȬ婒ĎɕÏǜ蚭馸諄W)偒½ + key: e2 + operator: bƤrZ + value: 8ssobF8u + topologySpreadConstraints: [] + volumes: + - configMap: + name: RttlJN + name: configs + - name: secrets + secret: + secretName: RttlJN +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "RttlJN-test-connection" + namespace: "default" + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: dDkIKgMwXv + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['RttlJN:8080'] + restartPolicy: Never + priorityClassName: BDUfm1wSRDI +-- testdata/case-014.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: Vi2vH + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: h6eHrUr + namespace: default +--- +# Source: console/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: Vi2vH + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: htymHJ +stringData: + enterprise-license: "" + kafka-protobuf-git-basicauth-password: "" + kafka-sasl-aws-msk-iam-secret-key: "" + kafka-sasl-password: "" + kafka-schema-registry-password: "" + kafka-schemaregistry-tls-ca: "" + kafka-schemaregistry-tls-cert: "" + kafka-schemaregistry-tls-key: "" + kafka-tls-ca: "" + kafka-tls-cert: "" + kafka-tls-key: "" + login-github-oauth-client-secret: "" + login-github-personal-access-token: "" + login-google-groups-service-account.json: "" + login-google-oauth-client-secret: "" + login-jwt-secret: SECRETKEY + login-oidc-client-secret: "" + login-okta-client-secret: "" + login-okta-directory-api-token: "" + redpanda-admin-api-password: "" + redpanda-admin-api-tls-ca: "" + redpanda-admin-api-tls-cert: "" + redpanda-admin-api-tls-key: "" +type: Opaque +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} + role-bindings.yaml: |- + roleBindings: + - null +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: Vi2vH + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: htymHJ +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: Vi2vH + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: htymHJ + namespace: default +spec: + ports: + - name: http + port: 41 + protocol: TCP + targetPort: 168 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: Vi2vH + type: Oiwzbmtjpb +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "htymHJ-test-connection" + namespace: "default" + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: Vi2vH + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['htymHJ:41'] + restartPolicy: Never + priorityClassName: rcxHoi +-- testdata/case-015.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: + IH: 3W + K5hNNf: "" + r: 9cmm + creationTimestamp: null + labels: + B0Pmybnj: gh8 + MdyMnFBP0Cd1: UUVRKbjhv + ShHkukRGF9k: KlIyX6upO + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: KD8DmV + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: zmr + namespace: default +--- +# Source: console/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + labels: + B0Pmybnj: gh8 + MdyMnFBP0Cd1: UUVRKbjhv + ShHkukRGF9k: KlIyX6upO + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: KD8DmV + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: 9RweMGWqBs +stringData: + enterprise-license: "" + kafka-protobuf-git-basicauth-password: "" + kafka-sasl-aws-msk-iam-secret-key: "" + kafka-sasl-password: "" + kafka-schema-registry-password: "" + kafka-schemaregistry-tls-ca: "" + kafka-schemaregistry-tls-cert: "" + kafka-schemaregistry-tls-key: "" + kafka-tls-ca: "" + kafka-tls-cert: "" + kafka-tls-key: "" + login-github-oauth-client-secret: "" + login-github-personal-access-token: "" + login-google-groups-service-account.json: "" + login-google-oauth-client-secret: "" + login-jwt-secret: SECRETKEY + login-oidc-client-secret: "" + login-okta-client-secret: "" + login-okta-directory-api-token: "" + redpanda-admin-api-password: "" + redpanda-admin-api-tls-ca: "" + redpanda-admin-api-tls-cert: "" + redpanda-admin-api-tls-key: "" +type: Opaque +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + B0Pmybnj: gh8 + MdyMnFBP0Cd1: UUVRKbjhv + ShHkukRGF9k: KlIyX6upO + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: KD8DmV + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: 9RweMGWqBs +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + B0Pmybnj: gh8 + MdyMnFBP0Cd1: UUVRKbjhv + ShHkukRGF9k: KlIyX6upO + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: KD8DmV + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: 9RweMGWqBs + namespace: default +spec: + ports: + - name: http + port: 8080 + protocol: TCP + targetPort: 0 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: KD8DmV + type: ClusterIP +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + 2V: 50l + jFB7K: 5ZqGXdsD94 + creationTimestamp: null + labels: + B0Pmybnj: gh8 + MdyMnFBP0Cd1: UUVRKbjhv + ShHkukRGF9k: KlIyX6upO + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: KD8DmV + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: 9RweMGWqBs + namespace: default +spec: + replicas: 128 + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: KD8DmV + strategy: {} + template: + metadata: + annotations: + checksum/config: c07b76ad8263a0560734a09b913b4c726efe461a7f519da293467d20a90d78bf + creationTimestamp: null + labels: + FlwBgvWNMrbg5: YKgnz8q + TGDbR: 4egH + Xr8XMOk: 1DAii + app.kubernetes.io/instance: console + app.kubernetes.io/name: KD8DmV + spec: + affinity: + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: 7eVqbmnw4 + operator: 屈ǧȔŗS#~¸Dd馔uÈ飏ƌĔ魼ȓ + values: + - eZapFDhb + - dBr2cD + - key: Z13Kq48NE0 + operator: ª + values: + - 03LE6GE + - key: s + operator: 箱+ʑ圼;0丢顃M媆熋熼妄瞬 + values: + - E + - jC2mNBN + matchLabels: + 4tdQRoO: Tgv + 7Apxz: EPl5 + bPvG5Bf: sCS + namespaceSelector: {} + namespaces: + - bkN0U + topologyKey: haPJ + weight: -1043017794 + - podAffinityTerm: + labelSelector: + matchLabels: + PP8DxAPJwUzY: z9RL6 + U1a: J + due4: eRc0tKn + namespaceSelector: + matchExpressions: + - key: "y" + operator: 霮ʡ`罵瀖Kʓa嚃*Q`UV邠想ɷġ + namespaces: + - M2GNeyD + - eDNVdz1ne46 + topologyKey: kQ + weight: -1134437930 + - podAffinityTerm: + namespaceSelector: + matchExpressions: + - key: SnD + operator: 6愔ȶ獧:öȰ浻珼»ǰs睑,s頀旓eX + - key: yt197hBb + operator: ȒǦ^(á咟獐赠5ĺĜ嶜庌愖V揺ɞ\Ș + values: + - pu5 + - Ywv1TEhK + - pAo + matchLabels: + "": rZ + topologyKey: WSD + weight: 613733383 + requiredDuringSchedulingIgnoredDuringExecution: + - topologyKey: 4b6nMCalUl1 + automountServiceAccountToken: true + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: iQE + value: Aj6RWPJE + - name: QwMCc + value: N9g6bDNI + - name: U5Qg5Qc0NWE + valueFrom: + configMapKeyRef: + key: R + name: n8 + optional: false + fieldRef: + apiVersion: zg0 + fieldPath: fNjpqJ + secretKeyRef: + key: MlF + name: h + - name: LOGIN_JWTSECRET + valueFrom: + secretKeyRef: + key: login-jwt-secret + name: 9RweMGWqBs + envFrom: [] + image: FezgEM/b4CZb:OoX + imagePullPolicy: '&Ŕ<駄AG' + livenessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 0 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: console + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 398655641 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 1516319657 + periodSeconds: -635156272 + successThreshold: 1338596793 + timeoutSeconds: -905426079 + resources: + requests: + I: "0" + b7jbi: "0" + r1cN: "0" + securityContext: + privileged: false + procMount: d聉l蝲ɓH>狱(Ȁ胄hʍy龝Ȼ埓Y + readOnlyRootFilesystem: false + runAsGroup: 2951274493718237000 + runAsNonRoot: true + runAsUser: -1772317555576666000 + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: /etc/console/secrets + name: secrets + readOnly: true + - mountPath: y5BZm9v9L5 + name: mE9WF + readOnly: true + subPathExpr: 3vKqLj2 + imagePullSecrets: [] + initContainers: + - 'error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string + into Go value of type []interface {}' + nodeSelector: + vy4h: rk + priorityClassName: "68" + securityContext: + fsGroup: 99 + fsGroupChangePolicy: ¶鮬眴帘ʥb豚DIĂ + runAsGroup: 4190388773600424000 + runAsUser: 99 + supplementalGroups: + - 6652209348598506000 + - 5521245057591626000 + - 6754698685787706000 + sysctls: + - name: "7" + value: vp + serviceAccountName: zmr + tolerations: + - effect: '#U媷ɑɥ±箑妌RɱfÈB矅蒟(' + key: g + operator: Řg~歟1ƹ,纙蝝垺 + tolerationSeconds: -9038490283678034000 + value: x6T1NM + - effect: ė{ɼ 5;^ʤàOKv泣0ƫ¢ + key: wdW6LI1a5 + operator: ú4ʫ-哖ýȻȣŦiĩġ膳". + tolerationSeconds: -5247520709138794000 + value: NXt + topologySpreadConstraints: + - labelSelector: + matchExpressions: + - key: dme + operator: )\鹮İ又Ȥ鏥Ĝ + matchLabels: + Cdk: atEBel + PhEVPxOjN: QTW4 + fC0YTiwm: fdAQN8t + maxSkew: 472867304 + minDomains: 1802867157 + nodeAffinityPolicy: ʈǔ聿ŶŹ&y鰜# + nodeTaintsPolicy: '"篍Ɛɰl鄱' + topologyKey: fqmSu + whenUnsatisfiable: äƟĻ鍣ųø啼ǫǷ" + - labelSelector: + matchExpressions: + - key: BEj + operator: Ɠ墳 + values: + - qBJ + - KZbk + - key: 9wxm2wFXlY + operator: ì蠁{\媽;ě8ɠ + values: + - yiuVv9DzzRse + - "N" + - z + - key: SWu + operator: Ī½曖1șWb3 + maxSkew: 774109577 + minDomains: -110979462 + nodeAffinityPolicy: 醿卨¬婾豜ʦKd` + topologyKey: 4iskW3Hbv + whenUnsatisfiable: ǮXƞ棤Ǘ + volumes: + - configMap: + name: 9RweMGWqBs + name: configs + - name: secrets + secret: + secretName: 9RweMGWqBs +--- +# Source: console/templates/ingress.yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + annotations: + "": ZKQ6I + ES: uo + creationTimestamp: null + labels: + B0Pmybnj: gh8 + MdyMnFBP0Cd1: UUVRKbjhv + ShHkukRGF9k: KlIyX6upO + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: KD8DmV + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: 9RweMGWqBs +spec: + ingressClassName: x7Um + rules: + - host: chart-example.local + http: + paths: + - backend: + service: + name: 9RweMGWqBs + port: + number: 8080 + path: / + pathType: ImplementationSpecific + tls: + - hosts: null + secretName: Ye6 + - hosts: + - nNQW2NL + - g + - "N" + secretName: YQl +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "9RweMGWqBs-test-connection" + namespace: "default" + labels: + B0Pmybnj: gh8 + MdyMnFBP0Cd1: UUVRKbjhv + ShHkukRGF9k: KlIyX6upO + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: KD8DmV + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['9RweMGWqBs:8080'] + restartPolicy: Never + priorityClassName: 68 +-- testdata/case-016.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: SC + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: DdF7ALq + namespace: default +--- +# Source: console/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: SC + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: 6maz +stringData: + enterprise-license: "" + kafka-protobuf-git-basicauth-password: "" + kafka-sasl-aws-msk-iam-secret-key: "" + kafka-sasl-password: "" + kafka-schema-registry-password: "" + kafka-schemaregistry-tls-ca: "" + kafka-schemaregistry-tls-cert: "" + kafka-schemaregistry-tls-key: "" + kafka-tls-ca: "" + kafka-tls-cert: "" + kafka-tls-key: "" + login-github-oauth-client-secret: "" + login-github-personal-access-token: "" + login-google-groups-service-account.json: "" + login-google-oauth-client-secret: "" + login-jwt-secret: SECRETKEY + login-oidc-client-secret: "" + login-okta-client-secret: "" + login-okta-directory-api-token: "" + redpanda-admin-api-password: "" + redpanda-admin-api-tls-ca: "" + redpanda-admin-api-tls-cert: "" + redpanda-admin-api-tls-key: "" +type: Opaque +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} + role-bindings.yaml: |- + roleBindings: + - Q0kslM: null + - null +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: SC + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: 6maz +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: SC + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: 6maz + namespace: default +spec: + ports: + - name: http + port: 8080 + protocol: TCP + targetPort: 0 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: SC + type: ClusterIP +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: SC + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: 6maz + namespace: default +spec: + replicas: 331 + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: SC + strategy: + rollingUpdate: {} + type: ŀ剭º(;ƍ4兖ȇ + template: + metadata: + annotations: + JYLUc483y: gTnWiG + checksum/config: e4b69acb9132e0c7dea94f0e868bb2c5850883e5487d4cca28762798c1b9dda6 + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: SC + spec: + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: 2Ldss9 + operator: ?霏ƦxǰA7ȇ(堃R + values: + - Ce7pGgB5o + - B8EWZ + - key: pJKw3VVY5 + operator: 2wq6JK?Ȏ惙徵r儊ǒ嵀匫W + matchFields: + - key: EQvFQjoLm1 + operator: «/o咑澇ƉɑȨŞƙ|5時 + weight: -508343495 + - preference: + matchExpressions: + - key: VRoHsoMNa + operator: cƄábŊɕg追ĦǙȿ男)hŬ + values: + - tcCIpd9m + - FsoFrK + - key: ReH4ocoZ + operator: "" + values: + - bnUyPckbz + - AE + - njW + - key: fZBGR + operator: 租ǜ藇錼 + weight: -1003115262 + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + namespaceSelector: + matchLabels: + qGlBCw: zUBwqj2xV + zlHLG: TDTkLQOC + namespaces: + - QWFH + - TEzgQKPSQ + topologyKey: "" + weight: 682123393 + - podAffinityTerm: + labelSelector: {} + matchLabelKeys: + - 1MiHrQ + namespaceSelector: + matchExpressions: + - key: JUYumiiJFrY + operator: .ƽCDZo& + values: + - t3wDXa + - 70HCTbI6g + - C + - key: ik + operator: Œ8v + values: + - Wp + - Zf + - c2q7e + topologyKey: Sc1Q + weight: 869908297 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: ore + operator: ?ɴ$瀜蝪ĪźȀŐƌS莣幮屒n×U锇Ľ + values: + - mJM + - oc + - aU + - key: SQmv + operator: ȥī+ūĬ诧犂¹ + - key: Hh1r9 + operator: h蓟x蹵D¨谧罬 + matchLabelKeys: + - mDk + - Hki8 + topologyKey: x2q0Rx1f1N + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + namespaceSelector: + matchExpressions: + - key: H1Ni + operator: Ȧ厜OŊ + values: + - UWzAFu2 + - key: M + operator: 罐hĹ;'ǫ貉yĊ啉刉DzQį + - key: zZ + operator: 颉śĴJ|@W補A篐S献;ɾ[_鶙ȱ + values: + - 4BL + namespaces: + - Thgfgf7Z + topologyKey: XBju19e + weight: 1392601493 + automountServiceAccountToken: false + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: LOGIN_JWTSECRET + valueFrom: + secretKeyRef: + key: login-jwt-secret + name: 6maz + envFrom: [] + image: PYDGV/HV3:cI8TzaYkws + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 713465020 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 1849009003 + periodSeconds: 2079209425 + successThreshold: 1679782943 + timeoutSeconds: 2000039211 + name: console + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: {} + securityContext: + allowPrivilegeEscalation: false + procMount: 垮Ř2 + readOnlyRootFilesystem: true + runAsGroup: 5797501600954334000 + runAsNonRoot: true + runAsUser: -8444673787636984000 + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: /etc/console/secrets + name: secrets + readOnly: true + - command: + - opIk + - v9eJ + - 4V + env: + - name: 5Q + value: o + envFrom: + - prefix: eBWmLK + secretRef: + name: FedJi + optional: false + - configMapRef: + name: M + optional: false + prefix: vUvV7W8k0 + secretRef: + name: IA + image: T4SYV + imagePullPolicy: Ƈ祃ǗǤɈ遖竀壙/ + livenessProbe: + failureThreshold: 20929095 + grpc: + port: -1775507003 + service: UZ6BT7NDI + httpGet: + host: QFkZxI6kA + path: tzQ + port: "" + scheme: Ƞ揞á惗É莏6XȪ/ʡ忨償 + initialDelaySeconds: 1046895310 + periodSeconds: -1971173139 + successThreshold: -476756841 + terminationGracePeriodSeconds: 144861231583008740 + timeoutSeconds: 814968592 + name: gEB + ports: + - containerPort: 2060914354 + hostIP: 9IXWKx38q5 + hostPort: -1191426039 + name: 5Mw7k + protocol: 悛ķ鳉ɍ恽j頔Œ6Eʮnx + resources: {} + restartPolicy: 樦ýȃ梪ĵ + stdin: true + stdinOnce: true + terminationMessagePath: c0e + imagePullSecrets: [] + initContainers: [] + nodeSelector: {} + priorityClassName: XtKq + securityContext: + fsGroup: -1425599568169885200 + fsGroupChangePolicy: ƶ Ÿ恢 + runAsGroup: -8737472966684837000 + runAsUser: 99 + supplementalGroups: + - 809809813702093200 + - 6124706841582845000 + - 6159358527003038000 + serviceAccountName: DdF7ALq + tolerations: [] + topologySpreadConstraints: + - labelSelector: {} + maxSkew: 972537130 + minDomains: -499606767 + topologyKey: q5 + whenUnsatisfiable: 鳯°ôŕƨʪuɘ"h貇榧0?cɉjA蜝 + - labelSelector: + matchExpressions: + - key: lAV + operator: 嵖xߟ擱ʄ衯"xɂ + - key: U6 + operator: =换J+Ř:嫚ʥ畠餐ǒŃ + values: + - Vj + - snF6cyZ + - 0sW9y4T5 + matchLabelKeys: + - 2wCjBs + maxSkew: -324080521 + minDomains: 695322418 + nodeAffinityPolicy: ʖ[兘Ũ鬎盦İƲ + topologyKey: z5y4Q8jyHH + whenUnsatisfiable: =Y~É.J樢ȃŤƫ甶Ȍ* + - labelSelector: {} + maxSkew: -1720129802 + minDomains: 1017048856 + nodeTaintsPolicy: 龨9猶e僦ɻ髧Ȍc + topologyKey: qKf6Ef3o + whenUnsatisfiable: ʂ?$鳴寘ŧ6脹餗ſ媷,峇埽 + volumes: + - configMap: + name: 6maz + name: configs + - name: secrets + secret: + secretName: 6maz +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "6maz-test-connection" + namespace: "default" + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: SC + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['6maz:8080'] + restartPolicy: Never + priorityClassName: XtKq +-- testdata/case-017.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: tPiY + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: 9XG3SZW + namespace: default +--- +# Source: console/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: tPiY + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: 9XG3SZW +stringData: + enterprise-license: "" + kafka-protobuf-git-basicauth-password: "" + kafka-sasl-aws-msk-iam-secret-key: "" + kafka-sasl-password: "" + kafka-schema-registry-password: "" + kafka-schemaregistry-tls-ca: "" + kafka-schemaregistry-tls-cert: "" + kafka-schemaregistry-tls-key: "" + kafka-tls-ca: "" + kafka-tls-cert: "" + kafka-tls-key: "" + login-github-oauth-client-secret: jw6tY22 + login-github-personal-access-token: JvG1jx + login-google-groups-service-account.json: "" + login-google-oauth-client-secret: "" + login-jwt-secret: SECRETKEY + login-oidc-client-secret: MalR2 + login-okta-client-secret: mDILgPMjOS9 + login-okta-directory-api-token: M2ywAiP + redpanda-admin-api-password: "" + redpanda-admin-api-tls-ca: "" + redpanda-admin-api-tls-cert: "" + redpanda-admin-api-tls-key: "" +type: Opaque +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} + roles.yaml: |- + roles: + - JlwOk: null + QUzHpm: null + ch3WnNF: null + - {} + - null +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: tPiY + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: 9XG3SZW +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: tPiY + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: 9XG3SZW + namespace: default +spec: + ports: + - name: http + port: 8080 + protocol: TCP + targetPort: 0 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: tPiY + type: ClusterIP +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + J5Z: aLYd149 + LCqYvOjK: Qsk + bU: "" + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: tPiY + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: 9XG3SZW + namespace: default +spec: + replicas: 173 + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: tPiY + strategy: {} + template: + metadata: + annotations: + checksum/config: a9353e622b2ed64d835d05830dc4357d8eb982e89685498d39ac88a30931fb87 + creationTimestamp: null + labels: + LBQpbD: AHB4hNVL + app.kubernetes.io/instance: console + app.kubernetes.io/name: tPiY + ey1GpAHh: fA + spec: + affinity: {} + automountServiceAccountToken: false + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: Z + value: 1PasJFATvz + valueFrom: + configMapKeyRef: + key: Out + name: Z + - name: pUN + value: QTGN + valueFrom: + configMapKeyRef: + key: BLzs5FKV + name: xsgY3vBvZ + optional: true + fieldRef: + apiVersion: 5Ng + fieldPath: Psowh + resourceFieldRef: + containerName: pMz + divisor: "0" + resource: "" + secretKeyRef: + key: IY9s0 + optional: false + - name: LOGIN_JWTSECRET + valueFrom: + secretKeyRef: + key: login-jwt-secret + name: 9XG3SZW + - name: LOGIN_GITHUB_CLIENTSECRET + valueFrom: + secretKeyRef: + key: login-github-oauth-client-secret + name: 9XG3SZW + - name: LOGIN_GITHUB_DIRECTORY_PERSONALACCESSTOKEN + valueFrom: + secretKeyRef: + key: login-github-personal-access-token + name: 9XG3SZW + - name: LOGIN_OKTA_CLIENTSECRET + valueFrom: + secretKeyRef: + key: login-okta-client-secret + name: 9XG3SZW + - name: LOGIN_OKTA_DIRECTORY_APITOKEN + valueFrom: + secretKeyRef: + key: login-okta-directory-api-token + name: 9XG3SZW + - name: LOGIN_OIDC_CLIENTSECRET + valueFrom: + secretKeyRef: + key: login-oidc-client-secret + name: 9XG3SZW + envFrom: + - prefix: oK16T1 + - configMapRef: + name: GxM9 + optional: false + prefix: Hj8 + secretRef: + name: o5P67 + image: 3s/kPWhaC:BcBi + imagePullPolicy: k痿蹒 + livenessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 0 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: console + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 738983906 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: -1729478206 + periodSeconds: 902558671 + successThreshold: 989047880 + timeoutSeconds: -402268186 + resources: + limits: + 0fvc8: "0" + W19cC: "0" + loZ4: "0" + securityContext: + capabilities: + add: + - "" + - 鸼ǀɛ_Y + - 利ƯǢ謼Ŀʇ佔4銣 + privileged: false + procMount: 頿ū詁ǎTɁ¯PlFd只鶗ƝǛƤ臃 + readOnlyRootFilesystem: true + runAsNonRoot: true + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: /etc/console/secrets + name: secrets + readOnly: true + - mountPath: TLaWLIiD + name: 3SwG7HrS + subPath: "" + - mountPath: dXXPfK + name: Bfv9SGjlbgN + subPath: "" + - mountPath: YEOA49 + name: wz4K9oIYM + subPath: "" + - args: + - Bd + command: + - QwtEp + - lLi7 + - kxB1 + image: RpMWaJ + imagePullPolicy: ~崆Ǭe侊k + livenessProbe: + exec: {} + failureThreshold: -2101638962 + grpc: + port: -208999597 + service: jICxjA + initialDelaySeconds: 925230214 + periodSeconds: -996383814 + successThreshold: 152844544 + terminationGracePeriodSeconds: -7802949917649734000 + timeoutSeconds: -188255799 + name: qwOkQZ + ports: + - containerPort: -255758148 + hostIP: R + hostPort: 316791912 + name: 09i3b5oQR + protocol: 腴醗9-鐶 + - containerPort: 247145105 + hostIP: L4 + hostPort: 1727912240 + name: bz7Y1N7 + protocol: 暄璎 + readinessProbe: + exec: + command: + - 2fQQ + failureThreshold: -873648342 + grpc: + port: 889903834 + service: C3 + httpGet: + host: IPHal + path: 5Nb6iW9 + port: tkqo + scheme: m说Ď盐2Ƹ,约h鰥Ȕť3 + initialDelaySeconds: 1391319902 + periodSeconds: -1638942635 + successThreshold: 644454270 + timeoutSeconds: -553602240 + resources: + requests: + 0XxId: "0" + VsY2R9: "0" + ZLtS2: "0" + restartPolicy: ų蓶Lj,g珯i'Sû竒 + terminationMessagePath: Mx7V + terminationMessagePolicy: =Jƈ乚貃庪ș¯ÑVȯ6筌巨华ɀ(v + tty: true + workingDir: nKFDPLJvOh + - args: + - AV3kjV + - Gwq78lY2 + - wq + command: + - D + - EI + - fY5J + env: + - name: eCtpNU + value: jLkcq8S + - name: rynLbx + value: CdqgJabHhM + valueFrom: + configMapKeyRef: + key: uBUH5 + name: Uxei4G1 + optional: false + fieldRef: + apiVersion: Ul9al + fieldPath: vtGid + resourceFieldRef: + containerName: Oc + divisor: "0" + resource: "" + - name: GmDNpa0 + value: 7VJM2XsPm8N + valueFrom: + configMapKeyRef: + key: x3J0PMWE + resourceFieldRef: + containerName: x9Q + divisor: "0" + resource: EKFgoq + secretKeyRef: + key: lOZRvK9 + name: V + image: 1xn6 + imagePullPolicy: ɀ稤¼Mɻ«鐾6Ú{ŬtŮ鄖SSɌ戲 + lifecycle: + postStart: + exec: {} + httpGet: + host: sT2dWyT + path: vvbIxNVANZ + port: aCK8 + scheme: 昿孊卿昤軒JYƜÁ嶠şe灶 + sleep: + seconds: -3542823673709563400 + preStop: + exec: + command: + - "N" + - qkHmJ + - HupYy + httpGet: + host: 137dx + path: y3u7HE + port: -1357399425 + scheme: '@济ɉ鳛讧跕(#7NJɓũǸ]ɨ梊sj' + sleep: + seconds: -2408406850575106600 + name: J6VFtJd3giFt + resources: + requests: + 3dqK0M: "0" + restartPolicy: 70ʆ氶応爱怙鉉塼tƗhY嚇 + securityContext: + allowPrivilegeEscalation: false + capabilities: {} + privileged: false + procMount: ȚƼ提瀴t8oƥc + startupProbe: + exec: {} + failureThreshold: 1782005431 + grpc: + port: 676289916 + service: 3xqeCsf + httpGet: + host: YDL1TP + path: "8" + port: lLWR + scheme: BKō筹 + initialDelaySeconds: 134613881 + periodSeconds: 1547524591 + successThreshold: 1778605907 + terminationGracePeriodSeconds: -7593859121613943000 + timeoutSeconds: 2026260743 + terminationMessagePath: E + terminationMessagePolicy: 碓 + workingDir: kl + - command: + - "" + env: + - name: TG1HQA + value: 5X + valueFrom: + fieldRef: + apiVersion: Vhn + fieldPath: jluMkQnv9 + resourceFieldRef: + containerName: rLfbH + divisor: "0" + resource: "" + - name: "" + value: TOTyqqGn + valueFrom: + fieldRef: + apiVersion: 0CAdSa + fieldPath: LWMRC + resourceFieldRef: + divisor: "0" + resource: G5eZP4R + secretKeyRef: + key: xYOgJL + name: vMTywG + image: 2Z + imagePullPolicy: z.鎸ƦʖFNj棪Ƃ鯌b抵#Dzr + lifecycle: + postStart: + exec: {} + httpGet: + host: k8z + path: TxNa2e + port: -573570086 + scheme: oɌdǹ[M灙螮伪芛探塢庖Njȕ仸 + sleep: + seconds: 4118046687980194000 + preStop: + exec: + command: + - 6iZbF + - OeZTW + httpGet: + host: rbqq + path: sno + port: -429531729 + scheme: s璙Ȼȗ榛ǵ0ƿ.忋闳溨 + name: Cms + ports: + - containerPort: -211101225 + hostIP: 8v + hostPort: 1994344080 + name: kyMvksZa + protocol: fȞ蚊悘ū錩Ȩ龒ċŴ + - containerPort: -806313867 + hostIP: Ky2F2 + hostPort: 1605736520 + name: oe0nMMl + protocol: 慿)"Ǒ3浹襈}(VE-B³閪叒k1绝 + readinessProbe: + exec: {} + failureThreshold: 1398486074 + grpc: + port: 1157090744 + service: oFrTS0 + httpGet: + host: 5pfrE + port: TJb4 + scheme: 畢î + initialDelaySeconds: -1830121652 + periodSeconds: -1398007905 + successThreshold: 1183454316 + timeoutSeconds: 1797763090 + resizePolicy: + - resourceName: hzxTj + restartPolicy: 渣箢樳掯ȉÏǼ店喘©g + resources: + limits: + zGvF9poISMtK: "0" + requests: + lUp3T: "0" + restartPolicy: '}賩6''V霟足''È''*F÷ƙǕ' + stdin: true + terminationMessagePath: 4tn + terminationMessagePolicy: ɢ荵鯴庡ǁ婛埽猜犝笖á7譃ǁ¦GɖC + volumeDevices: + - devicePath: eGfD9B + name: G3Bd + - devicePath: x + name: TB + workingDir: iKksE1 + imagePullSecrets: [] + initContainers: [] + nodeSelector: {} + priorityClassName: qcIlT + securityContext: + fsGroup: 99 + runAsUser: 99 + serviceAccountName: 9XG3SZW + tolerations: + - effect: 懻 + key: JifsKW + operator: 檧űÊǮȡ廄儱RəȏĮ顪ÅÞ + tolerationSeconds: 4501363800484543000 + value: KkCBzwToBMjJ + - effect: B囧ƉOß + key: Q3cj + operator: ɲ朁ß栢 + tolerationSeconds: 4944598504260379000 + value: Z5 + - effect: 敘愰ɰuƪ晐 + key: K8wM + operator: ș + tolerationSeconds: 8375376960471889000 + value: TnWS + topologySpreadConstraints: [] + volumes: + - configMap: + name: 9XG3SZW + name: configs + - name: secrets + secret: + secretName: 9XG3SZW + - name: 3SwG7HrS + secret: + defaultMode: 442 + secretName: VR + - name: Bfv9SGjlbgN + secret: + defaultMode: 383 + secretName: T + - name: wz4K9oIYM + secret: + defaultMode: 13 + secretName: WzM +-- testdata/case-018.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: + X7E: CRSzr + lPi: bGP + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 1qyLP36T + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: uAvlOXf + namespace: default +--- +# Source: console/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 1qyLP36T + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: ExFU3 +stringData: + enterprise-license: "" + kafka-protobuf-git-basicauth-password: IsvQ9 + kafka-sasl-aws-msk-iam-secret-key: 8GlUc + kafka-sasl-password: Vb + kafka-schema-registry-password: UJ7Zl + kafka-schemaregistry-tls-ca: T1Q + kafka-schemaregistry-tls-cert: 17r + kafka-schemaregistry-tls-key: O44 + kafka-tls-ca: n8k9 + kafka-tls-cert: aK + kafka-tls-key: "" + login-github-oauth-client-secret: t6z0n + login-github-personal-access-token: "" + login-google-groups-service-account.json: fpuCEFLL + login-google-oauth-client-secret: h + login-jwt-secret: SECRETKEY + login-oidc-client-secret: t + login-okta-client-secret: 3CcKl + login-okta-directory-api-token: AZt8H77 + redpanda-admin-api-password: NUkb3zIpwAR + redpanda-admin-api-tls-ca: t + redpanda-admin-api-tls-cert: zttTAvj + redpanda-admin-api-tls-key: "" +type: Opaque +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 1qyLP36T + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: ExFU3 + namespace: default +spec: + ports: + - name: http + port: 415 + protocol: TCP + targetPort: 489 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: 1qyLP36T + type: 2cM +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + "": 3E5rtKA + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 1qyLP36T + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: ExFU3 + namespace: default +spec: + replicas: 297 + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: 1qyLP36T + strategy: + rollingUpdate: {} + type: ɬ搢.Ƒ躂ɻɅȄ莨qc婔Åå + template: + metadata: + annotations: + checksum/config: 74234e98afe7498fb5daf1f36ac2d78acc339464f950703b8c019892f982b90b + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: 1qyLP36T + spec: + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: {} + weight: -37659402 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: [] + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + matchLabelKeys: + - ajbCE + - Y0MRgpE8 + namespaceSelector: + matchExpressions: + - key: Auai + operator: ùfƽÜQķɨ逑ʒÅģ + values: + - Q + - key: 1S2Nfq + operator: 臺瑷tƎ鍤p}滳`竦ÙǾ晖ǃʏȵ + namespaces: + - 4GTSAZF + topologyKey: NS733 + weight: -968286112 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: eyt3TPSYPBWDt + operator: e偁&蔄癳.ŚƘ + matchLabelKeys: + - eE7PA8D + - cKalkvb + mismatchLabelKeys: + - Lan + topologyKey: v + weight: -2133598054 + - podAffinityTerm: + mismatchLabelKeys: + - "5" + namespaceSelector: + matchExpressions: + - key: UrrD + operator: ƞ + - key: rkfCsnUcx + operator: ȇ睾¦棌鉝-m糤LPjX.;Ğ× + - key: kla + operator: '"竮壣祠ł9抵墙' + namespaces: + - gyF + topologyKey: ZG + weight: -428742233 + requiredDuringSchedulingIgnoredDuringExecution: + - matchLabelKeys: + - tZZj + namespaces: + - VuG + - I5XU + topologyKey: V2CZqa + - labelSelector: {} + mismatchLabelKeys: + - "" + - q9L4 + - C4YJ57 + namespaces: + - 8xRk06ngy + - WeZO2 + - 7tbTFK + topologyKey: rnpto + automountServiceAccountToken: false + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: KAFKA_SASL_PASSWORD + valueFrom: + secretKeyRef: + key: kafka-sasl-password + name: ExFU3 + - name: KAFKA_PROTOBUF_GIT_BASICAUTH_PASSWORD + valueFrom: + secretKeyRef: + key: kafka-protobuf-git-basicauth-password + name: ExFU3 + - name: KAFKA_SASL_AWSMSKIAM_SECRETKEY + valueFrom: + secretKeyRef: + key: kafka-sasl-aws-msk-iam-secret-key + name: ExFU3 + - name: KAFKA_TLS_CAFILEPATH + value: /etc/console/secrets/kafka-tls-ca + - name: KAFKA_TLS_CERTFILEPATH + value: /etc/console/secrets/kafka-tls-cert + - name: KAFKA_SCHEMAREGISTRY_TLS_CAFILEPATH + value: /etc/console/secrets/kafka-schemaregistry-tls-ca + - name: KAFKA_SCHEMAREGISTRY_TLS_CERTFILEPATH + value: /etc/console/secrets/kafka-schemaregistry-tls-cert + - name: KAFKA_SCHEMAREGISTRY_TLS_KEYFILEPATH + value: /etc/console/secrets/kafka-schemaregistry-tls-key + - name: KAFKA_SCHEMAREGISTRY_PASSWORD + valueFrom: + secretKeyRef: + key: kafka-schema-registry-password + name: ExFU3 + - name: LOGIN_JWTSECRET + valueFrom: + secretKeyRef: + key: login-jwt-secret + name: ExFU3 + - name: LOGIN_GOOGLE_CLIENTSECRET + valueFrom: + secretKeyRef: + key: login-google-oauth-client-secret + name: ExFU3 + - name: LOGIN_GOOGLE_DIRECTORY_SERVICEACCOUNTFILEPATH + value: /etc/console/secrets/login-google-groups-service-account.json + - name: LOGIN_GITHUB_CLIENTSECRET + valueFrom: + secretKeyRef: + key: login-github-oauth-client-secret + name: ExFU3 + - name: LOGIN_OKTA_CLIENTSECRET + valueFrom: + secretKeyRef: + key: login-okta-client-secret + name: ExFU3 + - name: LOGIN_OKTA_DIRECTORY_APITOKEN + valueFrom: + secretKeyRef: + key: login-okta-directory-api-token + name: ExFU3 + - name: LOGIN_OIDC_CLIENTSECRET + valueFrom: + secretKeyRef: + key: login-oidc-client-secret + name: ExFU3 + - name: REDPANDA_ADMINAPI_PASSWORD + valueFrom: + secretKeyRef: + key: redpanda-admin-api-password + name: ExFU3 + - name: REDPANDA_ADMINAPI_TLS_CAFILEPATH + value: /etc/console/secrets/redpanda-admin-api-tls-ca + - name: REDPANDA_ADMINAPI_TLS_CERTFILEPATH + value: /etc/console/secrets/redpanda-admin-api-tls-cert + envFrom: + - prefix: hg + secretRef: + name: eLM59WyoAXO + image: iCFSIwyDtoG/6V6:6uR + imagePullPolicy: 螣暛擂ɾ#鏲*胭8饭1胠 + livenessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 0 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: console + ports: + - containerPort: 489 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + limits: + QZqMxIAt: "0" + SUsu9: "0" + requests: + EMOXCuje: "0" + EzKKMIR: "0" + securityContext: + runAsNonRoot: true + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: /etc/console/secrets + name: secrets + readOnly: true + - envFrom: + - prefix: EVZ + secretRef: + name: MxD + optional: true + - configMapRef: + name: A + optional: false + prefix: HuqxI + secretRef: + name: A + optional: true + image: SU + imagePullPolicy: 禵7璙p + lifecycle: + postStart: + httpGet: + host: YZMjhOUO8IS + path: nzYfH + port: Fcx + scheme: 矪Q9 + sleep: + seconds: 3463625415546708000 + livenessProbe: + failureThreshold: -560403806 + grpc: + port: 1751268094 + service: I + httpGet: + host: 0Sb + path: Utm2X + port: 395973041 + scheme: 醆蚎忨ŕ縨ƍ爋釬šÒ暺ƒŎO記岣 + initialDelaySeconds: -1011110535 + periodSeconds: -1229381750 + successThreshold: 260149510 + timeoutSeconds: 74546945 + name: e + resizePolicy: + - resourceName: XNKV + restartPolicy: ì焹.¬哄ȾŢȎȴe$p尶m`飻Ȭ + - resourceName: "" + restartPolicy: 閭I哗.寢荨ʪɛ侭ȵ(8 + resources: + requests: + 3nUsL: "0" + securityContext: + allowPrivilegeEscalation: false + privileged: false + readOnlyRootFilesystem: false + runAsGroup: -8616852535795885000 + terminationMessagePath: FjZ + terminationMessagePolicy: ÿb熿3,ćp寫ʃ#叺渍ƣș + volumeDevices: + - devicePath: Xvjm + name: 7yLA + - devicePath: 1Ci + name: Y0AloAQS + - devicePath: Gt + name: ZMKKc + workingDir: Mh + imagePullSecrets: + - name: vlnGQbo3y + initContainers: [] + nodeSelector: + Vckw: ifBZ9p7 + priorityClassName: 6jxv + securityContext: + fsGroup: 99 + runAsUser: 99 + serviceAccountName: uAvlOXf + tolerations: + - effect: č喅Ȳ崥ï{禙ÊÿC逻準?霘2 + key: YJE + operator: 珟 + tolerationSeconds: 3838637075734495700 + value: 1VemeDTEk1 + - effect: 艋Ƿ淛襀|Ǽ&矠Ģ凍J賜ɰō + key: ggxS8L + operator: 閞判ŏ + tolerationSeconds: -2249155605077506300 + value: m3c + - effect: 'Ljə]IŴ:' + key: 4BkJSo + value: Le + topologySpreadConstraints: + - matchLabelKeys: + - uyTA + - rJcqdY3 + maxSkew: 1887613958 + nodeAffinityPolicy: u鞝侠轁蛃6Ơfrt迄ʇQ勭ĶÇǻě + topologyKey: 3f9j + whenUnsatisfiable: µ + volumes: + - configMap: + name: ExFU3 + name: configs + - name: secrets + secret: + secretName: ExFU3 +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "ExFU3-test-connection" + namespace: "default" + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 1qyLP36T + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + imagePullSecrets: + - name: vlnGQbo3y + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['ExFU3:415'] + restartPolicy: Never + priorityClassName: 6jxv +-- testdata/case-019.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 8MIg + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: NZ7h9 + namespace: default +--- +# Source: console/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 8MIg + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: NZ7h9 +stringData: + enterprise-license: "" + kafka-protobuf-git-basicauth-password: "" + kafka-sasl-aws-msk-iam-secret-key: "" + kafka-sasl-password: "" + kafka-schema-registry-password: "" + kafka-schemaregistry-tls-ca: "" + kafka-schemaregistry-tls-cert: "" + kafka-schemaregistry-tls-key: "" + kafka-tls-ca: "" + kafka-tls-cert: "" + kafka-tls-key: "" + login-github-oauth-client-secret: "" + login-github-personal-access-token: "" + login-google-groups-service-account.json: "" + login-google-oauth-client-secret: "" + login-jwt-secret: SECRETKEY + login-oidc-client-secret: "" + login-okta-client-secret: "" + login-okta-directory-api-token: "" + redpanda-admin-api-password: "" + redpanda-admin-api-tls-ca: "" + redpanda-admin-api-tls-cert: "" + redpanda-admin-api-tls-key: "" +type: Opaque +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 8MIg + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: NZ7h9 +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 8MIg + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: NZ7h9 + namespace: default +spec: + ports: + - name: http + port: 8080 + protocol: TCP + targetPort: 0 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: 8MIg + type: ClusterIP +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + lgiIA: u + wK8: JrSfKH + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 8MIg + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: NZ7h9 + namespace: default +spec: + replicas: 79 + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: 8MIg + strategy: + type: 鎦v財ɕŪ + template: + metadata: + annotations: + checksum/config: 9960ac5c5faddbc59ee9638bfac7f4fd7513b7e295e3fcc28b0fdfabc2aba1d3 + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: 8MIg + spec: + affinity: {} + automountServiceAccountToken: true + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: pJ + value: whmTukCTD + valueFrom: + configMapKeyRef: + key: OHk + name: "3" + fieldRef: + apiVersion: TSp7 + fieldPath: mEUVMSp7vUo + resourceFieldRef: + containerName: bBDw + divisor: "0" + resource: tIcs3z + secretKeyRef: + key: jIR5V + name: "9" + - name: ZCEPmHP + value: FhwE4R + valueFrom: + fieldRef: + apiVersion: Nv + fieldPath: WMXeIjk + resourceFieldRef: + containerName: Hbt + divisor: "0" + resource: mo7F + - name: LOGIN_JWTSECRET + valueFrom: + secretKeyRef: + key: login-jwt-secret + name: NZ7h9 + envFrom: [] + image: GNXgFQ/W3:2vPed + imagePullPolicy: 韃ĝ + livenessProbe: + failureThreshold: -1736131786 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 538755540 + periodSeconds: -937262167 + successThreshold: 2014961170 + timeoutSeconds: -614674118 + name: console + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + failureThreshold: -1936056692 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: -2019126091 + periodSeconds: -1696700553 + successThreshold: 398361977 + timeoutSeconds: -184667912 + resources: {} + securityContext: + allowPrivilegeEscalation: true + capabilities: + drop: + - 狞濮噞饅烥H}湛m=U+卓Ǭï呣8Ú + privileged: true + runAsNonRoot: true + runAsUser: -471077223001866500 + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: /etc/console/secrets + name: secrets + readOnly: true + - mountPath: UF6 + mountPropagation: ĻsŸ氂ǐ钋鮠Ĺ咳渼.pɫ + name: W1LIZa3 + subPath: qdDtjk + subPathExpr: Ew + imagePullSecrets: [] + initContainers: [] + nodeSelector: {} + priorityClassName: FERw + securityContext: + fsGroup: 99 + runAsUser: 99 + serviceAccountName: NZ7h9 + tolerations: + - effect: 飝壊%ǂP胅ɂǏ趸疷擁鹒DŽ营風顺z拇 + key: Ku2m + operator: ŲǪFTǗǔȟʥȰȎǎo玼Ü + value: 1u + - effect: 雾Ź歘ɇƇ昨OČƑɎ騨Ŗ=Ì楯 + key: 12vKa + operator: ( + value: u + topologySpreadConstraints: [] + volumes: + - configMap: + name: NZ7h9 + name: configs + - name: secrets + secret: + secretName: NZ7h9 +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "NZ7h9-test-connection" + namespace: "default" + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 8MIg + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['NZ7h9:8080'] + restartPolicy: Never + priorityClassName: FERw +-- testdata/case-020.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: + Cs0Tv: PNgn + tawhZGj4: yuBQ1 + xdl: jbYUlUI + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: zzmAR9 + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: HMpc + namespace: default +--- +# Source: console/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: zzmAR9 + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: Om7 +stringData: + enterprise-license: "" + kafka-protobuf-git-basicauth-password: "" + kafka-sasl-aws-msk-iam-secret-key: "" + kafka-sasl-password: "" + kafka-schema-registry-password: "" + kafka-schemaregistry-tls-ca: "" + kafka-schemaregistry-tls-cert: "" + kafka-schemaregistry-tls-key: "" + kafka-tls-ca: "" + kafka-tls-cert: "" + kafka-tls-key: "" + login-github-oauth-client-secret: XhRg8T + login-github-personal-access-token: oB8xbs + login-google-groups-service-account.json: "" + login-google-oauth-client-secret: "" + login-jwt-secret: SECRETKEY + login-oidc-client-secret: "" + login-okta-client-secret: saEi + login-okta-directory-api-token: tq8L + redpanda-admin-api-password: "" + redpanda-admin-api-tls-ca: "" + redpanda-admin-api-tls-cert: "" + redpanda-admin-api-tls-key: "" +type: Opaque +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: zzmAR9 + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: Om7 +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: zzmAR9 + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: Om7 + namespace: default +spec: + ports: + - name: http + port: 310 + protocol: TCP + targetPort: 28 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: zzmAR9 + type: "" +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + 0lA: PZvwfKrip + AUm: KY + KBFrJC: hkdfq + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: zzmAR9 + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: Om7 + namespace: default +spec: + replicas: 344 + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: zzmAR9 + strategy: + rollingUpdate: {} + type: x&N涮ĶJ­ɕ + template: + metadata: + annotations: + checksum/config: 2881fbe0f4a9d0f2f17dbbbe515c08d46dd6d4a6d2c84c3482c94ace8ee6b09f + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: zzmAR9 + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - {} + - matchExpressions: + - key: a23jbG + operator: yb庇ɍ闒ǰPâƟVsJu + values: + - "" + - 1lQmmGa8 + - XzVleDXV4YoRc + - key: 3Gwd9r + operator: 4Nj7Ġ$Ea狆Ö絞Ƙ殈廔as知 + - key: 7C4FjM + operator: ɩ.叧¬ʧ倒 + matchFields: + - key: H + operator: Ğų* + values: + - 0i + - qK + - key: 7ocDt + operator: 餯ǚ璗汭槰<ƤƐ評ź膹棅珢ȹ3鮑 + values: + - g5Aa1Hm + - LKNvXrtO + - key: o + operator: ŎJ甧鷓 + values: + - vJQQjLRrqIK + - Isj + - 6EBsy + - matchFields: + - key: H0oh1dBCg + operator: 鉔qƿ氵[ȕ凭Śȅ3džȿȳ + name: xYM + subPath: nMMkHAUoYIsN + subPathExpr: 579Yn2LXk + - mountPath: 5z + mountPropagation: Ƀ陪7k惿Ɏǚ霤ƨƱ«ɤ»ȣ薥頠媉fʠ + name: KIX5g + readOnly: true + subPath: CGOswgk + subPathExpr: oxiB23ZW2KX + workingDir: IzOAr + - args: + - jrZTvs + env: + - name: jxl5Q + value: fm2F7DzZA + image: r7sTpTP8N + imagePullPolicy: 眒弿 + lifecycle: + preStop: + httpGet: + host: WEBUk + path: "1" + port: -377365982 + scheme: 娖阋顿|儴Éȱ鋦 + livenessProbe: + exec: + command: + - 2j + failureThreshold: -1631622345 + grpc: + port: -188887701 + service: s + httpGet: + host: "6" + path: 07rm4AD + port: DCtZ5 + scheme: ʼnK襡5殛鯙ȋʛ稲(C姓 + initialDelaySeconds: -1011676147 + periodSeconds: -1141844037 + successThreshold: -1528778970 + terminationGracePeriodSeconds: 422553046190448100 + timeoutSeconds: 99607263 + name: rhg + ports: + - containerPort: 1265703793 + hostIP: lYiq + hostPort: -931710582 + name: r2OdlKyZ + protocol: ŌK4Ʒ霖R婧,Ģ墤ʠ_Ƒ亽vĨO + - containerPort: -1093198499 + hostIP: xHuDhI2 + hostPort: 1423992590 + name: WdH + protocol: K嚜pn犓ɯ`劮ƫķPLm + resizePolicy: + - resourceName: M3EK5NW + restartPolicy: Ɲ囩 + resources: + limits: + 4zeCyo: "0" + PgUjG: "0" + requests: + IseC3: "0" + WHgRSz: "0" + yzZn: "0" + restartPolicy: ijƞ墫噌L诠=脳%Ɗ + securityContext: + privileged: false + readOnlyRootFilesystem: false + runAsGroup: -1074724161449892000 + runAsUser: 8255497511479977000 + startupProbe: + exec: {} + failureThreshold: -1172398717 + grpc: + port: 1919051215 + service: "" + initialDelaySeconds: 2020291403 + periodSeconds: 450860281 + successThreshold: 193397000 + timeoutSeconds: -665894379 + stdin: true + terminationMessagePath: MCVu + terminationMessagePolicy: ŷÍ:+壩ùI賎Rɜ卮cɣS惕mIɭ + tty: true + workingDir: 2L97y + imagePullSecrets: + - name: iA1C + - name: ZOdo + - name: qTOK0W + initContainers: + - 'error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string + into Go value of type []interface {}' + nodeSelector: {} + priorityClassName: 0bGHQk7gL + securityContext: + fsGroup: -6946946538076897000 + fsGroupChangePolicy: 呆ɔȂwijà + runAsGroup: 3944693697856007700 + runAsNonRoot: true + runAsUser: -732766343758518300 + supplementalGroups: + - -5691922089175975000 + serviceAccountName: H5TDAALUdD + tolerations: + - effect: 媄 + key: IQD9Yww8 + operator: bǾå鱍 + tolerationSeconds: -7454358062612207000 + value: odxS1Q2Sd + - effect: Ɣv璔}oȡʞ¤ + key: ySGX + operator: ƪ渺¸貗ȹV廋ȉňu増嬎Ë韍ǘz茩Ƹ怯 + tolerationSeconds: -1083807005557333500 + value: bAy + topologySpreadConstraints: [] + volumes: + - configMap: + name: Uo + name: configs + - name: Jq0CSftnp + - name: QMHGzzYC2HW + - name: 1PkbzhfK +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "Uo-test-connection" + namespace: "default" + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: Mh + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + imagePullSecrets: + - name: iA1C + - name: ZOdo + - name: qTOK0W + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['Uo:8080'] + restartPolicy: Never + priorityClassName: 0bGHQk7gL +-- testdata/case-026.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: false +kind: ServiceAccount +metadata: + annotations: + "": tWl + 5mzy: 4t87VKeHA + a: UqD3iv5LoNYP + creationTimestamp: null + labels: + "": h0uSAPIi + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: vLjrafvp + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + kuKPk7: "" + name: Utu8ZHG2 + namespace: default +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + "": h0uSAPIi + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: vLjrafvp + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + kuKPk7: "" + name: qhaD + namespace: default +spec: + ports: + - name: http + port: 8080 + protocol: TCP + targetPort: 0 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: vLjrafvp + type: ClusterIP +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: {} + creationTimestamp: null + labels: + "": h0uSAPIi + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: vLjrafvp + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + kuKPk7: "" + name: qhaD + namespace: default +spec: + replicas: 78 + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: vLjrafvp + strategy: + rollingUpdate: {} + type: I6终j2炅ȲbȻ + template: + metadata: + annotations: + LtAjph: 8Q + MiPvJub: 0x + checksum/config: 74234e98afe7498fb5daf1f36ac2d78acc339464f950703b8c019892f982b90b + j: xR98FRh + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: vLjrafvp + spec: + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: GP94 + operator: 駑Ŀ峇[ɕdž0 + values: + - jjNFKv8 + - uG7Rs + - ApO075 + weight: -549077137 + - preference: + matchExpressions: + - key: R88 + operator: Dzv)bôȏ磜覐橮波赘T^ + values: + - DscaGMdgXV + - uy + - N3d + - key: "" + operator: 誮Vw!/毴Z匌忶ª渆 + values: + - 4mX0s + - key: byy + operator: 鿟y馡錥HJ鶟b左Ő*čt顭塶 + values: + - 6oQ + - 9r22TM + matchFields: + - key: fNLkt + operator: "" + values: + - tW + - M03GnpfhQn + - key: WQQs + operator: 騡(Í芝x焍麅ɰ窓ɶÜò鵹 + weight: 579622465 + podAffinity: {} + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: {} + namespaceSelector: + matchLabels: + IYAfjz: GloAc + namespaces: + - hfFjlR + - KWIdaP11Y + - 3Dn + topologyKey: UB + - labelSelector: + matchExpressions: + - key: B7LSh + operator: ɉ邦夝ɷ1傹Þ袳@ɲ鉴 + matchLabelKeys: + - "n" + namespaceSelector: {} + namespaces: + - 88M + - fIEJUewFK + topologyKey: i + automountServiceAccountToken: true + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: [] + envFrom: [] + image: docker.redpanda.com/redpandadata/console:v2.7.0 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 1372450161 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: -913177144 + periodSeconds: 912808843 + successThreshold: -765941931 + timeoutSeconds: 1174210794 + name: console + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 1666039794 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 989921147 + periodSeconds: 536392931 + successThreshold: 1020018972 + timeoutSeconds: 1790731281 + resources: {} + securityContext: + capabilities: + drop: + - ɿX齀蹪 + privileged: true + procMount: Ƚ[孠犥ƶʒ)遷U竕 + runAsGroup: 5229411704597624000 + runAsNonRoot: true + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: U6f3w + name: ooYxXE + subPath: "" + - mountPath: qzOMXCl + name: Hmms9 + subPath: "" + - mountPath: dXa6uPxR + name: "" + subPath: "" + - mountPath: q + mountPropagation: 跐ʩ4鄧SD炿ɜǚhU + name: "" + subPath: SCLzbAMUW3x + subPathExpr: nzFw + - mountPath: cX8U + mountPropagation: b幈簇@艭K + name: b + readOnly: true + subPath: u5fY + subPathExpr: TRymQ + imagePullSecrets: [] + initContainers: + - 'error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string + into Go value of type []interface {}' + nodeSelector: + ggwC: SQ + rIwToCbB: tUBM5 + priorityClassName: JnI8 + securityContext: + fsGroup: -2594082004410587000 + fsGroupChangePolicy: 'ċV1鯍E ' + runAsGroup: -880388195249084200 + runAsNonRoot: false + runAsUser: -9051010573896130000 + supplementalGroups: + - -2777109499517678000 + serviceAccountName: Utu8ZHG2 + tolerations: [] + topologySpreadConstraints: + - labelSelector: {} + maxSkew: -154369657 + minDomains: -319419210 + nodeTaintsPolicy: '#Vʅ糗斬ƈ橮IJȶ纀' + topologyKey: dTnKex + whenUnsatisfiable: '@OȤ驮Ʀ琓' + volumes: + - configMap: + name: qhaD + name: configs + - name: ooYxXE + secret: + defaultMode: 45 + secretName: LyH9zvv + - name: Hmms9 + secret: + defaultMode: 429 + secretName: zvR + - name: "" + secret: + defaultMode: 39 + secretName: PC2Ms7 + - name: LeIYAb + - name: 176OvjD + - name: b6NpMGfVo1N +--- +# Source: console/templates/ingress.yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + annotations: + Lftu: PjroKEh + qvZJNWSzR: Jpoyc0 + creationTimestamp: null + labels: + "": h0uSAPIi + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: vLjrafvp + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + kuKPk7: "" + name: qhaD +spec: + ingressClassName: cAir + rules: + - host: o + http: + paths: null + - host: i18Wi + http: + paths: + - backend: + service: + name: qhaD + port: + number: 8080 + path: apsXYvp + pathType: 7q5 + - host: 8eBXg + http: + paths: + - backend: + service: + name: qhaD + port: + number: 8080 + path: cMbMbCQl + pathType: gJT + - backend: + service: + name: qhaD + port: + number: 8080 + path: XvfTwH + pathType: 4se + tls: + - hosts: + - fqD + - JDOgIG + secretName: vzUD + - hosts: + - M6H + - T + - twxgtsi + secretName: lg5siLdo +-- testdata/case-027.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: + "": ta51q + RW5sX: LXvP + creationTimestamp: null + labels: + Q0: "" + T4ZmAFi: nfIb0b + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: h9P + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: 55C9f3 + namespace: default +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: + Gi0OSuP5jF: ARBECJB + qId: Bo + wPKI: "" + creationTimestamp: null + labels: + Q0: "" + T4ZmAFi: nfIb0b + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: h9P + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: 61hunk + namespace: default +spec: + ports: + - name: http + port: 376 + protocol: TCP + targetPort: 473 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: h9P + type: G2gqK +--- +# Source: console/templates/ingress.yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + annotations: + "": ZtbWlWc + y1ML9Hmg: d6h9 + creationTimestamp: null + labels: + Q0: "" + T4ZmAFi: nfIb0b + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: h9P + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: 61hunk +spec: + ingressClassName: Ijdd3 + rules: + - host: chart-example.local + http: + paths: + - backend: + service: + name: 61hunk + port: + number: 376 + path: / + pathType: ImplementationSpecific + tls: + - hosts: null + secretName: x + - hosts: null + secretName: aSf1 +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "61hunk-test-connection" + namespace: "default" + labels: + Q0: "" + T4ZmAFi: nfIb0b + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: h9P + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + imagePullSecrets: + - name: jkqm + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['61hunk:376'] + restartPolicy: Never + priorityClassName: bpi +-- testdata/case-028.yaml.golden -- +--- +# Source: console/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + labels: + BKrxjHNg8: qlqPhj + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 5XQu4RW + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: odFI2M4 +stringData: + enterprise-license: "" + kafka-protobuf-git-basicauth-password: aM + kafka-sasl-aws-msk-iam-secret-key: pcNJ4lPh + kafka-sasl-password: OT9m4 + kafka-schema-registry-password: 4VybIhiIU + kafka-schemaregistry-tls-ca: FVWvaL5HS3DE + kafka-schemaregistry-tls-cert: UqZl + kafka-schemaregistry-tls-key: ch + kafka-tls-ca: 0h0Ac6CS + kafka-tls-cert: pNm4uHVMn + kafka-tls-key: "" + login-github-oauth-client-secret: 5XbGmlDmls + login-github-personal-access-token: y0PF13 + login-google-groups-service-account.json: w3 + login-google-oauth-client-secret: lEvrgxa + login-jwt-secret: SECRETKEY + login-oidc-client-secret: VfRrL3 + login-okta-client-secret: 1Gm + login-okta-directory-api-token: hgmY7AyguR + redpanda-admin-api-password: WvzP1D53 + redpanda-admin-api-tls-ca: dxtnG + redpanda-admin-api-tls-cert: Rs3rHA8Qdb + redpanda-admin-api-tls-key: 7hsD +type: Opaque +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + BKrxjHNg8: qlqPhj + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 5XQu4RW + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: odFI2M4 +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + BKrxjHNg8: qlqPhj + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 5XQu4RW + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: odFI2M4 + namespace: default +spec: + ports: + - name: http + port: 8080 + protocol: TCP + targetPort: 0 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: 5XQu4RW + type: ClusterIP +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + VLzukyGLL5H: "" + creationTimestamp: null + labels: + BKrxjHNg8: qlqPhj + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 5XQu4RW + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: odFI2M4 + namespace: default +spec: + replicas: 278 + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: 5XQu4RW + strategy: + rollingUpdate: {} + type: 砓涶rƀł庫x烮ȯ~茤įêŎZ姮Ⱦ + template: + metadata: + annotations: + YefFO9J: uVUZra + checksum/config: cc3f7478d926a8c80ab516ac0060a56c87bbbfdd227b765567fa8644fbee7f09 + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: 5XQu4RW + n8PG: NEb + sINjD1zSK: exkAcWK3 + yG: T + spec: + affinity: + podAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + 9yhGd: kXTYKV + xb5Co: trB98 + matchLabelKeys: + - gTre + - 3SLXY + namespaceSelector: {} + namespaces: + - q + - j3 + - k76qB + topologyKey: gz6KtIn43 + - labelSelector: + matchLabels: + 9slaN: 9Cv + M: NcJRMIAxd6 + f4JK: QX + matchLabelKeys: + - BGI9Dr + mismatchLabelKeys: + - SZUKIlPB + - WzTTmXWoFc + - wXLg9viobEw + namespaceSelector: + matchLabels: + MZx: u + NztFyV3: EvzmJzLQcn + topologyKey: iLs + - labelSelector: + matchExpressions: + - key: d3S + operator: ò洏ʓ暝歆Ű鈰钌鸔栵ù舁Tb曯ƫ貊ȵ + values: + - sanCz + - lZ + - 5rZ0 + matchLabels: + MEoILl9k: Jd + hVfX4: "" + "n": yhV + matchLabelKeys: + - HOI + namespaceSelector: + matchLabels: + fodO5ovc74m: lvF + mlCh: E1 + ve7: r4P5biTA + topologyKey: CtXr + automountServiceAccountToken: true + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: wti + value: AYZm + valueFrom: + configMapKeyRef: + key: Sxryl + name: xXe78 + fieldRef: + apiVersion: HoyJsUxLKd + fieldPath: 2Ns + secretKeyRef: + key: w7WydZL + name: CgxV7 + optional: true + - name: eEKnv + value: BBAXaggk0n + valueFrom: + secretKeyRef: + key: GRP + name: dYBHtrO + optional: true + - name: KAFKA_SASL_PASSWORD + valueFrom: + secretKeyRef: + key: kafka-sasl-password + name: odFI2M4 + - name: KAFKA_PROTOBUF_GIT_BASICAUTH_PASSWORD + valueFrom: + secretKeyRef: + key: kafka-protobuf-git-basicauth-password + name: odFI2M4 + - name: KAFKA_SASL_AWSMSKIAM_SECRETKEY + valueFrom: + secretKeyRef: + key: kafka-sasl-aws-msk-iam-secret-key + name: odFI2M4 + - name: KAFKA_TLS_CAFILEPATH + value: /etc/console/secrets/kafka-tls-ca + - name: KAFKA_TLS_CERTFILEPATH + value: /etc/console/secrets/kafka-tls-cert + - name: KAFKA_SCHEMAREGISTRY_TLS_CAFILEPATH + value: /etc/console/secrets/kafka-schemaregistry-tls-ca + - name: KAFKA_SCHEMAREGISTRY_TLS_CERTFILEPATH + value: /etc/console/secrets/kafka-schemaregistry-tls-cert + - name: KAFKA_SCHEMAREGISTRY_TLS_KEYFILEPATH + value: /etc/console/secrets/kafka-schemaregistry-tls-key + - name: KAFKA_SCHEMAREGISTRY_PASSWORD + valueFrom: + secretKeyRef: + key: kafka-schema-registry-password + name: odFI2M4 + - name: LOGIN_JWTSECRET + valueFrom: + secretKeyRef: + key: login-jwt-secret + name: odFI2M4 + - name: LOGIN_GOOGLE_CLIENTSECRET + valueFrom: + secretKeyRef: + key: login-google-oauth-client-secret + name: odFI2M4 + - name: LOGIN_GOOGLE_DIRECTORY_SERVICEACCOUNTFILEPATH + value: /etc/console/secrets/login-google-groups-service-account.json + - name: LOGIN_GITHUB_CLIENTSECRET + valueFrom: + secretKeyRef: + key: login-github-oauth-client-secret + name: odFI2M4 + - name: LOGIN_GITHUB_DIRECTORY_PERSONALACCESSTOKEN + valueFrom: + secretKeyRef: + key: login-github-personal-access-token + name: odFI2M4 + - name: LOGIN_OKTA_CLIENTSECRET + valueFrom: + secretKeyRef: + key: login-okta-client-secret + name: odFI2M4 + - name: LOGIN_OKTA_DIRECTORY_APITOKEN + valueFrom: + secretKeyRef: + key: login-okta-directory-api-token + name: odFI2M4 + - name: LOGIN_OIDC_CLIENTSECRET + valueFrom: + secretKeyRef: + key: login-oidc-client-secret + name: odFI2M4 + - name: REDPANDA_ADMINAPI_PASSWORD + valueFrom: + secretKeyRef: + key: redpanda-admin-api-password + name: odFI2M4 + - name: REDPANDA_ADMINAPI_TLS_CAFILEPATH + value: /etc/console/secrets/redpanda-admin-api-tls-ca + - name: REDPANDA_ADMINAPI_TLS_KEYFILEPATH + value: /etc/console/secrets/redpanda-admin-api-tls-key + - name: REDPANDA_ADMINAPI_TLS_CERTFILEPATH + value: /etc/console/secrets/redpanda-admin-api-tls-cert + envFrom: + - configMapRef: + name: I6Dbq + optional: false + secretRef: + name: fhgE + optional: false + - prefix: L0m + - configMapRef: + name: pVHt + optional: true + prefix: 0xFYui3Ke2pJ + secretRef: + name: IBHH4sd + optional: false + image: qnkfx/ARBa:BetSp + imagePullPolicy: ȸ才TkâĆ8o + livenessProbe: + failureThreshold: -544797053 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 1464359845 + periodSeconds: -775253635 + successThreshold: -2065370772 + timeoutSeconds: 3873767 + name: console + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 286014638 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: -1755094379 + periodSeconds: 712612179 + successThreshold: 1265199044 + timeoutSeconds: 939664799 + resources: + limits: + H2g: "0" + requests: + i0vpd: "0" + piR58NXU: "0" + securityContext: + privileged: true + procMount: '`4乬+ʍÿȦ!常ʥ_' + readOnlyRootFilesystem: false + runAsNonRoot: true + runAsUser: 8119235947749130000 + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: /etc/console/secrets + name: secrets + readOnly: true + - mountPath: hHTC4sQ + mountPropagation: ƭ埢Ş@ʮ擈Ɓsmďĝ + name: mVbo + subPath: bI + subPathExpr: q6R + - mountPath: "" + name: gC + readOnly: true + subPath: 5xyS + subPathExpr: Ju9L6o + imagePullSecrets: + - name: Nu2 + - name: j0 + initContainers: + - 'error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string + into Go value of type []interface {}' + nodeSelector: + fD: q5Hun + priorityClassName: u8cTjKLB + securityContext: + fsGroup: -9123846953160880000 + fsGroupChangePolicy: UƻA竘锵]湞ȊM + runAsNonRoot: false + runAsUser: 2594597056592417300 + sysctls: + - name: 4eRaw + value: HnWeNFR + - name: 4hP + value: UoCU8Ni + - name: d + value: TpLFHKFo + serviceAccountName: 5zV + tolerations: + - effect: x)|綻%ŴC¸÷G) + key: 6c + operator: 皐łʨɆ挓R衯Ǫ诌ƍ爂vĂB麧尣Ć* + tolerationSeconds: 341291117142213700 + value: 45gIZCr + - effect: ɿ鎅ɸƱɿ韆頟R躦0P^,豐ƨe祠攇覙 + operator: ß¼ʐȻ*溃N妞 + tolerationSeconds: -7034164218355111000 + value: xb5 + topologySpreadConstraints: [] + volumes: + - configMap: + name: odFI2M4 + name: configs + - name: secrets + secret: + secretName: odFI2M4 + - name: 0nP + - name: 5Mq +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "odFI2M4-test-connection" + namespace: "default" + labels: + BKrxjHNg8: qlqPhj + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 5XQu4RW + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + imagePullSecrets: + - name: Nu2 + - name: j0 + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['odFI2M4:8080'] + restartPolicy: Never + priorityClassName: u8cTjKLB +-- testdata/case-029.yaml.golden -- +--- +# Source: console/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + labels: + HzuQ: mCfbHBQ + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 3Wh + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + xi7L: ibI45 + name: HK +stringData: + enterprise-license: "" + kafka-protobuf-git-basicauth-password: "" + kafka-sasl-aws-msk-iam-secret-key: "" + kafka-sasl-password: "" + kafka-schema-registry-password: "" + kafka-schemaregistry-tls-ca: "" + kafka-schemaregistry-tls-cert: "" + kafka-schemaregistry-tls-key: "" + kafka-tls-ca: "" + kafka-tls-cert: "" + kafka-tls-key: "" + login-github-oauth-client-secret: "" + login-github-personal-access-token: "" + login-google-groups-service-account.json: "" + login-google-oauth-client-secret: "" + login-jwt-secret: SECRETKEY + login-oidc-client-secret: "" + login-okta-client-secret: "" + login-okta-directory-api-token: "" + redpanda-admin-api-password: "" + redpanda-admin-api-tls-ca: "" + redpanda-admin-api-tls-cert: "" + redpanda-admin-api-tls-key: "" +type: Opaque +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} + roles.yaml: |- + roles: + - null + - null +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + HzuQ: mCfbHBQ + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 3Wh + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + xi7L: ibI45 + name: HK +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: + 33Yi: tesf5 + creationTimestamp: null + labels: + HzuQ: mCfbHBQ + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 3Wh + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + xi7L: ibI45 + name: HK + namespace: default +spec: + ports: + - name: http + port: 389 + protocol: TCP + targetPort: 52 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: 3Wh + type: sIQBZD +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + WVwaqt: gTMC + s6HZpOA: bc0 + sZaCXy: LXRQNTghxb1 + creationTimestamp: null + labels: + HzuQ: mCfbHBQ + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 3Wh + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + xi7L: ibI45 + name: HK + namespace: default +spec: + replicas: 385 + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: 3Wh + strategy: + rollingUpdate: {} + template: + metadata: + annotations: + IVy: ho3qpcI + checksum/config: ed80a6573dafe73ab884b6322e9c75c1018d618e61286f9e61f445266092293d + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: 3Wh + spec: + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: hPtYq9oSSQ + operator: ŗ妃Mīú玢盛 + values: + - T0M + - aywAkbl + - key: F7yCY + operator: '2Pl@äEɜś`PȾ槯c:' + values: + - n7sIXrD6 + - 5EPSQgq3v + matchFields: + - key: wOOgY + operator: 乾Ǧ + values: + - GqfE + - key: gRF5bu + operator: DŸQ95ʊÊj蕵髪OHōM4Ľɝ钣 + values: + - 2rEXM1C + - BB + - key: TK75p + operator: 譌嵡荀Ș枻賿ė + values: + - MHB + - sI + weight: -1638497382 + - preference: + matchExpressions: + - key: sgUr6t + operator: ʁE'[剳嫯Ȧ梳*&櫺窟ľ幣ɥ{紌 + values: + - 6x + - NRmDb1X + - key: VrZW4eZ + operator: 蘨ȘÚ籘J嬋JƒÎhUl田U + values: + - 0cG6ed0 + - I + - key: Ui + operator: 遂樸tUŏǞF)橷嵱 + values: + - mUT9H9 + matchFields: + - key: zzI6 + operator: ƈ肶帅ʒb漄i + values: + - 9Xi0r + - key: Bm + operator: 嚏鈻峓霙ʊcʔ暏g圖鹔夺mą¹跑 + values: + - tvOC + weight: 1006541829 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: ZlUi + operator: ʯ鼙%淹ȏ č>稄鱑Í朹s狑Ȱ螪;ǃ嘲 + values: + - gIlS + - 5lD7AvT7I + - "8" + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: hi0zfFEN + operator: 裧禿 + values: + - SymXRnv + - iKr + mismatchLabelKeys: + - wesfXhv + - Z78yvK + namespaceSelector: + matchExpressions: + - key: jqHt + operator: ûų:碃;ė燱5ìb-垢xźɆ + values: + - u8cOuqy + matchLabels: + "8": nCrnu + Fd: 5YhLJD3 + r5sMi70hp4TeB: KrDX7d + namespaces: + - LOH + - 9EvOI7HWh + - 5sHJp + topologyKey: "" + weight: 403248696 + - podAffinityTerm: + mismatchLabelKeys: + - Vrf + namespaceSelector: + matchExpressions: + - key: 5w + operator: '|泀ŏ咙ƚ' + matchLabels: + 4vRvwhR: Nz + T6uTCUGiwx: lS + ZuFER: Db8xhFevK + topologyKey: K7NA + weight: 249855905 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: No2 + operator: Ɗ]鿇躠骐 + matchLabels: + 7nohEoAMei: WrMV + ddLK: 2ehkh + qtrhf: EAAqHFcrjgT + mismatchLabelKeys: + - DrrBoq + - Nh + namespaceSelector: + matchExpressions: + - key: BEXHPr1wQ + operator: 傝魦voȪwć撈 + values: + - i3 + - gUU + - 7nmbvkGs + matchLabels: + Rh65F: rKR + namespaces: + - 1x9DGG + - xKj137E + topologyKey: CSNQy1M + - labelSelector: + matchExpressions: + - key: psq4G + operator: ɓƦ + - key: 3IlNf + operator: ćȬ4鏉1, + values: + - L0 + namespaceSelector: + matchExpressions: + - key: nVgt + operator: ɤ湿ŭò-ɋ鼴)箥Ȅ鋖ʄBK + - key: GD7 + operator: 峄9ƚ涙閉ʃ謩云飠:鎂玚wƁȖ] + values: + - i8cg6A + - TeOYSsj + topologyKey: rEB + - labelSelector: + matchLabels: + s0PrY366si5H: Qwj + ytBgNf0: e + mismatchLabelKeys: + - eylzvu + - q + namespaceSelector: + matchExpressions: + - key: os4H6DpxQ + operator: 5õċ鋵葿葄痄ɍ览逪ȋ`j + matchLabels: + vL3arho: gPmLG + namespaces: + - PjQTIWTFeK + - g5HCelWpMjnF + - QN3mXW + topologyKey: I5osiWTrzhb + automountServiceAccountToken: true + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: LOGIN_JWTSECRET + valueFrom: + secretKeyRef: + key: login-jwt-secret + name: HK + envFrom: [] + image: nZ5PG/5q2qCT:z10JAfCu + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: -1989869025 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 56050789 + periodSeconds: 193173949 + successThreshold: -1606638368 + timeoutSeconds: -1117024654 + name: console + ports: + - containerPort: 52 + name: http + protocol: TCP + readinessProbe: + failureThreshold: -509957017 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 1816814831 + periodSeconds: 406466643 + successThreshold: 450108513 + timeoutSeconds: -1862950899 + resources: {} + securityContext: + allowPrivilegeEscalation: true + capabilities: + drop: + - 邻ȸNJ"纴ý汫篤訙铵寄貹Z[逗ą弣 + - lǀ敕ɖ + privileged: true + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 3375680259081538600 + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: /etc/console/secrets + name: secrets + readOnly: true + - mountPath: P + name: zBgE7HVQ + subPath: hw6PBLgv5R + subPathExpr: YAI5mPj5 + - args: + - K9 + - 02olyp + env: + - name: F + value: rhVGTadjT + valueFrom: + configMapKeyRef: + key: 3TA0cg2R2 + name: DLZ + fieldRef: + apiVersion: s + fieldPath: Ux + resourceFieldRef: + containerName: avop + divisor: "0" + resource: itl5J4xK4 + secretKeyRef: + key: Av9eKok + optional: false + - name: QaOLYDLT + value: FQu + image: 1MFnpZG + imagePullPolicy: 脓 + livenessProbe: + exec: + command: + - lH4S + failureThreshold: 1311534645 + grpc: + port: 1048835191 + service: p5EtELTs + httpGet: + path: Zjrv + port: Ypah5av + scheme: þʙ龠ȉ%Vę皓ŏ蟝ǙĿìɋN + initialDelaySeconds: 1980070741 + periodSeconds: -728109708 + successThreshold: 1412960079 + terminationGracePeriodSeconds: 4797597904045468000 + timeoutSeconds: -1164059804 + name: oron + readinessProbe: + failureThreshold: -1734715333 + grpc: + port: -673781482 + service: 20iHh + initialDelaySeconds: 270804414 + periodSeconds: 1240219458 + successThreshold: 957649997 + terminationGracePeriodSeconds: -7921460752123720000 + timeoutSeconds: 2069469191 + resizePolicy: + - resourceName: M29 + restartPolicy: tL + - resourceName: WK + restartPolicy: T軂>ȋ1觫蚴Ș + resources: + limits: + KS: "0" + ZDx: "0" + kIjQHQZ: "0" + requests: + BSB: "0" + restartPolicy: LJW獮 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ɺ嚹晐囕胐ƻ + - ņɹ桴O塾q6賤呋f铰}Ʒ輽ʁ[顝 + runAsGroup: 6868723237582569000 + runAsNonRoot: true + runAsUser: 433131246318901200 + startupProbe: + exec: + command: + - mB6 + - Om9w + - "" + failureThreshold: -1184477652 + grpc: + port: -1276243610 + service: m6d + httpGet: + host: VzPuwIiTpY + path: C + port: 0NYj1C + scheme: V=@彆鈂t³Ɉµs斾m蛊ɲ + initialDelaySeconds: -898287287 + periodSeconds: -413255468 + successThreshold: -1510482870 + terminationGracePeriodSeconds: 4884332649151511000 + timeoutSeconds: -1445193311 + stdinOnce: true + terminationMessagePath: DQTH7 + terminationMessagePolicy: ÈɁ;ň);ɑI×ĕ觫'ɣ + volumeDevices: + - devicePath: v + name: AZ6wCimJFM + - devicePath: ZtIx + name: GFe3 + volumeMounts: + - mountPath: tt + mountPropagation: 侮E墝調cé攊疀" + name: UJ + readOnly: true + subPath: JlqP + subPathExpr: lA2v + workingDir: OV90 + - command: + - 8jHRuz + envFrom: + - configMapRef: + optional: false + prefix: yfl3PI + secretRef: + name: r7eR + optional: true + image: m4Etaoz8Bf + imagePullPolicy: okÛļ閷YƗzƄǧ + lifecycle: + postStart: + exec: {} + httpGet: + host: zu9aQLsX + path: xIFogzAoC + port: 1MjUE + scheme: 斔疏ʟn菝 + preStop: + exec: {} + livenessProbe: + failureThreshold: -1399917612 + grpc: + port: -876522011 + service: 2y + httpGet: + host: X9nNdf + path: 8mVJlz + port: 220487349 + scheme: 兇)hr裳ǔ湟钑>ȓn厠tū晣颊 + initialDelaySeconds: -968878635 + periodSeconds: 411754743 + successThreshold: 2083381130 + terminationGracePeriodSeconds: 2736468416107855400 + timeoutSeconds: -423937148 + name: Or + readinessProbe: + failureThreshold: 1628351372 + grpc: + port: -1466105410 + service: b + httpGet: + host: 8kOz + path: IhSlrBw8tiX + port: 1Vd + scheme: qV·dƖ> + initialDelaySeconds: 735135195 + periodSeconds: -175995819 + successThreshold: 1379601279 + terminationGracePeriodSeconds: 386635447886660740 + timeoutSeconds: 125503732 + resources: + limits: + LuudLJ9i: "0" + iXpYUWY: "0" + mHi: "0" + requests: + XLnFU: "0" + mSq9e3u: "0" + t6WYwzmga: "0" + securityContext: + allowPrivilegeEscalation: false + capabilities: + add: + - ɭ鎣肪綢ȀNj8)屫鈄骸嗢æ憰qWTƶ剡 + - "n" + - OwkʙƝk}ɾ丧< + drop: + - Ť<嶼ȯ愉9宆嵧pɡ%ɐxė鹞鸵鏞 + - ƅgʆ炊ƞąÙ$Ǯ帶SȔ黌畕ǦƖȫV9 + - Ŏʠ羮ɍ痘摬 + privileged: true + runAsGroup: 5710532895986022000 + runAsUser: -7207500526873246000 + startupProbe: + failureThreshold: 2053062827 + grpc: + port: -1076044334 + service: s8s7 + initialDelaySeconds: 7348194 + periodSeconds: 889500482 + successThreshold: -645465298 + terminationGracePeriodSeconds: 4356974427366500000 + timeoutSeconds: 136481601 + stdinOnce: true + terminationMessagePath: t4pW + terminationMessagePolicy: ƣ + volumeDevices: + - devicePath: Df8O3UFZ + name: QL93u + - devicePath: WKg + name: nD4H + volumeMounts: + - mountPath: xs9 + mountPropagation: e羝ș+oũ蘘汉 + name: grr + readOnly: true + subPath: aUYSuUM6f + subPathExpr: mm773yL + workingDir: o + imagePullSecrets: [] + initContainers: + - 'error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string + into Go value of type []interface {}' + nodeSelector: + Jy9: v + VcMeUW2U: xOwcDQYY + wkI: TbemvxUUg + priorityClassName: sLkcwZ + securityContext: + fsGroup: 99 + runAsGroup: -9040107238323409000 + runAsNonRoot: false + runAsUser: 99 + serviceAccountName: 43zobnL + tolerations: + - effect: 蜆³Ə抴璖獍ä鷲炥/=霒0ǷU伀稂ı + key: EMvrrkeG3 + operator: Ȓǒs夃Ȑɉ鋄蛓m÷,旂 + value: yd + - effect: 旌;"ȡ媟窐:ljʥh蓭殰Ȩƴ邃ȬIȻL + key: n87GpiB + operator: '偵~ȥʢȈ珎ſ龕5sʠŇưT4-§Ƀ ' + value: TUaznROmQffrRe1 + topologySpreadConstraints: [] + volumes: + - configMap: + name: HK + name: configs + - name: secrets + secret: + secretName: HK + - name: "" + - name: SXJ +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "HK-test-connection" + namespace: "default" + labels: + HzuQ: mCfbHBQ + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 3Wh + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + xi7L: ibI45 + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['HK:389'] + restartPolicy: Never + priorityClassName: sLkcwZ +-- testdata/case-030.yaml.golden -- +--- +# Source: console/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + labels: + T: f0 + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: J + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + jwrBMvwfg: K6I5HsI5 + nk8eJc: nS + name: G9 +stringData: + enterprise-license: "" + kafka-protobuf-git-basicauth-password: DtIy + kafka-sasl-aws-msk-iam-secret-key: 9xCf7 + kafka-sasl-password: 8F + kafka-schema-registry-password: krNk2 + kafka-schemaregistry-tls-ca: 5I73C + kafka-schemaregistry-tls-cert: "" + kafka-schemaregistry-tls-key: "34" + kafka-tls-ca: DaT + kafka-tls-cert: LaU0jwOpGv + kafka-tls-key: "" + login-github-oauth-client-secret: BoOjni + login-github-personal-access-token: uUxZ + login-google-groups-service-account.json: NulwlJ + login-google-oauth-client-secret: oeL6p7fcL + login-jwt-secret: SECRETKEY + login-oidc-client-secret: yRSh2 + login-okta-client-secret: xKLBJ9ZAR + login-okta-directory-api-token: HTZWfHt + redpanda-admin-api-password: 5DQTqKD + redpanda-admin-api-tls-ca: m5pg + redpanda-admin-api-tls-cert: yfP + redpanda-admin-api-tls-key: gzG +type: Opaque +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + T: f0 + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: J + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + jwrBMvwfg: K6I5HsI5 + nk8eJc: nS + name: G9 + namespace: default +spec: + ports: + - name: http + port: 250 + protocol: TCP + targetPort: 475 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: J + type: QAVsE +--- +# Source: console/templates/hpa.yaml +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + creationTimestamp: null + labels: + T: f0 + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: J + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + jwrBMvwfg: K6I5HsI5 + nk8eJc: nS + name: G9 +spec: + maxReplicas: 10 + metrics: + - resource: + name: cpu + target: + averageUtilization: 227 + type: Utilization + type: Resource + - resource: + name: memory + target: + averageUtilization: 477 + type: Utilization + type: Resource + minReplicas: 306 + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: G9 +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "G9-test-connection" + namespace: "default" + labels: + T: f0 + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: J + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + jwrBMvwfg: K6I5HsI5 + nk8eJc: nS + annotations: + "helm.sh/hook": test +spec: + imagePullSecrets: + - name: wu1 + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['G9:250'] + restartPolicy: Never + priorityClassName: KuRS +-- testdata/case-031.yaml.golden -- +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} + role-bindings.yaml: |- + roleBindings: + - {} + - {} + roles.yaml: |- + roles: + - {} +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: xknw + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + q4ZdG9q: IJWaYu9mhun + sFTTcyl: qVyaa0ULC + name: 59cQ0qKLI +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: xknw + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + q4ZdG9q: IJWaYu9mhun + sFTTcyl: qVyaa0ULC + name: 59cQ0qKLI + namespace: default +spec: + ports: + - name: http + port: 112 + protocol: TCP + targetPort: 375 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: xknw + type: N9chrF +--- +# Source: console/templates/hpa.yaml +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: xknw + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + q4ZdG9q: IJWaYu9mhun + sFTTcyl: qVyaa0ULC + name: 59cQ0qKLI +spec: + maxReplicas: 25 + metrics: + - resource: + name: cpu + target: + averageUtilization: 460 + type: Utilization + type: Resource + - resource: + name: memory + target: + averageUtilization: 169 + type: Utilization + type: Resource + minReplicas: 20 + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: 59cQ0qKLI +--- +# Source: console/templates/ingress.yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + annotations: + Q: 3KXvHleq + YUY: BD + mdCRk: Ilk9wDjAw + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: xknw + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + q4ZdG9q: IJWaYu9mhun + sFTTcyl: qVyaa0ULC + name: 59cQ0qKLI +spec: + ingressClassName: GuB1VTCp + rules: + - host: WsTbK7W + http: + paths: + - backend: + service: + name: 59cQ0qKLI + port: + number: 112 + path: MKCR56 + pathType: hEV + - backend: + service: + name: 59cQ0qKLI + port: + number: 112 + path: "6" + pathType: pv + - backend: + service: + name: 59cQ0qKLI + port: + number: 112 + path: rNv + pathType: L0CY1c8 + - host: OxFD + http: + paths: null + - host: Ojx + http: + paths: null + tls: + - hosts: + - C + - wxjmQWXDn + secretName: ESgom5IBQR +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "59cQ0qKLI-test-connection" + namespace: "default" + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: xknw + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + q4ZdG9q: IJWaYu9mhun + sFTTcyl: qVyaa0ULC + annotations: + "helm.sh/hook": test +spec: + imagePullSecrets: + - name: 2Ry3vDGf6 + - name: PE5R + - name: uWsoZ + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['59cQ0qKLI:112'] + restartPolicy: Never + priorityClassName: mFg +-- testdata/case-032.yaml.golden -- +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} + role-bindings.yaml: |- + roleBindings: + - K8wnWSD: null + bwYE7: null + y4j: null + - GvFfKdgL: null + enU8G4: null + wvnJcOn: null + - td7: null + roles.yaml: |- + roles: + - YQBucbbDX2R: null + - 2UuDKjR: null + IV0Yus9: null + ci20SljQkhw: null +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + B19ue: 8W + Kxm5R1: R + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: wB + app.kubernetes.io/version: v2.7.0 + e3Cx: MIAO + helm.sh/chart: console-0.7.29 + name: llK4G +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + B19ue: 8W + Kxm5R1: R + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: wB + app.kubernetes.io/version: v2.7.0 + e3Cx: MIAO + helm.sh/chart: console-0.7.29 + name: llK4G + namespace: default +spec: + ports: + - name: http + port: 418 + protocol: TCP + targetPort: 486 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: wB + type: aaIqePq +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + xpNWT: MpOZ + creationTimestamp: null + labels: + B19ue: 8W + Kxm5R1: R + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: wB + app.kubernetes.io/version: v2.7.0 + e3Cx: MIAO + helm.sh/chart: console-0.7.29 + name: llK4G + namespace: default +spec: + replicas: null + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: wB + strategy: + rollingUpdate: {} + type: ȁ进辫fu + template: + metadata: + annotations: + checksum/config: ae52af057e6331e5caa1d321881f906df93659aa45a5458c4dd4ae890cf7695b + creationTimestamp: null + labels: + So: waKMMvnY + VXPE0: 8ExVsj + app.kubernetes.io/instance: console + app.kubernetes.io/name: wB + ip1RGEzt4t6: "1" + spec: + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: {} + weight: 735732238 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: cFkyLM + operator: 岊B + - key: V3cKSq + operator: ǟ濈1ɑÎ"孲ȀŨFhŲ + values: + - hz + - matchExpressions: + - key: 8N + operator: 9´敤T + values: + - amWROpS + matchFields: + - key: 7hmWbsKS + operator: "" + values: + - lS + - slkOyX + - YlwPcdVh + - matchExpressions: + - key: n5YD + operator: Əüʢ軾ŚũɳnŒ + values: + - 5s4eD6x + - WMkZIzS40rxp + - zCnW + - key: JawyIOLo + operator: 巳c習Gnƛ{ɩ¯Ĭ枺lȜʩ泿趏ǙĊi + values: + - Fvzyw13fUZC + - 4w9T3GeG + - mVj9N + matchFields: + - key: 4amyTWvhx + operator: Ąŵ8雌%ɸ*W褒卒S + values: + - cPr0Nm2WFo1dBq + - a + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: XgsMMBS + operator: ȗ諹 + values: + - foI + - NN1yiUNR + matchLabels: + Qq: VB19aUlI + mismatchLabelKeys: + - hcD + namespaceSelector: + matchLabels: + vMT90cNq3PYf2z: upe + topologyKey: RSVn9W + weight: 603398420 + - podAffinityTerm: + labelSelector: {} + mismatchLabelKeys: + - 4IL0rEe9 + - yY0RMU2 + namespaceSelector: + matchExpressions: + - key: tIka9jS + operator: 7怘xə4ÏɦW + values: + - l + - ajs6c + - hkYj + - key: Qu + operator: ʊ鏀ɑ蒀刹gE + values: + - 2UvY + - hRB1wKXyHi9 + topologyKey: ZKWyn5kI + weight: -1674108352 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: KQfZ4 + operator: ġȁAu盝ȭƈŦ齬{z + values: + - itNS0T + - jL + - key: q0HemjU + operator: e銳ȇ葁õDÏ筃 + values: + - M5yeE + - gJJY + - HInHzXgX + - key: d1LKZ1 + operator: Q + matchLabels: + XElv: QGJ + nD: kNCk5qe + wUtw34v: sCjj5z + matchLabelKeys: + - ej9hOPjp7W + mismatchLabelKeys: + - lhU9gP + - T7rMlvu + namespaceSelector: {} + namespaces: + - ii3aa + topologyKey: 8U7 + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: CkQsu4fS + operator: 鄦&ɲȅ + values: + - RVnwZ + - EVk + - key: yt + operator: 傓N嬅宠H^÷ + values: + - 1L + - rVQPs + - dUHOKQ + - key: hQ1Tl + operator: ɣë筁尻!絜辩^riʨ莠8dƋ + values: + - 4D6Y + - 5TXh + - 8RH + matchLabels: + "9": jb2X + IdL: PQj0N + iB09Upiijt: JpN + matchLabelKeys: + - rKS9p8 + - sK8p + namespaceSelector: + matchExpressions: + - key: KQ6 + operator: '篛I6ÝBŘ F媍/:' + values: + - NXP47Fm + - Z0Qh2Y4 + - JeWX + - key: Yh + operator: '!j3W' + values: + - mTm5dkO58H + - "" + - key: 6q + operator: 景¨Sŝvo/ + values: + - TrgtrP + - zqIsId + matchLabels: + 7E3A1K: "7" + 63IlVL: aSxc + W1hP: 1H9k3O + namespaces: + - "" + - 2Ma + topologyKey: FFqt + - labelSelector: + matchLabels: + "": wklJJ + C8JZ: LP + U1pz: kAE1l4 + matchLabelKeys: + - shj5V + - oU074y + - Ufq2w + mismatchLabelKeys: + - oBzMiOSgd + - iSF + namespaceSelector: + matchExpressions: + - key: fCbLu + operator: 塊衅m鑀ȣ戢ŭ阻蹯ȟ獇ɨ + values: + - B6TgQ75 + - FAHTEOSesQ + - Ms2Kw7XQ + - key: 133fMqId + operator: "" + values: + - pJc0Zu8 + - T1PEuV0uism + matchLabels: + 1rfPa2b4Ny: cemR + Np9l: lcX + SjNYy4: VZX + namespaces: + - 7W + - umFBWrpUDHv + - "" + topologyKey: pPUIqPXo + automountServiceAccountToken: true + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: LICENSE + valueFrom: + secretKeyRef: + key: bujGpO7D0C + name: V + envFrom: + - configMapRef: + name: nJXDn + optional: true + prefix: g3ZpAEUJC + secretRef: + name: 5Yin + optional: true + - configMapRef: + name: spYG9o0 + optional: false + prefix: Wv01 + secretRef: + name: BxDbe + optional: true + image: mU/xY76Tj:AgKh6S1 + imagePullPolicy: "" + livenessProbe: + failureThreshold: 1396135036 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 1526591550 + periodSeconds: -972224922 + successThreshold: -39437670 + timeoutSeconds: -1229662908 + name: console + ports: + - containerPort: 486 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 1061708880 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 1618839364 + periodSeconds: -2098998213 + successThreshold: -846859522 + timeoutSeconds: 1824930679 + resources: {} + securityContext: + allowPrivilegeEscalation: true + capabilities: + drop: + - 退晦Ţ鲛 + - '}ʄ攏嫫;Mǐ豒ɇf,搅Ð貑ș|Óf' + privileged: false + procMount: D + readOnlyRootFilesystem: false + runAsGroup: 1564095685271138800 + runAsNonRoot: true + runAsUser: -3929576237300142600 + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - args: + - T + - Pvf1yAamEa + - jQE8UakuY + env: + - name: 3g + value: JexRP + valueFrom: + configMapKeyRef: + key: QZ + name: QcC + optional: true + fieldRef: + apiVersion: Iv + fieldPath: d7xQ + resourceFieldRef: + containerName: jLpJ + divisor: "0" + resource: m + secretKeyRef: + key: Quhh + name: HUhzPAEo85 + optional: true + - name: ehSBff + value: nHu + valueFrom: + configMapKeyRef: + key: v3Icanu + name: dNPJ8 + optional: false + fieldRef: + apiVersion: xO7UQDq0 + fieldPath: gAyGB6Nj4 + resourceFieldRef: + containerName: Bs2D + divisor: "0" + resource: xJCQsH + secretKeyRef: + key: 3T6tjIQWa0C + name: 8TvRbhP + optional: false + envFrom: + - configMapRef: + name: mf + optional: false + prefix: pZxp + secretRef: + name: v + optional: true + - configMapRef: + name: wosjc9 + optional: true + prefix: ehhmFeLY + secretRef: + name: Ll + optional: false + image: kZ8UUm + imagePullPolicy: Ɓ + lifecycle: + postStart: + exec: {} + httpGet: + host: K29SzZPo + path: y2bQL8 + port: Cr + scheme: 轂Ì蕏ʋ + sleep: + seconds: -3765902632580054500 + preStop: + exec: + command: + - 1pT5X + httpGet: + host: NouEQF + path: WITzSW + port: 1565482371 + scheme: ƒ塒廛鎐藽瀫 + sleep: + seconds: 1831382645860082000 + livenessProbe: + exec: {} + failureThreshold: -1525719681 + grpc: + port: 99688681 + service: xa0sl3k5KM + httpGet: + host: prjHPqf + path: RHwZIE + port: 2UZ7hXI + scheme: 瑀ċ廤ȵ + initialDelaySeconds: -1367665605 + periodSeconds: -1023789296 + successThreshold: 206844073 + terminationGracePeriodSeconds: -3901072071078889000 + timeoutSeconds: 1670691424 + name: t + ports: + - containerPort: 2046398071 + hostIP: pJg + hostPort: -1247541550 + name: DrYeHQ6 + protocol: ²ȑBŸ + readinessProbe: + exec: {} + failureThreshold: 852505381 + grpc: + port: 8093048 + service: "N" + httpGet: + host: uuaPC + path: Mpxk6p + port: -297149767 + scheme: 這伦礗鯪àe]雚腴k£ɂ闧ɦĚH鏰浳 + initialDelaySeconds: 296244720 + periodSeconds: 1237321103 + successThreshold: 722306410 + terminationGracePeriodSeconds: 7739978307238029000 + timeoutSeconds: -2129506856 + resizePolicy: + - resourceName: NBfNOBC + restartPolicy: ƞdWǝi鎠R殩杜Ś晚尒尧ǐ; + - resourceName: oDw8xEb + restartPolicy: ja侬ƕ + resources: + limits: + BJcVkW: "0" + Ub5Spt: "0" + nWi63TNlCyM: "0" + requests: + e5vcw0H: "0" + eKz0z: "0" + gK: "0" + restartPolicy: 嗈ǒɟNǭ臥穥Ť + securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - $拷霒Ø耖} + - ijĸN藬?w粯痵餒薃辕5勅ů + - 幒Ƹʁòĺǂ浼GX + drop: + - 宖 + privileged: true + procMount: 凝 + readOnlyRootFilesystem: false + runAsGroup: -7000080292188881000 + runAsNonRoot: false + runAsUser: 9107304642056619000 + startupProbe: + exec: {} + failureThreshold: -208121509 + grpc: + port: 133215347 + service: pj4Kw + httpGet: + path: hGLW3 + port: -239286046 + scheme: YsÌǮŦʁ¡ē峪3 + initialDelaySeconds: -817672524 + periodSeconds: 1846655614 + successThreshold: -243958761 + terminationGracePeriodSeconds: 4190490525804645400 + timeoutSeconds: -973067987 + terminationMessagePath: 9vMe3Y + terminationMessagePolicy: 雍Wȯ嘷台厃$Țʍ13b霞两e + tty: true + volumeMounts: + - mountPath: yZbL + mountPropagation: 鲫絎Q(銞ÎÕX堙Ľ銃曅注t锋ɮj覧« + name: UFfAqsgd + subPath: wSo + subPathExpr: bIsBP3O + workingDir: DYBcINRq + - command: + - wgBryFN + image: NorbK + imagePullPolicy: 鉓Ĕʠ;兮)Frë + lifecycle: + postStart: + exec: {} + httpGet: + host: Z + path: 3v + port: W1vDkt + scheme: ŷ索gp=ŵāǼ餆嬦Ƹl媓R}豟ɠĖ. + sleep: + seconds: 1583583004300077000 + preStop: + exec: + command: + - XztEol6So + - GveA + - H4aUl + httpGet: + host: 75LDW + path: nu + port: I + scheme: 胛Uȁ¬ + sleep: + seconds: 4617693270470586000 + livenessProbe: + exec: {} + failureThreshold: 1423393786 + grpc: + port: 2097410769 + service: "" + httpGet: + host: W7 + path: PyPprD6 + port: dHwCyz + initialDelaySeconds: -1439644816 + periodSeconds: 182024489 + successThreshold: -1861505070 + terminationGracePeriodSeconds: -4166230023615503400 + timeoutSeconds: -704907360 + name: sFz5 + ports: + - containerPort: 1977465061 + hostIP: kxqRig + hostPort: 393211643 + name: DRO + protocol: ķǔȈ + readinessProbe: + exec: + command: + - mn + - 4TZCjrWPW18 + failureThreshold: 972699487 + grpc: + port: -1384519737 + service: IY5quWWV4JC + httpGet: + host: wq91i + path: Zy + port: -1192576969 + scheme: Á^_ + initialDelaySeconds: 2107832874 + periodSeconds: 1041520026 + successThreshold: -118135340 + terminationGracePeriodSeconds: -4946782594204673000 + timeoutSeconds: -1933961678 + resizePolicy: + - resourceName: MG7PMkMMObJJU + restartPolicy: §觫困Ȏ龝ƃȃɩ芴ÎĽ + resources: + requests: + I4: "0" + zLy: "0" + restartPolicy: 粛醑綇蝙Ɣò犁鶓A + securityContext: + allowPrivilegeEscalation: false + capabilities: + add: + - 掀ǃA颺LnFąɏ動 + drop: + - 输6sĺ宯hĢ + - ĨƨO檔暰z + - Neɬ慿Ȁ0ɳ蠈ǚǦO¸Ğ崔ʂ¢剚 + privileged: false + procMount: 翄怉DžǬ?胉獄ǙƊɚx虉F + readOnlyRootFilesystem: false + runAsGroup: -1943526545280953900 + runAsNonRoot: true + runAsUser: -7089742793545457000 + startupProbe: + exec: + command: + - hDj + - ONyz91fkTFY9t3 + - ynDWkO + failureThreshold: -5561223 + grpc: + port: -1069825885 + service: oQmy + httpGet: + path: l4sWc + port: 53AhP + scheme: ȩ + initialDelaySeconds: -6165070 + periodSeconds: 1844899228 + successThreshold: 903779261 + terminationGracePeriodSeconds: -3909221818854749700 + timeoutSeconds: 746670574 + stdinOnce: true + terminationMessagePath: egr00cLki + terminationMessagePolicy: ɯ2鰌^坪yN蠏Ĵ + tty: true + volumeMounts: + - mountPath: YOyu1MjxN2 + mountPropagation: :鸛o鮓L`<]ơ1b忙n鲃{< + name: dODfVz + subPath: ZknFq + subPathExpr: oX1n + - mountPath: 4TEsoc + mountPropagation: 帺Õ斯剅ƫf鳌麓HƸŘÂ瘖?謾軌 + name: hau + subPath: w24Wq4e + subPathExpr: i2TEix + - mountPath: uuujj + mountPropagation: 氻ʃ2NFJ啼铗"O{À-ŧLJ弟 + name: klnXhhnxKk + subPath: SEx + subPathExpr: CK2FmmyYThL + workingDir: NCvZAa + imagePullSecrets: [] + initContainers: + - 'error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string + into Go value of type []interface {}' + nodeSelector: + ih: xT3Dk3PXT + xhq: vu + zLR9: wFjrfu + priorityClassName: WeB9y8 + securityContext: + fsGroup: 7101468120327600000 + fsGroupChangePolicy: ȴ鳁ƨ殳h`熡ƍʊ0ŀ擳琗图.AƱX滋 + runAsGroup: 4262945102741077000 + runAsNonRoot: false + runAsUser: -9214274730002703000 + supplementalGroups: + - 4135587743067906600 + - -2908166639165702700 + sysctls: + - name: Yo9 + value: zak2 + serviceAccountName: zpH + tolerations: [] + topologySpreadConstraints: [] + volumes: + - configMap: + name: llK4G + name: configs + - name: 1zZI6J + - name: D + - name: OUqOnvjvba +--- +# Source: console/templates/hpa.yaml +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + creationTimestamp: null + labels: + B19ue: 8W + Kxm5R1: R + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: wB + app.kubernetes.io/version: v2.7.0 + e3Cx: MIAO + helm.sh/chart: console-0.7.29 + name: llK4G +spec: + maxReplicas: 459 + metrics: + - resource: + name: cpu + target: + averageUtilization: 497 + type: Utilization + type: Resource + - resource: + name: memory + target: + averageUtilization: 146 + type: Utilization + type: Resource + minReplicas: 198 + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: llK4G +--- +# Source: console/templates/ingress.yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + annotations: + Lhm: f24CRNEJvs + pk6fq: "2" + creationTimestamp: null + labels: + B19ue: 8W + Kxm5R1: R + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: wB + app.kubernetes.io/version: v2.7.0 + e3Cx: MIAO + helm.sh/chart: console-0.7.29 + name: llK4G +spec: + ingressClassName: EXqR + rules: + - host: chart-example.local + http: + paths: + - backend: + service: + name: llK4G + port: + number: 418 + path: / + pathType: ImplementationSpecific + tls: + - hosts: + - xEciJGskt + - pBxfBltrqACoat + - INyj + secretName: Qy + - hosts: + - F6sf + - EHuJ + - 95my0 + secretName: XOIr +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "llK4G-test-connection" + namespace: "default" + labels: + B19ue: 8W + Kxm5R1: R + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: wB + app.kubernetes.io/version: v2.7.0 + e3Cx: MIAO + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['llK4G:418'] + restartPolicy: Never + priorityClassName: WeB9y8 +-- testdata/case-033.yaml.golden -- +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} + role-bindings.yaml: |- + roleBindings: + - 7x: null + Ia1K2tdRuYi: null + j6c9: null + roles.yaml: |- + roles: + - {} + - 6Vndf: null + f: null +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: bCPeYVWao + app.kubernetes.io/version: v2.7.0 + gZ85uw3T: e + helm.sh/chart: console-0.7.29 + qO: F4dqLo67vKYZ + name: foGC +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: + lrtdFF: 60R7 + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: bCPeYVWao + app.kubernetes.io/version: v2.7.0 + gZ85uw3T: e + helm.sh/chart: console-0.7.29 + qO: F4dqLo67vKYZ + name: foGC + namespace: default +spec: + ports: + - name: http + port: 229 + protocol: TCP + targetPort: 59 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: bCPeYVWao + type: 2K35 +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: bCPeYVWao + app.kubernetes.io/version: v2.7.0 + gZ85uw3T: e + helm.sh/chart: console-0.7.29 + qO: F4dqLo67vKYZ + name: foGC + namespace: default +spec: + replicas: 390 + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: bCPeYVWao + strategy: + rollingUpdate: {} + type: 呇弰$腕煴贔棳軀+œʃǀŖ* + template: + metadata: + annotations: + checksum/config: b3a4b261d0705e207d46ac15067d5c7d7c951cf0c0fa7736607331369bd47b6d + creationTimestamp: null + labels: + 1bb6: "" + 3U: mfPv + T: Q + app.kubernetes.io/instance: console + app.kubernetes.io/name: bCPeYVWao + spec: + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchFields: + - key: 1O + operator: 拺5ř(Ƅ餕ʟ{鐻Ƈ + weight: -2070567569 + - preference: + matchFields: + - key: JlGR + operator: 脱?ĶA蛜頒ǽGǷ藸 , + values: + - 8zZEVom + - TY + - FSSQQ + - key: w3C + operator: sɯeM^筘褑 + values: + - Q + - i48uKb + weight: -1969968900 + - preference: + matchExpressions: + - key: ZsgVr + operator: Eȗ + - key: RfMZL + operator: "" + - key: r + operator: džɬ毿鵮V町iAÉ橁zy题ʔu7ÆO9 + values: + - uj8h + matchFields: + - key: "" + operator: :止褮Ȃ宸 + values: + - 9h + - Do + weight: 1160212382 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: nmW + operator: '%U<Ȫk7家fƥ降]:' + values: + - e4hDXWb9G8Qi + - SynNDfUn + - C8kz + matchFields: + - key: QO0Q + operator: l!m0ʒbƹ豫ň + values: + - eh + - key: VE5mZtP + operator: ~x蹵#ÂvǗRɩ啭Ö澭肞¤7跜庛Ɍ + values: + - yT + - key: 1Cony + operator: 阃 + values: + - ahj6j + - matchExpressions: + - key: TvhlZutK + operator: 5叹ùz + values: + - rog + - key: qLPNTFw8 + operator: 藘鸘Œé溇ʄsoɷƱǺȾ蹾K混īl軇 + - key: F + operator: 則Yǹ郰饉貓伜ſ0|麊 az襽准 + matchFields: + - key: VcfFwmb + operator: WJMU狰槃žiǶq挿} + values: + - b7G + - "" + - wzxeij27DD + - key: "" + operator: 殀ǥ + values: + - "9" + - 0E3EkrfSX + - vzth + - key: omoz + operator: e´Ģ桇适TŽǤʈ + values: + - TVj0W7 + - 7HjUt2w + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: nN1614M7 + operator: '鰺/堅ý髉铊ɇƴ2友凇3 ' + values: + - D0tt + - sG9E + matchLabelKeys: + - l + mismatchLabelKeys: + - vqTKCL2D + namespaceSelector: + matchLabels: + LIgB: qqC9YL + namespaces: + - BLdVDzfY + - eq + - qB + topologyKey: qwces + weight: 899210618 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: hIz8wo + operator: ĥ\{ė + values: + - ZwYh1 + - 4l9U + - Q5Io + - key: sd3eCUDob + operator: 蒴ǚ<灁Q柷娸颂嘃üĸƢı + values: + - U0 + - "" + - WXJjoBRKrfEY + matchLabels: + QSrEl7t0: hxsiSGCubb + mismatchLabelKeys: + - PiUy + - VhBWFCyx6C + namespaceSelector: + matchLabels: + G: 07tU6 + ZCO1QQK: b + uq: HISLIo9ZC + topologyKey: 87eQuI + weight: 1750437304 + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: nK0RSDE + operator: R(陛m诜ȯơȴ豨躻 + matchLabels: + CE9: u8FukDT + U5N: "y" + matchLabelKeys: + - 5I6wiiY + - JDZsP + - zGyW + mismatchLabelKeys: + - 4WZHZ + namespaceSelector: + matchExpressions: + - key: N9E9 + operator: ȅ)礯占鷨ʫɩfǡnʎə掅Ux曶HŁ遐 + values: + - JdC + - 3NS25HFHxU + - key: "" + operator: ı獗& + - key: q + operator: 髢£Ȋ泽ZwVfc剻Ţ嬊j + topologyKey: "" + - labelSelector: + matchExpressions: + - key: Tof0 + operator: ĥM:ɑȏF叆綯炩藁û漄f + values: + - jTpj + - gYZ8IIq + - key: avL + operator: ɼƌ壟.敾¦ + matchLabels: + P1w: Nb9t3e + matchLabelKeys: + - TkIx94Dmu + - 8KVE + - UEJW + namespaceSelector: + matchExpressions: + - key: gQOOR5Pz + operator: Ȁ蛝畆粔辧殤,ǔžɨʜ + values: + - MiGt + topologyKey: nn1x + - labelSelector: + matchExpressions: + - key: C + operator: 瘎%瑧¹$兤 + values: + - p5TR + matchLabels: + c9PNRTZ: L + matchLabelKeys: + - 9xrNO + - saFgUzTD530EV + namespaceSelector: + matchExpressions: + - key: "" + operator: 琨j貙ŰĤ煾骣ƢƐ肾Q`ĥ?舶 + values: + - "7" + - T4pSI + - key: u0lbHcT + operator: čÉ壶霻*ǻ蠦Źê潡%!Ȱʁr.ň沀痊 + values: + - voUu0X + namespaces: + - tX + - uDgtoDt + topologyKey: "1" + automountServiceAccountToken: true + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: RTz9f + value: kK5WtZCFpsl + valueFrom: + configMapKeyRef: + key: CB1UV + name: 0pF + optional: false + fieldRef: + apiVersion: xO4s + fieldPath: n2G + resourceFieldRef: + containerName: GmnwMQ + divisor: "0" + resource: yX30Dke4u + secretKeyRef: + key: vPbHh + name: oBAn1EoZmPzN + optional: true + - name: LICENSE + valueFrom: + secretKeyRef: + key: 9y6KmPZ + name: QM + envFrom: + - configMapRef: + name: lo + optional: false + prefix: mSdySXyKqEkl + secretRef: + name: t4daT3 + optional: true + - configMapRef: + name: IFTvBGq + optional: false + prefix: qKk6o + secretRef: + name: "4" + optional: true + image: JWsGq/JAUpWzFL:3WF1aV + imagePullPolicy: 躂Qʢ瞶CǁȮ + livenessProbe: + failureThreshold: 604102540 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 93396392 + periodSeconds: 1323534907 + successThreshold: 2044410955 + timeoutSeconds: -725304614 + name: console + ports: + - containerPort: 59 + name: http + protocol: TCP + readinessProbe: + failureThreshold: -1216486926 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: -1636119248 + periodSeconds: -1587206371 + successThreshold: 1085720843 + timeoutSeconds: 1603673472 + resources: + limits: + HS: "0" + sspp8OAsyF: "0" + securityContext: + allowPrivilegeEscalation: true + capabilities: + drop: + - ɇǎȬ+丰DZ}薞ɎƐ + privileged: false + procMount: Ȧ杖煃a/ɓ<3ő+笽pȗdzSj + readOnlyRootFilesystem: true + runAsGroup: 8336843233603803000 + runAsNonRoot: true + runAsUser: 956863148985923500 + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: WfYQ + name: v1bEam0d + subPath: "" + - mountPath: hpZaUwi + name: 2keqwtlu + subPath: "" + - mountPath: bCeiaipj + name: RAI0g6yvn + subPath: "" + - mountPath: gRGvu + mountPropagation: Ŋ4ǔ盍薟惮睌ȿ濍ȯȀüƳ$ + name: oJv65V + readOnly: true + subPath: P20XHtoR + subPathExpr: SzD + - mountPath: xhuwGvn + mountPropagation: 搛悈nj鰣*颵俠Ʀ慫灗岵ȆǴ騔Ė栢č)q + name: ebDa1q2nKt + readOnly: true + subPath: "6" + subPathExpr: N0xOT + - mountPath: xHTM + mountPropagation: 0關ɮUeŪ + name: P8noEsWy3t + subPath: y5E + subPathExpr: oP2A6C + - args: + - 3OUsoZkVHy + - Gn3 + command: + - NLtY + env: + - name: 51Xcm68sAs + value: PUTq + valueFrom: + configMapKeyRef: + key: udLx6h9 + name: wSgnPbc + optional: false + fieldRef: + apiVersion: oVPbc + fieldPath: CGK + resourceFieldRef: + containerName: Ind7j + divisor: "0" + resource: 9tlZc + secretKeyRef: + key: z2i + name: aloI0W + optional: true + - name: nGb + value: I91 + valueFrom: + configMapKeyRef: + key: Ft8IZO4DX + name: 7PY9CO1 + optional: false + fieldRef: + apiVersion: DysSUO + fieldPath: M + resourceFieldRef: + containerName: i + divisor: "0" + resource: mbVAnrQ + secretKeyRef: + key: ZVD + name: 4gLX + optional: true + - name: SEd7KC2 + value: I0 + valueFrom: + configMapKeyRef: + key: 71k + name: B + optional: true + fieldRef: + apiVersion: vJE + fieldPath: nvSzEcQ + resourceFieldRef: + divisor: "0" + resource: fYaXGkFYlrz + secretKeyRef: + key: xDT4Uhi + name: a + optional: false + image: NLoqH + imagePullPolicy: U肵銨龋搁}ŗ=;ī篱ɺ頁掆薑 + lifecycle: + postStart: + exec: + command: + - NAmBp8Ijy9vgKS + httpGet: + path: GukCZ + port: umdXEe + scheme: ɭL莒ƠĦZ¢.0tȠȴF梩¯牏GȐ + sleep: + seconds: 2463489515348869600 + preStop: + exec: + command: + - RAP7lxh + - 0WRf37xLvaEE + httpGet: + host: Xi + port: 395093084 + scheme: '}Ä*諓懚泾ıɥ磀>ȃÓ愍瘞5' + sleep: + seconds: -2989387296528249000 + livenessProbe: + exec: + command: + - AondI + - CvX + - X9Dwm + failureThreshold: -1669443788 + grpc: + port: 1602861347 + service: 5dF71q + httpGet: + host: yOYLS + path: m99M + port: 1421693426 + scheme: cǶ嫙x勬´筮 + initialDelaySeconds: -348887387 + periodSeconds: -855526929 + successThreshold: -1868658835 + terminationGracePeriodSeconds: 7220662525875544000 + timeoutSeconds: -893266456 + name: 62y7 + ports: + - containerPort: 41082986 + hostIP: H + hostPort: -671022955 + name: Q + protocol: Ģ + - containerPort: -676585553 + hostIP: jdTqIIXMX + hostPort: 441858691 + name: bam + protocol: ã鯑 + readinessProbe: + exec: {} + failureThreshold: -1607827734 + grpc: + port: -732628448 + service: d + httpGet: + host: q2uSglvPX + path: 5YB9kNfy37 + port: -425352890 + scheme: ZʇįʔÌ玫Ʊ儝$緀ƥǣ鮀 + initialDelaySeconds: 1646541382 + periodSeconds: 597275764 + successThreshold: 1444783765 + terminationGracePeriodSeconds: -4224719974242331600 + timeoutSeconds: 1778484407 + resizePolicy: + - resourceName: YWwAdc + restartPolicy: 蓊ƽqs洊蛀Ƴ澠誉 + resources: + limits: + 9c5: "0" + DJI: "0" + uyw: "0" + requests: + 7livK1: "0" + PWZFD5fFpVA: "0" + restartPolicy: ǐ踊丸y苡汎0塛yM眗酊L攚dzyÚmG + securityContext: + allowPrivilegeEscalation: false + capabilities: + add: + - țƒ摨1娣Q札遢ʌā4魯 + drop: + - W~ + - ȮnLv|麬O稕Ʉ幖0Ţ&揵¸ + - àPĪɉɯ鋹芨ȲƿƛĞx + privileged: false + procMount: ɉq$|ŀ蘨寱彣ɎȈORe]O掓I + readOnlyRootFilesystem: false + runAsGroup: -2438856757446633000 + runAsNonRoot: false + runAsUser: -8511671649189409000 + startupProbe: + exec: + command: + - "" + failureThreshold: 157629836 + grpc: + port: -20533111 + service: vASy4b + httpGet: + host: 94HpH + path: t70 + port: W59mpID + scheme: ħ6琏 + initialDelaySeconds: -146258274 + periodSeconds: 47385732 + successThreshold: -1646222325 + terminationGracePeriodSeconds: -5575789846018255000 + timeoutSeconds: -351943504 + terminationMessagePath: r0ZY2 + terminationMessagePolicy: 傂G嶃a橢抴=Ȃĺ庆ɏ鬹揖絴鹥ɣ¸Ȫs + tty: true + workingDir: XFFilzd + - command: + - VSuU6yfyc8y + - gLgP + env: + - name: PSOr4 + value: m2ujo1f4 + valueFrom: + configMapKeyRef: + key: B9Gc + name: BaR3c + optional: true + fieldRef: + apiVersion: OFu + fieldPath: Pydi + resourceFieldRef: + containerName: jPiF + divisor: "0" + resource: jyp8A7uPD + secretKeyRef: + key: fcGCM + name: Hs + optional: false + - name: Ax9HfRa4p + value: S3R2 + valueFrom: + configMapKeyRef: + key: ZDzzhFD + name: soDgOej + optional: false + fieldRef: + apiVersion: iSfQ + fieldPath: Plzxy53z + resourceFieldRef: + containerName: DfBt3S + divisor: "0" + resource: 757s44h + secretKeyRef: + key: bn2IGjj + name: x8E + optional: false + - name: r + value: PmO + valueFrom: + configMapKeyRef: + key: Htzib1 + name: gfbsiTcDY + optional: true + fieldRef: + apiVersion: Frhab7p2yh + fieldPath: K6XKg + resourceFieldRef: + containerName: CLX + divisor: "0" + resource: cq + secretKeyRef: + key: R + name: zPHkUHXQ + optional: false + image: bSZCow + lifecycle: + postStart: + exec: + command: + - "y" + httpGet: + host: 2cDO + path: L5m + port: yhJI + sleep: + seconds: 6222265361848815000 + preStop: + exec: + command: + - yVT + httpGet: + host: Ibt0C5XF + path: Kf7kW1 + port: Tlj66QW + scheme: 砰僮 + sleep: + seconds: 4926532563180302000 + livenessProbe: + exec: {} + failureThreshold: 982752870 + grpc: + port: -257993986 + service: XKTDj + httpGet: + host: 7vfaAybCd + path: GuTTi + port: 1952486193 + scheme: 馾耼qȩ罔磙ɮƥŴ²叇yēņȮ藺 + initialDelaySeconds: -817095459 + periodSeconds: 603211453 + successThreshold: -1693358568 + terminationGracePeriodSeconds: 3002071779676479000 + timeoutSeconds: 992801771 + name: 9QZX + ports: + - containerPort: -1838828544 + hostIP: cQQMftB + hostPort: -321659395 + name: XBD7a + protocol: '>V>ŝO随;YƁ' + - containerPort: -439290918 + hostIP: Bp0lf + hostPort: 431013681 + name: WQ5qc + protocol: 髄Ĝ估螗ȳ鎷ʫh + readinessProbe: + exec: + command: + - PjwAB3G + - k + failureThreshold: -2015478850 + grpc: + port: 156976837 + service: RSgDfH + httpGet: + host: Yi7aQ + path: 8Ql9 + port: 1150587533 + scheme: C箿i綔ȍȢ ŅŴ娒燸孆5乬瓤Ɛ + initialDelaySeconds: -486757233 + periodSeconds: -994300453 + successThreshold: 2128356439 + terminationGracePeriodSeconds: 4683705418302065000 + timeoutSeconds: 1635565784 + resizePolicy: + - resourceName: deutsepb + restartPolicy: õ崑o¾oɞø°ŮƑ欩Ʋ + - resourceName: WaO + restartPolicy: ±蜊ư蕭材y昍U + resources: + limits: + XiOokB: "0" + gxJ8zn4y: "0" + requests: + "": "0" + RFaH: "0" + restartPolicy: 7岻ðȸɉo熮燍ȉ=n + securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - 迠譚綞撪颫,ʖʃ佞诌Ŧ丞śɧ璯PʥT + privileged: false + procMount: 荞£DS + readOnlyRootFilesystem: true + runAsGroup: 6728166770219184000 + runAsNonRoot: true + runAsUser: 2918288689668335000 + startupProbe: + exec: + command: + - o + failureThreshold: -949081542 + grpc: + port: 220928812 + service: EIuHGNT4 + httpGet: + host: 21BmFcJ50ov + path: WC7WP + port: njQtxPF + scheme: 鲰ʌȱ卹烛橇淃ō雀)缅tb憅棔JǓ*ɒ + initialDelaySeconds: 1631334347 + periodSeconds: -785602818 + successThreshold: -1111896125 + terminationGracePeriodSeconds: -8014749222013301000 + timeoutSeconds: 795835881 + stdinOnce: true + terminationMessagePath: m08AZSt + terminationMessagePolicy: 盛P1砦ǚ瀱#Ʌ穇嘜\Ɍ + volumeDevices: + - devicePath: NdQPZme + name: uHcdGnKv + volumeMounts: + - mountPath: IX + mountPropagation: diȔiN6ļɃƐ釭卬O + name: fPg + subPath: iY + subPathExpr: U + - mountPath: E + mountPropagation: 1ĵ氓ŝ瘛o扬=[蟗 + name: xt + readOnly: true + subPath: 2KRhR + subPathExpr: Vm0HMwn + workingDir: jusEo + - args: + - Ejt + - DYgNM8X + env: + - name: HkwQ + value: fpHbv + valueFrom: + configMapKeyRef: + key: 3e + name: Q + optional: true + fieldRef: + apiVersion: lh + fieldPath: "" + resourceFieldRef: + containerName: E1uEhn3 + divisor: "0" + resource: 0Pa + secretKeyRef: + key: co85cv7H + name: KL1I3G + optional: false + - name: 5MQMJhqUni + value: 34PEKwUkR + valueFrom: + configMapKeyRef: + key: ABhM + name: qq5b + optional: false + fieldRef: + apiVersion: vCLN + fieldPath: tge3Z + resourceFieldRef: + containerName: ST + divisor: "0" + resource: qFS8 + secretKeyRef: + key: Am + name: BLI353a5GI + optional: false + envFrom: + - configMapRef: + name: KBum1 + optional: false + prefix: 56g + secretRef: + name: zt5 + optional: true + image: XgUFG + imagePullPolicy: 锄ģnj[眈例ƚ淍ƁĐ~ + lifecycle: + postStart: + exec: {} + httpGet: + host: Yp7F87b + path: "y" + port: OtElY + scheme: ǐʮŕ + sleep: + seconds: 640752187186511100 + preStop: + exec: + command: + - 4GYkI2pQ + - QB + httpGet: + host: DFjlmWGAFM + path: qLfFaRePdtA + port: GTUH4 + scheme: 罛&ĥ顱Ƌ + sleep: + seconds: -1289822532228205800 + livenessProbe: + exec: + command: + - youyR + - J + - IiK3AJ + failureThreshold: 527043957 + grpc: + port: -1790391516 + service: wFKNeu + httpGet: + host: TjItsuCL + path: Lo07CoiEpmJ + port: 1449812891 + scheme: 聗œdz_x忔8 + initialDelaySeconds: -923296146 + periodSeconds: -920279093 + successThreshold: 1372003156 + terminationGracePeriodSeconds: 4545671926845562400 + timeoutSeconds: -1730135112 + name: ouxZOTiA7 + ports: + - containerPort: 365499724 + hostIP: c3z3 + hostPort: -1622732613 + name: jfpQ + protocol: 鬍匤<ɔɟǜ鼴`ʃ荞ɗ线亮Ô¼ + - containerPort: 387750436 + hostIP: 7OF + hostPort: -922470687 + name: 20ZoNWnefc + - containerPort: -1003650010 + hostIP: yK31 + hostPort: -479225666 + name: 1Up + protocol: 郣-齡^c艃7ɑU牌驀墭:煞 + readinessProbe: + exec: {} + failureThreshold: -189409295 + grpc: + port: -880806937 + service: N1zEO + httpGet: + host: vN9 + path: n8TKqPF + port: -995680865 + initialDelaySeconds: -2090855365 + periodSeconds: 1849358636 + successThreshold: 811072097 + terminationGracePeriodSeconds: -5833095732594203000 + timeoutSeconds: -65186305 + resizePolicy: + - resourceName: 9rUpDkTFnW + restartPolicy: KSʮ1ĩ`乀_Ɠ颩紵 慒¨ƶ挢¸s诡 + resources: + limits: + MYEa: "0" + ngW: "0" + requests: + 174vfq: "0" + restartPolicy: 軵ƿǽ嚢遳E + securityContext: + allowPrivilegeEscalation: true + capabilities: {} + privileged: true + procMount: Ő\烔Z座畄睸zɩCɎx簫S悍a + readOnlyRootFilesystem: false + runAsGroup: -6410700953715651000 + runAsNonRoot: true + runAsUser: -8187102783441072000 + startupProbe: + exec: {} + failureThreshold: 1640672315 + grpc: + port: -799307372 + service: w9KE22PLk + httpGet: + host: e6Zo4rWs + path: tscGwI + port: 2071839677 + scheme: '&ǂȞ<辳)9撆ʚ6&U}P%捸`y' + initialDelaySeconds: 652003075 + periodSeconds: 1077051101 + successThreshold: 1528128815 + terminationGracePeriodSeconds: -2176015428967645200 + timeoutSeconds: -998563216 + stdinOnce: true + terminationMessagePath: P + terminationMessagePolicy: 8痃v7ȱ噣愜Å%Ġ3 + volumeDevices: + - devicePath: k8uvc + name: GL + - devicePath: 31O9l + name: ivY + workingDir: PtgSFsc1GvC + imagePullSecrets: + - name: s1B + - name: R54rm + initContainers: + - 'error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string + into Go value of type []interface {}' + nodeSelector: + TDma3: eGasO + cs6G: CyEFp0L + r: xdylcKb + priorityClassName: uHKqx + securityContext: + fsGroup: -4412504815274792000 + fsGroupChangePolicy: Ȯƭhjb糯妔ȂǑʜ胴}轣 + runAsGroup: 3860793197532220000 + runAsNonRoot: true + runAsUser: -1963293898483195400 + supplementalGroups: + - 2429921255984048000 + - -2773566751575633000 + - 5629450590441919000 + sysctls: + - name: h + value: zKVw + - name: D5ekUqS2 + value: 5FxU + - name: dgHyyau + value: o + serviceAccountName: S9Bk + tolerations: + - effect: 酼駘宁ì<^ʉ逐GM¼韹宅劑圦ȢN鵸; + key: LjdOPUZjJ + operator: 窃銥ɺ嘭t緯ȇw,[t捻S麨vɂ閰 + tolerationSeconds: 1714321621775966700 + value: Uvm9nY3 + topologySpreadConstraints: + - labelSelector: + matchExpressions: + - key: AUro1 + operator: 聘 + values: + - x5E03owNK1 + - 61u06hoBRErcl + matchLabels: + HMA: 7iZSaiF + jCP15v: ksLC1iD + matchLabelKeys: + - cp + - CZpJKgP + maxSkew: 644443933 + minDomains: 1722624609 + nodeAffinityPolicy: ú(ʆɴȾ狍lfĒHȉ嫔7ix壿 + nodeTaintsPolicy: 遡lşř门Ǣl + topologyKey: qP + whenUnsatisfiable: "" + - labelSelector: + matchExpressions: + - key: i8xDfgO + operator: ʖĝ#烕ɋřĊI + values: + - bOA4n + - ByUsK + - key: 6fCdAFtmFF + operator: 靕ƭ錒Ĕ + values: + - JIMC2Pc + - a7wA08 + - key: xMn + operator: "" + values: + - gSa5XT + - 50IS6 + - "8" + matchLabels: + DoGCwvltR: vVXQcZcxdz + JLmhsQlh: L3AY0Pv + X9: U + maxSkew: -2038040013 + minDomains: -1884001920 + nodeAffinityPolicy: 嵋磋ɹ:ɢ慚TA烁.X幰 + nodeTaintsPolicy: 奒)ʅm=矕郔o鬻鴊ȵɯt债CŔ儤 + topologyKey: qkx4gKx7 + whenUnsatisfiable: 匊aO卞肝喚覕Ȭnr說ɉƢ/Æȧ婡賛 + volumes: + - configMap: + name: foGC + name: configs + - name: v1bEam0d + secret: + defaultMode: 64 + secretName: FOCtz7x + - name: 2keqwtlu + secret: + defaultMode: 494 + secretName: 1dug + - name: RAI0g6yvn + secret: + defaultMode: 354 + secretName: "2" + - name: MqQb15NA +-- testdata/case-034.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: false +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + 0fz: qRhpB + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: zE + app.kubernetes.io/version: v2.7.0 + blGSa: Hnim0SflkfpF + helm.sh/chart: console-0.7.29 + name: QxrM + namespace: default +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} + role-bindings.yaml: |- + roleBindings: + - zktoFv: null + - BnTf: null + N30: null + O: null + - "5": null + up6oELWDxO: null + roles.yaml: |- + roles: + - 3vFSt6CV6h: null + - zwoEunAfS: null + - "": null + Kz: null +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + 0fz: qRhpB + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: zE + app.kubernetes.io/version: v2.7.0 + blGSa: Hnim0SflkfpF + helm.sh/chart: console-0.7.29 + name: l +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: + W8Ix4: 4kOonr2 + g93: wNXcKSBg + creationTimestamp: null + labels: + 0fz: qRhpB + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: zE + app.kubernetes.io/version: v2.7.0 + blGSa: Hnim0SflkfpF + helm.sh/chart: console-0.7.29 + name: l + namespace: default +spec: + ports: + - name: http + port: 421 + protocol: TCP + targetPort: 214 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: zE + type: d2QGeqxiX +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "l-test-connection" + namespace: "default" + labels: + 0fz: qRhpB + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: zE + app.kubernetes.io/version: v2.7.0 + blGSa: Hnim0SflkfpF + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + imagePullSecrets: + - name: AGiMf + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['l:421'] + restartPolicy: Never + priorityClassName: ER4 +-- testdata/case-035.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: + 7lpi: QQ + RK: "" + od3x: "3" + creationTimestamp: null + labels: + 5NU: UG7t + 6NmZI: QxuTdplvdDdc + BYcISWrd5: YZbXA + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: HMyYp + namespace: default +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} + roles.yaml: |- + roles: + - CSJ: null + - 0hM2tbS5: null + ZhG3M: null +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + 5NU: UG7t + 6NmZI: QxuTdplvdDdc + BYcISWrd5: YZbXA + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: Bv0I +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: + C3p: uCspVMX + creationTimestamp: null + labels: + 5NU: UG7t + 6NmZI: QxuTdplvdDdc + BYcISWrd5: YZbXA + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: Bv0I + namespace: default +spec: + ports: + - name: http + port: 51 + protocol: TCP + targetPort: 456 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + type: ZQQlqx7Np +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: {} + creationTimestamp: null + labels: + 5NU: UG7t + 6NmZI: QxuTdplvdDdc + BYcISWrd5: YZbXA + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: Bv0I + namespace: default +spec: + replicas: 464 + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + strategy: + rollingUpdate: {} + type: Ʉ>朄崍ʡƥɼ戋\IJĹ + template: + metadata: + annotations: + checksum/config: 6556f5b75614fc7b5556cf3e548fa463f543604a0e97446ccd74584bf794de97 + creationTimestamp: null + labels: + Klzm: we + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + e: C2swj + s: vw1lrq + spec: + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: Zjc3H + operator: ~IJʚ伥ʜ1鷦鄪脳= + - key: AI40kXKS + operator: Tr^ǘõ8ù<鹶ĉ崱 + values: + - fCyDs + - nJRkjROTjd + matchFields: + - key: yFbZ + operator: Ĉ8%Sp + - key: AUDzh + operator: 礉 + values: + - agJ0f + - MD + - key: hREcH + operator: Ǻŀɏʉ紸戳禰ȸ酲 + values: + - JUaNJ + - CXFmegvU + weight: 1536882470 + - preference: + matchExpressions: + - key: pXW + operator: '@ļ矏鮯ɭ碊Gɽt蜮閻ƃǖ#ũ' + values: + - I8SZLF + - key: Rz + operator: '''p麛ȧ' + - key: mvD0aV1 + operator: 狴ȸ溂辷0Ġ + values: + - JpJWDh + matchFields: + - key: OB4 + operator: "" + values: + - tnWLH4yB + - "" + weight: 410194565 + - preference: + matchFields: + - key: 2C + operator: 屮少Ļɶ賊滺W + values: + - 28ZwpH + - ybv8 + - 8qy7 + - key: bs + operator: ŝ鮱芬Ǧ脸ƍ蠎Ā + weight: -1129044572 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: [] + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: ayaEl + operator: Ɗ琫 + values: + - WGZPb + - EzYpfj + - key: Isb + operator: '@£驍' + matchLabelKeys: + - 2NNt + - NCBB22ja0 + - retU + mismatchLabelKeys: + - x3 + namespaceSelector: + matchExpressions: + - key: iQ + operator: u倲鹩?úʈ腄跛[¤O + values: + - 5y4bG + topologyKey: STnAVX + weight: -1894745290 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: R + operator: xʣcǦ:槠ʒ鄊喁蠨 + values: + - P + - 348OOM + - "0" + - key: hpIVL + operator: 鷭ʚ櫹hȅɩ&嘨Ād旌³ƑǫʄcǶ + matchLabels: + h6hNi: II1Z29P + t: 8wxT + matchLabelKeys: + - P + - axCJXjr + - ICeVp + mismatchLabelKeys: + - ljKwc + - mr6kl5v + - e + namespaceSelector: + matchExpressions: + - key: C + operator: =ĥĕ壚_隈]Ȑ釀侹ʩʎ痿c揜 + values: + - K1K + - c8fwp + - 8vQ4EPywlatl + - key: 28EpNe + operator: 鼓頳'ʛ1挂ō緕当gToʇ接遫 + - key: "" + operator: ƝZĂ 寑=愝奚Ĩw桟t摧pŸ + values: + - BuqtJnV + - 0hpJEbg + matchLabels: + 4lNwC: NEzAktH + h3ErklId8G: qClR4lO9e + namespaces: + - AYtMy3oUrS + - aX5P8O + topologyKey: 6D + weight: -1152164451 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: F6jo11z + operator: 亊路+M + values: + - h + - mmuiW + - GIV7E3H + - key: C + operator: v2佉鱉v辑ɞȠXɎʫǸú81Ɵ + values: + - QL + - MPxVd + - dqj9PPnthc + - key: 6JaPa + operator: 8dž貒ɑzןlȍH琧3ɞ + values: + - 1vJUmwXUq + matchLabels: + CIFj: YwH + Y2kn8RCwh: 90KzxhieelQ + y05g7PKLJ: 75bPN + matchLabelKeys: + - bYiD + mismatchLabelKeys: + - IiTYx5K5t + namespaceSelector: {} + namespaces: + - rZw0zlprDr + topologyKey: sxEn3K + weight: -1384321177 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: VgaK0hEji + operator: Ĺ礇紈銠噐ɴ諠2稇Ɠ鸈ý藁 + - key: S + operator: 鋸ɢǎ"膤ƭU軖tg埞鴤駩蹡 + - key: 9CwIty + operator: '`\糖ť8弤娹)覇gƲ妒墲9n' + values: + - 3j6O7C1tYz8 + matchLabels: + 0gEuFD: 74yF5 + matchLabelKeys: + - C + - IaGS + mismatchLabelKeys: + - W1 + - x + namespaceSelector: + matchExpressions: + - key: WXQ4P + operator: eĈ峧ʔƟ±ps缆D戭ǟ + values: + - "" + - EyV7u6ShG55 + topologyKey: DHgv6 + - labelSelector: + matchExpressions: + - key: RrGr5 + operator: 苭 + values: + - s + - Uk9D + - qTA4 + matchLabels: + yvalC: zQDHWOCId + matchLabelKeys: + - j1mN0G + mismatchLabelKeys: + - VdCZU8 + namespaceSelector: + matchExpressions: + - key: YzPO7z + operator: Lȇ杦娀 + values: + - 4UCJLskm4 + - VY + - key: arPd + operator: 燔佰馛{I諵Gƣ_*e + matchLabels: + g3PzQTKu: EtFrI + namespaces: + - ZXe + - ik9z + topologyKey: Os0u + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: DTU + operator: 鷚OíDzRě¤觹J闬#6U脥狍 + values: + - "" + - A5o + - gC + matchLabels: + Dm: WpOLJ + matchLabelKeys: + - z + mismatchLabelKeys: + - ICMl + namespaceSelector: + matchLabels: + XY9q9YY6uD: CiedBn + namespaces: + - vZ6M + topologyKey: OpLnLGsE + weight: 538966601 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: kEha + operator: Ę沌`f帞qA'躚S郻Ɏ珍韄 + values: + - etjdRyp + - zavjaM + - OYvYj + matchLabels: + KVwZfB: KEPzsU59 + RkZ: 0VcRQYQ + YpbOAE: DLjKEd + mismatchLabelKeys: + - djF + - SUMMj + - TGSC2G8I1Up + namespaceSelector: + matchExpressions: + - key: menWm + operator: k÷餌Ō + values: + - x9N + - mtsmYut + - key: szQb + operator: °« + values: + - hkxKeWqC + - key: YJUom + operator: ź²%FÔ縥:嗚K + values: + - NiQwKD + matchLabels: + 4AI5GYaY: ALH1BY + Bu43TOQ: WD + H: iujH1 + namespaces: + - Lc1PZ + - Z7LIE + - s4c0o + topologyKey: P7xmm2 + weight: 1130067767 + - podAffinityTerm: + labelSelector: {} + matchLabelKeys: + - yJiUSi + mismatchLabelKeys: + - 3ulP + - "66" + - "4" + namespaceSelector: + matchExpressions: + - key: eK + operator: 钕Ŧ + values: + - yRj + - Ukm + - "" + - key: "" + operator: 锧BȾLF譨Ɣ? + values: + - MtLk2 + - mUrlwRAdRoNX + - key: rlSqK0xlaaI + operator: 'Ɏƶʗ疇ȵMÇŕ翸鑉d劯kʦĺʄ4 ' + matchLabels: + FGHX9SlJz: MRMXuk + topologyKey: 4morNsk6TdYi + weight: -971499940 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: zosngP + operator: ʒ蠜¡ȂŧIH闦º弓鳾蠖Ą批9}_ + matchLabels: + "": wEhn + P1O8tGwJ: ZC + matchLabelKeys: + - IN0 + namespaceSelector: + matchLabels: + wMID0: aOr1UxM + topologyKey: krnVB + - labelSelector: + matchExpressions: + - key: mE + operator: 虵xǯ6熋湧ƳʝŅU节擎隆X鏯 + values: + - k + - bcx + - ks + matchLabels: + nYs: Hv5tuwQ + zAVu: G1PF + matchLabelKeys: + - u + - Gi6tJR + - "60" + namespaceSelector: + matchExpressions: + - key: bqRj + operator: ĭ啞&/sFş(墠O1Ÿ( + values: + - fe2dTLTbB + - QLUYqgc + - XBuCBfk27 + - key: exMkm + operator: m輚ɮ凪哇褚 + values: + - EQROy + - XQDPF7uw + - key: MwOO + operator: 鹗u仏兤o*>蒟顨ƽėȰ + values: + - TGv + - VVtqHApm + - 7Mub + matchLabels: + PI: elzxW + Wd1Q: MYEPScu1su + i: uENdc + topologyKey: QlwUBoDWM + automountServiceAccountToken: true + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: 14jKCyMC + value: Mb95Ivlchi + valueFrom: + configMapKeyRef: + key: FMRh9 + name: VwME2dRYnb + optional: true + fieldRef: + apiVersion: NlY1uxRPgql + fieldPath: NDrKU5 + resourceFieldRef: + containerName: gPQ1TD3MX + divisor: "0" + resource: r6HOpjj + secretKeyRef: + key: "n" + name: RQLa2rQL7Y + optional: false + - name: LICENSE + valueFrom: + secretKeyRef: + key: xLO4B2BCZUJ + name: BQR2Y + envFrom: [] + image: XB9ke7yB/EwU0pzhz:SmZAnO7 + imagePullPolicy: 垿儣Ƈ#WMƻ + livenessProbe: + failureThreshold: 724782955 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 1633166106 + periodSeconds: 2105675880 + successThreshold: 225361138 + timeoutSeconds: -1665363921 + name: console + ports: + - containerPort: 456 + name: http + protocol: TCP + readinessProbe: + failureThreshold: -1128918125 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: -116128728 + periodSeconds: -1936485392 + successThreshold: -1735161598 + timeoutSeconds: -1293939870 + resources: + limits: + 0PRJ1bi: "0" + JUjtrq: "0" + WN9h: "0" + requests: + TCeGWCB: "0" + x5O0IxuN: "0" + securityContext: + allowPrivilegeEscalation: false + capabilities: + add: + - '@晏駚T!UɎȉépg鎘Ȉ' + drop: + - ÚơĊ猴渋ĭ8膔櫔ż択ůĦ抹 + privileged: true + procMount: 偖躪 + readOnlyRootFilesystem: false + runAsGroup: -543916493751029760 + runAsNonRoot: false + runAsUser: 7772713475568768000 + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: pqfdKzb + mountPropagation: "" + name: 6btv + subPath: xLjoA + subPathExpr: UseM + - mountPath: EYXxm + mountPropagation: 煊`ś蠶+蓲慅4曌Ƥ4臜.魼簌m缽荈巇 + name: 6ut6g + subPath: 7N + subPathExpr: ypY + - command: + - DlBCuc8xa + - X2hi8Mp + image: 00GQ5 + imagePullPolicy: 賎ʂG}Ƌ煚6ūaĠ腻f + lifecycle: + postStart: + exec: + command: + - mVlE + - cFmlozRTJ + - "" + httpGet: + host: RIzcOYFo + path: eZge9wzJjW + port: ugY08 + scheme: 讣Ɨƶ"ɇǘƓƮ + sleep: + seconds: -5362042555365295000 + preStop: + exec: + command: + - "" + httpGet: + host: hLxRfJhv + path: JA8kOIY + port: tpH1 + scheme: '''k:嘡葊佒ďȏǓɡ毫/视倴ĩ}Ɓ u' + sleep: + seconds: -915316715834475000 + livenessProbe: + exec: {} + failureThreshold: 1628387875 + grpc: + port: -119747124 + service: 3cnWKI + httpGet: + host: 6Wzb9 + path: Af + port: RAzYX + scheme: 嘾Q經f + initialDelaySeconds: 4951530 + periodSeconds: 1309655668 + successThreshold: 918641827 + terminationGracePeriodSeconds: -3073080783253286400 + timeoutSeconds: -1896420637 + name: yML27O + ports: + - containerPort: 509868797 + hostIP: XMFIjyy7MNejY + hostPort: 2083818454 + name: gd + protocol: 槏 R¨ƽT³簑ƤA$<猿.0d + - containerPort: -164866787 + hostIP: eh + hostPort: 1842390272 + name: H7 + protocol: y擫`/洄]ʢÓ7Ā紐ǟ塋 + readinessProbe: + exec: + command: + - 5MrELPMn + - 23x1a + failureThreshold: 1394382122 + grpc: + port: -96138878 + service: DBq + httpGet: + host: 60SrHkgc + path: OwZeja1P + port: 721461548 + scheme: ' `$ħ' + initialDelaySeconds: -2125734502 + periodSeconds: 66441733 + successThreshold: 130216629 + terminationGracePeriodSeconds: -7113768241875088000 + timeoutSeconds: -977567736 + resizePolicy: + - resourceName: 8VNf4C + restartPolicy: Ě} + resources: + limits: + 2TX: "0" + Yd3: "0" + avcFFX: "0" + restartPolicy: Ę<彪6 + securityContext: + allowPrivilegeEscalation: false + capabilities: + add: + - ūW銹fn|óOB¶őǝ:ɛ暙- 嫴 + - 韣噺Ȑ主鋥Ɣ睩熾@Ĥvƈ + - 気ʎɭ愢勈īɔ垆ŀ槌,q儇p顼ǯ歳 + drop: + - EģIJ>筡|n譌ɶd2鍇$X/ȴ偎穾7 + - "赻探ǞiN胂a + name: 79CeZyd + subPath: xMQ + subPathExpr: NvU + - mountPath: smgfnmvP + mountPropagation: ʈ + name: CuKUC + subPath: hZ8KJ3 + subPathExpr: CK4WsX + - mountPath: zm + mountPropagation: 傩骟Ⱥ|尤fŇɓ呣ɘĩŽ + name: wRtUU + readOnly: true + subPath: T1 + subPathExpr: cidBhX8I + workingDir: M0jsi8 + - args: + - rQ7QBmZ4 + - Q32wY3lGUA + - VGeP + command: + - "6" + - 5vVr2Q + - 4YDd + env: + - name: DY1 + value: sge + valueFrom: + configMapKeyRef: + key: O8RUTpJ + name: SCF5ph + optional: true + fieldRef: + apiVersion: NY0hb + fieldPath: ViZ0f + resourceFieldRef: + containerName: "Y" + divisor: "0" + resource: sCX + secretKeyRef: + key: Ma + name: 6s6lc5 + optional: false + - name: m19lk2eiDtcdB7 + value: 0JaB + valueFrom: + configMapKeyRef: + key: VolU + name: jnFjMLIQ19 + optional: true + fieldRef: + apiVersion: "6" + fieldPath: N0wIEnFmQ + resourceFieldRef: + containerName: QwDG86d + divisor: "0" + resource: pda + secretKeyRef: + key: Uc7x1XF + name: efgc + optional: true + - name: 8A + value: 1kUmljHSb + valueFrom: + configMapKeyRef: + key: "" + name: z18yxT + optional: true + fieldRef: + apiVersion: 1qaE + fieldPath: vEzPx + resourceFieldRef: + containerName: GYhSz + divisor: "0" + resource: Ttq + secretKeyRef: + key: aaGRQS + name: C + optional: false + envFrom: + - configMapRef: + name: "0" + optional: false + prefix: 5cqcw + secretRef: + name: O7Gex12 + optional: false + - configMapRef: + name: DHEYwZ + optional: false + prefix: wSbyGx + secretRef: + name: 9nM86dZi + optional: false + image: E + imagePullPolicy: 栧Z + lifecycle: + postStart: + exec: + command: + - 6775E + httpGet: + host: hIoYmpbc + path: qEf + port: rnJpXG69m + scheme: 赙¯6a腚 + sleep: + seconds: 4894208532244896000 + preStop: + exec: + command: + - mHtY + - 0hh1Tr + - "" + httpGet: + host: BuElf + path: fJPDiyG + port: PybmIT + scheme: M*Ķ + sleep: + seconds: 7544543348205058000 + livenessProbe: + exec: + command: + - z7IJ + failureThreshold: -360493877 + grpc: + port: -1395908290 + service: zV1i + httpGet: + host: GLn + port: -279409955 + scheme: ǃU螄骰褃Ʀ诐Ɯ{,ɍb萎Ɲʢ鰪\U + initialDelaySeconds: 1831688310 + periodSeconds: -280461011 + successThreshold: 84363106 + terminationGracePeriodSeconds: 7513815341722355000 + timeoutSeconds: 442815657 + name: pGthpc + readinessProbe: + exec: + command: + - T39QO5 + - "" + - DbSsPel + failureThreshold: -1901163919 + grpc: + port: 1255815597 + service: xeTv + httpGet: + host: bipPJGJ + path: nghEbF + port: uyLPK + scheme: 翁渹牯澖 + initialDelaySeconds: 1295268788 + periodSeconds: 17921235 + successThreshold: -212369586 + terminationGracePeriodSeconds: 1061046207943693700 + timeoutSeconds: -1707711843 + resizePolicy: + - resourceName: RLHi + restartPolicy: 掳?帐(Ǖčĭ纜 + - resourceName: H1Bv + restartPolicy: Ɉ駃愝ɲƁ2*ʍJ蕦ʃĹr}尕5J埉g + - resourceName: f + restartPolicy: ɧ帨y晒ʪäǗ«ǤǞugT埤X澇寿Ù\ + resources: {} + restartPolicy: 7Y熀7rúǬ轘 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - Ǒn%Aʙ]m* + privileged: false + procMount: 鼷R珍沌 + readOnlyRootFilesystem: false + runAsGroup: -287129322294347260 + runAsNonRoot: true + runAsUser: 3942212766283409400 + startupProbe: + exec: + command: + - gN + - zpmlcJ + - DeLJ4s + failureThreshold: 102924404 + grpc: + port: -1304933194 + service: 0iK + httpGet: + host: jbg + path: ZqaSpx8C + port: UPJqfy9dOO + scheme: 韼QY岩沴ì釪儇9ĩN + initialDelaySeconds: -46268668 + periodSeconds: -1126074804 + successThreshold: -2093938118 + terminationGracePeriodSeconds: -3498490773203628500 + timeoutSeconds: -736335366 + terminationMessagePath: "7" + terminationMessagePolicy: 辺OB¯悱楆3Ǫ首傭ɟ鮛ïƇ豙ǁUȵ + tty: true + volumeDevices: + - devicePath: DSh1 + name: 1OMawuQAlZD7 + - devicePath: "Y" + name: liCI2j + volumeMounts: + - mountPath: JPO9Ewk3kgaeuBD + mountPropagation: k釂Żɮ>ɸêW箁B| + name: QGO7HtoR + readOnly: true + subPath: oYudCrOqA + subPathExpr: Z1oG + - mountPath: iH6 + mountPropagation: dP帗俪Ťŷ/6¤þ剛&Ģ趽qi + name: 9Ro4aQU5yby + readOnly: true + subPath: piBl3 + subPathExpr: nfDFn + - mountPath: uU2H4 + mountPropagation: ljQ + name: "" + subPath: rj2 + subPathExpr: E + workingDir: BveK3 + imagePullSecrets: + - name: ygWNP7C0W9 + - name: lo0PU + initContainers: + - 'error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string + into Go value of type []interface {}' + nodeSelector: + LAqpO: N7lh0C2 + RqG8qj: ltTa5 + X3q: F5c + priorityClassName: F + securityContext: + fsGroup: -8750452531563962000 + fsGroupChangePolicy: RȗɻÎ + runAsGroup: 3754171381447903000 + runAsNonRoot: false + runAsUser: 2565919490422334500 + supplementalGroups: + - 2907772986244332000 + - -4686580881125536000 + - -7134026849524392000 + sysctls: + - name: 8gezWufB + value: 2Jv + - name: 4nhjhT6P + value: 32ZuT + - name: cQk5tljX + value: Aimzt8kirN + serviceAccountName: HMyYp + tolerations: + - effect: aƻƀi + key: 7II7D0fA + operator: 跳<ȴŤƇ梐ȸŷR + tolerationSeconds: -92963183946417040 + value: U + - effect: p鸿xś冣9ɩ揊Ů忁琺ȖP壡o繊堮 + key: 5sC + operator: XɦǨ燖Ż綯逆挤ʦ斝蟏滣ʣ + tolerationSeconds: -6405135249548566000 + value: c2m6hlo + topologySpreadConstraints: + - labelSelector: + matchExpressions: + - key: bsO + operator: Ⱥ8欟慡Ƿţ6氙絿鐘黬聠ç + values: + - hbuLC + - SdAZnchI + - key: b4Pjya + operator: jɀh5湧,Ȳǣ6謉<ɦ + - key: gXEm + operator: ',k涃栏岴g橚甇ȳ0禰餝榖睌ěB縩侾F' + values: + - q9VqX4l + - zoMoc9Vb5 + matchLabels: + B0T: uiIEpLD2 + V: jdhpTcaa + pz: V1dJXS8 + matchLabelKeys: + - yoFhTrxV + - o + maxSkew: -1837539887 + minDomains: 2144009248 + nodeAffinityPolicy: 怓覷環ʤ苷疿ʡB聧!]LJƱĿGť + nodeTaintsPolicy: V~0韾¾Ȣû&嵙纠&ȠVƧ鍌 + topologyKey: GldA + whenUnsatisfiable: Ƀk纩{寍HƋ&庝僟D徼聊 + volumes: + - configMap: + name: Bv0I + name: configs + - name: 00PT1WRWHX + - name: P4 + - name: fn +--- +# Source: console/templates/ingress.yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + annotations: {} + creationTimestamp: null + labels: + 5NU: UG7t + 6NmZI: QxuTdplvdDdc + BYcISWrd5: YZbXA + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: Bv0I +spec: + ingressClassName: vg + rules: + - host: daRMGxIy7gKoE + http: + paths: + - backend: + service: + name: Bv0I + port: + number: 51 + path: GVhF41Ue + pathType: TeM8 + - backend: + service: + name: Bv0I + port: + number: 51 + path: UontjIzl + pathType: MN + - backend: + service: + name: Bv0I + port: + number: 51 + path: "" + pathType: xN + - host: YCgI + http: + paths: + - backend: + service: + name: Bv0I + port: + number: 51 + path: MPhdfahEcn + pathType: ECPrn + - host: GDOlAVRM + http: + paths: + - backend: + service: + name: Bv0I + port: + number: 51 + path: H5pExfzke + pathType: v8 + tls: + - hosts: + - dQiMWdJ8cYKS + - 35K + - 8Kin + secretName: C + - hosts: + - zPo + - Z7 + secretName: SiZz +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "Bv0I-test-connection" + namespace: "default" + labels: + 5NU: UG7t + 6NmZI: QxuTdplvdDdc + BYcISWrd5: YZbXA + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + imagePullSecrets: + - name: ygWNP7C0W9 + - name: lo0PU + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['Bv0I:51'] + restartPolicy: Never + priorityClassName: F +-- testdata/case-036.yaml.golden -- +--- +# Source: console/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + labels: + Nv: YHcp9u + RMi5: o4 + ViLr0: zrEw3 + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 9mG8n4Wu4 + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: AumW +stringData: + enterprise-license: "" + kafka-protobuf-git-basicauth-password: EfQbyB + kafka-sasl-aws-msk-iam-secret-key: B + kafka-sasl-password: w + kafka-schema-registry-password: qiltVq + kafka-schemaregistry-tls-ca: kyT4j + kafka-schemaregistry-tls-cert: Tu4varJ + kafka-schemaregistry-tls-key: bmT + kafka-tls-ca: UyskLmDZ + kafka-tls-cert: "" + kafka-tls-key: "" + login-github-oauth-client-secret: hPt + login-github-personal-access-token: vRbRqD0 + login-google-groups-service-account.json: lcc9 + login-google-oauth-client-secret: "" + login-jwt-secret: SECRETKEY + login-oidc-client-secret: A9RDbO6GzTtHYG + login-okta-client-secret: HktzleLAg + login-okta-directory-api-token: qX + redpanda-admin-api-password: 5imX8ztdqjU + redpanda-admin-api-tls-ca: opQQ + redpanda-admin-api-tls-cert: PGcfJC3zH + redpanda-admin-api-tls-key: IhqyTvQn4T +type: Opaque +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + Nv: YHcp9u + RMi5: o4 + ViLr0: zrEw3 + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 9mG8n4Wu4 + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: AumW + namespace: default +spec: + ports: + - name: http + port: 113 + protocol: TCP + targetPort: 414 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: 9mG8n4Wu4 + type: XHYb2qmrk +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + GvX4jkWw: xAyNk + MdtXxfH: "" + WyrWx: 8QO + creationTimestamp: null + labels: + Nv: YHcp9u + RMi5: o4 + ViLr0: zrEw3 + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 9mG8n4Wu4 + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: AumW + namespace: default +spec: + replicas: 24 + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: 9mG8n4Wu4 + strategy: + rollingUpdate: {} + type: LJėwǮ甧 + template: + metadata: + annotations: + checksum/config: 74234e98afe7498fb5daf1f36ac2d78acc339464f950703b8c019892f982b90b + jLE31lUP: LWc + creationTimestamp: null + labels: + 6W: FQvOa + YwkBSNWK: 0qqd + app.kubernetes.io/instance: console + app.kubernetes.io/name: 9mG8n4Wu4 + jP3: iNkD + spec: + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: bkwD5 + operator: B砟摫ʟ]估ȽÓĖ頒ʙǯ + - key: 4n + operator: "" + - key: DDWUTPllaee + operator: ǒ@訹Ðđɤ軗ɲǃZ袓6悔ʙ[x] + values: + - bHwxZg + - iPWF3DQz + - yhiFQZ98w6h + weight: -551427274 + - preference: + matchExpressions: + - key: kZ + operator: "" + values: + - BMfDa + - key: l + operator: unɚʀɂ7Ǩ蘕 + values: + - 1vsAjW + - lEGj0 + matchFields: + - key: EYCyU + operator: 袒雬Ǐ蔡|骐pOĆƍbʌʝl + - key: e9QdJHV + operator: Ɏ鼛鏗擌-悝Ű + values: + - DToToJ + - Gq4 + - key: M4b3wwVy + operator: 煛苅=İ哋ońɢ\Głh斳hɷ韙 + values: + - fMIoNrUiyJdi + - tcNEhOds + - N0 + weight: -906035045 + - preference: + matchExpressions: + - key: 05VafuKQo + operator: ƃèĢC篘 + values: + - McUwm + - oMXVW + matchFields: + - key: "" + operator: 9ȮLǟ3V廉\5膏ɩ袴 + values: + - t + - r8d6G + - FevHe + - key: KeJd9X4 + operator: \Y#uɆɫwĉɎ卲S + weight: -773391374 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: PiRY + operator: 週畯嘰Œ铖'ȸ0Į5k,逊 + values: + - Fo9oE + - KLfm4 + - PiZJC + - key: 6HCuuj + operator: Ȋ!ʈh牅HŹ蓓% + values: + - PU34U + - bZ12kwJ4s1 + matchFields: + - key: CCVSIZH + operator: (铴Njʦ釖Ĩ鎅ƒ獞p)唓u¸::2 + values: + - DjvLD + - key: 9gy6tFM + operator: ø + values: + - lPjPu0 + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: 2oL + operator: Ì溄祤BNjɎ_ )jðZF + - key: Tl1mGP + operator: r0ȨȵeēP眼饾j + - key: 98uL + operator: "" + matchLabels: + "": H0F + IGfr: 8iR8 + pTjU: 2vy5Ol + matchLabelKeys: + - l2d3an + mismatchLabelKeys: + - gomcuJ + - UMhaBnQUuSH4 + namespaceSelector: + matchExpressions: + - key: CyYjfraf + operator: 鸫ʊűoǪĞ3 + values: + - uPW + - key: vuREiHB + operator: ^ĄçȂ挌 + matchLabels: + tlcI6jz: 87JK + namespaces: + - eUszN + topologyKey: yJ + weight: 1657692208 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: 3d3mr + operator: 鿈Ė聭焚歉Ð(币帄Ⱥ + values: + - h + - key: Z5c + operator: ma琓 + values: + - i5Ae6oUo + - EWixIB + - "y" + namespaceSelector: + matchExpressions: + - key: XFYbW + operator: M~ + - key: lWHcsQ + operator: 铿X异~<ÿ缇ī*^ĩ + matchLabels: + s: l6sxM + vFiVA7j: WEOy1jtU + topologyKey: JW85dr45m2G + weight: 444678250 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: bMT + operator: ^)4ɊDZǸDŽ + values: + - CG9Onrt + - key: T + operator: ƞ傏 + values: + - bXs59oj + matchLabels: + 6BRwn: Pdm + Yy: aaoLnp + myN: rwJGrW + mismatchLabelKeys: + - "n" + - c + namespaceSelector: + matchLabels: + 5QMzPp: AP + D: "2" + u: Dca + namespaces: + - 8Af + - NYfxoYf + - R4G + topologyKey: yY + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: 2uhHhqog + operator: Ȧ + values: + - YgsgGf + - key: EaR + operator: 愅YVǵ楔¢4Ʋ + values: + - xaEk + - key: NV5iPi5Kw + operator: ' 軕氡#晉Ʀ筜篧e蹶ʀSɟʂÊʕT' + values: + - BY4 + matchLabelKeys: + - 9fTYFH7s + - aK6HB6 + mismatchLabelKeys: + - 13L + namespaceSelector: + matchExpressions: + - key: 3FT + operator: Tğ枕Ōo*a種JU-ɶƠdz鱓fƑS + values: + - 4ISUCT + - po8yM2L + - T5Q0UARu + - key: RhB + operator: "" + values: + - Re7 + - 7id + - 91GFPdrt + - key: ShRTzNRj + operator: ʬ吇Ȭ?搰Ç + values: + - HiGOGJE + - wOi + - HmllR83Dbvoz + namespaces: + - "" + - TBCPW + topologyKey: 0H + weight: 1493754197 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: CESaz + operator: ŢaæX#暁鲸'媩俛5齗aw'ĥ煆W + values: + - "" + - key: YtpoWP + operator: 瀽LƠ' + values: + - uS13z + - ip0h + - o8m9MWnmr92 + matchLabels: + 7o4tt: QX9gjN + KScJOoR95: Dpu + wfAk1b: rH5Z + matchLabelKeys: + - Yh1S1nZ7hm + - Fwx + - 6mhp + mismatchLabelKeys: + - ihvyNa7 + - m8 + - Q + namespaceSelector: + matchLabels: + 2KH67NR4: Vy8qZyy + topologyKey: w0KJ + weight: 1592497187 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + 1UcAh: h + namespaceSelector: + matchExpressions: + - key: yxz + operator: ',酵ýhȿ鲹芫澥 Ǧ_Ź躄_莯ʊ傡硬M' + values: + - Fof + - key: 8KwNEN + operator: 8炮逴8`M鞵ȍȟ蟷盱 + - key: N0 + operator: Ì崌爷矉&佷* JQȴ躀厇退ƿƍ肙 + values: + - kjlwyKc + - DDz + - Yf8Vf5Ar7w7 + topologyKey: n5cRtvXjK + automountServiceAccountToken: false + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: 0iCX + value: UfKNkXj6I + valueFrom: + configMapKeyRef: + key: GGYmdb5PBtUx + name: Zl1rWu9 + optional: true + fieldRef: + apiVersion: 1pKgni + fieldPath: 8Zmv + resourceFieldRef: + containerName: nK + divisor: "0" + resource: Yizp + secretKeyRef: + key: Dxqh + name: td + optional: false + - name: bm + value: K06vl + valueFrom: + configMapKeyRef: + key: dOTjzfwtRPzX + name: YleYOzRS + optional: true + fieldRef: + apiVersion: xl + fieldPath: 6NM2 + resourceFieldRef: + containerName: jreT + divisor: "0" + resource: "" + secretKeyRef: + key: B7 + name: cu + optional: true + - name: F4Vp + value: 9q + valueFrom: + configMapKeyRef: + key: dAPalKT0 + name: UXC7S + optional: false + fieldRef: + apiVersion: bTxwQmS + fieldPath: XW + resourceFieldRef: + containerName: iqnl + divisor: "0" + resource: e9 + secretKeyRef: + key: c1WJ + name: sg2TuPSW + optional: false + - name: KAFKA_SASL_PASSWORD + valueFrom: + secretKeyRef: + key: kafka-sasl-password + name: AumW + - name: KAFKA_PROTOBUF_GIT_BASICAUTH_PASSWORD + valueFrom: + secretKeyRef: + key: kafka-protobuf-git-basicauth-password + name: AumW + - name: KAFKA_SASL_AWSMSKIAM_SECRETKEY + valueFrom: + secretKeyRef: + key: kafka-sasl-aws-msk-iam-secret-key + name: AumW + - name: KAFKA_TLS_CAFILEPATH + value: /etc/console/secrets/kafka-tls-ca + - name: KAFKA_SCHEMAREGISTRY_TLS_CAFILEPATH + value: /etc/console/secrets/kafka-schemaregistry-tls-ca + - name: KAFKA_SCHEMAREGISTRY_TLS_CERTFILEPATH + value: /etc/console/secrets/kafka-schemaregistry-tls-cert + - name: KAFKA_SCHEMAREGISTRY_TLS_KEYFILEPATH + value: /etc/console/secrets/kafka-schemaregistry-tls-key + - name: KAFKA_SCHEMAREGISTRY_PASSWORD + valueFrom: + secretKeyRef: + key: kafka-schema-registry-password + name: AumW + - name: LOGIN_JWTSECRET + valueFrom: + secretKeyRef: + key: login-jwt-secret + name: AumW + - name: LOGIN_GOOGLE_DIRECTORY_SERVICEACCOUNTFILEPATH + value: /etc/console/secrets/login-google-groups-service-account.json + - name: LOGIN_GITHUB_CLIENTSECRET + valueFrom: + secretKeyRef: + key: login-github-oauth-client-secret + name: AumW + - name: LOGIN_GITHUB_DIRECTORY_PERSONALACCESSTOKEN + valueFrom: + secretKeyRef: + key: login-github-personal-access-token + name: AumW + - name: LOGIN_OKTA_CLIENTSECRET + valueFrom: + secretKeyRef: + key: login-okta-client-secret + name: AumW + - name: LOGIN_OKTA_DIRECTORY_APITOKEN + valueFrom: + secretKeyRef: + key: login-okta-directory-api-token + name: AumW + - name: LOGIN_OIDC_CLIENTSECRET + valueFrom: + secretKeyRef: + key: login-oidc-client-secret + name: AumW + - name: REDPANDA_ADMINAPI_PASSWORD + valueFrom: + secretKeyRef: + key: redpanda-admin-api-password + name: AumW + - name: REDPANDA_ADMINAPI_TLS_CAFILEPATH + value: /etc/console/secrets/redpanda-admin-api-tls-ca + - name: REDPANDA_ADMINAPI_TLS_KEYFILEPATH + value: /etc/console/secrets/redpanda-admin-api-tls-key + - name: REDPANDA_ADMINAPI_TLS_CERTFILEPATH + value: /etc/console/secrets/redpanda-admin-api-tls-cert + envFrom: + - configMapRef: + name: 3PT + optional: true + prefix: l + secretRef: + name: zakko + optional: false + - configMapRef: + name: RdxlkV + optional: false + prefix: 9Ae4W + secretRef: + name: UiJ + optional: true + - configMapRef: + name: bp + optional: true + prefix: SU + secretRef: + name: fy + optional: true + image: ai/f54I:iO + imagePullPolicy: ǫtŖŮƘ瓧ù¹勍u + livenessProbe: + failureThreshold: 864346345 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: -1341055636 + periodSeconds: 2055603833 + successThreshold: -175204389 + timeoutSeconds: -589897727 + name: console + ports: + - containerPort: 414 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 1075627654 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 333726894 + periodSeconds: 1376975278 + successThreshold: 112483424 + timeoutSeconds: 669945326 + resources: + limits: + 7VHN3: "0" + securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - '*·戌ɳKõʚK(懷ë蟅ȣg' + - vOpɔm&ɞ法槪ųf + drop: + - l¤0ɖK樌ŕDĪ箰ɬȓũ梫h揼 + - 躟OBZş互鹫Íʨƶ`ã + privileged: false + procMount: 9®俠ɳ屑ŏO'pe,Q+膿麣 + readOnlyRootFilesystem: false + runAsGroup: -289823929905824060 + runAsNonRoot: true + runAsUser: -4392330066259666400 + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: /etc/console/secrets + name: secrets + readOnly: true + - mountPath: Oly + mountPropagation: ƈįlñ + name: QuM + readOnly: true + subPath: NPJ + subPathExpr: vn + - mountPath: xsiqpcicm + mountPropagation: Ŝȃ燩čƃʤǸ儼 + name: blYv + readOnly: true + subPath: 8f + subPathExpr: I + - mountPath: "" + mountPropagation: 犒k洐ɨ3UʓďȏUm8/x艂" + name: i2 + readOnly: true + subPath: G + subPathExpr: Wo47OrA + - args: + - gfDaDhh + command: + - Eu + envFrom: + - configMapRef: + name: 9LtiYU + optional: false + prefix: dS5JDbtZJ + secretRef: + name: 3X5 + optional: false + - configMapRef: + name: vpOLCCmA + optional: true + prefix: IJpeUVYk3 + secretRef: + name: TaghAr + optional: true + image: Nw59jHFBw + imagePullPolicy: Eźz购綗映ò#ZuS絇溾^飷 + lifecycle: + postStart: + exec: + command: + - N2F2q + - XKeJn + - CfoVd + httpGet: + host: 0u3Kgf + port: PVA8u + scheme: ȧX[噦摼鎥憈ǴńƘŅ + sleep: + seconds: 9185496374723368000 + preStop: + exec: + command: + - lrWSClt + httpGet: + host: uS + path: 51Gzg9s + port: -1680102290 + scheme: 8涒齃ɠĬ諛鰅jyr塸ȷg× + sleep: + seconds: -302278202696680100 + livenessProbe: + exec: + command: + - fmu + - wJR3 + - 60zV6s4327rKb9 + failureThreshold: 2122798666 + grpc: + port: 1914605377 + service: ES + httpGet: + host: 7LAmwy8 + path: o2XAC + port: S5 + scheme: 犘ßħɚÂ剐*鬰ȇxȺ錎 + initialDelaySeconds: 343978803 + periodSeconds: -1725283583 + successThreshold: 1055506692 + terminationGracePeriodSeconds: -737021961431151200 + timeoutSeconds: 1721351711 + name: r + ports: + - containerPort: -341996687 + hostIP: zR + hostPort: -641414216 + name: AGa7X6lnw + protocol: 阧 + - containerPort: -1616018360 + hostIP: 8q + hostPort: -2060443566 + name: B + protocol: 位ŲȟHbfp餪魹| + - containerPort: -321829785 + hostIP: S + hostPort: 850049722 + protocol: ĢŔ=ɦŊ鳺醩hĂ踻鉀 + readinessProbe: + exec: + command: + - VRq0lZK + - nCUDH3Zgc + - f2h2C + failureThreshold: -444080905 + grpc: + port: -1484737838 + service: UL8hSUw + httpGet: + host: 8DDb + path: Z + port: It67aEO18 + scheme: 蹐疒Į浤 + initialDelaySeconds: -1225398553 + periodSeconds: -1497056806 + successThreshold: -1256842388 + terminationGracePeriodSeconds: -3265344141862786600 + timeoutSeconds: 1127947387 + resources: + limits: + "36": "0" + Oaiu: "0" + v: "0" + requests: + F0olO: "0" + tvGpYtd: "0" + restartPolicy: Ě卿ɫȰLZ懁 + securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - "" + drop: + - Ę螅7O5Ɵ駢Ó宮緂 + privileged: true + procMount: ʤ敠æx漭fƈŸʄ + readOnlyRootFilesystem: true + runAsGroup: -1779689763650766000 + runAsNonRoot: true + runAsUser: -1786517016760367000 + startupProbe: + exec: + command: + - Mcn36l + - "n" + - OMT3J + failureThreshold: 1137002720 + grpc: + port: -2106637755 + service: OYW + httpGet: + path: K + port: STUmUBT + scheme: 貪iɐ巶ɿiɲbɎ;Ŏċ2橺汲ŋ刢g + initialDelaySeconds: -648188998 + periodSeconds: -278768915 + successThreshold: 890955082 + terminationGracePeriodSeconds: 5660177701724483000 + timeoutSeconds: 959596283 + stdin: true + terminationMessagePath: h2a2mAm + terminationMessagePolicy: pjĉ + volumeDevices: + - devicePath: cZ95 + name: wLm + - devicePath: P9RW + name: PjzHR + volumeMounts: + - mountPath: b + mountPropagation: 脣Į + name: bOY + readOnly: true + subPath: mBuB + subPathExpr: 0io + - mountPath: DYp + mountPropagation: 9鹺t"Ĭij(?NB4ɖ鴼B屈桲ȋ噤ǁ + name: O + readOnly: true + subPath: EcI7mF + subPathExpr: HKfaS + - mountPath: NTgHw + mountPropagation: (ńÆ;裉嵀 + name: U6TGXB + subPath: wjpyjQ + subPathExpr: nqq + workingDir: NpjQN3dM + - args: + - m + - fmRfLPl + command: + - okKsRu + env: + - name: y8FxBu + valueFrom: + configMapKeyRef: + key: 1kdTq + name: NGzFHD + optional: false + fieldRef: + apiVersion: WDoDm + fieldPath: HTHz + resourceFieldRef: + containerName: aWk + divisor: "0" + resource: RcTwrpd4PaqW + secretKeyRef: + key: 27uDnW9fM1 + name: diwId6SMC + optional: true + - name: NZ1pEV + value: Xq7fA + valueFrom: + configMapKeyRef: + key: cYo + name: IhK1oKNNr + optional: true + fieldRef: + apiVersion: 0C + fieldPath: "" + resourceFieldRef: + containerName: OywKEud3 + divisor: "0" + resource: E4 + secretKeyRef: + key: gGTl + name: V + optional: false + envFrom: + - configMapRef: + name: fJ + optional: true + prefix: zFUU1PguE + secretRef: + name: S7Jre + optional: false + image: gbZ4mqT + imagePullPolicy: '*罖Ē掙*uĕĥ世û煨o曁ɖ)嬫噩肖Ñ' + lifecycle: + postStart: + exec: + command: + - nxKsxt + - F25ka4x + httpGet: + host: "0" + path: 9k0yMphk + port: GJdG + scheme: 婁箅蝼đ杣Ɗ°VAƭ0ĺ钘1 + sleep: + seconds: 8039264634100238000 + preStop: + exec: + command: + - NuJoJm + - gykEI + - "6" + httpGet: + host: UnkqD3SS + path: BhN + port: 712546393 + scheme: u + sleep: + seconds: 409536667065008450 + livenessProbe: + exec: {} + failureThreshold: 204373937 + grpc: + port: 1803358082 + service: VXsxSeh + httpGet: + host: Ht64jf7Eo + path: u1jjW9Qu + port: 556487018 + scheme: 熖Ű存ŖT磇ɘ外 + initialDelaySeconds: -1152834471 + periodSeconds: -1133396594 + successThreshold: -1385193405 + terminationGracePeriodSeconds: 2915006546098799000 + timeoutSeconds: -1401054296 + name: dfD716 + ports: + - containerPort: 691082006 + hostIP: b + hostPort: 636825973 + name: S5FmEWKv + protocol: g]se墰掀媸晓櫚驟憽hbƥsư° + readinessProbe: + exec: {} + failureThreshold: 152987910 + grpc: + port: 642951905 + service: q2qfom8L + httpGet: + host: GaxyfqlQ + path: Oh0t + port: -766612198 + scheme: UÂ_ + initialDelaySeconds: -1382761032 + periodSeconds: 967018272 + successThreshold: -178373997 + terminationGracePeriodSeconds: 6605400648980209000 + timeoutSeconds: -1404918452 + resources: + limits: + 7cu: "0" + 22n7v: "0" + XsU5mrE: "0" + requests: + kyXuqf: "0" + mBk4P9DWW: "0" + restartPolicy: ʓdT>NȚks_q祈 + securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - ȸŏ脸(Yǃ¯~垇耗A) + - T翱ĥ + drop: + - 商ʏ軒Ƣ厢 + - Ⱥãt\跋þ漙苣ű吡憕鿶0傜om + privileged: false + procMount: Ŷ% + readOnlyRootFilesystem: true + runAsGroup: -1052699124096043900 + runAsNonRoot: false + runAsUser: 3737016357651072500 + startupProbe: + exec: + command: + - jefRNS + failureThreshold: -9144267 + grpc: + port: 642233169 + service: WjvgDkGG + httpGet: + host: 8hzgS0q + path: z + port: -885964296 + scheme: ɸliŵ + initialDelaySeconds: 1014078949 + periodSeconds: 1410148112 + successThreshold: 1164669668 + terminationGracePeriodSeconds: -3385668069040238000 + timeoutSeconds: -1723583731 + stdin: true + terminationMessagePath: zbCh + terminationMessagePolicy: 4攨2õė+軩Ç + tty: true + volumeDevices: + - devicePath: Nx + name: QLHA + - devicePath: 9JAgFLSdSqQ + name: "5" + volumeMounts: + - mountPath: KXG1 + mountPropagation: ȁ捄ɺ絒馢A¥`Èť + name: aghWO + readOnly: true + subPath: el7KEVsV + subPathExpr: tdksniBM + - mountPath: 5nus8 + mountPropagation: N饢杼M7X尅扐ǗÃɱNƞeuĦg儡 + name: TS4kHG + readOnly: true + subPath: i + subPathExpr: ktDaTCGG + - mountPath: CSkt9N0i + mountPropagation: 爕ɐYYȁ<獱椂@椗áʇ憣>\Ɋ筙纉Ë + name: KIKRXUR + readOnly: true + subPath: bWYTiq + subPathExpr: cgxlHqVV + workingDir: F + imagePullSecrets: + - name: bbjdn + - name: VI + initContainers: + - 'error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string + into Go value of type []interface {}' + nodeSelector: + U3Rfg9: WSTvjvP + hODw: LSv + iwleZ: fD + priorityClassName: gPB + securityContext: + fsGroup: 8205502301244812000 + fsGroupChangePolicy: "" + runAsGroup: -8440674019915816000 + runAsNonRoot: true + runAsUser: 4432310384984167400 + supplementalGroups: + - 7965846110903122000 + - -9174375158887063000 + sysctls: + - name: OkeQ + value: A + - name: 24y + value: fIPA + - name: "" + value: b3 + serviceAccountName: Jg + tolerations: [] + topologySpreadConstraints: [] + volumes: + - configMap: + name: AumW + name: configs + - name: secrets + secret: + secretName: AumW + - name: HUa7xM +-- testdata/case-037.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + BJ: Gq0Rw + FPcPYvmbB7dAZe: Cy7WaeI + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: u2r6 + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + uEVMkDkYRvnn: zvptNai + name: ItYso + namespace: default +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} + role-bindings.yaml: |- + roleBindings: + - 2m: null + VNrY1fwY: null + eaGm2c: null + - Ng0sM: null + Txhv6: null + e2uo: null + roles.yaml: |- + roles: + - Dd: null + H0QLXtA: null +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + BJ: Gq0Rw + FPcPYvmbB7dAZe: Cy7WaeI + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: u2r6 + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + uEVMkDkYRvnn: zvptNai + name: ADIhC +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + BJ: Gq0Rw + FPcPYvmbB7dAZe: Cy7WaeI + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: u2r6 + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + uEVMkDkYRvnn: zvptNai + name: ADIhC + namespace: default +spec: + ports: + - name: http + port: 226 + protocol: TCP + targetPort: 87 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: u2r6 + type: At +--- +# Source: console/templates/ingress.yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + annotations: + "8": SeJ + creationTimestamp: null + labels: + BJ: Gq0Rw + FPcPYvmbB7dAZe: Cy7WaeI + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: u2r6 + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + uEVMkDkYRvnn: zvptNai + name: ADIhC +spec: + ingressClassName: PHr + rules: + - host: PXAcFs520n + http: + paths: + - backend: + service: + name: ADIhC + port: + number: 226 + path: 1uGP0 + pathType: dWpX + - backend: + service: + name: ADIhC + port: + number: 226 + path: hAH + pathType: LjzFf + - backend: + service: + name: ADIhC + port: + number: 226 + path: 7Qy + pathType: vjB + - host: z9QAJ5 + http: + paths: null + - host: "" + http: + paths: + - backend: + service: + name: ADIhC + port: + number: 226 + path: Hc0IpaX + pathType: bc0T + - backend: + service: + name: ADIhC + port: + number: 226 + path: dzn1ldJ5h + pathType: M + tls: null +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "ADIhC-test-connection" + namespace: "default" + labels: + BJ: Gq0Rw + FPcPYvmbB7dAZe: Cy7WaeI + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: u2r6 + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + uEVMkDkYRvnn: zvptNai + annotations: + "helm.sh/hook": test +spec: + imagePullSecrets: + - name: Yi + - name: 6XnEhUN + - name: oeoW + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['ADIhC:226'] + restartPolicy: Never + priorityClassName: U7wS +-- testdata/case-038.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: ld + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: fP77cJ3T + namespace: default +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} + role-bindings.yaml: |- + roleBindings: + - zn: null + - WCQKaiaj: null + py: null + roles.yaml: |- + roles: + - {} +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: ld + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: j1dUk8TGy8Np +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: ld + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: j1dUk8TGy8Np + namespace: default +spec: + ports: + - name: http + port: 46 + protocol: TCP + targetPort: 43 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: ld + type: uqFB +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "j1dUk8TGy8Np-test-connection" + namespace: "default" + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: ld + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + imagePullSecrets: + - name: OlRQO + - name: Hkuk3 + - name: fP + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['j1dUk8TGy8Np:46'] + restartPolicy: Never + priorityClassName: 89gnK9rXyDXui +-- testdata/case-039.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: false +kind: ServiceAccount +metadata: + annotations: + PPZDrdmxKV: UBjiSx + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: o2F37Lr + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: 8s2qVhKEW + namespace: default +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} + role-bindings.yaml: |- + roleBindings: + - 6O4d: null + EY: null + oPTMvYGp: null +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: o2F37Lr + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: bbshm +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: + 4yhZo: zLVEslN + Amz4VM: QAvK + IPCS: b1R + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: o2F37Lr + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: bbshm + namespace: default +spec: + ports: + - name: http + port: 400 + protocol: TCP + targetPort: 329 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: o2F37Lr + type: dPOD9Kzb +--- +# Source: console/templates/ingress.yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: o2F37Lr + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: bbshm +spec: + ingressClassName: qyKUEOUT4u + rules: + - host: chart-example.local + http: + paths: + - backend: + service: + name: bbshm + port: + number: 400 + path: / + pathType: ImplementationSpecific + tls: + - hosts: + - F7m23 + - "7" + secretName: M +-- testdata/case-040.yaml.golden -- +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + X: zjmrl + "Y": yG0 + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 6sW + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: KchYZFsbB3 +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + X: zjmrl + "Y": yG0 + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 6sW + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: KchYZFsbB3 + namespace: default +spec: + ports: + - name: http + port: 424 + protocol: TCP + targetPort: 17 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: 6sW + type: oZi +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: {} + creationTimestamp: null + labels: + X: zjmrl + "Y": yG0 + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 6sW + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: KchYZFsbB3 + namespace: default +spec: + replicas: 291 + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: 6sW + strategy: + rollingUpdate: {} + type: G阏发6s + template: + metadata: + annotations: + checksum/config: 6f40381c972fd418dd311a992b76c4181a57129add8096d427da1c5284bcdd8a + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: 6sW + spec: + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: 7RRFnuao + operator: 鑿梞e璺瀧敢tȱ + - key: 3qz030r9N4 + operator: 脟óȨq駥Ƽx垤R$L + - key: 4egJ + operator: 敕ƒ洀ņ+Ō轲C丼Ʒij.ƾ蚯ƺ痻3皆咒 + values: + - "" + - J66saNw8 + - xBRUfDKhiA + matchFields: + - key: Kgp4qFm + operator: 桋iz<ïŃǃ襶D齿 + - key: 7F + operator: "" + values: + - iquNT + - aFPIw + - lYMJn4Un3 + weight: -954635927 + - preference: + matchExpressions: + - key: ePHgEs + operator: 撹ł + weight: -2109244754 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: gK + operator: 垭ʮȌ)"彛 + values: + - Vvo + - "" + - key: n0 + operator: 挪VɱȒ + values: + - 595ST + - sHQoTQgQ + - ZyYxnGB + matchFields: + - key: "8" + operator: 餒ơ鋦r)锟壃m汇 + values: + - H8 + - matchExpressions: + - key: nErJm + operator: Ûɟ敀淽 + values: + - sbjW + - 1l + - go + matchFields: + - key: ozzkD4D + operator: Ʌ\h崭蠒ȓ旉蹖楚_掁S5 + values: + - NrN0Id15O + - VrahPz + - YJfhO + - {} + podAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: qiGNj + operator: jƯȨ穞ɿPȧ + - key: HPRR + operator: ž8ƃKKDz蠽ƚ0ƻ + values: + - NAx + - Pr2F + matchLabels: + LY: ZRjD + matchLabelKeys: + - ikCO + - n25 + - IY0AqNStYm + mismatchLabelKeys: + - uO6G + - EFKfLOM0 + namespaceSelector: + matchExpressions: + - key: frBwUGG + operator: ǧ啯ʖ6džȡ衺Z莋æȘzv + values: + - 68q + - PrId4k5Nk + - 1Izg6c + - key: H5neR + operator: "" + values: + - gf2 + - "" + - key: LTEiVQV + operator: ʅďl$y韙bO儺e籾吕ŃV + values: + - LccIflVn3 + - QX + - kRZLtn + matchLabels: + lccn5: lx6 + topologyKey: AE + - labelSelector: + matchExpressions: + - key: ljGag0 + operator: "" + values: + - 3AlcF9eOiK + - key: XPoIj + operator: ĻĵN稙²x鸴ʊ + - key: "" + operator: m[ɻD«ʯĢĥɖHÃú锺N蓍!f + values: + - cwRFs + - wJtpMgyV1I + matchLabels: + 6gzmw2BW: v1eC + QI6Gl: Ckzyw0v + uRw21: 36kl + mismatchLabelKeys: + - XiX9Mrhv + - Xk2Ri + namespaceSelector: + matchExpressions: + - key: Roq9G + operator: 槓G{? + values: + - YCBJEhS + matchLabels: + 9X5C: TU1y + PG1k: 8j76iX8R + iYq9QLUSh3bk: Mvl2WRQ + namespaces: + - Pp + - z1O9mW5rB + topologyKey: U + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: pqtCgWlk + operator: eŭñZ) + values: + - 6eUrtsX + - GmGeP7 + - pBhe0 + - key: gctw + operator: L?岤紎!蠾黅誽帯÷Ʉ坏q + values: + - G + - "" + - "" + matchLabelKeys: + - IGYc + mismatchLabelKeys: + - C + - XlxD2Y5h + - Eut + namespaceSelector: + matchExpressions: + - key: QNvJq6Uc + operator: Ǔƀ閝遨垛簙UdĢ7ȍ騽¹DŽ + values: + - m4wq + - TmuqVB1 + - key: PTVC + operator: 珙'ɀɒ虃龓楼ƺ譄êǿ + values: + - w + - K + matchLabels: + GQp: tw + namespaces: + - t + topologyKey: I9Ng7D + weight: -278680619 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: IaZiqfV6 + operator: 幋x:Ȗ + values: + - XmaYG80 + - aaEScB + - DxB + matchLabels: + J3Ny9zUJ2DOTKO: eiUL0RR + lt: bqOs + matchLabelKeys: + - XYHp1S + - JKj1 + namespaceSelector: + matchLabels: + WopugltEP1J: eaGpkiS + namespaces: + - H9w9Q + - A8D + topologyKey: pvkKW + weight: 252280673 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: lSi + operator: 襚ǫAŇþ腦W[ĕ嘱ʌſœɃ槏Z岪 + matchLabels: + OzmceOBQ: F2mtk + QcoH: qt3OR6ZcjY + t5Cqg1: 1x9WW8EUyyn + matchLabelKeys: + - 0XGJ + mismatchLabelKeys: + - K6T + namespaceSelector: + matchExpressions: + - key: KoofEA + operator: ' íɀ馩Ȭɫġo娤螗暴Û漷ʦO腔' + values: + - nj + - U + - onkfJ4 + - key: 0aO + operator: Ŷű輖+¶)罩ƌ×螂 + matchLabels: + 2hf: GeFfROs4 + pA23: kqkG + rZ: DH6cT + namespaces: + - yvfsu + - L3Pu + topologyKey: BBBCjZel + weight: 392487334 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + 0hp: sd9 + mwTeR: D3HlJbmoK8 + matchLabelKeys: + - MwDkniC + - "" + mismatchLabelKeys: + - VuQB + namespaceSelector: + matchLabels: + 1x: Pj + D3J: 4gFps + bQU: weT0tI + namespaces: + - y9zrYKWApO + - rq0K3 + - 5XUeP7 + topologyKey: P7V + - labelSelector: + matchExpressions: + - key: Jv + operator: 啽ŃŐø + matchLabelKeys: + - s + namespaceSelector: + matchExpressions: + - key: Fy5Deb + operator: 旉錛!荕Ɂ! + values: + - nbiy + - "" + - 6QORDbd6zn + matchLabels: + bba0KJ: NE1j + nYif5xu0Hy9XW: 0s + qAoT: "46" + namespaces: + - 4JHyx + topologyKey: 7621t + automountServiceAccountToken: false + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: cD + value: JW + valueFrom: + configMapKeyRef: + key: "" + name: 8Ri7OfQ + optional: false + fieldRef: + apiVersion: Qc + fieldPath: 6ZYFg + resourceFieldRef: + containerName: qkUV + divisor: "0" + resource: yEf5zz13U + secretKeyRef: + key: xozuxs + name: z + optional: true + - name: "" + value: gea3 + valueFrom: + configMapKeyRef: + key: hwe3l3k2h + name: QX + optional: true + fieldRef: + apiVersion: kx + fieldPath: m7f + resourceFieldRef: + containerName: 0XEGE + divisor: "0" + resource: y4ce5 + secretKeyRef: + key: hmvX + name: 18Z + optional: true + - name: LICENSE + valueFrom: + secretKeyRef: + key: a7Ph + name: zsHNWVcS9 + envFrom: + - configMapRef: + name: DR3hdrvZIv + optional: true + prefix: kGV4HZ8 + secretRef: + name: tR3Yu1G + optional: true + - configMapRef: + name: 6pMd0VA0 + optional: true + prefix: Csp + secretRef: + name: ceqZBJ7fdqP + optional: true + image: cwfXN2KlU/qYQHJ:RIG + imagePullPolicy: -0Ź桛ɼ訚Ņ;秵ňĝ苒9麡ñà臸ʫ + livenessProbe: + failureThreshold: -1894321442 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 1986051838 + periodSeconds: 541607099 + successThreshold: -1968479306 + timeoutSeconds: 1374945691 + name: console + ports: + - containerPort: 17 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 467513555 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: -6410364 + periodSeconds: -623380707 + successThreshold: 1641270972 + timeoutSeconds: 1203716236 + resources: + limits: + "1": "0" + MrwIP: "0" + hgaW: "0" + requests: + 1lF: "0" + securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - 阊 + - DIȜO吽解诎-曅 + drop: + - 贎秨Ůɭ懾Ù盾| + privileged: true + procMount: ʪ勪įOew\Ǡ礓 + readOnlyRootFilesystem: true + runAsGroup: -6230225082797374000 + runAsNonRoot: true + runAsUser: -2569068293811685000 + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: d + name: ieSo8V + subPath: "" + - args: + - jlI16Xnnb0 + - x0Z + - Tv6z + command: + - 3MnkZe0L + - OK + - cKvaGI + env: + - name: 7RtgX9 + value: TQH + valueFrom: + configMapKeyRef: + key: "" + name: GE2 + optional: false + fieldRef: + apiVersion: x2H + fieldPath: iVYVzT + resourceFieldRef: + containerName: 3QSG + divisor: "0" + resource: AgMtPE + secretKeyRef: + key: BhGA6 + name: LKemd3Cs9 + optional: false + - name: 9dFxchX + value: huoZj + valueFrom: + configMapKeyRef: + key: skdmo + name: gSEkUx + optional: true + fieldRef: + apiVersion: ymAcwLzaJ00G + fieldPath: de9Q + resourceFieldRef: + containerName: ZgwwQvA + divisor: "0" + resource: OTraA + secretKeyRef: + key: Pe8 + name: 39mCZV7ERv + optional: true + envFrom: + - configMapRef: + name: l + optional: false + prefix: kGdnbCakM + secretRef: + name: JrDM + optional: true + - configMapRef: + name: 0iH67 + optional: true + prefix: 3JVMhcII7 + secretRef: + name: PS1J + optional: true + image: Bx3IW17kjF7 + imagePullPolicy: È8秏糇 + lifecycle: + postStart: + exec: {} + httpGet: + host: EeLx + path: JC + port: 638412697 + scheme: 翔ĩñɁɬj局³喪Eů磘Ʒ唡嬤 + sleep: + seconds: -2739564842418698000 + preStop: + exec: + command: + - zjNyV + - 3i + httpGet: + host: RxhMCXQN + path: Dq + port: -821303664 + scheme: 髒xD>?ǠĆ踃w¬ + sleep: + seconds: 8925361607851383000 + livenessProbe: + exec: {} + failureThreshold: -2015695369 + grpc: + port: 102189788 + service: VG2k6Atq + httpGet: + host: 0dxm + path: Pix7SytH + port: 284583441 + scheme: 畝ǂƬƜ聞|b + initialDelaySeconds: 1150668189 + periodSeconds: 1279412097 + successThreshold: 337444728 + terminationGracePeriodSeconds: -665826210809930800 + timeoutSeconds: -802810999 + name: 1KSo0a + readinessProbe: + exec: + command: + - 3cCL4 + - en + - VN0 + failureThreshold: 448729232 + grpc: + port: -174942651 + service: paUcCUtV8A6 + httpGet: + host: tSEChhvGgDsf + path: Jrr + port: 516172996 + scheme: c{Ƭ臾斡:Ɣ?Í + initialDelaySeconds: -714126900 + periodSeconds: -88316167 + successThreshold: -1820867160 + terminationGracePeriodSeconds: 272130190949654340 + timeoutSeconds: 1803351679 + resources: + limits: + f9GQWFTKPFP: "0" + g5: "0" + requests: + 4A89zLoFG: "0" + SmOBH: "0" + restartPolicy: Ű高ǙG%7BČCaďʥyď + securityContext: + allowPrivilegeEscalation: false + capabilities: + add: + - H鞕ă鶅镀秀 + - Ŏ昮0yƤɯ斺R妕Je芓BɜCĵ + privileged: false + procMount: ÿʑ鎆乭cŇ陛ǼȠn + readOnlyRootFilesystem: true + runAsGroup: 5591360478943232000 + runAsNonRoot: false + runAsUser: 6381588597473823000 + startupProbe: + exec: + command: + - rV83LKQ + - 87Vc + failureThreshold: -2022114361 + grpc: + port: 1348736621 + service: Gx8f9phR + httpGet: + host: fWnW4CGV + path: yQl0PNEE3g + port: TYi + scheme: 絅xn,ȵ6ʎ癙 + initialDelaySeconds: 205090742 + periodSeconds: -1401542741 + successThreshold: -2130268569 + terminationGracePeriodSeconds: 4104437343850793000 + timeoutSeconds: 604054255 + terminationMessagePath: ec8kHaD + terminationMessagePolicy: 甎i + tty: true + volumeDevices: + - devicePath: NFjF + name: AH + - devicePath: "" + name: u + - devicePath: 0q6A + name: nFe3FY4 + volumeMounts: + - mountPath: ad7JXhGN + mountPropagation: =廄殞+ + name: qVHWCUHp + readOnly: true + subPath: m3RBekA0 + subPathExpr: 7F0F8Ge + workingDir: LmnqIVV + - args: + - 3g94Jb + - "n" + - HxatWli7Qe + env: + - name: yKfn + value: fni0 + valueFrom: + configMapKeyRef: + key: cQjxg02ud + name: DqLUCO + optional: false + fieldRef: + apiVersion: dS + fieldPath: aH + resourceFieldRef: + containerName: BVSH2Bxu + divisor: "0" + resource: ZLW3 + secretKeyRef: + key: J + name: APYyG5qY + optional: false + - name: b4i9WEf + value: Ru + valueFrom: + configMapKeyRef: + key: mzxgZ + name: XgDd + optional: false + fieldRef: + apiVersion: U1l + fieldPath: sG2pcjz + resourceFieldRef: + containerName: Vlc1Ru + divisor: "0" + resource: hZpqB + secretKeyRef: + key: X0W3QpdAhux + name: I3L + optional: true + envFrom: + - configMapRef: + name: DJjN7Phe + optional: true + prefix: 4K2MBzNl + secretRef: + name: s4GF + optional: true + - configMapRef: + name: td0aZ + optional: true + prefix: CYvFW + secretRef: + name: WaBWGCRa8 + optional: true + - configMapRef: + name: ehHs9m + optional: false + prefix: n1x + secretRef: + name: TdUJ + optional: true + image: UNJ6E6 + imagePullPolicy: 砓³绔丬A + lifecycle: + postStart: + exec: + command: + - Qs8Sd + - JGX4Qj + - eCw00uq + httpGet: + host: NNLSd + path: y4tS + port: QzOfwe3a + scheme: º猗ĥɮƅLɘ隮术ƒ赥;,ǝ髳Ĝ7Ĭ嬳 + sleep: + seconds: 1170469124057922000 + preStop: + exec: + command: + - TN62uDLAuIx + - ndI + httpGet: + host: t7H6l2 + port: RHeYpAvJ8 + scheme: KǠɀƴ杔¸Ɉ$毕削peýfv! + sleep: + seconds: -5232306180460338000 + livenessProbe: + exec: {} + failureThreshold: -1900233123 + grpc: + port: -1323381498 + service: wJ + httpGet: + host: pAHsn3 + path: k31zW1 + port: 2elbrK + scheme: 痯秿丌 + initialDelaySeconds: 537756270 + periodSeconds: 1139432456 + successThreshold: -289377675 + terminationGracePeriodSeconds: -709025030374540900 + timeoutSeconds: 254134433 + name: zWs + readinessProbe: + exec: + command: + - x093a + - v1 + - Ef + failureThreshold: 75768089 + grpc: + port: -237977747 + service: "y" + httpGet: + host: EBEth + path: C + port: 790399211 + scheme: ær堹mhʢ + initialDelaySeconds: -157687184 + periodSeconds: 1071897332 + successThreshold: 824432298 + terminationGracePeriodSeconds: -54575953702939670 + timeoutSeconds: -1190752843 + resizePolicy: + - resourceName: R9fM + restartPolicy: ?ʖȒƅƀ逎v鐰wģ籫 + - resourceName: 7C + restartPolicy: óʌF鿯薸k} + - resourceName: Bqy + restartPolicy: E吻X秤} + resources: + limits: + UMJnobyO: "0" + qJmAwr: "0" + requests: + ZktW7e51vRUG: "0" + restartPolicy: '>ŀ鎙莸鼔茷蝼薼Ƽƅ°3貦罌臣洴軟處姼' + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - 儜vƝ¾ + - 輝Ġ$琑+檂 + - 飂 + privileged: false + procMount: ɓĎʙʗG0瑑娄K坢Ö&Ù + readOnlyRootFilesystem: true + runAsGroup: 2234167178876811300 + runAsNonRoot: true + runAsUser: -1191472066985646800 + startupProbe: + exec: + command: + - KGi9U + - D6 + - HZ3aC1 + failureThreshold: -2057203764 + grpc: + port: -1203229903 + service: Xd + httpGet: + host: tTW + path: oWk + port: -1347841801 + scheme: 檸`sȝBULj懄 + initialDelaySeconds: 1386184157 + periodSeconds: 2110004457 + successThreshold: -692279219 + terminationGracePeriodSeconds: -7060466210747559000 + timeoutSeconds: -905577521 + terminationMessagePath: g + terminationMessagePolicy: 頨Ĥ° òȯǤū暓坐ƚă杋鍄 + volumeMounts: + - mountPath: FmQht + mountPropagation: 饌^ǩ朳ųW磀ĥAijƨ+= + name: j5 + subPath: aoEWb7k + subPathExpr: 0ra + workingDir: zmwmt + - command: + - oFEaN2U1 + - HuBj9vk17eCjI + - "" + env: + - name: n3JVvVY + value: U14PEXs + valueFrom: + configMapKeyRef: + key: Ai0Xg3owIe7XlG + name: U4 + optional: false + fieldRef: + apiVersion: ZyO4Jpwkp2hV + fieldPath: roNil + resourceFieldRef: + containerName: gx + divisor: "0" + resource: Z + secretKeyRef: + key: AcP + name: qMy + optional: false + - name: oSWakHA + value: eR + valueFrom: + configMapKeyRef: + key: qsSVOr + name: o + optional: false + fieldRef: + apiVersion: SeP3aPXfjLIcfE + fieldPath: 091i + resourceFieldRef: + containerName: T5hI + divisor: "0" + resource: KxGi43CVGe + secretKeyRef: + key: "" + name: 5uI + optional: true + envFrom: + - configMapRef: + name: MujT + optional: false + prefix: cVRH + secretRef: + name: mpF + optional: true + - configMapRef: + name: MeO3F + optional: false + prefix: w3C4 + secretRef: + name: hnYx + optional: false + - configMapRef: + name: NT5MFmC65 + optional: true + prefix: "7" + secretRef: + name: yl2ze1 + optional: false + image: A8o + imagePullPolicy: ?晐T鴭Xp + lifecycle: + postStart: + exec: + command: + - zaLOG2 + httpGet: + host: kA51kbv + path: LMnFclIJczBo + port: 402299955 + scheme: :踖坯(Iȷ碨劅 + sleep: + seconds: 245674034851902980 + preStop: + exec: + command: + - Tz87qO + httpGet: + host: Xr6sP + path: xxE + port: 1901089000 + scheme: 3媧ş>La芸`Lzuŀɽ坤¦.痻Jǻ + sleep: + seconds: 6906639179439192000 + livenessProbe: + exec: + command: + - yxk0313sz + failureThreshold: 385001414 + grpc: + port: 1589713469 + service: UA + httpGet: + host: ZWfT + path: vTNYug5RZh + port: -192111662 + scheme: e¢dYÜdz + initialDelaySeconds: 1708942834 + periodSeconds: 1356452566 + successThreshold: 1750780088 + terminationGracePeriodSeconds: -1272770054640189000 + timeoutSeconds: 1656218869 + name: FxzTg + ports: + - containerPort: 63673829 + hostIP: 4xjED0VKV0G + hostPort: 2007665826 + name: xbwJ + protocol: ¼vb皪螯ʉwʒR玔È覦劙 + readinessProbe: + exec: + command: + - 0S + - "" + - GkPj + failureThreshold: 1405674719 + grpc: + port: -1659132742 + service: gIFP + httpGet: + host: jYnI3ins7 + path: bIEaFAc1 + port: UHfz + scheme: ʼn + initialDelaySeconds: 1531278754 + periodSeconds: -238235402 + successThreshold: -1690388514 + terminationGracePeriodSeconds: -2788228502880198700 + timeoutSeconds: -567709755 + resizePolicy: + - resourceName: nxpzTS + restartPolicy: ƫŀMs+,ǼƞȒ + - resourceName: 61uCVQ1 + restartPolicy: /澰ɍ½鑀a帷[鞺鏨攬姟壃F$R犬 + resources: + requests: + YfM: "0" + restartPolicy: œ|F彟S崘Ȑ貸1Ũȷ+齳 + securityContext: + allowPrivilegeEscalation: true + capabilities: + drop: + - 鸎dĉç荧 + privileged: true + procMount: "" + readOnlyRootFilesystem: false + runAsGroup: 5795239965908151000 + runAsNonRoot: true + runAsUser: 2409160731771391000 + startupProbe: + exec: + command: + - D6j2Q + failureThreshold: 975103738 + grpc: + port: -2081980063 + service: Nh + httpGet: + host: vdLm3FUXIs + path: jqCqF + port: "" + scheme: Ű"ƆĩNÙ襔冠ʈ + initialDelaySeconds: 524220215 + periodSeconds: 923596095 + successThreshold: 547119693 + terminationGracePeriodSeconds: 7382309226647739000 + timeoutSeconds: -1902082444 + terminationMessagePath: 2i5 + terminationMessagePolicy: 踑ĆĦ荷ýA/ǎ桫 + tty: true + volumeDevices: + - devicePath: KlUUX + name: NWO + - devicePath: W1JLM + name: qNw + - devicePath: BVE + name: c + volumeMounts: + - mountPath: yCztpht + mountPropagation: 巧苄;钽肇謌ʭɿw刄wɰM迵. + name: Mv9 + subPath: RWmlw + subPathExpr: Oy + - mountPath: Gf + mountPropagation: ɩ + name: On78O + readOnly: true + subPath: s7p + subPathExpr: 57aJIvpEm + - mountPath: m + mountPropagation: 崌蠿Ƣ湺 + name: CXSu + subPath: F8oe + subPathExpr: S + imagePullSecrets: + - name: V1 + - name: AyLzRkaGE + - name: 3pZ8 + initContainers: + - 'error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string + into Go value of type []interface {}' + nodeSelector: + y63G: wNiNvOMv + priorityClassName: 3A + securityContext: + fsGroup: 2302511509023017200 + fsGroupChangePolicy: 闦ñ禢`J鉤 + runAsGroup: -2347956389924857000 + runAsNonRoot: true + runAsUser: 1720952380350228700 + supplementalGroups: + - -621944387099711200 + sysctls: + - name: CvGz + value: "" + - name: dO + value: qwZyE + serviceAccountName: Cj + tolerations: [] + topologySpreadConstraints: + - labelSelector: + matchExpressions: + - key: pPoL + operator: ǭȉćŴ讶Y + values: + - "69" + - UC9 + - "7" + - key: 6toZoG + operator: Ġ+kʫȸ颷ʅÓ欽V譵; + values: + - go8adRXrn + - key: S + operator: ĕȻ*Gɝ靿暛_洳瑼Ĩ + matchLabelKeys: + - "" + - V7xIs1 + - eqq + maxSkew: 983843814 + minDomains: 854272231 + nodeAffinityPolicy: '>S篐ö抏茄(6' + nodeTaintsPolicy: e3äTȦ硷B捕萑Ǵ吷Ǿ邂Ǝièø + topologyKey: NoEcMWkg + whenUnsatisfiable: 幗鞲&渶Ÿɪ`鹵N + volumes: + - configMap: + name: KchYZFsbB3 + name: configs + - name: ieSo8V + secret: + defaultMode: 83 + secretName: mD0jl + - name: iPeR + - name: ZgdCb2kUB +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "KchYZFsbB3-test-connection" + namespace: "default" + labels: + X: zjmrl + "Y": yG0 + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 6sW + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + imagePullSecrets: + - name: V1 + - name: AyLzRkaGE + - name: 3pZ8 + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['KchYZFsbB3:424'] + restartPolicy: Never + priorityClassName: 3A +-- testdata/case-041.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: false +kind: ServiceAccount +metadata: + annotations: + 5DCBJ96u: 12Himnm + ZQrRxpb: Aa + abcRNo3AHIw: gH1 + creationTimestamp: null + labels: + T1: pMf7C + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: x + app.kubernetes.io/version: v2.7.0 + cxAL7zvwvb: tmEjSXwTK6 + helm.sh/chart: console-0.7.29 + name: 0Z71mJNQUx + namespace: default +--- +# Source: console/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + labels: + T1: pMf7C + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: x + app.kubernetes.io/version: v2.7.0 + cxAL7zvwvb: tmEjSXwTK6 + helm.sh/chart: console-0.7.29 + name: Wq +stringData: + enterprise-license: "" + kafka-protobuf-git-basicauth-password: 4uTKbvRNSh + kafka-sasl-aws-msk-iam-secret-key: tfc + kafka-sasl-password: NAMo + kafka-schema-registry-password: 5LUUey + kafka-schemaregistry-tls-ca: "" + kafka-schemaregistry-tls-cert: "" + kafka-schemaregistry-tls-key: i + kafka-tls-ca: Fydyp8 + kafka-tls-cert: R4y + kafka-tls-key: "" + login-github-oauth-client-secret: Y0 + login-github-personal-access-token: xyn + login-google-groups-service-account.json: zFJbYJ + login-google-oauth-client-secret: CsVVc6 + login-jwt-secret: SECRETKEY + login-oidc-client-secret: dsx + login-okta-client-secret: wr9eIA + login-okta-directory-api-token: Dy + redpanda-admin-api-password: O7kPq + redpanda-admin-api-tls-ca: 7ORz + redpanda-admin-api-tls-cert: IT + redpanda-admin-api-tls-key: KR25cT +type: Opaque +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} + role-bindings.yaml: |- + roleBindings: + - EQY9390E: null + WXyS: null + roles.yaml: |- + roles: + - {} +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + T1: pMf7C + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: x + app.kubernetes.io/version: v2.7.0 + cxAL7zvwvb: tmEjSXwTK6 + helm.sh/chart: console-0.7.29 + name: Wq +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: + Sxsz0HWh: z9cj + creationTimestamp: null + labels: + T1: pMf7C + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: x + app.kubernetes.io/version: v2.7.0 + cxAL7zvwvb: tmEjSXwTK6 + helm.sh/chart: console-0.7.29 + name: Wq + namespace: default +spec: + ports: + - name: http + port: 359 + protocol: TCP + targetPort: 363 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: x + type: tJUW +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + I4K: K1yz + creationTimestamp: null + labels: + T1: pMf7C + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: x + app.kubernetes.io/version: v2.7.0 + cxAL7zvwvb: tmEjSXwTK6 + helm.sh/chart: console-0.7.29 + name: Wq + namespace: default +spec: + replicas: null + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: x + strategy: + rollingUpdate: {} + type: 稫启玩ɡʂ56 龪o + template: + metadata: + annotations: + checksum/config: 2e1f5f5401bac9a6ca8b2205a50f20ebc4a08fcafa78467ca458eb9e8411b634 + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: x + spec: + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: gRchHJ + operator: g>騿b鈐ʃB¾偡医選ȍ恋 + values: + - I + - Ei + - "" + - key: hyf + operator: 斒ʃǜƆƲ + values: + - QUyyD + - key: Bkmx + operator: ư酰姺醪芄堑 + weight: 751548356 + - preference: + matchExpressions: + - key: oLam + operator: 蟹 + values: + - ouUaVpYnKDUI + - key: vjw6GPYYTKt + operator: 竣iN¸嚿×ɮib + values: + - ZTaqp + - key: d8VuBX6qV + operator: 脼Ȩ + values: + - a8aOe1 + matchFields: + - key: twbeCR + operator: óçøG靼Ɏȸ­乷ɍ + values: + - fJAm6rm + - 2h8IU + - zE9 + weight: 291395585 + - preference: + matchExpressions: + - key: qC6uf99en + operator: 鼢犖龆醑IÐ肣ɚòĺIGʖƟ穿ź' + readOnlyRootFilesystem: true + runAsGroup: -6867300864246943000 + runAsNonRoot: true + runAsUser: 972586500223089800 + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: ctE5Qa + name: gcTdF + subPath: "" + - mountPath: n8KpOJZ + name: "4" + subPath: "" + - mountPath: 3Ka7 + name: lBE0nAE + subPath: "" + - mountPath: cIK + mountPropagation: 爂 YLƝ«煘?沀#朚ń鮾+ğÔ + name: orwvhF0 + subPath: ivP1ha4I + subPathExpr: VPCFJYVRHf + - mountPath: s + mountPropagation: m椥扶ȟqÈ倕{峙刷} + name: O35 + subPath: AN + subPathExpr: vm7 + - mountPath: 7P72D19W + mountPropagation: 堂窜B,Ś贃腔Ʈ£顽ąfYR + name: 6Z + readOnly: true + subPath: d7MJ + subPathExpr: LF + - args: + - M5GoLEac + command: + - "" + env: + - name: xn + value: gHloqKCZA0M + valueFrom: + configMapKeyRef: + key: 9EasdvqH1 + name: 3Jm5qlVRdb + optional: false + fieldRef: + apiVersion: IEuh0S + fieldPath: yGW + resourceFieldRef: + containerName: 6ytjPS + divisor: "0" + resource: Z + secretKeyRef: + key: a1KfCCp1 + name: OspUW + optional: false + - name: 1jMB + value: gsvW9h + valueFrom: + configMapKeyRef: + key: lEB1Z + name: sB + optional: true + fieldRef: + fieldPath: zsUJ + resourceFieldRef: + containerName: 11SE1A + divisor: "0" + resource: OFZYobDs5 + secretKeyRef: + key: wwZ + name: 0z + optional: false + envFrom: + - configMapRef: + name: AuPTaMX7 + optional: true + prefix: YNB9WA + secretRef: + name: QyV6 + optional: true + - configMapRef: + name: N5izN44MJ + optional: true + prefix: 103jYU2pj + secretRef: + name: IsJ + optional: true + image: f + imagePullPolicy: ']L7掻钏ĚxǢRʃd×?ŠɓT{' + lifecycle: + postStart: + exec: + command: + - 1Kv + - F2E + - uX1vDFV + httpGet: + host: XQ5sY + path: 5X8E + port: ZEAsx0C5i + scheme: 巇L嶤n蔢ȥ.&h喵趶旃 + sleep: + seconds: 3646722142291548000 + preStop: + exec: + command: + - "98" + httpGet: + host: MWUlhjhJA + path: JM3LkEQY + port: I4x4q + scheme: ʄȀ%ʎ兒餐oc-c + sleep: + seconds: 2358122019278204000 + livenessProbe: + exec: + command: + - dyqr + - 79j + - 6N2YiU + failureThreshold: 1763651267 + grpc: + port: 1387074657 + service: m + httpGet: + host: G + path: 9kp6wlF5 + port: 5zuLtPI + scheme: d輢殣ſē诧Wɹ讏 + initialDelaySeconds: -1520109712 + periodSeconds: -1170771093 + successThreshold: -1383663641 + terminationGracePeriodSeconds: -1296467687071372800 + timeoutSeconds: 1017261975 + name: xf5VXbM9DX + ports: + - containerPort: -1245943187 + hostIP: iVo + hostPort: -1606480480 + protocol: à唿Ň癫俤健ǛƵ虰響 + - containerPort: 1088776251 + hostIP: mN + hostPort: 2006200810 + name: izfW + protocol: 蠣狓j霎緦(Lǫ[ + readinessProbe: + exec: + command: + - w + - ZZzn + failureThreshold: -841549142 + grpc: + port: -1318693763 + service: z3 + httpGet: + host: DK8AT0w + path: TQEPNMTrmL26 + port: -1446467943 + scheme: ś檊:& + initialDelaySeconds: -768827532 + periodSeconds: -2057604270 + successThreshold: -1558550931 + terminationGracePeriodSeconds: 6890017506404353000 + timeoutSeconds: -1558365951 + resizePolicy: + - resourceName: BhJ20rFM28sOexT + restartPolicy: 槟"äÅ緦Xjê荀谆 + resources: + limits: + 3yphxx: "0" + requests: + "71": "0" + qj1cwc9x: "0" + xIH2: "0" + restartPolicy: 兜藄墲皀 + securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - 翇ƒ\Ý琂麌褶犗錀Ć姉溬[I珵巖â迍Õ + - ȖnS¦ºǀʼndz&ü1 + privileged: false + procMount: ǻ\頧ADȜ[ʋɺɗ鬌ʢ栵鏆W剨 + readOnlyRootFilesystem: true + runAsGroup: -8217745538717204000 + runAsNonRoot: false + runAsUser: 8409092840666673000 + startupProbe: + exec: {} + failureThreshold: 514371514 + grpc: + port: 1386630692 + service: 5k9JljF + httpGet: + host: Yxa + path: KKzxL + port: 1749552838 + scheme: ǁ1钥`岺ȱ$ + initialDelaySeconds: 198009978 + periodSeconds: 1269387330 + successThreshold: 150401625 + terminationGracePeriodSeconds: 756942197968954200 + timeoutSeconds: -1507606503 + stdin: true + stdinOnce: true + terminationMessagePath: Yuuqhx + tty: true + workingDir: cNvZ0 + - args: + - EBJwKsy + - 88iT6Xcn + - XcT28aSWj + command: + - KYgqdbR + envFrom: + - configMapRef: + name: N30BWF9jx + optional: true + prefix: b + secretRef: + name: g + optional: true + - configMapRef: + name: vkY + optional: false + prefix: gn67ft + secretRef: + name: 9bmgS + optional: true + image: mhs + imagePullPolicy: agŒJ!Ǽƴ硴ĘBjp¸ǟ鏔ȫv + lifecycle: + postStart: + exec: {} + httpGet: + host: k1oZic + port: kWma + scheme: /A縊$/Ðl脿ʅK\Yû¡DȜ + sleep: + seconds: 4880710696024837000 + preStop: + exec: + command: + - mE1S + httpGet: + host: wmLvZ + path: P8Lw + port: 2130804875 + scheme: Aɷĝ/éȏ圳%)n帣 + sleep: + seconds: 5681554568621785000 + livenessProbe: + exec: + command: + - g + - 1tbHYej2 + failureThreshold: 721918154 + grpc: + port: 977234381 + service: K8 + httpGet: + host: o1a + path: EL + port: 606530945 + scheme: ɬ憋} + initialDelaySeconds: 527377871 + periodSeconds: 1831783866 + successThreshold: -925249104 + terminationGracePeriodSeconds: -5462814855858063000 + timeoutSeconds: 1067001478 + name: Cyr + ports: + - containerPort: -1582092218 + hostIP: HefrxT + hostPort: -1694778841 + name: "5" + protocol: 5訙奆Ņ蘹Ǭ馲ǧõsg + - containerPort: -1709296974 + hostIP: S + hostPort: -12435236 + name: RQIJVqVp + protocol: ı+=Ŷ\褭昊 + readinessProbe: + exec: + command: + - LxHQI2 + failureThreshold: -1670032382 + grpc: + port: 2038020216 + service: uS1pHYQuE + httpGet: + host: dFCk9 + path: 2YYVJoTxFI + port: 1533020718 + scheme: 侅弴噉讀ŲĨ趚ʉB + initialDelaySeconds: 753694711 + periodSeconds: -620933924 + successThreshold: 1935472803 + terminationGracePeriodSeconds: -1414957386950590200 + timeoutSeconds: 1810571120 + resources: + limits: + SwVZL: "0" + m6OD8E: "0" + requests: + bZQK: "0" + h9G0: "0" + hCGxGGtFgSx: "0" + restartPolicy: 毄鶏疡ɍʛ啔l鹯ą9掇悋ƦjþË + securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - '*6珛åǪ' + drop: + - qć纣cȈʊ«Ȯ¤u俳糐郭ȉHT5į軌 + - ³R语 + privileged: false + procMount: GɛFȖ黸ȋȤá峠缂蛞·NN + readOnlyRootFilesystem: true + runAsGroup: 2219217566755129900 + runAsNonRoot: false + runAsUser: -6958635490019934000 + startupProbe: + exec: + command: + - VqKEGlA + - h1eQQmyq + failureThreshold: 1344510971 + grpc: + port: 1296412500 + service: 0FZIq + httpGet: + host: Gk + path: J1ncBCi + port: yqdEt689 + scheme: Ƹ陳ƨj>喐蠿鯌ʛB契p + initialDelaySeconds: -879591831 + periodSeconds: 1110714898 + successThreshold: -1301180826 + terminationGracePeriodSeconds: 3872467306429463000 + timeoutSeconds: 674947774 + terminationMessagePath: bm28lY3K2pwh + terminationMessagePolicy: Ȇƍ@¦Ț'±0ž + tty: true + volumeDevices: + - devicePath: o8dr + name: XmhFb + workingDir: 5wQN + - args: + - o0cO9clz7 + - HMSb + - 6uV0c + env: + - name: M3V9WePpx + value: ysO25 + valueFrom: + configMapKeyRef: + key: UqaJg4r + name: RfxtXP + optional: true + fieldRef: + apiVersion: lwe4YmNPx + fieldPath: tQj57vj + resourceFieldRef: + containerName: ZQ + divisor: "0" + resource: T + secretKeyRef: + key: x + name: ny4NEtt3z + optional: false + - name: cc2 + value: L0hw + valueFrom: + configMapKeyRef: + key: 385Ue36 + name: mmjoQw + optional: false + fieldRef: + apiVersion: 6oECJJ + fieldPath: viT + resourceFieldRef: + containerName: gwdJxK + divisor: "0" + resource: ck7 + secretKeyRef: + key: UuNsYAQvXJ0 + name: 1NAqDCU3 + optional: true + envFrom: + - configMapRef: + name: ZFk + optional: true + prefix: bXa4IzYR + secretRef: + name: aAJU + optional: false + image: JPgUP + imagePullPolicy: Q ¶ + lifecycle: + postStart: + exec: + command: + - r1uMNf + - M + - 8G + httpGet: + host: cuhhh + path: lXMriYoe + port: -988033465 + scheme: ',轄kzĒfť' + sleep: + seconds: -8820103652541682000 + preStop: + exec: + command: + - bElmX + httpGet: + host: bCNS + path: A0F + port: "" + scheme: 砘ɁA甜猷14ʣ)ǨƿŊ\ + sleep: + seconds: 821413986956195800 + livenessProbe: + exec: + command: + - M9y + - ay + - sRaY + failureThreshold: 600887441 + grpc: + port: 1597779369 + service: ua8K + httpGet: + host: 0XuF + path: V3 + port: -703127215 + scheme: 舷$趺É螳P阁]嚂驶钋琦袳$ƸO侎 + initialDelaySeconds: -1230549565 + periodSeconds: -335663932 + successThreshold: -1184112514 + terminationGracePeriodSeconds: 9077275487127833000 + timeoutSeconds: 1992088322 + name: pz + readinessProbe: + exec: + command: + - lVaA + - E9DNIWT7reP + - NW1Cc5O2 + failureThreshold: 1119300491 + grpc: + port: 2061347792 + service: fUXdOYJ9On + httpGet: + host: "0" + path: Us3pM3OkquAEW2 + port: -1693856749 + scheme: 鞡|鬟扝}肾~ + initialDelaySeconds: 1307857751 + periodSeconds: 1903760018 + successThreshold: 612917619 + terminationGracePeriodSeconds: -4296518247806248400 + timeoutSeconds: 1025631498 + resizePolicy: + - resourceName: "8" + restartPolicy: ȯy髚ʦ=ǰɮ瓿b:劀ǴáiO3IĮ + - resourceName: 8mFXK1FTs + restartPolicy: ėv|冿瀱Ƥ鐻D[ƼŮ/ + resources: + limits: + TVwPaoBqGL: "0" + juxQS6V3mr: "0" + requests: + igiG: "0" + restartPolicy: 皷ƴȿOvJ郦'欝 + securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - ǐ缠]館ʚƾó|őɤ + - 6 銨dN_ZɻǦ絛顆麓 + - u鹍u鼓练gʘɍK]痰痁鶄Ȼ咶嚅俊ǙǕ + drop: + - 沎闸埲dz + privileged: false + procMount: "" + readOnlyRootFilesystem: false + runAsGroup: -265773045457612130 + runAsNonRoot: true + runAsUser: -6489119899323829000 + startupProbe: + exec: + command: + - 95NULc + - cCLaGfz + failureThreshold: -414102461 + grpc: + port: 339886942 + service: 7hdbpU + httpGet: + host: bN6EBrngIW + path: Luv09 + port: plsGDEJ + scheme: ʔ垃桪抴痺MM温ǹ + initialDelaySeconds: 2135898388 + periodSeconds: 1107416140 + successThreshold: -648919802 + terminationGracePeriodSeconds: 4653203112295128000 + timeoutSeconds: 1294917615 + terminationMessagePath: C + terminationMessagePolicy: 擎:Ȓ + volumeDevices: + - devicePath: TGjb8dLs + name: QN5Dj50Kuoc + - devicePath: aRIfAur + name: wQ47Fq7W3WPNDG + - devicePath: 2Smu + name: 1Q3d5wRJf6 + volumeMounts: + - mountPath: 5Trbk9 + mountPropagation: 秮驇穁 + name: YvM + readOnly: true + subPath: pFKsUV + subPathExpr: mhIjzA + - mountPath: F3lqb + mountPropagation: 窆f + name: NJXDvoxv + subPath: zVGgP + subPathExpr: H + workingDir: IEObw8N + imagePullSecrets: [] + initContainers: + - 'error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string + into Go value of type []interface {}' + nodeSelector: + JDRn7n: tOGfx + lKq0V88a: uR3S + vXzm2Hny: tURxvlp + priorityClassName: 6ZbHC + securityContext: + fsGroup: 3426922926776119300 + fsGroupChangePolicy: 橣 + runAsGroup: 8316915980597683000 + runAsNonRoot: false + runAsUser: 6270039107728701000 + supplementalGroups: + - -2399342924686736400 + - 620655430084388100 + serviceAccountName: gIkiPRSc53Eb4w + tolerations: + - effect: ć`湇Ȏ2篤螕巴蛬>@ø£鞌q + key: E7p + operator: 畁鼄瓈貔Ĕ釲ĸȚ貺|ǴĄl蔺İɽ糹 + tolerationSeconds: 3092681449541781000 + value: Zmrz8 + topologySpreadConstraints: [] + volumes: + - configMap: + name: eHZ + name: configs + - name: gcTdF + secret: + defaultMode: 210 + secretName: MPU + - name: "4" + secret: + defaultMode: 186 + secretName: s6 + - name: lBE0nAE + secret: + defaultMode: 412 + secretName: RG + - name: "4" + - name: Kry +--- +# Source: console/templates/hpa.yaml +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + creationTimestamp: null + labels: + "": vWjW + G: qF + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 84QIe + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: eHZ +spec: + maxReplicas: 165 + metrics: + - resource: + name: cpu + target: + averageUtilization: 42 + type: Utilization + type: Resource + - resource: + name: memory + target: + averageUtilization: 454 + type: Utilization + type: Resource + minReplicas: 187 + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: eHZ +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "eHZ-test-connection" + namespace: "default" + labels: + "": vWjW + G: qF + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 84QIe + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['eHZ:190'] + restartPolicy: Never + priorityClassName: 6ZbHC +-- testdata/case-043.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: Gma + namespace: default +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: y0pa6pm83 + namespace: default +spec: + ports: + - name: http + port: 11 + protocol: TCP + targetPort: 465 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + type: 9TsjJQkJZ +--- +# Source: console/templates/ingress.yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + annotations: + GOF: Fk7wcu + J2: ViiBwn6 + WODaheluZ: jCoFdBnr + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: y0pa6pm83 +spec: + ingressClassName: 4Z1r6JSTY + rules: + - host: chart-example.local + http: + paths: + - backend: + service: + name: y0pa6pm83 + port: + number: 11 + path: / + pathType: ImplementationSpecific + tls: + - hosts: + - hAi45 + - N3wGXf + - 2Og0 + secretName: 11BdzGx + - hosts: + - MPqkMom + - mBwetJrK + - PcEKgK + secretName: HtA + - hosts: null + secretName: jRYKg +-- testdata/case-044.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + BvJq2xZ: jY6O0 + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: tvDI + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: W9k + namespace: default +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} + role-bindings.yaml: |- + roleBindings: + - UiHg9: null + - "": null + mAYLjAybA: null + roles.yaml: |- + roles: + - 0NpG04j: null + UxtPt: null + l5dMdK: null + - J9: null + MzWfEl: null + yNu: null + - "": null + Pv: null + tGJIDyXG: null +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + BvJq2xZ: jY6O0 + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: tvDI + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: resP +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: + CRHNsVY: Nl04 + creationTimestamp: null + labels: + BvJq2xZ: jY6O0 + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: tvDI + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: resP + namespace: default +spec: + ports: + - name: http + port: 103 + protocol: TCP + targetPort: 329 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: tvDI + type: "" +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + 4i: zwiMMKf + ZTKUDg2t: qHc7 + fGsx: dIpd + creationTimestamp: null + labels: + BvJq2xZ: jY6O0 + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: tvDI + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: resP + namespace: default +spec: + replicas: 410 + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: tvDI + strategy: + rollingUpdate: {} + type: ɬdW5f + template: + metadata: + annotations: + N0F: vSjZxkjW + checksum/config: 8ebe1d816245b967e7ea3109d93ad79599a2b8a33eed8e72fc85166d6ffa7aaf + creationTimestamp: null + labels: + K1uahi: UMygEU2O2 + app.kubernetes.io/instance: console + app.kubernetes.io/name: tvDI + ecdKkB: "1" + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: AFOKvXU + operator: ¸藬 + values: + - vIFxLM + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + ZpWVx: agTJ2kP3DWNYN + matchLabelKeys: + - "4" + mismatchLabelKeys: + - 0qG + namespaceSelector: + matchExpressions: + - key: D8 + operator: d|ɬ曖 + values: + - p3iQYi6Y + - key: c + operator: ǵmV逛鲳鈐譮稹ÚȾČXú + values: + - a + - 3C55L6S7 + - SQaxr + matchLabels: + "5": jC + namespaces: + - oDKjy + - "" + topologyKey: C9jgFk + weight: 1276231314 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: lGp2 + operator: "" + matchLabels: + "": sKP1q2 + 44krG: UrYUSMsisV + unYZqLh67: tMKQ + matchLabelKeys: + - orDt3ZdEA + - LIBJK3 + mismatchLabelKeys: + - bgz2i + - CNqlQJ + namespaceSelector: + matchExpressions: + - key: 35CZTXLY + operator: 掟0笝润ɲDGĪ1Ɋ乧鴹ǥ + values: + - OOB1s + - o4H + - key: f21 + operator: nȿqh + namespaces: + - L0w7 + - DB9 + - T1mom4CrS + topologyKey: OWKJz + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: WaOHp + operator: Ƥ熅ǒe²敹Ņ0ľ(Ȯɩ6ÿ + - key: 0X + operator: be3蚛鷿_鴈y+圚ʀF虹D + values: + - ZIZDTnyfwD + - B4NWO9ffPz + - 1jsu + matchLabelKeys: + - mXhYg + mismatchLabelKeys: + - mp6 + namespaceSelector: + matchExpressions: + - key: xE + operator: ʩ畕 + values: + - uc7IZ + - Hxl1 + - key: Xb41Q + operator: cʓʁ卡嵷韻 + values: + - pA + namespaces: + - edcrY + topologyKey: sP2BdI + - labelSelector: + matchExpressions: + - key: U0 + operator: 卢ʩ + values: + - OBtefl + - yMIZlx + - key: X + operator: Ǔ%é鵔:ß侙鞅 + values: + - s1qg3meB + - e6J6ZH89 + - key: dhFO + operator: ƋŎ頖,é襺枣Ť卩骏ɰ抟篧JɂǛȝȵ + values: + - R9sJoCz + matchLabels: + 2T: 84ZhksfB + matchLabelKeys: + - Yc41 + mismatchLabelKeys: + - zgncb + - pCwXYOK + - hViR + namespaceSelector: + matchExpressions: + - key: 3hWtuB6Y + operator: ʪ+ʜǻ拎奜跁ª4鶒鲒[ʒJi\ʝ)皡 + values: + - s + - key: xGSn + operator: 羥/Br=Z擧Ŀ泀Ą舨cïŕɘʡȽIJ鉽 + values: + - lOZtQ2cI + - Vk6 + - Ri3t + - key: Z6UDhR9VLqSA + operator: 淸c欨pɝo腛ı廓齩鄬檏繑郭>Ö呡 + values: + - s6hp + topologyKey: wZZTf + - labelSelector: {} + matchLabelKeys: + - afDo + mismatchLabelKeys: + - S + namespaceSelector: + matchExpressions: + - key: AWObA + operator: ĝf表OS厅啬児0~L槩华L稙訐\Tȼ + values: + - M39 + matchLabels: + 0D9: u5 + T1: xiLiZn + v6: nSQp5 + topologyKey: mr + automountServiceAccountToken: false + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: Ahlf + value: UEv + valueFrom: + configMapKeyRef: + key: uwaRvb + name: M8Iklu7qx + optional: true + fieldRef: + apiVersion: H + fieldPath: 43xb + resourceFieldRef: + containerName: t8wgC87mO + divisor: "0" + resource: Z + secretKeyRef: + key: "" + name: EQfJ3z7tv + optional: false + - name: xj + value: lwmxmxP + valueFrom: + configMapKeyRef: + key: "" + name: cdBhO + optional: true + fieldRef: + apiVersion: U + fieldPath: Dj1sswKP + resourceFieldRef: + containerName: 1p3yUdrvd + divisor: "0" + resource: 5A + secretKeyRef: + key: DDcgdcu + name: oD38 + optional: true + - name: LICENSE + valueFrom: + secretKeyRef: + key: x8ik3q + name: K7c7oe + envFrom: + - configMapRef: + name: 2ECaB + optional: true + prefix: bao + secretRef: + name: CA5S95 + optional: false + image: UqWwteW0x/TZqk:0fpMB + imagePullPolicy: 讘ɂȴɩF壜î栒p + livenessProbe: + failureThreshold: 1147871047 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: -470682176 + periodSeconds: 842863336 + successThreshold: 2078067842 + timeoutSeconds: 1252398573 + name: console + ports: + - containerPort: 329 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 1026367217 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: -233395254 + periodSeconds: -96619339 + successThreshold: -2083481091 + timeoutSeconds: 1827269276 + resources: + limits: + eYVLCq: "0" + requests: + P: "0" + VsuQcjg: "0" + jwq: "0" + securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - ɐ毻sǨ斩麀|髦 + - (波F= + - 2鱶ɥǚ蘃齯ʃE桹蹝Ȓ畸蘋桙0 + drop: + - c掁轖e9\Ǟ¦ + - ȽT下Zź%賂蕄3 + - 乯`ŤĊŸ眸ʞ缔Ň妌嵳楕ǐwč*ǩ妩ɴ + privileged: true + procMount: ŃE诩Ŗś僆 + readOnlyRootFilesystem: true + runAsGroup: 6580465723841054000 + runAsNonRoot: true + runAsUser: -56006153890553620 + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: v + mountPropagation: ?IJ純ʈxɧʅ + name: 9AiRaE35OlCv + readOnly: true + subPath: 2dv5RZ + subPathExpr: H7f + - mountPath: "4" + mountPropagation: 涾頴tOĜʥ朤 + name: ePEz + readOnly: true + subPath: BY + subPathExpr: w + - mountPath: n5FPgiJmk + mountPropagation: Ǵ棢__@ŗɆ4瞑5ŗ­L/ķ{篦ǯ + name: NryERK9Q + readOnly: true + subPath: tINFMAR5 + subPathExpr: VrBKy + - args: + - CCdc + - xnWsPf + - K9Lp8whZH + envFrom: + - configMapRef: + name: eRd + optional: true + prefix: jF9v + secretRef: + name: QS0dQM4 + optional: false + image: UEbFmY + imagePullPolicy: ɂǖ耒ȯ+Ǎ妸ÄĊ wʠB堯¥ƿɤp + lifecycle: + postStart: + exec: + command: + - 89MtW + - LOaqkcP + - JzjyxNZS + httpGet: + host: "3" + path: V + port: RUOELw + scheme: u*暪÷鰦ʭ,0噱D #干 + sleep: + seconds: 7312334685976475000 + preStop: + exec: + command: + - Cmo91luAq + - DTCwI + - d3Q8xly + httpGet: + host: e + port: -1761554680 + scheme: '|' + sleep: + seconds: -8572473558022234000 + livenessProbe: + exec: + command: + - 1K0Fir + - Ws + - jWym + failureThreshold: 1492079208 + grpc: + port: -1612320137 + service: wk3AYU + httpGet: + host: U + path: yLWf + port: dE + scheme: (魠ʫ倳|岺溻IJħu|æ粅 + initialDelaySeconds: -1551121242 + periodSeconds: 101556636 + successThreshold: -690762638 + terminationGracePeriodSeconds: -7606489989577612000 + timeoutSeconds: -947750725 + name: GKPhj2 + ports: + - containerPort: 690563670 + hostIP: mVXvug29A + hostPort: -1389446008 + name: pcUz3a8NWF + protocol: o& + readinessProbe: + exec: {} + failureThreshold: 816403475 + grpc: + port: 2090385753 + service: pp5W00 + httpGet: + host: sP9DV + path: cpLL + port: TNUIzm + scheme: '!敓GĜƝ塀ȏ@{8嶤ɍ|' + initialDelaySeconds: 911169006 + periodSeconds: 257542772 + successThreshold: 1702435185 + terminationGracePeriodSeconds: -4557510245814657500 + timeoutSeconds: -581799810 + resources: + limits: + 5UdZ91O: "0" + TXdC: "0" + bK0pEj0Mb: "0" + requests: + s8hZFXOGF: "0" + tCP: "0" + restartPolicy: Ǩ轡´@ǂȟ + securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - 鿞;P粜鬌)Ǭ郑&鑉k!f] + - Ċ + drop: + - ?孡渄:Ơ廔晞!ē8瞅@rDZ_ + - cfdú¯'ƱơÅś祏侪 + privileged: true + procMount: ȝ?A@û2蝓撕%o摤絡) + readOnlyRootFilesystem: true + runAsGroup: -2314751572399379000 + runAsNonRoot: true + runAsUser: 989961539055775400 + startupProbe: + exec: {} + failureThreshold: 971752114 + grpc: + port: -1594677871 + service: O + httpGet: + host: EIXRs + path: EA1CukJtUZ + port: g9g0 + scheme: 遱O靑課淁hɕ怡ņ鲥 + initialDelaySeconds: -1020857297 + periodSeconds: 1332161137 + successThreshold: -1412285197 + terminationGracePeriodSeconds: -7087737322486666000 + timeoutSeconds: 563432789 + stdin: true + terminationMessagePath: S + terminationMessagePolicy: =ɑ_èʊâ錯Ɛ窾O亇_ + tty: true + volumeDevices: + - devicePath: 2EtZS + name: "" + - devicePath: glBRF4 + name: e8K + volumeMounts: + - mountPath: L4U + mountPropagation: '}6ʓ蓱9峖3疖售Ʉ朞' + name: 4oVeDs + subPath: RoA + subPathExpr: b + - mountPath: b3TFcP + mountPropagation: ʘʟ| + name: jg4Ya + subPath: F + subPathExpr: flS + workingDir: VZi6ElPHw + - command: + - 3xxCjTRw + env: + - name: 1n + value: cHl + valueFrom: + configMapKeyRef: + key: "95" + name: gi + optional: true + fieldRef: + apiVersion: sQA8hZeZu + fieldPath: xgpJlFJ2 + resourceFieldRef: + containerName: fLR0HyM + divisor: "0" + resource: Sanx4 + secretKeyRef: + key: XgKm5 + name: gvoS9jB + optional: false + - name: s2cwze + value: hu + valueFrom: + configMapKeyRef: + key: fDoUz3 + name: XKG + optional: true + fieldRef: + apiVersion: q0CUy1W + fieldPath: B3Lkh + resourceFieldRef: + containerName: V1gnkr8hpTmU + divisor: "0" + resource: 7PEJNYX + secretKeyRef: + key: IiBIw + name: kiXa5 + optional: false + envFrom: + - configMapRef: + name: JayMLn + optional: true + prefix: Iyk + secretRef: + name: I8 + optional: true + image: uuJKCAGoiYb + imagePullPolicy: '&mɈ{DC鹪ŘƖ暢C镯VĪɮJ樟' + lifecycle: + postStart: + exec: {} + httpGet: + host: TlUl + path: v9nd + port: Khf + scheme: 雦G'獲ɕ垑Ɠ奚 + sleep: + seconds: 3204757101293724700 + preStop: + exec: + command: + - s8505Cg5U + httpGet: + host: hAMBGK + port: LNxGid + scheme: 9?Ɉ + sleep: + seconds: -7512312074000843000 + livenessProbe: + exec: {} + failureThreshold: -1252597876 + grpc: + port: -544919593 + service: "N" + httpGet: + host: xfP + path: ByIZxFF1w + port: 465839308 + scheme: ôȔʄǽȕ$Ɨ嫸% + initialDelaySeconds: 1827740835 + periodSeconds: 1434348082 + successThreshold: 1145653124 + terminationGracePeriodSeconds: -9056662989967493000 + timeoutSeconds: -741454610 + name: pkN5 + readinessProbe: + exec: + command: + - pmJ6cF + failureThreshold: -182850181 + grpc: + port: -30654612 + service: q + httpGet: + host: Vra + path: tovB7 + port: -934938952 + scheme: Ⱥǵ1茆鯨ț]ų1ơñ澂 + initialDelaySeconds: -1966697414 + periodSeconds: -1866944455 + successThreshold: -259752087 + terminationGracePeriodSeconds: -4535014313385885000 + timeoutSeconds: -1545912021 + resizePolicy: + - resourceName: RxDBqX + restartPolicy: 韌ʮ濅& + - resourceName: spCee + restartPolicy: 腋+桯PɆ誎z4µ&ȁou-囈鵼夵v| + resources: + limits: + rElH: "0" + requests: + "": "0" + restartPolicy: 7GK¦碦ǒ抩Z芍緜 + securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - NjǗA窇ţ + - 逈%Ǵ7QǚƶƜr + drop: + - 鹭Iv0蠤'Ɵ皝ƨ=¨ + privileged: false + procMount: èįƤ;L虥u籖ʄƎ}橃V炖 + readOnlyRootFilesystem: false + runAsGroup: -1041723617216276900 + runAsNonRoot: false + runAsUser: -3933065726531016000 + startupProbe: + exec: {} + failureThreshold: -983644738 + grpc: + port: 1827183629 + service: X7oC1 + httpGet: + host: vGk + path: ohKaYc + port: l1rVsh9 + initialDelaySeconds: -648569392 + periodSeconds: 873065120 + successThreshold: -612441773 + terminationGracePeriodSeconds: 6808330544454598000 + timeoutSeconds: 1534439066 + terminationMessagePath: VYh + terminationMessagePolicy: 唌Üi+ + volumeDevices: + - devicePath: DGsn + name: Ia + volumeMounts: + - mountPath: "14" + mountPropagation: 渉seǝ蕟厪ë嵎ǥ墮@ + name: "" + readOnly: true + subPath: C1G4VS1 + subPathExpr: eU + workingDir: odPxO + imagePullSecrets: [] + initContainers: + - 'error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string + into Go value of type []interface {}' + nodeSelector: + 2i: dRi6btw6 + R4: UsW + fFNJXGk: XBkx + priorityClassName: 8KMLup9vb + securityContext: + fsGroup: -3027126285888131000 + fsGroupChangePolicy: 袺芥ŵ罋o郘渢e堫柝dž + runAsGroup: -3172565869747058000 + runAsNonRoot: true + runAsUser: 5739747577453986000 + supplementalGroups: + - -1289730562709624600 + - 2918948066534341000 + - 8836988143915676000 + sysctls: + - name: ZSspAgrV + value: ES11 + serviceAccountName: W9k + tolerations: [] + topologySpreadConstraints: + - labelSelector: + matchLabels: + 435gSB: cXqM + XuT: nA + sKWX6pPX: YyYe + maxSkew: -1347306472 + minDomains: 1890499147 + nodeAffinityPolicy: 扒Ŕ + nodeTaintsPolicy: 諹uɔM_灢ʫ6ªWŢ庿ɛ + topologyKey: 34nlpPe2Tl + whenUnsatisfiable: šĉ鎨嶕鯖Ťȯ蝲萤ɪeCŒ5ő3|押 + volumes: + - configMap: + name: resP + name: configs + - name: Kt6NIoVzEY + - name: O +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "resP-test-connection" + namespace: "default" + labels: + BvJq2xZ: jY6O0 + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: tvDI + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['resP:103'] + restartPolicy: Never + priorityClassName: 8KMLup9vb +-- testdata/case-045.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: false +kind: ServiceAccount +metadata: + annotations: + "": zL + EANkzh: rmy + creationTimestamp: null + labels: + M1diW: PVb + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: tOoxEiwdVpT + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: nX5G + namespace: default +--- +# Source: console/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + labels: + M1diW: PVb + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: tOoxEiwdVpT + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: 9gCm5xz +stringData: + enterprise-license: "" + kafka-protobuf-git-basicauth-password: naFpMBw + kafka-sasl-aws-msk-iam-secret-key: "" + kafka-sasl-password: nKEzr + kafka-schema-registry-password: xU + kafka-schemaregistry-tls-ca: pc + kafka-schemaregistry-tls-cert: fF1z9FE + kafka-schemaregistry-tls-key: tx + kafka-tls-ca: bhhbwypQ + kafka-tls-cert: Dw1477 + kafka-tls-key: "" + login-github-oauth-client-secret: 1UD4N + login-github-personal-access-token: LmFkP6BgmLQ + login-google-groups-service-account.json: "" + login-google-oauth-client-secret: m + login-jwt-secret: SECRETKEY + login-oidc-client-secret: cXdjG + login-okta-client-secret: eF90RohF + login-okta-directory-api-token: 1zXLSJEQ + redpanda-admin-api-password: rr4c4 + redpanda-admin-api-tls-ca: Eonnpq + redpanda-admin-api-tls-cert: aPCNgYI + redpanda-admin-api-tls-key: vlrLQ9I9 +type: Opaque +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + M1diW: PVb + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: tOoxEiwdVpT + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: 9gCm5xz + namespace: default +spec: + ports: + - name: http + port: 314 + protocol: TCP + targetPort: 398 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: tOoxEiwdVpT + type: C +--- +# Source: console/templates/hpa.yaml +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + creationTimestamp: null + labels: + M1diW: PVb + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: tOoxEiwdVpT + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: 9gCm5xz +spec: + maxReplicas: 305 + metrics: + - resource: + name: cpu + target: + averageUtilization: 344 + type: Utilization + type: Resource + - resource: + name: memory + target: + averageUtilization: 186 + type: Utilization + type: Resource + minReplicas: 326 + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: 9gCm5xz +--- +# Source: console/templates/ingress.yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + annotations: {} + creationTimestamp: null + labels: + M1diW: PVb + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: tOoxEiwdVpT + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: 9gCm5xz +spec: + ingressClassName: y6u9o + rules: + - host: V + http: + paths: + - backend: + service: + name: 9gCm5xz + port: + number: 314 + path: VRp3 + pathType: WX + - backend: + service: + name: 9gCm5xz + port: + number: 314 + path: ZXqa + pathType: LXDjotJK + - backend: + service: + name: 9gCm5xz + port: + number: 314 + path: b + pathType: 6l3svu + tls: + - hosts: + - SzMunki + secretName: OT +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "9gCm5xz-test-connection" + namespace: "default" + labels: + M1diW: PVb + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: tOoxEiwdVpT + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + imagePullSecrets: + - name: rTO7I + - {} + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['9gCm5xz:314'] + restartPolicy: Never + priorityClassName: Op +-- testdata/case-046.yaml.golden -- +--- +# Source: console/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + labels: + "": WcYTY + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + rHtDM6k: ZY6Kw + name: fB6TF +stringData: + enterprise-license: "" + kafka-protobuf-git-basicauth-password: BKbdr + kafka-sasl-aws-msk-iam-secret-key: Xs8UvJPyL + kafka-sasl-password: xW3EDKA + kafka-schema-registry-password: Vewx + kafka-schemaregistry-tls-ca: te + kafka-schemaregistry-tls-cert: JxH + kafka-schemaregistry-tls-key: jhxioPhQ + kafka-tls-ca: eP + kafka-tls-cert: H9 + kafka-tls-key: "" + login-github-oauth-client-secret: Q + login-github-personal-access-token: akEcq + login-google-groups-service-account.json: pJ8NQ + login-google-oauth-client-secret: vj6 + login-jwt-secret: SECRETKEY + login-oidc-client-secret: 8SCyi + login-okta-client-secret: Yd + login-okta-directory-api-token: q1rSa + redpanda-admin-api-password: mON + redpanda-admin-api-tls-ca: rNzsp + redpanda-admin-api-tls-cert: UStA + redpanda-admin-api-tls-key: 3E +type: Opaque +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: + aDeGG7F9S: 5d + creationTimestamp: null + labels: + "": WcYTY + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + rHtDM6k: ZY6Kw + name: fB6TF + namespace: default +spec: + ports: + - name: http + port: 271 + protocol: TCP + targetPort: 481 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + type: PK7oH1pcU3 +--- +# Source: console/templates/ingress.yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + annotations: + A4M6T: IUmZ9 + AHN: gcT00IU6 + S: lzi1Q + creationTimestamp: null + labels: + "": WcYTY + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + rHtDM6k: ZY6Kw + name: fB6TF +spec: + ingressClassName: aU0xOzsFN + rules: + - host: chart-example.local + http: + paths: + - backend: + service: + name: fB6TF + port: + number: 271 + path: / + pathType: ImplementationSpecific + tls: + - hosts: + - PV + secretName: aHG1 + - hosts: + - bX + - Cu + - xuscoJ + secretName: fBCynrlb +-- testdata/case-047.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: + DQxrtk8: buiWLPbYq + HHbP: sAY + Y0DKOcTa: D82Nfh + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: nEojiMtRc + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: DSw7 + namespace: default +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: + 8v2: JbH + 95cxbjjD7C: JBMaJ + VY: yRV7d + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: nEojiMtRc + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: YUi5JpG + namespace: default +spec: + ports: + - name: http + port: 168 + protocol: TCP + targetPort: 227 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: nEojiMtRc + type: WAAXkZY +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + Bx5i3M: s + svlaTGpSHD: 7P9k + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: nEojiMtRc + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: YUi5JpG + namespace: default +spec: + replicas: null + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: nEojiMtRc + strategy: + rollingUpdate: {} + type: żʧȟ + template: + metadata: + annotations: + Mfsd: hmi + checksum/config: 74234e98afe7498fb5daf1f36ac2d78acc339464f950703b8c019892f982b90b + creationTimestamp: null + labels: + 6dZAs: xJPaLHKS1Y2 + app.kubernetes.io/instance: console + app.kubernetes.io/name: nEojiMtRc + spec: + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: {} + weight: 182966451 + - preference: {} + weight: -2028220392 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: [] + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: 5a5MXO + operator: kƎǦƙ«嚄ƭr騥邜Fċʐ叧F& + values: + - BRA + - Ywt7JHE + - key: TjE3wFb6 + operator: O`6ƥ縈L:Ckʄ鹟瑧 + values: + - "" + - dxDLfiL + - 0IgsneLlLo + - key: tuBbSOMR + operator: 桛ʫ褛ʒɩWkv濱瘛#Ěi邱CNǖ4孳 + values: + - 9zJ + - 7T3iJAwX + matchLabelKeys: + - ZYcvinlq + - PwQO9 + - M3gb + mismatchLabelKeys: + - e + - K1XrVh + - D1CkR8 + namespaceSelector: + matchExpressions: + - key: uqnyV6k + operator: rĮ'示嶠ĵ攛Ņ + - key: 0ONfMVB + operator: n梷E8ʟ菛晉 + values: + - Q + matchLabels: + IqH8n: pCJ16S + mUE: HyxdirX0F + namespaces: + - gptVP + - L + - 7CmPHtA + topologyKey: XDhewcrvK + weight: 2033587292 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: jcAfZ5VF + operator: 饀re + - key: sj + operator: U姑R° + values: + - p8zbO + - key: 2LmP5 + operator: ŸȢ庾塁BƖ + values: + - NN + matchLabels: + ApvKyKe: kHE9lIIleR + mismatchLabelKeys: + - n3VRcT5qX + - zGNqgUGNX + - hDZ + namespaceSelector: + matchExpressions: + - key: "7" + operator: 砃=G墈赞飍鵝7d + values: + - Uiz9BnY + - key: hd76 + operator: '{緶ɡnW' + values: + - vc1yj10y + - Je + - eg + - key: 06pjmB + operator: =帛胏 + values: + - RQ10 + - Z5WWhGqt + namespaces: + - seMTT1 + topologyKey: E + - labelSelector: + matchLabels: + oplIL: 67Fs0Yu4 + mismatchLabelKeys: + - T1 + namespaceSelector: + matchExpressions: + - key: hOQWYMD + operator: vǑ壞2â飿"Xʝ簮倏c + values: + - "0" + - key: WWGKqAgL + operator: '''OƼŪ祰ǑŗiU嘏ɮ?Ī語' + values: + - yU5IOsL + - koP + namespaces: + - lDs + - xQZsD + - J + topologyKey: j0k4ds + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: 9nDdXGQwP + operator: '[痵lǝ,ǶÜÂD' + values: + - th + - u8xZ + - ucr3vqZeG + - key: QWVrK8k + operator: ʀăɼy耯#運+3坽« + values: + - 2lcZKn + - G2IQ + - YbYwv + - key: N4bc7Wn + operator: '%7`iɊȑ槦醒}' + values: + - NiSH90 + - 98iHVkt + - 0r3Yu9i + matchLabelKeys: + - zrV + - Ey + - R + namespaceSelector: + matchExpressions: + - key: gEbVS1wo + operator: z + matchLabels: + 2YURuF: "" + CJTjm6: nOFN + oUtlWUD: 0k14ag + topologyKey: M1yF5YA + weight: 477520510 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: mdjoxbr + operator: V2SŨǰ8嫟淦 + values: + - 3ww0Ei + - 2PjudE + - pmpvETB0n + - key: NFqQGo + operator: 处;Ƕk鎹û絹褡Sy + values: + - V + - key: HuZ + operator: ȓő&ś>S怭ť]E榕 + values: + - sUume + matchLabels: + ef2q: 4ZL0O9b + r8xqG: MJ + matchLabelKeys: + - "" + - "Y" + mismatchLabelKeys: + - djn6fDf + - ukZi8 + namespaceSelector: {} + namespaces: + - dOU1F + - 1ygQdj3xZ3YIf + - wvpeJx + topologyKey: Rq4K6z6 + weight: -1277100698 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: b + operator: "" + values: + - tmuB5 + - 9qE9GM + - oJpaRDn2 + - key: WY + operator: u酘b + values: + - RhO + - Cs2rDIRrPlii + - nG4bqoAkQU + - key: eMae + operator: ǟĕȴnjI覿9¥H艞ɋ + matchLabels: + ToIBbWL: 4k8X + i2qGkWjvF7QJ: pb0sZq + u12o4B4: Ybz + matchLabelKeys: + - HCKtJC7hm + mismatchLabelKeys: + - 21r0Z + - "" + namespaceSelector: + matchLabels: + 2BNgnKr7Ob: 5RffK5NB3ghhfO + bJC: WTOgH + uA: bxdRwsU + topologyKey: 2CsbupZ + - labelSelector: + matchExpressions: + - key: RIP + operator: Oȝ(氧罻 + values: + - 1bx3Fix9 + - key: eqQoi + operator: 68+ʈĘ + values: + - FgfwmYrR + - mznlyr2aLTGF + - GfAoC8M + matchLabels: + FKwNoJ: aJZxa + cEeo8ix: 3dHunLjp5 + ihSd: qG7x + matchLabelKeys: + - F6LQK + mismatchLabelKeys: + - ULcGW + - RYv + - fF + namespaceSelector: + matchExpressions: + - key: Tkp5 + operator: ȴ潺谡Ƣh躈ŮâÿȒũĔ + values: + - fY9NuWB + - O84 + matchLabels: + 09fI: EDSEVi + Dl: 4u38aD4O + vZCciR: neqAXd7k + namespaces: + - ozziI6FZ + - URQlLJF + topologyKey: SeSq4K + automountServiceAccountToken: true + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: "" + value: YbKo + valueFrom: + configMapKeyRef: + key: bIruuA + name: x8 + optional: true + fieldRef: + apiVersion: EqX + fieldPath: ZOh + resourceFieldRef: + containerName: IDJTm5lv + divisor: "0" + resource: QDC8v + secretKeyRef: + key: "8" + name: LcSdNiKff4 + optional: false + - name: RZHq9C + value: m + valueFrom: + configMapKeyRef: + key: PZVqf + name: x + optional: true + fieldRef: + apiVersion: xQi + fieldPath: vxeo + resourceFieldRef: + divisor: "0" + resource: l7 + secretKeyRef: + key: i3lK + optional: true + - name: LICENSE + valueFrom: + secretKeyRef: + key: nj + name: rl + envFrom: [] + image: zUsK/lQjo:p + imagePullPolicy: ȕ蚧竔/´苅oC + livenessProbe: + failureThreshold: -1392926461 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: -1384385388 + periodSeconds: -1660079876 + successThreshold: 680842396 + timeoutSeconds: 213455290 + name: console + ports: + - containerPort: 227 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 1689894479 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: -1753994274 + periodSeconds: -1189421015 + successThreshold: 1278527365 + timeoutSeconds: -209775227 + resources: + limits: + 8ycM: "0" + requests: + CvglPI: "0" + s5: "0" + uiHB: "0" + securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - «Ƙz损 + - ɟE鄱Į惪Y桦ŗɘoȍ蠣4ƪ呀R> + - "" + drop: + - 娤b + privileged: false + procMount: ʍ曏(ƶæ + readOnlyRootFilesystem: true + runAsGroup: -406748533537085800 + runAsNonRoot: false + runAsUser: 3238073083343117300 + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: g + name: L8dbWip + subPath: "" + - mountPath: OO0aO6h + mountPropagation: "" + name: kDKM + readOnly: true + subPath: AlRCH + subPathExpr: 7UemLsIe + - mountPath: Z8zdlU + mountPropagation: 醗¡°v:胡 + name: aedAMG + subPath: zo5P1xa + subPathExpr: WmuiME + - mountPath: ufiUx + mountPropagation: '`ʡÔ关Ľ?' + name: PWBh + subPath: 2hslJ + subPathExpr: pUtN3 + - args: + - lW + - lpUVzUh + command: + - 3mEGtoKbEWE2Jw5T + - b1GBFA + env: + - name: hsiWF93 + value: zBco + valueFrom: + configMapKeyRef: + key: 8hvvaoHB + name: "y" + optional: false + fieldRef: + apiVersion: WPT5J + fieldPath: sc + resourceFieldRef: + containerName: 0xbTU4O + divisor: "0" + resource: tPBV2ObG + secretKeyRef: + key: YEKZukl + name: px + optional: false + - name: PM0MyyH3R6R + value: yOzX + valueFrom: + configMapKeyRef: + key: I3pi + name: DC + optional: true + fieldRef: + apiVersion: "25" + fieldPath: "" + resourceFieldRef: + containerName: aZj1E7LU + divisor: "0" + resource: sxs0nE31 + secretKeyRef: + key: Ktb3c4 + name: g98T + optional: true + - name: 6kDq8UgFIS8 + value: L0i4 + valueFrom: + configMapKeyRef: + key: 9WUe9 + name: tZrRUK + optional: false + fieldRef: + apiVersion: GIc + fieldPath: AXTmU + resourceFieldRef: + containerName: E2 + divisor: "0" + resource: a63tq + secretKeyRef: + key: luWp + name: lPdowo + optional: true + envFrom: + - configMapRef: + name: vzVk + optional: true + prefix: DONFyRd + secretRef: + name: 9uct + optional: false + - configMapRef: + name: z5nC9D + optional: true + prefix: 5epUyS1iy5m8 + secretRef: + name: zqRFC + optional: true + - configMapRef: + name: awjfJlZxN + optional: true + prefix: LhArOQgbq1OCR2L + secretRef: + name: mb5axzX5 + optional: true + image: qPLiX + imagePullPolicy: '{Ĩ檽]ĻĹňɋ偌Ȏ.阛魉' + lifecycle: + postStart: + exec: + command: + - yAeOM + - s53um + - 3m + httpGet: + host: GJWsJm + path: iDQ + port: 1781170742 + scheme: 皐ű葺ȝĬ麐&ʉ執dz0娸叹 + sleep: + seconds: -4230531115544534500 + preStop: + exec: + command: + - sIGb5 + httpGet: + host: AbxhPKar + path: 3ZZ5 + port: 88852320 + scheme: 砨Ĝ_筀¤痟氻劊űI俼员z幛F + sleep: + seconds: -4758564920159899000 + livenessProbe: + exec: + command: + - ty6JMTW6vA + failureThreshold: -1459976999 + grpc: + port: -1689493187 + service: ihsDMVYd + httpGet: + host: e9NNlO5d + path: iBo4 + port: 334788778 + scheme: ƿ:ħȠL$ + initialDelaySeconds: 1625633184 + periodSeconds: 1327859251 + successThreshold: 1766792721 + terminationGracePeriodSeconds: -3971501657411371000 + timeoutSeconds: 557348614 + name: U3U + readinessProbe: + exec: + command: + - "Y" + failureThreshold: 391027623 + grpc: + port: -1858356724 + service: hnqm + httpGet: + host: g + path: C48 + port: F + scheme: 苎lɲÁ频×ȊDžȀ9Ď"昽 + initialDelaySeconds: -1404160881 + periodSeconds: 521131323 + successThreshold: 2005094455 + terminationGracePeriodSeconds: -5942417190535485000 + timeoutSeconds: 2118365394 + resources: + limits: + Ms1A: "0" + WkWhM: "0" + requests: + b4kR9nm9BfQZy: "0" + eLg: "0" + huME: "0" + restartPolicy: ľ慔/PpǏ銢9滖ɝ韍I鍌$ʪ辫Uz + securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - wą&嘪研Z`ȧȢfʘ*ō + drop: + - ƿ`ĉĎ苦Ǧ蘈NJ她笻Ƞ + - 磨3踦煨1JƸc錚捁 ĊZe)ám \ + privileged: true + procMount: 鋶XJm/覹ɋ¶ȉĒȤ瀶|ƻŒ(咡 + readOnlyRootFilesystem: false + runAsGroup: -8452021579348254000 + runAsNonRoot: true + runAsUser: 5983932912975749000 + startupProbe: + exec: + command: + - sZhTLr + - GK + - kqL9aDDm + failureThreshold: 1004086477 + grpc: + port: 1266077274 + service: l1ji1IW1ic + httpGet: + host: rJI + path: H731Dr + port: 1333462733 + scheme: 项鰚ɽ洍êƳ + initialDelaySeconds: 1806670133 + periodSeconds: 1290098703 + successThreshold: -490255445 + terminationGracePeriodSeconds: -206080146769410300 + timeoutSeconds: 270060590 + terminationMessagePath: P1HCGJEbJiD4 + terminationMessagePolicy: ʇ鞯BC鸼樁÷ǹ楺 + tty: true + volumeDevices: + - devicePath: a4 + name: 0bA + - devicePath: VeRXU9 + name: A0XbFJhG + - devicePath: fdim + name: RJf + workingDir: ZoDFb + imagePullSecrets: [] + initContainers: + - 'error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string + into Go value of type []interface {}' + nodeSelector: {} + priorityClassName: 0P6RnoBeb5 + securityContext: + fsGroup: -6567182940167159000 + fsGroupChangePolicy: 6iɰ堂:齐ǪÈ + runAsGroup: -1787219330993537800 + runAsNonRoot: true + runAsUser: -5627543087390805000 + supplementalGroups: + - -3306962996817147400 + - 975882030005456500 + - -5263492609498468000 + sysctls: + - name: YC + value: 7JlDTCP6hs + serviceAccountName: DSw7 + tolerations: [] + topologySpreadConstraints: [] + volumes: + - configMap: + name: YUi5JpG + name: configs + - name: L8dbWip + secret: + defaultMode: 184 + secretName: LF0O +--- +# Source: console/templates/hpa.yaml +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: nEojiMtRc + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: YUi5JpG +spec: + maxReplicas: 122 + metrics: + - resource: + name: cpu + target: + averageUtilization: 218 + type: Utilization + type: Resource + - resource: + name: memory + target: + averageUtilization: 488 + type: Utilization + type: Resource + minReplicas: 449 + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: YUi5JpG +-- testdata/case-048.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + 4kU: mkn8 + Ro: NFx1P + Z1p: WE + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: W7q3X + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: sKa + namespace: default +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} + role-bindings.yaml: |- + roleBindings: + - FZ5NQS6: null + - 0ToI: null + RTwav: null + mWwdgyM: null + - {} +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + 4kU: mkn8 + Ro: NFx1P + Z1p: WE + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: W7q3X + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: 3um +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: + c: DNy + kDPtPpnL: kFmmx + creationTimestamp: null + labels: + 4kU: mkn8 + Ro: NFx1P + Z1p: WE + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: W7q3X + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: 3um + namespace: default +spec: + ports: + - name: http + port: 311 + protocol: TCP + targetPort: 29 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: W7q3X + type: l5gj +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + Dgw3Wl: 7aofTp + creationTimestamp: null + labels: + 4kU: mkn8 + Ro: NFx1P + Z1p: WE + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: W7q3X + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: 3um + namespace: default +spec: + replicas: null + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: W7q3X + strategy: + rollingUpdate: {} + type: 顓ǝSm + template: + metadata: + annotations: + checksum/config: 1f1200550e8f17e44439daf44ec8c9721945fe5e499d9d558666a7a6516a4bd3 + eG: vxInc0 + g: BI6yk + xCtSP: rQ + creationTimestamp: null + labels: + ZEXh: zufy + app.kubernetes.io/instance: console + app.kubernetes.io/name: W7q3X + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchFields: + - key: v + operator: ė + values: + - ln + - lU4zX8iz + - t0Xc + - key: s3fpu + operator: ɥ娿ăʄĠ mʓ銈E'袭ĵ + values: + - ljJlhx + - matchExpressions: + - key: qPBvuBghor + operator: 泱诅ʫt + values: + - a05XZwN + - SiAvFWs + - FhW1 + - key: MVFTcW + operator: º囜N赧0索d + values: + - c + - ghZI + - AjB0J + matchFields: + - key: QzMSpLW + operator: :ɉùȪÇzǥC货°ÕV? + - matchExpressions: + - key: pA7a1gYdV + operator: '[ĪtOK' + values: + - 2bE4Bw + - fyMOYi + - key: wshbw7Ix + operator: J槭~撑MS=ÑƎ薽饵a緗 + values: + - 9jt6 + matchFields: + - key: s1 + operator: 犫茬睶ňv + values: + - XhyH + - Ng1r1 + - nqis + - key: mHLiT + operator: ȁ佝L郗s稷tŻ+f舭拳鰵2e{a + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: jdvk + operator: ƶ + values: + - NV + - y4 + - V2XRZS + - key: 9VvAl5 + operator: <坎陸$§¤_ã檠奙Å饉J夗ɓ翩锸辸 + values: + - x26kYkJ + matchLabels: + DziixIJYd: yCXzPc + matchLabelKeys: + - XNuk + - RGLu + mismatchLabelKeys: + - aF3 + - R + - Tnj6SmTq + namespaceSelector: + matchExpressions: + - key: e1XR + operator: Kɞ窏ǿ,鸣ŰcNc + values: + - Yrq + matchLabels: + F2Pe7J: dlwTdhs + lK: nolQ + ys9z: euXWPiaJ3Bv + namespaces: + - tAzvw4OH1G + topologyKey: 6y + weight: -1640008169 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: XbjQvP + operator: V嶙NZ谡筩ǒ抂 + - key: i + operator: ɔŃ旓Ɍ鬺X + values: + - Zvx + - 7HWJ + - e4ucTP + matchLabelKeys: + - 0LSTZ + - ESk2r + mismatchLabelKeys: + - CKhfvR0Sg + namespaceSelector: + matchExpressions: + - key: A0tc + operator: 辛§ʢ垝V矋n握匞~嶯筪溆¸ + values: + - ML + matchLabels: + K1pr: ROFIwZhJYYo + ODc: 48WQ + namespaces: + - Wv7 + - zenLPw + topologyKey: tIVDde5U + weight: 1977587462 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: 3YyUamlR + operator: 橯F + values: + - dHitre + - 90jUjk + - key: NtnSL + operator: 臰sR=坵Ěcñ黪:ɻ寊â9dƎ\V + values: + - qqzycK + - key: ICXJGRFS + operator: $貕^eėǭD鳅ʇ + values: + - txX + - SFrkJ9r + - 3jOnwEW1 + matchLabels: + Uwj1kpV: oUXOYkF + o: ts5wRqjTyCy + matchLabelKeys: + - V2DNNCORe7ZRA + - pglXe4D + - w3881 + mismatchLabelKeys: + - xbi5KtUmR + - eZenitLdd + namespaceSelector: + matchExpressions: + - key: fxd5Y + operator: 頣R熗!A麳Ƚ6r爤暓 + values: + - oe46YF + - rT30v + matchLabels: + 4WA: EH + nRhlLLx1yHy: 5UFrj + namespaces: + - 7j92oP + - 2hf + topologyKey: "" + weight: 92207265 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: wBvol + operator: Ɂüɯ + values: + - eKmyok + - key: B2uj69 + operator: "" + - key: hLrZlh + operator: ȕ嵠味 ɼ_ + mismatchLabelKeys: + - W + namespaceSelector: + matchExpressions: + - key: Qu + operator: 亣i拴ÿ + values: + - OeiUsmYu + - oGXa6Ma + matchLabels: + "": Li + oDV7yR: NP + namespaces: + - PQjQb3LP + topologyKey: Gs1 + - labelSelector: + matchLabels: + "": nF + mismatchLabelKeys: + - YG6aQj + namespaceSelector: + matchExpressions: + - key: HpxPVtw + operator: z畘ŠƽǢ蘟\ɡ忕ɋ蜹5B + values: + - EQ + - RP3fBi + - key: Lv60cZut + operator: 裰ƈ + values: + - I9JbN + - dt + - Cya + - key: 0MGm8N + operator: 遍Ż + matchLabels: + nELvnrAFr: DClM + topologyKey: N57yxG + - labelSelector: + matchExpressions: + - key: "" + operator: KǞ}ɣȿ嚶宗荝«Dž + values: + - CGw32z4JHya + - E + - u5CDtdc + matchLabels: + J5LzcLei: kBwTCGZ + iLpqu: j4bqBNDjAK + jN: jUZ0u + matchLabelKeys: + - lNM + - K3nOO5 + - 9norFQpMiC + namespaceSelector: + matchExpressions: + - key: y4teb + operator: 蚯 + values: + - P + - O0 + - MvxOu + - key: v8w1Ok + operator: 8ƴņŨƊ¹艗胲ƦpYƿ9d脙~Ë + values: + - "4" + - "66" + namespaces: + - OtWsVW + - p + topologyKey: GeF + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: GRLHy + operator: Ä椶 + - key: Z + operator: ė牫ȃ汥Ƈ娍q\桕ɄNǴ + values: + - S1hMkP + - K + - x5coDg + - key: kJzBQ + operator: ʉĻ孺bɧɬʬ柿娤e¯]每) + values: + - DbD1 + - C5dyvNew + matchLabelKeys: + - 8G + - 7cCVU + - lN + mismatchLabelKeys: + - xJ5l + namespaceSelector: + matchExpressions: + - key: U89y + operator: ȓ2浿澰V缐厧钎wň莁願菶ʈ杈 + values: + - 9m6ydjpHu + - CatqpZmUCL + - dJz + - key: SIePbOJc6H + operator: ljR2qɟ$s櫮c雕Ů幔莁沥ʫľƙŝ + values: + - 75tj75r + - XiO + - key: "" + operator: 舄或崙Ĭɐ耼Ī弋禽$ + values: + - HWwXVr4o + - WEkwi8ZNDQ + - f + matchLabels: + fi8w0BX: Z48LRdXmkJ + namespaces: + - Yaw2NnfJ + topologyKey: ElKfd7Eo + weight: 1078166465 + automountServiceAccountToken: true + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: rd10f1l + value: GtUE + valueFrom: + configMapKeyRef: + key: C1N + name: bi + optional: true + fieldRef: + apiVersion: 9GWlMsB + fieldPath: l2 + resourceFieldRef: + containerName: 4t + divisor: "0" + resource: eyjvzsf + secretKeyRef: + key: xBMOaej + name: O8AG + optional: false + - name: C + value: fYlde + valueFrom: + configMapKeyRef: + key: 4HvhDAkW + name: 5bgA7leE7 + optional: false + fieldRef: + fieldPath: zY6rf + resourceFieldRef: + containerName: S3 + divisor: "0" + resource: 3sD + secretKeyRef: + key: s43 + name: LpaQ + optional: true + - name: LICENSE + valueFrom: + secretKeyRef: + key: enterprise-license + name: 3VGefRh + envFrom: [] + image: VHbf77MFq/9Gz:Tg + imagePullPolicy: Ƀşb?師Ğ`3H觉趟糯襖 + livenessProbe: + failureThreshold: 279778022 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 1098820524 + periodSeconds: 414174316 + successThreshold: 1178515566 + timeoutSeconds: 873461419 + name: console + ports: + - containerPort: 29 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 37001950 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: -396024246 + periodSeconds: -1467409206 + successThreshold: -1328773613 + timeoutSeconds: -1781454259 + resources: + limits: + 8cdWaeK7jVrR: "0" + HYBi6o: "0" + requests: + NOz: "0" + gH: "0" + securityContext: + allowPrivilegeEscalation: false + capabilities: + add: + - Ɋ闻ǃɗʀd撪 + - 蘑ǪY桼ɮǚɳ爥ňB + drop: + - 乄}ñ0詘蛾牪坣缰ƩǏ薷©瓚`Ʋ虯r + - ǓJğ&ĊƯʝbǠCŪzgì + - ńǜ[ɪ判Uʋ]泘狔 + privileged: false + procMount: 媹:堏_ɟ榧禙Ɲ'瞟 + readOnlyRootFilesystem: false + runAsGroup: 2759228957449300500 + runAsNonRoot: true + runAsUser: -812867783664200800 + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: WsSL4vxNxCkXP + name: Mt1 + subPath: "" + - mountPath: M5 + mountPropagation: 稤Bơ觓Ð琋 + name: yQHj49RtdzN + subPath: GdQkAKF + subPathExpr: Gvswh + - mountPath: QRg + mountPropagation: 搚Kƕ欕K貵蠜d旓ĀÝ虩釓 + name: qCEH27RF + readOnly: true + subPath: nHB05RuTZ + subPathExpr: K0yH + - args: + - 3QF + - k1BJBm + command: + - PMW + - j + - V7MAcfomz + env: + - name: rAzI53 + value: WlHlq + valueFrom: + configMapKeyRef: + key: zzIBsb + name: Bh261F + optional: false + fieldRef: + apiVersion: SlA + fieldPath: "6" + resourceFieldRef: + containerName: q0BBEv + divisor: "0" + resource: JE + secretKeyRef: + key: FvrZgBz + name: ZTBeic + optional: false + - name: uPptX + value: i9 + valueFrom: + configMapKeyRef: + key: JeHwi + name: TiQHOG1EsFUgIE + optional: true + fieldRef: + apiVersion: i7dd + fieldPath: Tu + resourceFieldRef: + containerName: ChdvA + divisor: "0" + resource: Eq1V33RTZQSJRJFg3V + secretKeyRef: + key: ojxn54r + name: L + optional: false + - name: Sl9Py25FX + value: e9 + valueFrom: + configMapKeyRef: + key: Zq80J9tyR0opcz + name: gy00dyvHFa + optional: true + fieldRef: + apiVersion: UJLSQy7zL + fieldPath: Xm4sg5H + resourceFieldRef: + containerName: ZmY7Fno6Fcop3 + divisor: "0" + resource: gqZwW + secretKeyRef: + key: v + name: hJDoWtjkfL + optional: true + envFrom: + - configMapRef: + name: RdWA + optional: true + prefix: Dq + secretRef: + name: BOBOO0sLIWw0e + optional: false + - configMapRef: + name: MoMnWNTC + optional: false + prefix: "3" + secretRef: + name: B58Vvj3 + optional: false + image: Vn5V + imagePullPolicy: 筥ǏŤČ癳嶧GĒH挕ÄHɡ + lifecycle: + postStart: + exec: + command: + - hTIx + - lslygl + - lSgx5G2IfU + httpGet: + host: GNVKz7 + path: d0Y + port: Igi + scheme: 莵łEǐ嫖ʒʔvŊ>ry5贛 + sleep: + seconds: -184172880642712450 + preStop: + exec: {} + httpGet: + host: tD1TkKV0ES + path: s6 + port: OpK5riOe96 + scheme: 琊*i#欱E唂ȧ鐄膶詃7 + sleep: + seconds: -4889549574266894000 + livenessProbe: + exec: {} + failureThreshold: 1591130939 + grpc: + port: -540029946 + service: aoAN2Lx03 + httpGet: + host: vWu + path: Lo + port: 1468671948 + scheme: ȯ煐IŢ + initialDelaySeconds: -1879733088 + periodSeconds: 1106663448 + successThreshold: 240850805 + terminationGracePeriodSeconds: -7405296717602936000 + timeoutSeconds: 524743651 + name: AInfx2Rak + readinessProbe: + exec: + command: + - oIA3 + - H + - 96Uj2 + failureThreshold: -1855887857 + grpc: + port: -495541010 + service: X + httpGet: + host: ZplmMg + path: tAAr + port: 1950182935 + scheme: ʂ綽oa;n轮ęB觼Z=G泇跢揌韇锶 + initialDelaySeconds: 1057136331 + periodSeconds: -2025421367 + successThreshold: -812558156 + terminationGracePeriodSeconds: 4314843605692522000 + timeoutSeconds: -1609986779 + resizePolicy: + - resourceName: EvmpG + restartPolicy: 4ɱ + - resourceName: hTB20ObO1 + restartPolicy: ½ŏ伐Q蔏ʝ噙漃袩J]Ɣ蒘岇 + resources: + limits: + KWlx2c: "0" + O: "0" + requests: + ZCJwGBL: "0" + restartPolicy: 1nĔ:蹮>s蹬ÍǺ + securityContext: + allowPrivilegeEscalation: false + capabilities: + add: + - 迠寈搣弝渎İ- + drop: + - 檹Ɩ + - ɧ麧ç2ā兛杧蔙團载^P蚡5缿ʒU襩 + - cLD|ƶ虌Ȗ + privileged: false + procMount: ïƋ圏滜ľ転謀ĤP蹥ȅ|髃蒃Q癎æ + readOnlyRootFilesystem: false + runAsGroup: -4850605470374304000 + runAsNonRoot: false + runAsUser: 7731251064648991000 + startupProbe: + exec: + command: + - LqYoUQy3c4BE + - 5N + - Ug + failureThreshold: -1290004088 + grpc: + port: -1721281251 + service: H2p + httpGet: + host: 02CP5 + path: F609y + port: JjwFH + scheme: 珑 + initialDelaySeconds: -402608647 + periodSeconds: -1520214127 + successThreshold: 209058699 + terminationGracePeriodSeconds: -1900030585542850300 + timeoutSeconds: 1686394545 + terminationMessagePath: qixKzKz + terminationMessagePolicy: Ǥ衚蔁ʙ剠Ǡɭf~ + volumeDevices: + - devicePath: zM1 + name: jmc + - devicePath: IZ + name: PS + - devicePath: kN24U + name: Apu0r1U2 + workingDir: WgB + - args: + - 2Z37 + - 75kO + - TjvjkZTrc8s + command: + - M0NtzJ + env: + - name: 2EH + value: O + valueFrom: + configMapKeyRef: + key: J1ozKsuji + name: glLvAIHP7i + optional: true + fieldRef: + apiVersion: 3gAjGu + fieldPath: sNpuR8m + resourceFieldRef: + containerName: oxx + divisor: "0" + resource: PuKq + secretKeyRef: + key: Iua2L1LoCWMs2 + name: YfKwS8s + optional: true + image: PKNM + imagePullPolicy: ÍĪ0魣Ŋʒ + lifecycle: + postStart: + exec: {} + httpGet: + host: fsZ + path: EGnu + port: 765491661 + scheme: ?ğ叆ɂ&pʠ溶Ǚu + sleep: + seconds: 4688626474961013000 + preStop: + exec: {} + httpGet: + host: TB + path: "6" + port: -50369560 + scheme: ~Ǚɇ>ƃ\7]歉sh羘y4 + sleep: + seconds: -5293607398165582000 + livenessProbe: + exec: + command: + - 1g8dewdj + - lRmD + failureThreshold: -125369558 + grpc: + port: -1490211482 + service: R + httpGet: + host: CSGThzhG + path: 9NBKzoiFzs + port: -272474300 + scheme: ŀ + initialDelaySeconds: -1094670881 + periodSeconds: 1768141210 + successThreshold: -985604418 + terminationGracePeriodSeconds: -1297054466922920700 + timeoutSeconds: -1289231356 + name: KtKv6dg + ports: + - containerPort: -632764671 + hostIP: 8CU + hostPort: 917138107 + name: 1VgOx + protocol: 典ȫ窃ÛǪ3m患 + - containerPort: 739656218 + hostIP: dQQ3 + hostPort: -1348301133 + name: "3" + protocol: '?Ū慾ŘLº桒J:茦扰絥ǗȑĎ:' + readinessProbe: + exec: + command: + - qZ2J + failureThreshold: 293719665 + grpc: + port: 1235836411 + service: ig3 + httpGet: + host: Ws + path: FVnJhZq7I + port: -1075951148 + initialDelaySeconds: 321800409 + periodSeconds: -556535717 + successThreshold: -625124830 + terminationGracePeriodSeconds: -4084380722124342300 + timeoutSeconds: -904900305 + resizePolicy: + - resourceName: GKINnuJx + restartPolicy: Řl©=嬈牍]佧& + resources: + requests: + omO: "0" + uga5: "0" + xnRsp6C: "0" + restartPolicy: ʝdŌİ蒘傥>晑|癶x&ĭmŭƙŵ + securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - 約nɤưHĞ4WƳǤȣ糥蠇t + - ¾ʃŔ冻楟?¿揈h嘼œ + drop: + - 7忭譺屩嫕ƞʅ袬/氼Xg养ȸ陣萓 + - 胨`鯵ƪĽ藹 + privileged: true + procMount: Ulƙxȿƌ乜溬噕瀆储铐\纬 + readOnlyRootFilesystem: true + runAsGroup: 4589112012742887000 + runAsNonRoot: true + runAsUser: 3204614620414442500 + startupProbe: + exec: + command: + - TFJ + failureThreshold: -585814509 + grpc: + port: 178002023 + service: lAuHCrE + httpGet: + host: "88" + path: Th + port: In + scheme: 鷵菭g顲Ⱦ穪 + initialDelaySeconds: -1856697198 + periodSeconds: 1469578394 + successThreshold: 160563852 + terminationGracePeriodSeconds: -4442318275257517600 + timeoutSeconds: -16211809 + terminationMessagePath: 513sVbgA + terminationMessagePolicy: 隓Ǽ屼Å7嗟Ʈ麝0{ȦDžĐ! + tty: true + volumeDevices: + - devicePath: ugQAJ + name: Jf + - devicePath: BFfnTD + name: kfF6CZ + volumeMounts: + - mountPath: C3 + mountPropagation: 呍婻厦ǒ絶偂蠛ƺ蠖蕍v貰Ė + name: DQvHajhHx + subPath: aYHGugq + subPathExpr: MSs + workingDir: OE + imagePullSecrets: [] + initContainers: + - 'error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string + into Go value of type []interface {}' + nodeSelector: + Bm9U: oTYglG6dh + priorityClassName: l4Mowg + securityContext: + fsGroup: -3794452885502571500 + fsGroupChangePolicy: 欲飹Rɦ薕µL<Ĕ + runAsGroup: -3171560656159467000 + runAsNonRoot: true + runAsUser: -4412205905842408400 + supplementalGroups: + - -7215185124091152000 + - 5139656417921063000 + - 600742233156257700 + sysctls: + - name: Te + value: cKzihj + serviceAccountName: sKa + tolerations: + - effect: 嫜ʎ愤wßj硭 + key: JO1 + operator: ȼ¾Pȇ挮ƶȋ'蹑鶚嗵ïG + tolerationSeconds: -6027642013843151000 + value: a3XbyS + topologySpreadConstraints: [] + volumes: + - configMap: + name: 3um + name: configs + - name: Mt1 + secret: + defaultMode: 80 + secretName: ZxXI0Hhv +--- +# Source: console/templates/hpa.yaml +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + creationTimestamp: null + labels: + 4kU: mkn8 + Ro: NFx1P + Z1p: WE + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: W7q3X + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: 3um +spec: + maxReplicas: 1 + metrics: + - resource: + name: cpu + target: + averageUtilization: 468 + type: Utilization + type: Resource + - resource: + name: memory + target: + averageUtilization: 256 + type: Utilization + type: Resource + minReplicas: 224 + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: 3um +-- testdata/case-049.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: + 5bpPp: ponDVyZ + Ml1: "" + lt: 6VN8BRlJd + creationTimestamp: null + labels: + 0HYkOrz: JCwpSW + 0TgDztQSY: P + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 8dJzE + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + ztm: qegfb80 + name: z12W + namespace: default +--- +# Source: console/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + labels: + 0HYkOrz: JCwpSW + 0TgDztQSY: P + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 8dJzE + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + ztm: qegfb80 + name: 0BIfuN +stringData: + enterprise-license: "" + kafka-protobuf-git-basicauth-password: SBJl + kafka-sasl-aws-msk-iam-secret-key: INqD5 + kafka-sasl-password: 78E + kafka-schema-registry-password: YMuFCG7qR + kafka-schemaregistry-tls-ca: 1y5yRb6O2b + kafka-schemaregistry-tls-cert: NuhkhpMV7b + kafka-schemaregistry-tls-key: 9zcrFj + kafka-tls-ca: 0PF + kafka-tls-cert: wArD + kafka-tls-key: "" + login-github-oauth-client-secret: jdPGF7 + login-github-personal-access-token: y6xqv + login-google-groups-service-account.json: xi1j27Lipj8 + login-google-oauth-client-secret: m6FeI + login-jwt-secret: SECRETKEY + login-oidc-client-secret: zbsTootC + login-okta-client-secret: rHSfT + login-okta-directory-api-token: rOXaN + redpanda-admin-api-password: 8c + redpanda-admin-api-tls-ca: CJbHIM + redpanda-admin-api-tls-cert: uO + redpanda-admin-api-tls-key: uhB0L +type: Opaque +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: + L: CP + Yf: K4waOjMg + tIYLLgy: d1szIPW6xt + creationTimestamp: null + labels: + 0HYkOrz: JCwpSW + 0TgDztQSY: P + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 8dJzE + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + ztm: qegfb80 + name: 0BIfuN + namespace: default +spec: + ports: + - name: http + port: 269 + protocol: TCP + targetPort: 479 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: 8dJzE + type: IfYfRoHRG +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + BceQMZiOm: E1uakdHPkLNL + creationTimestamp: null + labels: + 0HYkOrz: JCwpSW + 0TgDztQSY: P + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 8dJzE + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + ztm: qegfb80 + name: 0BIfuN + namespace: default +spec: + replicas: null + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: 8dJzE + strategy: + rollingUpdate: {} + type: 擺m鷾DžPĨ + template: + metadata: + annotations: + "": cuRn + checksum/config: 74234e98afe7498fb5daf1f36ac2d78acc339464f950703b8c019892f982b90b + qBdeU: EQv + creationTimestamp: null + labels: + O2n4u: kpFpu + app.kubernetes.io/instance: console + app.kubernetes.io/name: 8dJzE + g1c: XEOMg + spec: + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: L + operator: 域%Ɠ礇!ʘl.ǷŠ该貹&N + values: + - oAk8rvkey + - Fb08GpumY + - key: YJGr + operator: '|4\i事!ų藦x鳜Ǫ' + values: + - 63Yvc + - key: j + operator: ¸瀖čņ!彅搀 + values: + - RnzdW + - Nxs + - unZuno + matchFields: + - key: wLP0QqdHBmd9e + operator: ȑwȼ嶢vC`ȖĜƐ桡牆ēIa,謧ŗ + - key: mdgmMZ + operator: Ō§ȶƔ>#Z骻5S洝岛Ċ啞. + values: + - Fvf6 + - key: GQsV + operator: 涥ȕêȩȋ婍0毙舺糩\DŽŅ饒 + values: + - XccQkxG + weight: -1172839714 + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: JpS0BkW + operator: 聣耥ʒ昼|Ȏ)ß瞖a癨櫒缮{v + - key: HLL3gv + operator: 铡ÞC腢z蟒Á + - key: iDGQV8Bjyu5Q + operator: 舢脛歛ƻ68 + values: + - eLCH7Nc + - QQqPUN + - "" + matchFields: + - key: AY2q9fnL + operator: ȏ伌鎩5桀ʁ + values: + - Uac + - K0q + - bY71A + - key: rBwZz + operator: '*ĴȉǼ矼SN]ʛ源' + values: + - 5yMkn + - key: S1C + operator: ÿƙ彋,嘲樦 + values: + - OXH + - vl1 + - uCYaO8Cn + - {} + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: mZ3rAF9 + operator: yŲĺȫ阁笵W®詃Œ + values: + - bhvFz + - key: uiaNXZcXT + operator: "" + - key: AAM + operator: 閸鬼駝洁c奊(Ƅ謍MǍ辰T堍癩)丗 + values: + - "9" + - ESiN3 + matchLabels: + kCSDZtsm5: vVk + oBlyCq: jlh + matchLabelKeys: + - BCZ8FFbh + - A + namespaceSelector: + matchExpressions: + - key: Lsf + operator: L + values: + - a0HB + - C + - key: eoj6ic3 + operator: ż伌oA汄俔ɿ7巪娻% + matchLabels: + Cx: wwPPM + namespaces: + - 9xhG + - JAutZqe4gGeuf + - "" + topologyKey: 1a + weight: 223935020 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: LtGRhs + operator: 棺ǔ'ɘ砒Æ擑Ɵģ + values: + - GhM4BSJqNOf + matchLabels: + "": 7Ni + matchLabelKeys: + - yxF4 + - 22RoWr + - etRteovEh9 + mismatchLabelKeys: + - 7NOfe + namespaceSelector: + matchExpressions: + - key: 3KCX2 + operator: 臞ʀ¯弄Ɨ橎琜ġ鍳¶ȣ2墛.ɮ濎ɕ磞 + values: + - 5YiE0xEC + - 4spxMd + - vUPA + matchLabels: + YHIq: nS + topologyKey: F4 + weight: 716052627 + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: "9" + operator: ĠƑȥ兾3ŶJ + - key: pPvuyWZ + operator: ;bļo刲+圊}MǏŅ惤ć + values: + - 9pMXT + - Ezwo11 + matchLabels: + 66347W: ccFxZoF9 + X: VrN5kt + mismatchLabelKeys: + - u4LyY1 + - zT + namespaceSelector: + matchExpressions: + - key: qwhutJo + operator: 垴ǞƼ + matchLabels: + OFxMkYx: lhxtM + topologyKey: WN8qbUgigF + weight: -1609734055 + - podAffinityTerm: + labelSelector: {} + matchLabelKeys: + - "" + mismatchLabelKeys: + - XnhP + - "" + - Bk + namespaceSelector: + matchExpressions: + - key: M + operator: Ǽ糨ʡ毺Ɇw + values: + - ntvI + - vs + matchLabels: + "4": 2Y2FBpcbg + namespaces: + - 1S8c + topologyKey: jxiZ4d + weight: 1993833508 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: EpKkdimp + operator: 额ƀ箰L禼aÅ顙)C舉 + - key: e2Zu7Kb + operator: t潱髦pö鵺b澁6銹 + values: + - z9n + - LdMQ + - r + matchLabels: + F: Nc + Qa2h5toVwd: GGxZ3BQ + l: Z6Rh + matchLabelKeys: + - LsCC + - dgmxxZW + mismatchLabelKeys: + - e + - Cb + - e0DAEluN + namespaceSelector: + matchLabels: + oJ56D: 33m + tkP8tO: mIkfyE6E + namespaces: + - VxN + - hbwB9 + - t + topologyKey: qag0unul + automountServiceAccountToken: true + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: KAFKA_SASL_PASSWORD + valueFrom: + secretKeyRef: + key: kafka-sasl-password + name: 0BIfuN + - name: KAFKA_PROTOBUF_GIT_BASICAUTH_PASSWORD + valueFrom: + secretKeyRef: + key: kafka-protobuf-git-basicauth-password + name: 0BIfuN + - name: KAFKA_SASL_AWSMSKIAM_SECRETKEY + valueFrom: + secretKeyRef: + key: kafka-sasl-aws-msk-iam-secret-key + name: 0BIfuN + - name: KAFKA_TLS_CAFILEPATH + value: /etc/console/secrets/kafka-tls-ca + - name: KAFKA_TLS_CERTFILEPATH + value: /etc/console/secrets/kafka-tls-cert + - name: KAFKA_SCHEMAREGISTRY_TLS_CAFILEPATH + value: /etc/console/secrets/kafka-schemaregistry-tls-ca + - name: KAFKA_SCHEMAREGISTRY_TLS_CERTFILEPATH + value: /etc/console/secrets/kafka-schemaregistry-tls-cert + - name: KAFKA_SCHEMAREGISTRY_TLS_KEYFILEPATH + value: /etc/console/secrets/kafka-schemaregistry-tls-key + - name: KAFKA_SCHEMAREGISTRY_PASSWORD + valueFrom: + secretKeyRef: + key: kafka-schema-registry-password + name: 0BIfuN + - name: LOGIN_JWTSECRET + valueFrom: + secretKeyRef: + key: login-jwt-secret + name: 0BIfuN + - name: LOGIN_GOOGLE_CLIENTSECRET + valueFrom: + secretKeyRef: + key: login-google-oauth-client-secret + name: 0BIfuN + - name: LOGIN_GOOGLE_DIRECTORY_SERVICEACCOUNTFILEPATH + value: /etc/console/secrets/login-google-groups-service-account.json + - name: LOGIN_GITHUB_CLIENTSECRET + valueFrom: + secretKeyRef: + key: login-github-oauth-client-secret + name: 0BIfuN + - name: LOGIN_GITHUB_DIRECTORY_PERSONALACCESSTOKEN + valueFrom: + secretKeyRef: + key: login-github-personal-access-token + name: 0BIfuN + - name: LOGIN_OKTA_CLIENTSECRET + valueFrom: + secretKeyRef: + key: login-okta-client-secret + name: 0BIfuN + - name: LOGIN_OKTA_DIRECTORY_APITOKEN + valueFrom: + secretKeyRef: + key: login-okta-directory-api-token + name: 0BIfuN + - name: LOGIN_OIDC_CLIENTSECRET + valueFrom: + secretKeyRef: + key: login-oidc-client-secret + name: 0BIfuN + - name: REDPANDA_ADMINAPI_PASSWORD + valueFrom: + secretKeyRef: + key: redpanda-admin-api-password + name: 0BIfuN + - name: REDPANDA_ADMINAPI_TLS_CAFILEPATH + value: /etc/console/secrets/redpanda-admin-api-tls-ca + - name: REDPANDA_ADMINAPI_TLS_KEYFILEPATH + value: /etc/console/secrets/redpanda-admin-api-tls-key + - name: REDPANDA_ADMINAPI_TLS_CERTFILEPATH + value: /etc/console/secrets/redpanda-admin-api-tls-cert + envFrom: + - configMapRef: + name: GTjM + optional: true + prefix: GSbKp + secretRef: + name: vhsV8Pl5 + optional: true + - configMapRef: + name: cvXs + optional: false + prefix: cBFtb + secretRef: + name: x9N + optional: false + - configMapRef: + name: rDSrOmdL + optional: false + prefix: 0u3 + secretRef: + name: A6PG37zBJfwNR + optional: false + image: RCYS61Exfql/8ZLfmymq:4BSL9iL + imagePullPolicy: õ鴀铑û + livenessProbe: + failureThreshold: -567921134 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: -507660572 + periodSeconds: 1912372611 + successThreshold: -232304560 + timeoutSeconds: 582403024 + name: console + ports: + - containerPort: 479 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 1010917423 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: -986314779 + periodSeconds: 1763110639 + successThreshold: 1473932979 + timeoutSeconds: 1291669389 + resources: + limits: + x6: "0" + requests: + eeR: "0" + l: "0" + xppI8xB: "0" + securityContext: + allowPrivilegeEscalation: false + capabilities: + add: + - 趩燡º嗂{踦 + - CƮ + drop: + - 殟kĔ=ņŧɋ] + privileged: false + procMount: aŻ釯fȠ埱ɺȚ + readOnlyRootFilesystem: true + runAsGroup: 4284419790643993000 + runAsNonRoot: true + runAsUser: -4828746969388386000 + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: /etc/console/secrets + name: secrets + readOnly: true + - mountPath: AQpWvptFEk7y + name: 99SgdOsZD + subPath: "" + - mountPath: p44 + name: U + subPath: "" + - mountPath: UiI + name: WFd + subPath: "" + - mountPath: De7 + mountPropagation: 1k噟霞ƁĹ + name: 1Z2WnghTc + subPath: Ts5Ful + subPathExpr: YyidD + - mountPath: onM7c3 + mountPropagation: m=Cɬ + name: GC5ZsY07Mr + readOnly: true + subPath: Xt + subPathExpr: r6gZk + - mountPath: 8gPjX7hc + mountPropagation: ƃ柅珚ȭ能 + name: oN + subPath: auYcD + subPathExpr: aheb25w + - args: + - kn0F9 + command: + - M + - Hph3 + - lZfWKF + env: + - name: HBWtNh10A + value: 8guE + valueFrom: + configMapKeyRef: + key: Chnm + name: UlwzEQ + optional: false + fieldRef: + apiVersion: 8pq9 + fieldPath: qpnfP4p + resourceFieldRef: + divisor: "0" + resource: L0tn + secretKeyRef: + key: J + name: gbfgF + optional: true + envFrom: + - configMapRef: + name: n32MM + optional: true + prefix: cp3 + secretRef: + name: Uc + optional: true + - configMapRef: + name: VGBL + optional: true + prefix: NTMU + secretRef: + name: CEg + optional: true + image: zIWYBi7 + imagePullPolicy: 蘂ȱʃ& + lifecycle: + postStart: + exec: + command: + - QpTcv + - MS0T0N + - wiE + httpGet: + host: ZCUJOIH + path: UsXT + port: 8nExSP2u + scheme: 'uŊ6熀: 焆 烷ʫ-Ŗ亾ɣʖ氝"肰' + sleep: + seconds: -2519616411083819500 + preStop: + exec: + command: + - rmQ7 + - GxRXQk + httpGet: + host: UIVpXMrzW + path: 4tHQ + port: 8xLK1VyM + scheme: ƳǃóɃȊ{回żz闓葊G嚥 + sleep: + seconds: 3595323074300269600 + livenessProbe: + exec: {} + failureThreshold: -882825879 + grpc: + port: 503069299 + service: W + httpGet: + host: FilCCd + path: NPZrCEq + port: 6NoPho8wIsxe + scheme: āȹ顺悩錣Xƕ灄ĿG乒 + initialDelaySeconds: 781680731 + periodSeconds: 205458 + successThreshold: 1115648780 + terminationGracePeriodSeconds: 4579765768791485400 + timeoutSeconds: -676867842 + name: 2tf + readinessProbe: + exec: + command: + - edKf + - 0U + - MFr2Oh + failureThreshold: 1812906550 + grpc: + port: -791379232 + service: IAqADBco + httpGet: + host: 55GZ + path: AQC + port: sxTXcp + scheme: ƷMg靚珨嘸ȗʒ鑉Ȝ梒ŗǐkōĕĵ鞍 + initialDelaySeconds: -130429301 + periodSeconds: 876742351 + successThreshold: -1424043483 + terminationGracePeriodSeconds: -1574530902871555300 + timeoutSeconds: 764935409 + resources: + limits: + 9eHi: "0" + rO52puR: "0" + requests: + UF8LV7N: "0" + ao: "0" + cRVsAz8v: "0" + restartPolicy: ɥ]×璳 + securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - ɖ膵7&ʞíXĦx-ǰİɾ榩聨ŗ% + - DŽ熲鴼玜覲杷ȆƠ沺伤{拢 + - ɉȋʠRÂo霾噜奩ƻv$Áő + drop: + - ɑ摿愻J«ʘA宜ƹ¶ + - 餫aJ矐sǁ隑z36渢X赼 + - )ǜ鄰挺溒ŒV栜Ù涸JH-_d + privileged: false + procMount: Ito縎 + readOnlyRootFilesystem: false + runAsGroup: 2484782727894659600 + runAsNonRoot: false + runAsUser: -6936271037843915000 + startupProbe: + exec: + command: + - X + failureThreshold: -256045507 + grpc: + port: 376282302 + service: wdQrDn0 + httpGet: + host: teaO6 + path: DBHpGkYdgAJ + port: -1625640156 + scheme: Ʌ + initialDelaySeconds: 673272264 + periodSeconds: -1050905915 + successThreshold: 282500457 + terminationGracePeriodSeconds: 5768805478519710000 + timeoutSeconds: -601307290 + stdinOnce: true + terminationMessagePath: POO + terminationMessagePolicy: '#d鿂Hk閎=ɰ蜐ġOʡ蠁żǖ' + tty: true + workingDir: Z3pdGL + - args: + - a7Tqs + - UuID5t + - gRCnbjyp + env: + - name: ZV1KP + value: WrT0 + valueFrom: + configMapKeyRef: + key: zZzTgax + name: 3z3eoets + optional: true + fieldRef: + apiVersion: 88zo + fieldPath: z0vE72 + resourceFieldRef: + containerName: DF4t + divisor: "0" + resource: hfVfYFW4 + secretKeyRef: + key: I6JwpO5 + name: I88w22gsx3 + optional: true + - name: z8 + value: sgj8UHZ + valueFrom: + configMapKeyRef: + key: Q85vN + name: lYGl4 + optional: true + fieldRef: + apiVersion: oQu7 + fieldPath: TYd + resourceFieldRef: + containerName: "Y" + divisor: "0" + resource: Yx + secretKeyRef: + key: f + name: 0Pjf9YBj + optional: false + envFrom: + - configMapRef: + name: fAH + optional: false + prefix: vjjU + secretRef: + name: 9A8OgEQ9 + optional: false + image: R7L + imagePullPolicy: '}m6铤<豎ŵ,#M狥ʬo' + lifecycle: + postStart: + exec: + command: + - 2E + - gzntg + httpGet: + host: BOoVI + path: ns7ZMdNwQC + port: XF + scheme: ky咊ʅ ʂ娼ȟƐ橽ǿ唔ARɨ罙 + sleep: + seconds: -3978858376823544000 + preStop: + exec: + command: + - Hns + httpGet: + host: Lw8 + path: wdo + port: -239095421 + scheme: ƹ禍OÇ + sleep: + seconds: 3838288160382434000 + livenessProbe: + exec: + command: + - 8E + failureThreshold: -1052479375 + grpc: + port: 82058135 + service: S3UA2HwQaN + httpGet: + host: T0 + path: wYV6 + port: cEf + scheme: 斡1{嘫b葎剜屙唯皎図Ǜ錮ơxȒt駦Ƨ + initialDelaySeconds: -1976610733 + periodSeconds: 436460884 + successThreshold: -949159248 + terminationGracePeriodSeconds: 1786907735670591200 + timeoutSeconds: -2035324376 + name: 0ygO + readinessProbe: + exec: + command: + - "" + - YQ + failureThreshold: 1469514474 + grpc: + port: -1835111333 + service: 5WmTypZfT + httpGet: + host: BDf + path: ZY + port: tyrBXIqhX + scheme: 趬扬鉰昵 + initialDelaySeconds: -683847692 + periodSeconds: -95594828 + successThreshold: -1707399501 + terminationGracePeriodSeconds: 3256417681193515500 + timeoutSeconds: -2088454060 + resources: + limits: + zVX: "0" + restartPolicy: 晄d塮@ʥO%驮ÆgǍô + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ' 吓zǘa畷' + - 鲃ʍ瑘ƴɛjV艑ǔpMK杣Ġ + privileged: true + procMount: zɱÙŭǫäƿ诧聉ń醽Ƥ裩5 + readOnlyRootFilesystem: true + runAsGroup: -2381715627246700500 + runAsNonRoot: false + runAsUser: 6590063474480016000 + startupProbe: + exec: + command: + - "9" + - oRMM2F + - "" + failureThreshold: -1711876939 + grpc: + port: 1138187974 + service: OvdS + httpGet: + host: GZWJ + path: vzJeBCvGMHn7 + port: h9p1Pak + initialDelaySeconds: 447733263 + periodSeconds: 1805541821 + successThreshold: -1114184264 + terminationGracePeriodSeconds: 2730048172651207700 + timeoutSeconds: -1850805595 + terminationMessagePath: GK8 + terminationMessagePolicy: ɾDŽ÷郃ɻ玗璺,4 + volumeDevices: + - devicePath: bLf + name: UVN1o + - devicePath: fIT + name: Qiswb + - devicePath: 9b8i + name: h1 + workingDir: 1IOT + imagePullSecrets: + - name: h5x + initContainers: + - 'error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string + into Go value of type []interface {}' + nodeSelector: + ra78: fJ + priorityClassName: JhGfjGXQ + securityContext: + fsGroup: 6449559755791186000 + fsGroupChangePolicy: 慩梱ʂcƎƱ\火ɘ²ɉ_ + runAsGroup: 841256803887707600 + runAsNonRoot: true + runAsUser: -2824253868920734700 + supplementalGroups: + - 8145086042470337000 + - -5005570809576723000 + serviceAccountName: z12W + tolerations: + - key: ka + tolerationSeconds: 2857628758439265300 + value: Ohni9QGx + topologySpreadConstraints: + - labelSelector: + matchLabels: + 3Ym: o2h5aVp + yR4PPZO: 3X + matchLabelKeys: + - vCKujB + - UqCFKCN + - Xnjfai + maxSkew: -943395897 + minDomains: 1955399000 + nodeAffinityPolicy: 噙撢馥櫱m>Q脕擏w梪 + nodeTaintsPolicy: 蝚溄鑝刉=歱Mr踄 + topologyKey: cHyq + whenUnsatisfiable: Q輒ƗȈʑǯƐ| + - labelSelector: + matchLabels: + E: lyK5b9t + UuSjduy: NcK4 + fty: iP6ai + maxSkew: 1881677866 + minDomains: -561571142 + nodeAffinityPolicy: ȫ寴ī嘌.樥'ǹs + nodeTaintsPolicy: ɇ剀ǨUǜ!俛dz餂~匹呃 + topologyKey: pCHj + whenUnsatisfiable: 尘I:Ƒ匌,騸 + volumes: + - configMap: + name: 0BIfuN + name: configs + - name: secrets + secret: + secretName: 0BIfuN + - name: 99SgdOsZD + secret: + defaultMode: 500 + secretName: B6Fq + - name: U + secret: + defaultMode: 337 + secretName: DddF02 + - name: WFd + secret: + defaultMode: 246 + secretName: tz +--- +# Source: console/templates/hpa.yaml +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + creationTimestamp: null + labels: + 0HYkOrz: JCwpSW + 0TgDztQSY: P + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 8dJzE + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + ztm: qegfb80 + name: 0BIfuN +spec: + maxReplicas: 292 + metrics: + - resource: + name: cpu + target: + averageUtilization: 255 + type: Utilization + type: Resource + - resource: + name: memory + target: + averageUtilization: 99 + type: Utilization + type: Resource + minReplicas: 381 + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: 0BIfuN +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "0BIfuN-test-connection" + namespace: "default" + labels: + 0HYkOrz: JCwpSW + 0TgDztQSY: P + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: 8dJzE + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + ztm: qegfb80 + annotations: + "helm.sh/hook": test +spec: + imagePullSecrets: + - name: h5x + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['0BIfuN:269'] + restartPolicy: Never + priorityClassName: JhGfjGXQ +-- testdata/console-config-listen-and-target-port.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +--- +# Source: console/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console +stringData: + enterprise-license: "" + kafka-protobuf-git-basicauth-password: "" + kafka-sasl-aws-msk-iam-secret-key: "" + kafka-sasl-password: "" + kafka-schema-registry-password: "" + kafka-schemaregistry-tls-ca: "" + kafka-schemaregistry-tls-cert: "" + kafka-schemaregistry-tls-key: "" + kafka-tls-ca: "" + kafka-tls-cert: "" + kafka-tls-key: "" + login-github-oauth-client-secret: "" + login-github-personal-access-token: "" + login-google-groups-service-account.json: "" + login-google-oauth-client-secret: "" + login-jwt-secret: SECRETKEY + login-oidc-client-secret: "" + login-okta-client-secret: "" + login-okta-directory-api-token: "" + redpanda-admin-api-password: "" + redpanda-admin-api-tls-ca: "" + redpanda-admin-api-tls-cert: "" + redpanda-admin-api-tls-key: "" +type: Opaque +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + server: + listenPort: 3333 +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +spec: + ports: + - name: http + port: 8080 + protocol: TCP + targetPort: 4444 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + type: ClusterIP +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + strategy: {} + template: + metadata: + annotations: + checksum/config: f57fffad24d8562b91b674515ee68bfe758dbbfe634dcd2bb3497934f70538c9 + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + spec: + affinity: {} + automountServiceAccountToken: true + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: LOGIN_JWTSECRET + valueFrom: + secretKeyRef: + key: login-jwt-secret + name: console + envFrom: [] + image: docker.redpanda.com/redpandadata/console:v2.7.0 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 0 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: console + ports: + - containerPort: 3333 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: {} + securityContext: + runAsNonRoot: true + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: /etc/console/secrets + name: secrets + readOnly: true + imagePullSecrets: [] + initContainers: [] + nodeSelector: {} + priorityClassName: "" + securityContext: + fsGroup: 99 + runAsUser: 99 + serviceAccountName: console + tolerations: [] + topologySpreadConstraints: [] + volumes: + - configMap: + name: console + name: configs + - name: secrets + secret: + secretName: console +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "console-test-connection" + namespace: "default" + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['console:8080'] + restartPolicy: Never + priorityClassName: +-- testdata/console-config-listen-port.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +--- +# Source: console/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console +stringData: + enterprise-license: "" + kafka-protobuf-git-basicauth-password: "" + kafka-sasl-aws-msk-iam-secret-key: "" + kafka-sasl-password: "" + kafka-schema-registry-password: "" + kafka-schemaregistry-tls-ca: "" + kafka-schemaregistry-tls-cert: "" + kafka-schemaregistry-tls-key: "" + kafka-tls-ca: "" + kafka-tls-cert: "" + kafka-tls-key: "" + login-github-oauth-client-secret: "" + login-github-personal-access-token: "" + login-google-groups-service-account.json: "" + login-google-oauth-client-secret: "" + login-jwt-secret: SECRETKEY + login-oidc-client-secret: "" + login-okta-client-secret: "" + login-okta-directory-api-token: "" + redpanda-admin-api-password: "" + redpanda-admin-api-tls-ca: "" + redpanda-admin-api-tls-cert: "" + redpanda-admin-api-tls-key: "" +type: Opaque +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + server: + listenPort: 3333 +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +spec: + ports: + - name: http + port: 8080 + protocol: TCP + targetPort: 0 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + type: ClusterIP +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + strategy: {} + template: + metadata: + annotations: + checksum/config: f57fffad24d8562b91b674515ee68bfe758dbbfe634dcd2bb3497934f70538c9 + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + spec: + affinity: {} + automountServiceAccountToken: true + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: LOGIN_JWTSECRET + valueFrom: + secretKeyRef: + key: login-jwt-secret + name: console + envFrom: [] + image: docker.redpanda.com/redpandadata/console:v2.7.0 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 0 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: console + ports: + - containerPort: 3333 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: {} + securityContext: + runAsNonRoot: true + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: /etc/console/secrets + name: secrets + readOnly: true + imagePullSecrets: [] + initContainers: [] + nodeSelector: {} + priorityClassName: "" + securityContext: + fsGroup: 99 + runAsUser: 99 + serviceAccountName: console + tolerations: [] + topologySpreadConstraints: [] + volumes: + - configMap: + name: console + name: configs + - name: secrets + secret: + secretName: console +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "console-test-connection" + namespace: "default" + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['console:8080'] + restartPolicy: Never + priorityClassName: +-- testdata/console-with-role-bindings.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +--- +# Source: console/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console +stringData: + enterprise-license: "" + kafka-protobuf-git-basicauth-password: "" + kafka-sasl-aws-msk-iam-secret-key: "" + kafka-sasl-password: "" + kafka-schema-registry-password: "" + kafka-schemaregistry-tls-ca: "" + kafka-schemaregistry-tls-cert: "" + kafka-schemaregistry-tls-key: "" + kafka-tls-ca: "" + kafka-tls-cert: "" + kafka-tls-key: "" + login-github-oauth-client-secret: "" + login-github-personal-access-token: "" + login-google-groups-service-account.json: "" + login-google-oauth-client-secret: "" + login-jwt-secret: SECRETKEY + login-oidc-client-secret: "" + login-okta-client-secret: "" + login-okta-directory-api-token: "" + redpanda-admin-api-password: "" + redpanda-admin-api-tls-ca: "" + redpanda-admin-api-tls-cert: "" + redpanda-admin-api-tls-key: "" +type: Opaque +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} + role-bindings.yaml: |- + roleBindings: + - metadata: + name: Redpanda POC + roleName: admin + subjects: + - kind: user + name: e2euser + provider: Plain +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +spec: + ports: + - name: http + port: 8080 + protocol: TCP + targetPort: 0 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + type: ClusterIP +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + strategy: {} + template: + metadata: + annotations: + checksum/config: fb8e6e138b819f5ea3ae5c413e14f624501b139f2294e15c4f188ec463049755 + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + spec: + affinity: {} + automountServiceAccountToken: true + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: LOGIN_JWTSECRET + valueFrom: + secretKeyRef: + key: login-jwt-secret + name: console + envFrom: [] + image: docker.redpanda.com/redpandadata/console:v2.7.0 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 0 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: console + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: {} + securityContext: + runAsNonRoot: true + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: /etc/console/secrets + name: secrets + readOnly: true + imagePullSecrets: [] + initContainers: [] + nodeSelector: {} + priorityClassName: "" + securityContext: + fsGroup: 99 + runAsUser: 99 + serviceAccountName: console + tolerations: [] + topologySpreadConstraints: [] + volumes: + - configMap: + name: console + name: configs + - name: secrets + secret: + secretName: console +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "console-test-connection" + namespace: "default" + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['console:8080'] + restartPolicy: Never + priorityClassName: +-- testdata/console-with-roles-and-bindings.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +--- +# Source: console/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console +stringData: + enterprise-license: "" + kafka-protobuf-git-basicauth-password: "" + kafka-sasl-aws-msk-iam-secret-key: "" + kafka-sasl-password: "" + kafka-schema-registry-password: "" + kafka-schemaregistry-tls-ca: "" + kafka-schemaregistry-tls-cert: "" + kafka-schemaregistry-tls-key: "" + kafka-tls-ca: "" + kafka-tls-cert: "" + kafka-tls-key: "" + login-github-oauth-client-secret: "" + login-github-personal-access-token: "" + login-google-groups-service-account.json: "" + login-google-oauth-client-secret: "" + login-jwt-secret: SECRETKEY + login-oidc-client-secret: "" + login-okta-client-secret: "" + login-okta-directory-api-token: "" + redpanda-admin-api-password: "" + redpanda-admin-api-tls-ca: "" + redpanda-admin-api-tls-cert: "" + redpanda-admin-api-tls-key: "" +type: Opaque +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} + role-bindings.yaml: |- + roleBindings: + - metadata: + name: Redpanda POC + roleName: admin + subjects: + - kind: user + name: e2euser + provider: Plain + roles.yaml: |- + roles: + - name: my-role + permissions: + - allowedActions: + - '*' + excludes: + - '*' + includes: + - '*' + resource: 1234 +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +spec: + ports: + - name: http + port: 8080 + protocol: TCP + targetPort: 0 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + type: ClusterIP +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + strategy: {} + template: + metadata: + annotations: + checksum/config: a586a304567f15fd4a79d95e15044439368fd8985e42a1a93cdcb6d0b540ed57 + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + spec: + affinity: {} + automountServiceAccountToken: true + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: LOGIN_JWTSECRET + valueFrom: + secretKeyRef: + key: login-jwt-secret + name: console + envFrom: [] + image: docker.redpanda.com/redpandadata/console:v2.7.0 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 0 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: console + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: {} + securityContext: + runAsNonRoot: true + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: /etc/console/secrets + name: secrets + readOnly: true + imagePullSecrets: [] + initContainers: [] + nodeSelector: {} + priorityClassName: "" + securityContext: + fsGroup: 99 + runAsUser: 99 + serviceAccountName: console + tolerations: [] + topologySpreadConstraints: [] + volumes: + - configMap: + name: console + name: configs + - name: secrets + secret: + secretName: console +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "console-test-connection" + namespace: "default" + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['console:8080'] + restartPolicy: Never + priorityClassName: +-- testdata/console-with-roles.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +--- +# Source: console/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console +stringData: + enterprise-license: "" + kafka-protobuf-git-basicauth-password: "" + kafka-sasl-aws-msk-iam-secret-key: "" + kafka-sasl-password: "" + kafka-schema-registry-password: "" + kafka-schemaregistry-tls-ca: "" + kafka-schemaregistry-tls-cert: "" + kafka-schemaregistry-tls-key: "" + kafka-tls-ca: "" + kafka-tls-cert: "" + kafka-tls-key: "" + login-github-oauth-client-secret: "" + login-github-personal-access-token: "" + login-google-groups-service-account.json: "" + login-google-oauth-client-secret: "" + login-jwt-secret: SECRETKEY + login-oidc-client-secret: "" + login-okta-client-secret: "" + login-okta-directory-api-token: "" + redpanda-admin-api-password: "" + redpanda-admin-api-tls-ca: "" + redpanda-admin-api-tls-cert: "" + redpanda-admin-api-tls-key: "" +type: Opaque +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} + roles.yaml: |- + roles: + - name: my-role + permissions: + - allowedActions: + - '*' + excludes: + - '*' + includes: + - '*' + resource: 1234 +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +spec: + ports: + - name: http + port: 8080 + protocol: TCP + targetPort: 0 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + type: ClusterIP +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + strategy: {} + template: + metadata: + annotations: + checksum/config: 1afc8dfaddbbe103d0707800bfc71b4cc8f14e12334b3e22484d2b73ef5d57c0 + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + spec: + affinity: {} + automountServiceAccountToken: true + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: LOGIN_JWTSECRET + valueFrom: + secretKeyRef: + key: login-jwt-secret + name: console + envFrom: [] + image: docker.redpanda.com/redpandadata/console:v2.7.0 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 0 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: console + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: {} + securityContext: + runAsNonRoot: true + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: /etc/console/secrets + name: secrets + readOnly: true + imagePullSecrets: [] + initContainers: [] + nodeSelector: {} + priorityClassName: "" + securityContext: + fsGroup: 99 + runAsUser: 99 + serviceAccountName: console + tolerations: [] + topologySpreadConstraints: [] + volumes: + - configMap: + name: console + name: configs + - name: secrets + secret: + secretName: console +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "console-test-connection" + namespace: "default" + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['console:8080'] + restartPolicy: Never + priorityClassName: +-- testdata/custom-tag-no-registry.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +--- +# Source: console/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console +stringData: + enterprise-license: "" + kafka-protobuf-git-basicauth-password: "" + kafka-sasl-aws-msk-iam-secret-key: "" + kafka-sasl-password: "" + kafka-schema-registry-password: "" + kafka-schemaregistry-tls-ca: "" + kafka-schemaregistry-tls-cert: "" + kafka-schemaregistry-tls-key: "" + kafka-tls-ca: "" + kafka-tls-cert: "" + kafka-tls-key: "" + login-github-oauth-client-secret: "" + login-github-personal-access-token: "" + login-google-groups-service-account.json: "" + login-google-oauth-client-secret: "" + login-jwt-secret: SECRETKEY + login-oidc-client-secret: "" + login-okta-client-secret: "" + login-okta-directory-api-token: "" + redpanda-admin-api-password: "" + redpanda-admin-api-tls-ca: "" + redpanda-admin-api-tls-cert: "" + redpanda-admin-api-tls-key: "" +type: Opaque +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +spec: + ports: + - name: http + port: 8080 + protocol: TCP + targetPort: 0 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + type: ClusterIP +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + strategy: {} + template: + metadata: + annotations: + checksum/config: 4f717eb67ef3f4c7e8737af0264bfe0922c76494c9ee31f7f52c63a13b02de86 + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + spec: + affinity: {} + automountServiceAccountToken: true + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: LOGIN_JWTSECRET + valueFrom: + secretKeyRef: + key: login-jwt-secret + name: console + envFrom: [] + image: redpandadata/console:my-custom-tag + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 0 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: console + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: {} + securityContext: + runAsNonRoot: true + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: /etc/console/secrets + name: secrets + readOnly: true + imagePullSecrets: [] + initContainers: [] + nodeSelector: {} + priorityClassName: "" + securityContext: + fsGroup: 99 + runAsUser: 99 + serviceAccountName: console + tolerations: [] + topologySpreadConstraints: [] + volumes: + - configMap: + name: console + name: configs + - name: secrets + secret: + secretName: console +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "console-test-connection" + namespace: "default" + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['console:8080'] + restartPolicy: Never + priorityClassName: +-- testdata/default-values.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +--- +# Source: console/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console +stringData: + enterprise-license: "" + kafka-protobuf-git-basicauth-password: "" + kafka-sasl-aws-msk-iam-secret-key: "" + kafka-sasl-password: "" + kafka-schema-registry-password: "" + kafka-schemaregistry-tls-ca: "" + kafka-schemaregistry-tls-cert: "" + kafka-schemaregistry-tls-key: "" + kafka-tls-ca: "" + kafka-tls-cert: "" + kafka-tls-key: "" + login-github-oauth-client-secret: "" + login-github-personal-access-token: "" + login-google-groups-service-account.json: "" + login-google-oauth-client-secret: "" + login-jwt-secret: SECRETKEY + login-oidc-client-secret: "" + login-okta-client-secret: "" + login-okta-directory-api-token: "" + redpanda-admin-api-password: "" + redpanda-admin-api-tls-ca: "" + redpanda-admin-api-tls-cert: "" + redpanda-admin-api-tls-key: "" +type: Opaque +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +spec: + ports: + - name: http + port: 8080 + protocol: TCP + targetPort: 0 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + type: ClusterIP +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + strategy: {} + template: + metadata: + annotations: + checksum/config: 4f717eb67ef3f4c7e8737af0264bfe0922c76494c9ee31f7f52c63a13b02de86 + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + spec: + affinity: {} + automountServiceAccountToken: true + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: LOGIN_JWTSECRET + valueFrom: + secretKeyRef: + key: login-jwt-secret + name: console + envFrom: [] + image: docker.redpanda.com/redpandadata/console:v2.7.0 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 0 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: console + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: {} + securityContext: + runAsNonRoot: true + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: /etc/console/secrets + name: secrets + readOnly: true + imagePullSecrets: [] + initContainers: [] + nodeSelector: {} + priorityClassName: "" + securityContext: + fsGroup: 99 + runAsUser: 99 + serviceAccountName: console + tolerations: [] + topologySpreadConstraints: [] + volumes: + - configMap: + name: console + name: configs + - name: secrets + secret: + secretName: console +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "console-test-connection" + namespace: "default" + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['console:8080'] + restartPolicy: Never + priorityClassName: +-- testdata/extra-init-containers.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +--- +# Source: console/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console +stringData: + enterprise-license: "" + kafka-protobuf-git-basicauth-password: "" + kafka-sasl-aws-msk-iam-secret-key: "" + kafka-sasl-password: "" + kafka-schema-registry-password: "" + kafka-schemaregistry-tls-ca: "" + kafka-schemaregistry-tls-cert: "" + kafka-schemaregistry-tls-key: "" + kafka-tls-ca: "" + kafka-tls-cert: "" + kafka-tls-key: "" + login-github-oauth-client-secret: "" + login-github-personal-access-token: "" + login-google-groups-service-account.json: "" + login-google-oauth-client-secret: "" + login-jwt-secret: SECRETKEY + login-oidc-client-secret: "" + login-okta-client-secret: "" + login-okta-directory-api-token: "" + redpanda-admin-api-password: "" + redpanda-admin-api-tls-ca: "" + redpanda-admin-api-tls-cert: "" + redpanda-admin-api-tls-key: "" +type: Opaque +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +spec: + ports: + - name: http + port: 8080 + protocol: TCP + targetPort: 0 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + type: ClusterIP +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + strategy: {} + template: + metadata: + annotations: + checksum/config: 4f717eb67ef3f4c7e8737af0264bfe0922c76494c9ee31f7f52c63a13b02de86 + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + spec: + affinity: {} + automountServiceAccountToken: true + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: LOGIN_JWTSECRET + valueFrom: + secretKeyRef: + key: login-jwt-secret + name: console + envFrom: [] + image: docker.redpanda.com/redpandadata/console:v2.7.0 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 0 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: console + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: {} + securityContext: + runAsNonRoot: true + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: /etc/console/secrets + name: secrets + readOnly: true + imagePullSecrets: [] + initContainers: + - args: + - |- + set -xe + echo "Hello 3!" + command: + - /bin/bash + - -c + image: mintel/docker-alpine-bash-curl-jq:latest + name: test-init-container + nodeSelector: {} + priorityClassName: "" + securityContext: + fsGroup: 99 + runAsUser: 99 + serviceAccountName: console + tolerations: [] + topologySpreadConstraints: [] + volumes: + - configMap: + name: console + name: configs + - name: secrets + secret: + secretName: console +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "console-test-connection" + namespace: "default" + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['console:8080'] + restartPolicy: Never + priorityClassName: +-- testdata/ingress-templating.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +--- +# Source: console/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console +stringData: + enterprise-license: "" + kafka-protobuf-git-basicauth-password: "" + kafka-sasl-aws-msk-iam-secret-key: "" + kafka-sasl-password: "" + kafka-schema-registry-password: "" + kafka-schemaregistry-tls-ca: "" + kafka-schemaregistry-tls-cert: "" + kafka-schemaregistry-tls-key: "" + kafka-tls-ca: "" + kafka-tls-cert: "" + kafka-tls-key: "" + login-github-oauth-client-secret: "" + login-github-personal-access-token: "" + login-google-groups-service-account.json: "" + login-google-oauth-client-secret: "" + login-jwt-secret: SECRETKEY + login-oidc-client-secret: "" + login-okta-client-secret: "" + login-okta-directory-api-token: "" + redpanda-admin-api-password: "" + redpanda-admin-api-tls-ca: "" + redpanda-admin-api-tls-cert: "" + redpanda-admin-api-tls-key: "" +type: Opaque +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +spec: + ports: + - name: http + port: 8080 + protocol: TCP + targetPort: 0 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + type: ClusterIP +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + strategy: {} + template: + metadata: + annotations: + checksum/config: 4f717eb67ef3f4c7e8737af0264bfe0922c76494c9ee31f7f52c63a13b02de86 + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + spec: + affinity: {} + automountServiceAccountToken: true + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: LOGIN_JWTSECRET + valueFrom: + secretKeyRef: + key: login-jwt-secret + name: console + envFrom: [] + image: docker.redpanda.com/redpandadata/console:v2.7.0 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 0 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: console + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: {} + securityContext: + runAsNonRoot: true + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: /etc/console/secrets + name: secrets + readOnly: true + imagePullSecrets: [] + initContainers: [] + nodeSelector: {} + priorityClassName: "" + securityContext: + fsGroup: 99 + runAsUser: 99 + serviceAccountName: console + tolerations: [] + topologySpreadConstraints: [] + volumes: + - configMap: + name: console + name: configs + - name: secrets + secret: + secretName: console +--- +# Source: console/templates/ingress.yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + annotations: + ingress: test + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console +spec: + ingressClassName: null + rules: + - host: '"a-host"' + http: + paths: + - backend: + service: + name: console + port: + number: 8080 + path: / + pathType: Exact + tls: + - hosts: + - '"blah"' + secretName: my-secret +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "console-test-connection" + namespace: "default" + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['console:8080'] + restartPolicy: Never + priorityClassName: +-- testdata/no-registry.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +--- +# Source: console/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console +stringData: + enterprise-license: "" + kafka-protobuf-git-basicauth-password: "" + kafka-sasl-aws-msk-iam-secret-key: "" + kafka-sasl-password: "" + kafka-schema-registry-password: "" + kafka-schemaregistry-tls-ca: "" + kafka-schemaregistry-tls-cert: "" + kafka-schemaregistry-tls-key: "" + kafka-tls-ca: "" + kafka-tls-cert: "" + kafka-tls-key: "" + login-github-oauth-client-secret: "" + login-github-personal-access-token: "" + login-google-groups-service-account.json: "" + login-google-oauth-client-secret: "" + login-jwt-secret: SECRETKEY + login-oidc-client-secret: "" + login-okta-client-secret: "" + login-okta-directory-api-token: "" + redpanda-admin-api-password: "" + redpanda-admin-api-tls-ca: "" + redpanda-admin-api-tls-cert: "" + redpanda-admin-api-tls-key: "" +type: Opaque +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +spec: + ports: + - name: http + port: 8080 + protocol: TCP + targetPort: 0 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + type: ClusterIP +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + strategy: {} + template: + metadata: + annotations: + checksum/config: 4f717eb67ef3f4c7e8737af0264bfe0922c76494c9ee31f7f52c63a13b02de86 + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + spec: + affinity: {} + automountServiceAccountToken: true + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: LOGIN_JWTSECRET + valueFrom: + secretKeyRef: + key: login-jwt-secret + name: console + envFrom: [] + image: redpandadata/console:v2.7.0 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 0 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: console + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: {} + securityContext: + runAsNonRoot: true + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: /etc/console/secrets + name: secrets + readOnly: true + imagePullSecrets: [] + initContainers: [] + nodeSelector: {} + priorityClassName: "" + securityContext: + fsGroup: 99 + runAsUser: 99 + serviceAccountName: console + tolerations: [] + topologySpreadConstraints: [] + volumes: + - configMap: + name: console + name: configs + - name: secrets + secret: + secretName: console +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "console-test-connection" + namespace: "default" + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['console:8080'] + restartPolicy: Never + priorityClassName: +-- testdata/service-nodeport.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +--- +# Source: console/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console +stringData: + enterprise-license: "" + kafka-protobuf-git-basicauth-password: "" + kafka-sasl-aws-msk-iam-secret-key: "" + kafka-sasl-password: "" + kafka-schema-registry-password: "" + kafka-schemaregistry-tls-ca: "" + kafka-schemaregistry-tls-cert: "" + kafka-schemaregistry-tls-key: "" + kafka-tls-ca: "" + kafka-tls-cert: "" + kafka-tls-key: "" + login-github-oauth-client-secret: "" + login-github-personal-access-token: "" + login-google-groups-service-account.json: "" + login-google-oauth-client-secret: "" + login-jwt-secret: SECRETKEY + login-oidc-client-secret: "" + login-okta-client-secret: "" + login-okta-directory-api-token: "" + redpanda-admin-api-password: "" + redpanda-admin-api-tls-ca: "" + redpanda-admin-api-tls-cert: "" + redpanda-admin-api-tls-key: "" +type: Opaque +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +spec: + ports: + - name: http + port: 8080 + protocol: TCP + targetPort: 2000 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + type: NodePort +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + strategy: {} + template: + metadata: + annotations: + checksum/config: 4f717eb67ef3f4c7e8737af0264bfe0922c76494c9ee31f7f52c63a13b02de86 + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + spec: + affinity: {} + automountServiceAccountToken: true + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: LOGIN_JWTSECRET + valueFrom: + secretKeyRef: + key: login-jwt-secret + name: console + envFrom: [] + image: docker.redpanda.com/redpandadata/console:v2.7.0 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 0 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: console + ports: + - containerPort: 2000 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: {} + securityContext: + runAsNonRoot: true + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: /etc/console/secrets + name: secrets + readOnly: true + imagePullSecrets: [] + initContainers: [] + nodeSelector: {} + priorityClassName: "" + securityContext: + fsGroup: 99 + runAsUser: 99 + serviceAccountName: console + tolerations: [] + topologySpreadConstraints: [] + volumes: + - configMap: + name: console + name: configs + - name: secrets + secret: + secretName: console +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "console-test-connection" + namespace: "default" + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['console:8080'] + restartPolicy: Never + priorityClassName: +-- testdata/service-with-nodeport.yaml.golden -- +--- +# Source: console/templates/serviceaccount.yaml +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +--- +# Source: console/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console +stringData: + enterprise-license: "" + kafka-protobuf-git-basicauth-password: "" + kafka-sasl-aws-msk-iam-secret-key: "" + kafka-sasl-password: "" + kafka-schema-registry-password: "" + kafka-schemaregistry-tls-ca: "" + kafka-schemaregistry-tls-cert: "" + kafka-schemaregistry-tls-key: "" + kafka-tls-ca: "" + kafka-tls-cert: "" + kafka-tls-key: "" + login-github-oauth-client-secret: "" + login-github-personal-access-token: "" + login-google-groups-service-account.json: "" + login-google-oauth-client-secret: "" + login-jwt-secret: SECRETKEY + login-oidc-client-secret: "" + login-okta-client-secret: "" + login-okta-directory-api-token: "" + redpanda-admin-api-password: "" + redpanda-admin-api-tls-ca: "" + redpanda-admin-api-tls-cert: "" + redpanda-admin-api-tls-key: "" +type: Opaque +--- +# Source: console/templates/configmap.yaml +apiVersion: v1 +data: + config.yaml: | + # from .Values.console.config + {} +kind: ConfigMap +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console +--- +# Source: console/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + annotations: + hello: world + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +spec: + ports: + - name: http + nodePort: 1000 + port: 8080 + protocol: TCP + targetPort: 0 + selector: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + type: NodePort +--- +# Source: console/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: {} + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + name: console + namespace: default +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + strategy: {} + template: + metadata: + annotations: + checksum/config: 4f717eb67ef3f4c7e8737af0264bfe0922c76494c9ee31f7f52c63a13b02de86 + creationTimestamp: null + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/name: console + spec: + affinity: {} + automountServiceAccountToken: true + containers: + - args: + - --config.filepath=/etc/console/configs/config.yaml + command: null + env: + - name: LOGIN_JWTSECRET + valueFrom: + secretKeyRef: + key: login-jwt-secret + name: console + envFrom: [] + image: docker.redpanda.com/redpandadata/console:v2.7.0 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 0 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: console + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /admin/health + port: http + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: {} + securityContext: + runAsNonRoot: true + volumeMounts: + - mountPath: /etc/console/configs + name: configs + readOnly: true + - mountPath: /etc/console/secrets + name: secrets + readOnly: true + imagePullSecrets: [] + initContainers: [] + nodeSelector: {} + priorityClassName: "" + securityContext: + fsGroup: 99 + runAsUser: 99 + serviceAccountName: console + tolerations: [] + topologySpreadConstraints: [] + volumes: + - configMap: + name: console + name: configs + - name: secrets + secret: + secretName: console +--- +# Source: console/templates/tests/test-connection.yaml +apiVersion: v1 +kind: Pod +metadata: + name: "console-test-connection" + namespace: "default" + labels: + app.kubernetes.io/instance: console + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: console + app.kubernetes.io/version: v2.7.0 + helm.sh/chart: console-0.7.29 + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['console:8080'] + restartPolicy: Never + priorityClassName: diff --git a/charts/redpanda/redpanda/5.9.2/charts/console/testdata/template-cases.txtar b/charts/redpanda/redpanda/5.9.2/charts/console/testdata/template-cases.txtar new file mode 100644 index 0000000000..804cca4a6b --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/console/testdata/template-cases.txtar @@ -0,0 +1,136 @@ +Manually crafted test cases for TestTemplate +-- default-values -- +# Intentionally left blank. (test of default values) + +-- console-with-roles -- +# console.roles specified +console: + roles: + - name: my-role + permissions: + - resource: 1234 + includes: + - "*" + excludes: + - "*" + allowedActions: ["*"] + +-- console-with-role-bindings -- +# console.roleBindings specified +console: + roleBindings: + - roleName: admin + metadata: + name: Redpanda POC + subjects: + - kind: user + provider: Plain + name: "e2euser" + +-- console-with-roles-and-bindings -- +# console.roles and console.roleBindings both specified +console: + roles: + - name: my-role + permissions: + - resource: 1234 + includes: + - "*" + excludes: + - "*" + allowedActions: ["*"] + roleBindings: + - roleName: admin + metadata: + name: Redpanda POC + subjects: + - kind: user + provider: Plain + name: "e2euser" + +-- autoscaling-nulls -- +# Autoscaling w/ explicit nulls +autoscaling: + enabled: true + targetCPUUtilizationPercentage: null + targetMemoryUtilizationPercentage: null + +-- autoscaling-cpu -- +# Autoscaling w/ memory no cpu +autoscaling: + enabled: true + targetCPUUtilizationPercentage: null + targetMemoryUtilizationPercentage: 10 + +-- autoscaling-memory -- +# Autoscaling w/ cpu no memory +autoscaling: + enabled: true + targetCPUUtilizationPercentage: 14 + targetMemoryUtilizationPercentage: null + +-- service-nodeport -- +# Service type NodePort +service: + type: "NodePort" + targetPort: 2000 + +-- service-with-nodeport -- +# Service w/ NodePort +service: + type: "NodePort" + nodePort: 1000 + annotations: + hello: world + +-- ingress-templating -- +ingress: + enabled: true + annotations: + ingress: test + hosts: + - host: '{{ "a-host" | quote }}' + paths: + - path: / + pathType: Exact + tls: + - secretName: my-secret + hosts: + - '{{ "blah" | quote }}' + +-- no-registry -- +image: + registry: "" + +-- custom-tag-no-registry -- +image: + registry: "" + tag: my-custom-tag + +-- console-config-listen-port -- +console: + config: + server: + listenPort: 3333 + +-- console-config-listen-and-target-port -- +service: + targetPort: 4444 +console: + config: + server: + listenPort: 3333 + +-- extra-init-containers -- +# NB: Many of the generated tests have an invalid value for extraInitContainers +# as it's just a string and render an error message. This case showcases what +# valid YAML looks like. +initContainers: + extraInitContainers: |- + - name: {{ "test-init-container" | quote }} + image: "mintel/docker-alpine-bash-curl-jq:latest" + command: [ "/bin/bash", "-c" ] + args: + - | + set -xe + echo "Hello {{ add 1 2 }}!" diff --git a/charts/redpanda/redpanda/5.9.2/charts/console/values.go b/charts/redpanda/redpanda/5.9.2/charts/console/values.go new file mode 100644 index 0000000000..0a855af598 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/console/values.go @@ -0,0 +1,215 @@ +// +gotohelm:ignore=true +package console + +import ( + _ "embed" + + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + networkingv1 "k8s.io/api/networking/v1" +) + +var ( + //go:embed values.yaml + DefaultValuesYAML []byte + + //go:embed values.schema.json + ValuesSchemaJSON []byte +) + +type Values struct { + ReplicaCount int32 `json:"replicaCount"` + Image Image `json:"image"` + ImagePullSecrets []corev1.LocalObjectReference `json:"imagePullSecrets"` + NameOverride string `json:"nameOverride"` + FullnameOverride string `json:"fullnameOverride"` + AutomountServiceAccountToken bool `json:"automountServiceAccountToken"` + ServiceAccount ServiceAccountConfig `json:"serviceAccount"` + CommonLabels map[string]string `json:"commonLabels"` + Annotations map[string]string `json:"annotations"` + PodAnnotations map[string]string `json:"podAnnotations"` + PodLabels map[string]string `json:"podLabels"` + PodSecurityContext corev1.PodSecurityContext `json:"podSecurityContext"` + SecurityContext corev1.SecurityContext `json:"securityContext"` + Service ServiceConfig `json:"service"` + Ingress IngressConfig `json:"ingress"` + Resources corev1.ResourceRequirements `json:"resources"` + Autoscaling AutoScaling `json:"autoscaling"` + NodeSelector map[string]string `json:"nodeSelector"` + Tolerations []corev1.Toleration `json:"tolerations"` + Affinity corev1.Affinity `json:"affinity"` + TopologySpreadConstraints []corev1.TopologySpreadConstraint `json:"topologySpreadConstraints"` + PriorityClassName string `json:"priorityClassName"` + Console Console `json:"console"` + ExtraEnv []corev1.EnvVar `json:"extraEnv"` + ExtraEnvFrom []corev1.EnvFromSource `json:"extraEnvFrom"` + ExtraVolumes []corev1.Volume `json:"extraVolumes"` + ExtraVolumeMounts []corev1.VolumeMount `json:"extraVolumeMounts"` + ExtraContainers []corev1.Container `json:"extraContainers"` + InitContainers InitContainers `json:"initContainers"` + SecretMounts []SecretMount `json:"secretMounts"` + Secret SecretConfig `json:"secret"` + Enterprise Enterprise `json:"enterprise"` + LivenessProbe corev1.Probe `json:"livenessProbe"` + ReadinessProbe corev1.Probe `json:"readinessProbe"` + ConfigMap Creatable `json:"configmap"` + Deployment DeploymentConfig `json:"deployment"` + Strategy appsv1.DeploymentStrategy `json:"strategy"` + Tests Enableable `json:"tests"` +} + +type DeploymentConfig struct { + Create bool `json:"create"` + Command []string `json:"command,omitempty"` + ExtraArgs []string `json:"extraArgs,omitempty"` +} + +type Enterprise struct { + LicenseSecretRef SecretKeyRef `json:"licenseSecretRef"` +} + +type ServiceAccountConfig struct { + Create bool `json:"create"` + AutomountServiceAccountToken bool `json:"automountServiceAccountToken"` + Annotations map[string]string `json:"annotations"` + Name string `json:"name"` +} + +type ServiceConfig struct { + Type corev1.ServiceType `json:"type"` + Port int32 `json:"port"` + NodePort *int32 `json:"nodePort,omitempty"` + TargetPort *int32 `json:"targetPort"` + Annotations map[string]string `json:"annotations"` +} + +type IngressConfig struct { + Enabled bool `json:"enabled"` + ClassName *string `json:"className"` + Annotations map[string]string `json:"annotations"` + Hosts []IngressHost `json:"hosts"` + TLS []networkingv1.IngressTLS `json:"tls"` +} + +type IngressHost struct { + Host string `json:"host"` + Paths []IngressPath `json:"paths"` +} + +type IngressPath struct { + Path string `json:"path"` + PathType *networkingv1.PathType `json:"pathType"` +} + +type AutoScaling struct { + Enabled bool `json:"enabled"` + MinReplicas int32 `json:"minReplicas"` + MaxReplicas int32 `json:"maxReplicas"` + TargetCPUUtilizationPercentage *int32 `json:"targetCPUUtilizationPercentage"` + TargetMemoryUtilizationPercentage *int32 `json:"targetMemoryUtilizationPercentage,omitempty"` +} + +// TODO the typing of these values are unclear. All of them get marshalled to +// YAML and then run through tpl which gives no indication of what they are +// aside from YAML marshal-able. +type Console struct { + Config map[string]any `json:"config"` + Roles []map[string]any `json:"roles,omitempty"` + RoleBindings []map[string]any `json:"roleBindings,omitempty"` +} + +type InitContainers struct { + ExtraInitContainers *string `json:"extraInitContainers"` // XXX Templated YAML +} + +type SecretConfig struct { + Create bool `json:"create"` + Kafka KafkaSecrets `json:"kafka"` + Login LoginSecrets `json:"login"` + Enterprise EnterpriseSecrets `json:"enterprise"` + Redpanda RedpandaSecrets `json:"redpanda"` +} + +type SecretMount struct { + Name string `json:"name"` + SecretName string `json:"secretName"` + Path string `json:"path"` + SubPath *string `json:"subPath,omitempty"` + DefaultMode *int32 `json:"defaultMode"` +} + +type KafkaSecrets struct { + SASLPassword *string `json:"saslPassword,omitempty"` + AWSMSKIAMSecretKey *string `json:"awsMskIamSecretKey,omitempty"` + TLSCA *string `json:"tlsCa,omitempty"` + TLSCert *string `json:"tlsCert,omitempty"` + TLSKey *string `json:"tlsKey,omitempty"` + TLSPassphrase *string `json:"tlsPassphrase,omitempty"` + SchemaRegistryPassword *string `json:"schemaRegistryPassword,omitempty"` + SchemaRegistryTLSCA *string `json:"schemaRegistryTlsCa,omitempty"` + SchemaRegistryTLSCert *string `json:"schemaRegistryTlsCert,omitempty"` + SchemaRegistryTLSKey *string `json:"schemaRegistryTlsKey,omitempty"` + ProtobufGitBasicAuthPassword *string `json:"protobufGitBasicAuthPassword,omitempty"` +} + +type LoginSecrets struct { + JWTSecret string `json:"jwtSecret"` + Google GoogleLoginSecrets `json:"google"` + Github GithubLoginSecrets `json:"github"` + Okta OktaLoginSecrets `json:"okta"` + OIDC OIDCLoginSecrets `json:"oidc"` +} + +type GoogleLoginSecrets struct { + ClientSecret *string `json:"clientSecret,omitempty"` + GroupsServiceAccount *string `json:"groupsServiceAccount,omitempty"` +} + +type GithubLoginSecrets struct { + ClientSecret *string `json:"clientSecret,omitempty"` + PersonalAccessToken *string `json:"personalAccessToken,omitempty"` +} + +type OktaLoginSecrets struct { + ClientSecret *string `json:"clientSecret,omitempty"` + DirectoryAPIToken *string `json:"directoryApiToken,omitempty"` +} + +type OIDCLoginSecrets struct { + ClientSecret *string `json:"clientSecret,omitempty"` +} + +type EnterpriseSecrets struct { + License *string `json:"License,omitempty"` +} + +type RedpandaSecrets struct { + AdminAPI RedpandaAdminAPISecrets `json:"adminApi"` +} + +type RedpandaAdminAPISecrets struct { + Password *string `json:"password,omitempty"` + TLSCA *string `json:"tlsCa,omitempty"` + TLSCert *string `json:"tlsCert,omitempty"` + TLSKey *string `json:"tlsKey,omitempty"` +} + +type SecretKeyRef struct { + Name string `json:"name"` + Key string `json:"key"` +} + +type Enableable struct { + Enabled bool `json:"enabled"` +} + +type Creatable struct { + Create bool `json:"create"` +} + +type Image struct { + Registry string `json:"registry"` + Repository string `json:"repository"` + PullPolicy corev1.PullPolicy `json:"pullPolicy"` + Tag *string `json:"tag"` +} diff --git a/charts/redpanda/redpanda/5.9.2/charts/console/values.schema.json b/charts/redpanda/redpanda/5.9.2/charts/console/values.schema.json new file mode 100644 index 0000000000..f4f369e98a --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/console/values.schema.json @@ -0,0 +1,323 @@ +{ + "$schema": "http://json-schema.org/schema#", + "type": "object", + "required": [ + "image" + ], + "properties": { + "affinity": { + "type": "object" + }, + "autoscaling": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "maxReplicas": { + "type": "integer" + }, + "minReplicas": { + "type": "integer" + }, + "targetCPUUtilizationPercentage": { + "type": "integer" + } + } + }, + "configmap": { + "type": "object", + "properties": { + "create": { + "type": "boolean" + } + } + }, + "console": { + "type": "object" + }, + "deployment": { + "type": "object", + "properties": { + "create": { + "type": "boolean" + } + } + }, + "extraContainers": { + "type": "array" + }, + "extraEnv": { + "type": "array" + }, + "extraEnvFrom": { + "type": "array" + }, + "extraVolumeMounts": { + "type": "array" + }, + "extraVolumes": { + "type": "array" + }, + "fullnameOverride": { + "type": "string" + }, + "image": { + "type": "object", + "required": [ + "repository" + ], + "properties": { + "pullPolicy": { + "type": "string" + }, + "registry": { + "type": "string" + }, + "repository": { + "type": "string", + "minLength": 1 + }, + "tag": { + "type": "string" + } + } + }, + "imagePullSecrets": { + "type": "array" + }, + "ingress": { + "type": "object", + "properties": { + "annotations": { + "type": "object" + }, + "className": { + "type": ["string", "null"] + }, + "enabled": { + "type": "boolean" + }, + "hosts": { + "type": "array", + "items": { + "type": "object", + "properties": { + "host": { + "type": "string" + }, + "paths": { + "type": "array", + "items": { + "type": "object", + "properties": { + "path": { + "type": "string" + }, + "pathType": { + "type": "string" + } + } + } + } + } + } + }, + "tls": { + "type": "array" + } + } + }, + "livenessProbe": { + "type": "object", + "properties": { + "failureThreshold": { + "type": "integer" + }, + "initialDelaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "successThreshold": { + "type": "integer" + }, + "timeoutSeconds": { + "type": "integer" + } + } + }, + "nameOverride": { + "type": "string" + }, + "nodeSelector": { + "type": "object" + }, + "annotations": { + "type": "object" + }, + "podAnnotations": { + "type": "object" + }, + "podSecurityContext": { + "type": "object", + "properties": { + "fsGroup": { + "type": "integer" + }, + "runAsUser": { + "type": "integer" + } + } + }, + "readinessProbe": { + "type": "object", + "properties": { + "failureThreshold": { + "type": "integer" + }, + "initialDelaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "successThreshold": { + "type": "integer" + }, + "timeoutSeconds": { + "type": "integer" + } + } + }, + "replicaCount": { + "type": "integer" + }, + "resources": { + "type": "object" + }, + "secret": { + "type": "object", + "properties": { + "create": { + "type": "boolean" + }, + "enterprise": { + "type": "object" + }, + "kafka": { + "type": "object" + }, + "login": { + "type": "object", + "properties": { + "jwtSecret": { + "type": "string" + }, + "github": { + "type": "object" + }, + "google": { + "type": "object" + }, + "oidc": { + "type": "object" + }, + "okta": { + "type": "object" + } + } + }, + "redpanda": { + "type": "object", + "properties": { + "adminApi": { + "type": "object" + } + } + } + } + }, + "secretMounts": { + "type": "array" + }, + "securityContext": { + "type": "object", + "properties": { + "runAsNonRoot": { + "type": "boolean" + } + } + }, + "service": { + "type": "object", + "properties": { + "annotations": { + "type": "object" + }, + "port": { + "type": "integer" + }, + "nodePort": { + "type": "integer" + }, + "targetPort": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ] + }, + "type": { + "type": "string" + } + } + }, + "automountServiceAccountToken": { + "type": "boolean" + }, + "serviceAccount": { + "type": "object", + "properties": { + "annotations": { + "type": "object" + }, + "create": { + "type": "boolean" + }, + "automountServiceAccountToken": { + "type": "boolean" + }, + "name": { + "type": "string" + } + } + }, + "tolerations": { + "type": "array" + }, + "initContainers": { + "type": "object", + "properties": { + "extraInitContainers": { + "type": "string" + } + } + }, + "strategy": { + "type": "object" + }, + "tests": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + } + } + } + } +} diff --git a/charts/redpanda/redpanda/5.9.2/charts/console/values.yaml b/charts/redpanda/redpanda/5.9.2/charts/console/values.yaml new file mode 100644 index 0000000000..4825fc4876 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/console/values.yaml @@ -0,0 +1,279 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Default values for console. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +replicaCount: 1 + +# -- Redpanda Console Docker image settings. +image: + registry: docker.redpanda.com + # -- Docker repository from which to pull the Redpanda Docker image. + repository: redpandadata/console + # -- The imagePullPolicy. + pullPolicy: IfNotPresent + # -- The Redpanda Console version. + # See DockerHub for: + # [All stable versions](https://hub.docker.com/r/redpandadata/console/tags) + # and [all unstable versions](https://hub.docker.com/r/redpandadata/console-unstable/tags). + # @default -- `Chart.appVersion` + tag: "" + +# -- Pull secrets may be used to provide credentials to image repositories +# See https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ +imagePullSecrets: [] + +# -- Override `console.name` template. +nameOverride: "" +# -- Override `console.fullname` template. +fullnameOverride: "" + +# -- Automount API credentials for the Service Account into the pod. +automountServiceAccountToken: true + +serviceAccount: + # -- Specifies whether a service account should be created. + create: true + # -- Specifies whether a service account should automount API-Credentials + automountServiceAccountToken: true + # -- Annotations to add to the service account. + annotations: {} + # -- The name of the service account to use. + # If not set and `serviceAccount.create` is `true`, + # a name is generated using the `console.fullname` template + name: "" + +# Common labels to add to all the pods +commonLabels: {} + +# -- Annotations to add to the deployment. +annotations: {} + +podAnnotations: {} + +podLabels: {} + +podSecurityContext: + runAsUser: 99 + fsGroup: 99 + +securityContext: + runAsNonRoot: true + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + type: ClusterIP + port: 8080 + # nodePort: 30001 + # -- Override the value in `console.config.server.listenPort` if not `nil` + targetPort: + annotations: {} + +ingress: + enabled: false + className: + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + hosts: + - host: chart-example.local + paths: + - path: / + pathType: ImplementationSpecific + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + +resources: {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as minikube. If you want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 100 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +nodeSelector: {} + +tolerations: [] + +affinity: {} + +topologySpreadConstraints: [] + +# -- PriorityClassName given to Pods. +# For details, +# see the [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#priorityclass). +priorityClassName: "" + +console: + # -- Settings for the `Config.yaml` (required). + # For a reference of configuration settings, + # see the [Redpanda Console documentation](https://docs.redpanda.com/docs/reference/console/config/). + config: {} + # roles: + # roleBindings: + +# -- Additional environment variables for the Redpanda Console Deployment. +extraEnv: [] + # - name: KAFKA_RACKID + # value: "1" + +# -- Additional environment variables for Redpanda Console mapped from Secret or ConfigMap. +extraEnvFrom: [] +# - secretRef: +# name: kowl-config-secret + +# -- Add additional volumes, such as for TLS keys. +extraVolumes: [] +# - name: kafka-certs +# secret: +# secretName: kafka-certs +# - name: config +# configMap: +# name: console-config + +# -- Add additional volume mounts, such as for TLS keys. +extraVolumeMounts: [] +# - name: kafka-certs # Must match the volume name +# mountPath: /etc/kafka/certs +# readOnly: true + +# -- Add additional containers, such as for oauth2-proxy. +extraContainers: [] + +# -- Any initContainers defined should be written here +initContainers: + # -- Additional set of init containers + extraInitContainers: |- +# - name: "test-init-container" +# image: "mintel/docker-alpine-bash-curl-jq:latest" +# command: [ "/bin/bash", "-c" ] +# args: +# - | +# set -xe +# echo "Hello World!" + +# -- SecretMounts is an abstraction to make a Secret available in the container's filesystem. +# Under the hood it creates a volume and a volume mount for the Redpanda Console container. +secretMounts: [] +# - name: kafka-certs +# secretName: kafka-certs +# path: /etc/console/certs +# defaultMode: 0755 + +# -- Create a new Kubernetes Secret for all sensitive configuration inputs. +# Each provided Secret is mounted automatically and made available to the +# Pod. +# If you want to use one or more existing Secrets, +# you can use the `extraEnvFrom` list to mount environment variables from string and secretMounts to mount files such as Certificates from Secrets. +secret: + create: true + + # Secret values in case you want the chart to create a Secret. All Certificates are mounted + # as files and the path to those files are configured through environment variables so + # that Console can automatically pick them up. + # -- Kafka Secrets. + kafka: {} + # saslPassword: + # awsMskIamSecretKey: + # tlsCa: + # tlsCert: + # tlsKey: + # tlsPassphrase: + # schemaRegistryPassword: + # schemaRegistryTlsCa: + # schemaRegistryTlsCert: + # schemaRegistryTlsKey: + # protobufGitBasicAuthPassword + # Enterprise version secrets + # - SSO secrets (Enterprise version). + login: + # Configurable JWT value + jwtSecret: "" + google: {} + # clientSecret: + # groupsServiceAccount: + github: {} + # clientSecret: + # personalAccessToken: + okta: {} + # clientSecret: + # directoryApiToken: + oidc: {} + # clientSecret: + + enterprise: {} + # license: + + redpanda: + adminApi: {} + # password: + # tlsCa: + # tlsCert: + # tlsKey: + +# -- Settings for license key, as an alternative to secret.enterprise when +# a license secret is available +enterprise: + licenseSecretRef: + name: "" + key: "" + +# -- Settings for liveness and readiness probes. +# For details, +# see the [Kubernetes documentation](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes). +livenessProbe: + # initialDelaySeconds: 0 + periodSeconds: 10 + timeoutSeconds: 1 + successThreshold: 1 + failureThreshold: 3 + +readinessProbe: + # -- Grant time to test connectivity to upstream services such as Kafka and Schema Registry. + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 1 + successThreshold: 1 + failureThreshold: 3 + +configmap: + create: true +deployment: + create: true + +strategy: {} + +tests: + enabled: true diff --git a/charts/redpanda/redpanda/5.9.2/charts/console/values_partial.gen.go b/charts/redpanda/redpanda/5.9.2/charts/console/values_partial.gen.go new file mode 100644 index 0000000000..723065a25c --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/charts/console/values_partial.gen.go @@ -0,0 +1,206 @@ +//go:build !generate + +// +gotohelm:ignore=true +// +// Code generated by genpartial DO NOT EDIT. +package console + +import ( + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + networkingv1 "k8s.io/api/networking/v1" +) + +type PartialValues struct { + ReplicaCount *int32 "json:\"replicaCount,omitempty\"" + Image *PartialImage "json:\"image,omitempty\"" + ImagePullSecrets []corev1.LocalObjectReference "json:\"imagePullSecrets,omitempty\"" + NameOverride *string "json:\"nameOverride,omitempty\"" + FullnameOverride *string "json:\"fullnameOverride,omitempty\"" + AutomountServiceAccountToken *bool "json:\"automountServiceAccountToken,omitempty\"" + ServiceAccount *PartialServiceAccountConfig "json:\"serviceAccount,omitempty\"" + CommonLabels map[string]string "json:\"commonLabels,omitempty\"" + Annotations map[string]string "json:\"annotations,omitempty\"" + PodAnnotations map[string]string "json:\"podAnnotations,omitempty\"" + PodLabels map[string]string "json:\"podLabels,omitempty\"" + PodSecurityContext *corev1.PodSecurityContext "json:\"podSecurityContext,omitempty\"" + SecurityContext *corev1.SecurityContext "json:\"securityContext,omitempty\"" + Service *PartialServiceConfig "json:\"service,omitempty\"" + Ingress *PartialIngressConfig "json:\"ingress,omitempty\"" + Resources *corev1.ResourceRequirements "json:\"resources,omitempty\"" + Autoscaling *PartialAutoScaling "json:\"autoscaling,omitempty\"" + NodeSelector map[string]string "json:\"nodeSelector,omitempty\"" + Tolerations []corev1.Toleration "json:\"tolerations,omitempty\"" + Affinity *corev1.Affinity "json:\"affinity,omitempty\"" + TopologySpreadConstraints []corev1.TopologySpreadConstraint "json:\"topologySpreadConstraints,omitempty\"" + PriorityClassName *string "json:\"priorityClassName,omitempty\"" + Console *PartialConsole "json:\"console,omitempty\"" + ExtraEnv []corev1.EnvVar "json:\"extraEnv,omitempty\"" + ExtraEnvFrom []corev1.EnvFromSource "json:\"extraEnvFrom,omitempty\"" + ExtraVolumes []corev1.Volume "json:\"extraVolumes,omitempty\"" + ExtraVolumeMounts []corev1.VolumeMount "json:\"extraVolumeMounts,omitempty\"" + ExtraContainers []corev1.Container "json:\"extraContainers,omitempty\"" + InitContainers *PartialInitContainers "json:\"initContainers,omitempty\"" + SecretMounts []PartialSecretMount "json:\"secretMounts,omitempty\"" + Secret *PartialSecretConfig "json:\"secret,omitempty\"" + Enterprise *PartialEnterprise "json:\"enterprise,omitempty\"" + LivenessProbe *corev1.Probe "json:\"livenessProbe,omitempty\"" + ReadinessProbe *corev1.Probe "json:\"readinessProbe,omitempty\"" + ConfigMap *PartialCreatable "json:\"configmap,omitempty\"" + Deployment *PartialDeploymentConfig "json:\"deployment,omitempty\"" + Strategy *appsv1.DeploymentStrategy "json:\"strategy,omitempty\"" + Tests *PartialEnableable "json:\"tests,omitempty\"" +} + +type PartialImage struct { + Registry *string "json:\"registry,omitempty\"" + Repository *string "json:\"repository,omitempty\"" + PullPolicy *corev1.PullPolicy "json:\"pullPolicy,omitempty\"" + Tag *string "json:\"tag,omitempty\"" +} + +type PartialServiceAccountConfig struct { + Create *bool "json:\"create,omitempty\"" + AutomountServiceAccountToken *bool "json:\"automountServiceAccountToken,omitempty\"" + Annotations map[string]string "json:\"annotations,omitempty\"" + Name *string "json:\"name,omitempty\"" +} + +type PartialServiceConfig struct { + Type *corev1.ServiceType "json:\"type,omitempty\"" + Port *int32 "json:\"port,omitempty\"" + NodePort *int32 "json:\"nodePort,omitempty\"" + TargetPort *int32 "json:\"targetPort,omitempty\"" + Annotations map[string]string "json:\"annotations,omitempty\"" +} + +type PartialIngressConfig struct { + Enabled *bool "json:\"enabled,omitempty\"" + ClassName *string "json:\"className,omitempty\"" + Annotations map[string]string "json:\"annotations,omitempty\"" + Hosts []PartialIngressHost "json:\"hosts,omitempty\"" + TLS []networkingv1.IngressTLS "json:\"tls,omitempty\"" +} + +type PartialAutoScaling struct { + Enabled *bool "json:\"enabled,omitempty\"" + MinReplicas *int32 "json:\"minReplicas,omitempty\"" + MaxReplicas *int32 "json:\"maxReplicas,omitempty\"" + TargetCPUUtilizationPercentage *int32 "json:\"targetCPUUtilizationPercentage,omitempty\"" + TargetMemoryUtilizationPercentage *int32 "json:\"targetMemoryUtilizationPercentage,omitempty\"" +} + +type PartialConsole struct { + Config map[string]any "json:\"config,omitempty\"" + Roles []map[string]any "json:\"roles,omitempty\"" + RoleBindings []map[string]any "json:\"roleBindings,omitempty\"" +} + +type PartialInitContainers struct { + ExtraInitContainers *string "json:\"extraInitContainers,omitempty\"" +} + +type PartialSecretConfig struct { + Create *bool "json:\"create,omitempty\"" + Kafka *PartialKafkaSecrets "json:\"kafka,omitempty\"" + Login *PartialLoginSecrets "json:\"login,omitempty\"" + Enterprise *PartialEnterpriseSecrets "json:\"enterprise,omitempty\"" + Redpanda *PartialRedpandaSecrets "json:\"redpanda,omitempty\"" +} + +type PartialEnterprise struct { + LicenseSecretRef *PartialSecretKeyRef "json:\"licenseSecretRef,omitempty\"" +} + +type PartialCreatable struct { + Create *bool "json:\"create,omitempty\"" +} + +type PartialDeploymentConfig struct { + Create *bool "json:\"create,omitempty\"" + Command []string "json:\"command,omitempty\"" + ExtraArgs []string "json:\"extraArgs,omitempty\"" +} + +type PartialEnableable struct { + Enabled *bool "json:\"enabled,omitempty\"" +} + +type PartialSecretMount struct { + Name *string "json:\"name,omitempty\"" + SecretName *string "json:\"secretName,omitempty\"" + Path *string "json:\"path,omitempty\"" + SubPath *string "json:\"subPath,omitempty\"" + DefaultMode *int32 "json:\"defaultMode,omitempty\"" +} + +type PartialKafkaSecrets struct { + SASLPassword *string "json:\"saslPassword,omitempty\"" + AWSMSKIAMSecretKey *string "json:\"awsMskIamSecretKey,omitempty\"" + TLSCA *string "json:\"tlsCa,omitempty\"" + TLSCert *string "json:\"tlsCert,omitempty\"" + TLSKey *string "json:\"tlsKey,omitempty\"" + TLSPassphrase *string "json:\"tlsPassphrase,omitempty\"" + SchemaRegistryPassword *string "json:\"schemaRegistryPassword,omitempty\"" + SchemaRegistryTLSCA *string "json:\"schemaRegistryTlsCa,omitempty\"" + SchemaRegistryTLSCert *string "json:\"schemaRegistryTlsCert,omitempty\"" + SchemaRegistryTLSKey *string "json:\"schemaRegistryTlsKey,omitempty\"" + ProtobufGitBasicAuthPassword *string "json:\"protobufGitBasicAuthPassword,omitempty\"" +} + +type PartialLoginSecrets struct { + JWTSecret *string "json:\"jwtSecret,omitempty\"" + Google *PartialGoogleLoginSecrets "json:\"google,omitempty\"" + Github *PartialGithubLoginSecrets "json:\"github,omitempty\"" + Okta *PartialOktaLoginSecrets "json:\"okta,omitempty\"" + OIDC *PartialOIDCLoginSecrets "json:\"oidc,omitempty\"" +} + +type PartialEnterpriseSecrets struct { + License *string "json:\"License,omitempty\"" +} + +type PartialRedpandaSecrets struct { + AdminAPI *PartialRedpandaAdminAPISecrets "json:\"adminApi,omitempty\"" +} + +type PartialSecretKeyRef struct { + Name *string "json:\"name,omitempty\"" + Key *string "json:\"key,omitempty\"" +} + +type PartialIngressHost struct { + Host *string "json:\"host,omitempty\"" + Paths []PartialIngressPath "json:\"paths,omitempty\"" +} + +type PartialGoogleLoginSecrets struct { + ClientSecret *string "json:\"clientSecret,omitempty\"" + GroupsServiceAccount *string "json:\"groupsServiceAccount,omitempty\"" +} + +type PartialGithubLoginSecrets struct { + ClientSecret *string "json:\"clientSecret,omitempty\"" + PersonalAccessToken *string "json:\"personalAccessToken,omitempty\"" +} + +type PartialOktaLoginSecrets struct { + ClientSecret *string "json:\"clientSecret,omitempty\"" + DirectoryAPIToken *string "json:\"directoryApiToken,omitempty\"" +} + +type PartialOIDCLoginSecrets struct { + ClientSecret *string "json:\"clientSecret,omitempty\"" +} + +type PartialRedpandaAdminAPISecrets struct { + Password *string "json:\"password,omitempty\"" + TLSCA *string "json:\"tlsCa,omitempty\"" + TLSCert *string "json:\"tlsCert,omitempty\"" + TLSKey *string "json:\"tlsKey,omitempty\"" +} + +type PartialIngressPath struct { + Path *string "json:\"path,omitempty\"" + PathType *networkingv1.PathType "json:\"pathType,omitempty\"" +} diff --git a/charts/redpanda/redpanda/5.9.2/templates/NOTES.txt b/charts/redpanda/redpanda/5.9.2/templates/NOTES.txt new file mode 100644 index 0000000000..6992f8e36d --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/NOTES.txt @@ -0,0 +1,26 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You 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. +*/}} + +{{- $warnings := (get ((include "redpanda.Warnings" (dict "a" (list .))) | fromJson) "r") }} +{{- range $_, $warning := $warnings }} +{{ $warning }} +{{- end }} + +{{- $notes := (get ((include "redpanda.Notes" (dict "a" (list .))) | fromJson) "r") }} +{{- range $_, $note := $notes }} +{{ $note }} +{{- end }} diff --git a/charts/redpanda/redpanda/5.9.2/templates/_cert-issuers.go.tpl b/charts/redpanda/redpanda/5.9.2/templates/_cert-issuers.go.tpl new file mode 100644 index 0000000000..ce5bf092a5 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/_cert-issuers.go.tpl @@ -0,0 +1,57 @@ +{{- /* Generated from "cert_issuers.go" */ -}} + +{{- define "redpanda.CertIssuers" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $tmp_tuple_1 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "redpanda.certIssuersAndCAs" (dict "a" (list $dot) ))) "r")) ))) "r") -}} +{{- $issuers := $tmp_tuple_1.T1 -}} +{{- $_is_returning = true -}} +{{- (dict "r" $issuers) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.RootCAs" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $tmp_tuple_2 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "redpanda.certIssuersAndCAs" (dict "a" (list $dot) ))) "r")) ))) "r") -}} +{{- $cas := $tmp_tuple_2.T2 -}} +{{- $_is_returning = true -}} +{{- (dict "r" $cas) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.certIssuersAndCAs" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $issuers := (coalesce nil) -}} +{{- $certs := (coalesce nil) -}} +{{- if (not (get (fromJson (include "redpanda.TLSEnabled" (dict "a" (list $dot) ))) "r")) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list $issuers $certs)) | toJson -}} +{{- break -}} +{{- end -}} +{{- range $name, $data := $values.tls.certs -}} +{{- if (or (not (empty $data.secretRef)) (not (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $data.enabled true) ))) "r"))) -}} +{{- continue -}} +{{- end -}} +{{- if (eq $data.issuerRef (coalesce nil)) -}} +{{- $issuers = (concat (default (list ) $issuers) (list (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "spec" (dict ) "status" (dict ) ) (mustMergeOverwrite (dict ) (dict "apiVersion" "cert-manager.io/v1" "kind" "Issuer" )) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "name" (printf `%s-%s-selfsigned-issuer` (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r") $name) "namespace" $dot.Release.Namespace "labels" (get (fromJson (include "redpanda.FullLabels" (dict "a" (list $dot) ))) "r") )) "spec" (mustMergeOverwrite (dict ) (mustMergeOverwrite (dict ) (dict "selfSigned" (mustMergeOverwrite (dict ) (dict )) )) (dict )) )))) -}} +{{- end -}} +{{- $issuers = (concat (default (list ) $issuers) (list (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "spec" (dict ) "status" (dict ) ) (mustMergeOverwrite (dict ) (dict "apiVersion" "cert-manager.io/v1" "kind" "Issuer" )) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "name" (printf `%s-%s-root-issuer` (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r") $name) "namespace" $dot.Release.Namespace "labels" (get (fromJson (include "redpanda.FullLabels" (dict "a" (list $dot) ))) "r") )) "spec" (mustMergeOverwrite (dict ) (mustMergeOverwrite (dict ) (dict "ca" (mustMergeOverwrite (dict "secretName" "" ) (dict "secretName" (printf `%s-%s-root-certificate` (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r") $name) )) )) (dict )) )))) -}} +{{- $certs = (concat (default (list ) $certs) (list (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "spec" (dict "secretName" "" "issuerRef" (dict "name" "" ) ) "status" (dict ) ) (mustMergeOverwrite (dict ) (dict "apiVersion" "cert-manager.io/v1" "kind" "Certificate" )) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "name" (printf `%s-%s-root-certificate` (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r") $name) "namespace" $dot.Release.Namespace "labels" (get (fromJson (include "redpanda.FullLabels" (dict "a" (list $dot) ))) "r") )) "spec" (mustMergeOverwrite (dict "secretName" "" "issuerRef" (dict "name" "" ) ) (dict "duration" (default "43800h" $data.duration) "isCA" true "commonName" (printf `%s-%s-root-certificate` (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r") $name) "secretName" (printf `%s-%s-root-certificate` (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r") $name) "privateKey" (mustMergeOverwrite (dict ) (dict "algorithm" "ECDSA" "size" (256 | int) )) "issuerRef" (mustMergeOverwrite (dict "name" "" ) (dict "name" (printf `%s-%s-selfsigned-issuer` (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r") $name) "kind" "Issuer" "group" "cert-manager.io" )) )) )))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list $issuers $certs)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + diff --git a/charts/redpanda/redpanda/5.9.2/templates/_certs.go.tpl b/charts/redpanda/redpanda/5.9.2/templates/_certs.go.tpl new file mode 100644 index 0000000000..b8d1160e5a --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/_certs.go.tpl @@ -0,0 +1,71 @@ +{{- /* Generated from "certs.go" */ -}} + +{{- define "redpanda.ClientCerts" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (not (get (fromJson (include "redpanda.TLSEnabled" (dict "a" (list $dot) ))) "r")) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list )) | toJson -}} +{{- break -}} +{{- end -}} +{{- $values := $dot.Values.AsMap -}} +{{- $fullname := (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r") -}} +{{- $service := (get (fromJson (include "redpanda.ServiceName" (dict "a" (list $dot) ))) "r") -}} +{{- $ns := $dot.Release.Namespace -}} +{{- $domain := (trimSuffix "." $values.clusterDomain) -}} +{{- $certs := (coalesce nil) -}} +{{- range $name, $data := $values.tls.certs -}} +{{- if (or (not (empty $data.secretRef)) (not (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $data.enabled true) ))) "r"))) -}} +{{- continue -}} +{{- end -}} +{{- $names := (coalesce nil) -}} +{{- if (or (eq $data.issuerRef (coalesce nil)) (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $data.applyInternalDNSNames false) ))) "r")) -}} +{{- $names = (concat (default (list ) $names) (list (printf "%s-cluster.%s.%s.svc.%s" $fullname $service $ns $domain))) -}} +{{- $names = (concat (default (list ) $names) (list (printf "%s-cluster.%s.%s.svc" $fullname $service $ns))) -}} +{{- $names = (concat (default (list ) $names) (list (printf "%s-cluster.%s.%s" $fullname $service $ns))) -}} +{{- $names = (concat (default (list ) $names) (list (printf "*.%s-cluster.%s.%s.svc.%s" $fullname $service $ns $domain))) -}} +{{- $names = (concat (default (list ) $names) (list (printf "*.%s-cluster.%s.%s.svc" $fullname $service $ns))) -}} +{{- $names = (concat (default (list ) $names) (list (printf "*.%s-cluster.%s.%s" $fullname $service $ns))) -}} +{{- $names = (concat (default (list ) $names) (list (printf "%s.%s.svc.%s" $service $ns $domain))) -}} +{{- $names = (concat (default (list ) $names) (list (printf "%s.%s.svc" $service $ns))) -}} +{{- $names = (concat (default (list ) $names) (list (printf "%s.%s" $service $ns))) -}} +{{- $names = (concat (default (list ) $names) (list (printf "*.%s.%s.svc.%s" $service $ns $domain))) -}} +{{- $names = (concat (default (list ) $names) (list (printf "*.%s.%s.svc" $service $ns))) -}} +{{- $names = (concat (default (list ) $names) (list (printf "*.%s.%s" $service $ns))) -}} +{{- end -}} +{{- if (ne $values.external.domain (coalesce nil)) -}} +{{- $names = (concat (default (list ) $names) (list (tpl $values.external.domain $dot))) -}} +{{- $names = (concat (default (list ) $names) (list (tpl (printf "*.%s" $values.external.domain) $dot))) -}} +{{- end -}} +{{- $duration := (default "43800h" $data.duration) -}} +{{- $issuerRef := (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $data.issuerRef (mustMergeOverwrite (dict "name" "" ) (dict "kind" "Issuer" "group" "cert-manager.io" "name" (printf "%s-%s-root-issuer" $fullname $name) ))) ))) "r") -}} +{{- $certs = (concat (default (list ) $certs) (list (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "spec" (dict "secretName" "" "issuerRef" (dict "name" "" ) ) "status" (dict ) ) (mustMergeOverwrite (dict ) (dict "apiVersion" "cert-manager.io/v1" "kind" "Certificate" )) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "name" (printf "%s-%s-cert" $fullname $name) "labels" (get (fromJson (include "redpanda.FullLabels" (dict "a" (list $dot) ))) "r") "namespace" $dot.Release.Namespace )) "spec" (mustMergeOverwrite (dict "secretName" "" "issuerRef" (dict "name" "" ) ) (dict "dnsNames" $names "duration" $duration "isCA" false "issuerRef" $issuerRef "secretName" (printf "%s-%s-cert" $fullname $name) "privateKey" (mustMergeOverwrite (dict ) (dict "algorithm" "ECDSA" "size" (256 | int) )) )) )))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $name := $values.listeners.kafka.tls.cert -}} +{{- $tmp_tuple_1 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.dicttest" (dict "a" (list $values.tls.certs $name (coalesce nil)) ))) "r")) ))) "r") -}} +{{- $ok := $tmp_tuple_1.T2 -}} +{{- $data := $tmp_tuple_1.T1 -}} +{{- if (not $ok) -}} +{{- $_ := (fail (printf "Certificate %q referenced but not defined" $name)) -}} +{{- end -}} +{{- if (or (not (empty $data.secretRef)) (not (get (fromJson (include "redpanda.ClientAuthRequired" (dict "a" (list $dot) ))) "r"))) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $certs) | toJson -}} +{{- break -}} +{{- end -}} +{{- $issuerRef := (mustMergeOverwrite (dict "name" "" ) (dict "group" "cert-manager.io" "kind" "Issuer" "name" (printf "%s-%s-root-issuer" $fullname $name) )) -}} +{{- if (ne $data.issuerRef (coalesce nil)) -}} +{{- $issuerRef = $data.issuerRef -}} +{{- $_ := (set $issuerRef "group" "cert-manager.io") -}} +{{- end -}} +{{- $duration := (default "43800h" $data.duration) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (concat (default (list ) $certs) (list (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "spec" (dict "secretName" "" "issuerRef" (dict "name" "" ) ) "status" (dict ) ) (mustMergeOverwrite (dict ) (dict "apiVersion" "cert-manager.io/v1" "kind" "Certificate" )) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "name" (printf "%s-client" $fullname) "labels" (get (fromJson (include "redpanda.FullLabels" (dict "a" (list $dot) ))) "r") )) "spec" (mustMergeOverwrite (dict "secretName" "" "issuerRef" (dict "name" "" ) ) (dict "commonName" (printf "%s-client" $fullname) "duration" $duration "isCA" false "secretName" (printf "%s-client" $fullname) "privateKey" (mustMergeOverwrite (dict ) (dict "algorithm" "ECDSA" "size" (256 | int) )) "issuerRef" $issuerRef )) ))))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + diff --git a/charts/redpanda/redpanda/5.9.2/templates/_configmap.go.tpl b/charts/redpanda/redpanda/5.9.2/templates/_configmap.go.tpl new file mode 100644 index 0000000000..d9263686c7 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/_configmap.go.tpl @@ -0,0 +1,517 @@ +{{- /* Generated from "configmap.tpl.go" */ -}} + +{{- define "redpanda.ConfigMaps" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $cms := (list (get (fromJson (include "redpanda.RedpandaConfigMap" (dict "a" (list $dot true) ))) "r")) -}} +{{- $cms = (concat (default (list ) $cms) (default (list ) (get (fromJson (include "redpanda.RPKProfile" (dict "a" (list $dot) ))) "r"))) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $cms) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.ConfigMapsWithoutSeedServer" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $cms := (list (get (fromJson (include "redpanda.RedpandaConfigMap" (dict "a" (list $dot false) ))) "r")) -}} +{{- $cms = (concat (default (list ) $cms) (default (list ) (get (fromJson (include "redpanda.RPKProfile" (dict "a" (list $dot) ))) "r"))) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $cms) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.RedpandaConfigMap" -}} +{{- $dot := (index .a 0) -}} +{{- $includeSeedServer := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $_is_returning = true -}} +{{- (dict "r" (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) ) (mustMergeOverwrite (dict ) (dict "kind" "ConfigMap" "apiVersion" "v1" )) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "name" (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r") "namespace" $dot.Release.Namespace "labels" (get (fromJson (include "redpanda.FullLabels" (dict "a" (list $dot) ))) "r") )) "data" (dict "bootstrap.yaml" (get (fromJson (include "redpanda.BootstrapFile" (dict "a" (list $dot) ))) "r") "redpanda.yaml" (get (fromJson (include "redpanda.RedpandaConfigFile" (dict "a" (list $dot $includeSeedServer) ))) "r") ) ))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.BootstrapFile" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $bootstrap := (dict "kafka_enable_authorization" (get (fromJson (include "redpanda.Auth.IsSASLEnabled" (dict "a" (list $values.auth) ))) "r") "enable_sasl" (get (fromJson (include "redpanda.Auth.IsSASLEnabled" (dict "a" (list $values.auth) ))) "r") "enable_rack_awareness" $values.rackAwareness.enabled "storage_min_free_bytes" ((get (fromJson (include "redpanda.Storage.StorageMinFreeBytes" (dict "a" (list $values.storage) ))) "r") | int64) ) -}} +{{- $bootstrap = (merge (dict ) $bootstrap (get (fromJson (include "redpanda.AuditLogging.Translate" (dict "a" (list $values.auditLogging $dot (get (fromJson (include "redpanda.Auth.IsSASLEnabled" (dict "a" (list $values.auth) ))) "r")) ))) "r")) -}} +{{- $bootstrap = (merge (dict ) $bootstrap (get (fromJson (include "redpanda.Logging.Translate" (dict "a" (list $values.logging) ))) "r")) -}} +{{- $bootstrap = (merge (dict ) $bootstrap (get (fromJson (include "redpanda.TunableConfig.Translate" (dict "a" (list $values.config.tunable) ))) "r")) -}} +{{- $bootstrap = (merge (dict ) $bootstrap (get (fromJson (include "redpanda.ClusterConfig.Translate" (dict "a" (list $values.config.cluster ($values.statefulset.replicas | int) false) ))) "r")) -}} +{{- $bootstrap = (merge (dict ) $bootstrap (get (fromJson (include "redpanda.Auth.Translate" (dict "a" (list $values.auth (get (fromJson (include "redpanda.Auth.IsSASLEnabled" (dict "a" (list $values.auth) ))) "r")) ))) "r")) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (toYaml $bootstrap)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.RedpandaConfigFile" -}} +{{- $dot := (index .a 0) -}} +{{- $includeSeedServer := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $redpanda := (dict "kafka_enable_authorization" (get (fromJson (include "redpanda.Auth.IsSASLEnabled" (dict "a" (list $values.auth) ))) "r") "enable_sasl" (get (fromJson (include "redpanda.Auth.IsSASLEnabled" (dict "a" (list $values.auth) ))) "r") "empty_seed_starts_cluster" false "storage_min_free_bytes" ((get (fromJson (include "redpanda.Storage.StorageMinFreeBytes" (dict "a" (list $values.storage) ))) "r") | int64) ) -}} +{{- if $includeSeedServer -}} +{{- $_ := (set $redpanda "seed_servers" (get (fromJson (include "redpanda.Listeners.CreateSeedServers" (dict "a" (list $values.listeners ($values.statefulset.replicas | int) (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r") (get (fromJson (include "redpanda.InternalDomain" (dict "a" (list $dot) ))) "r")) ))) "r")) -}} +{{- end -}} +{{- $redpanda = (merge (dict ) $redpanda (get (fromJson (include "redpanda.AuditLogging.Translate" (dict "a" (list $values.auditLogging $dot (get (fromJson (include "redpanda.Auth.IsSASLEnabled" (dict "a" (list $values.auth) ))) "r")) ))) "r")) -}} +{{- $redpanda = (merge (dict ) $redpanda (get (fromJson (include "redpanda.Logging.Translate" (dict "a" (list $values.logging) ))) "r")) -}} +{{- $redpanda = (merge (dict ) $redpanda (get (fromJson (include "redpanda.TunableConfig.Translate" (dict "a" (list $values.config.tunable) ))) "r")) -}} +{{- $redpanda = (merge (dict ) $redpanda (get (fromJson (include "redpanda.ClusterConfig.Translate" (dict "a" (list $values.config.cluster ($values.statefulset.replicas | int) true) ))) "r")) -}} +{{- $redpanda = (merge (dict ) $redpanda (get (fromJson (include "redpanda.Auth.Translate" (dict "a" (list $values.auth (get (fromJson (include "redpanda.Auth.IsSASLEnabled" (dict "a" (list $values.auth) ))) "r")) ))) "r")) -}} +{{- $redpanda = (merge (dict ) $redpanda (get (fromJson (include "redpanda.NodeConfig.Translate" (dict "a" (list $values.config.node) ))) "r")) -}} +{{- $_ := (get (fromJson (include "redpanda.configureListeners" (dict "a" (list $redpanda $dot) ))) "r") -}} +{{- $redpandaYaml := (dict "redpanda" $redpanda "schema_registry" (get (fromJson (include "redpanda.schemaRegistry" (dict "a" (list $dot) ))) "r") "schema_registry_client" (get (fromJson (include "redpanda.kafkaClient" (dict "a" (list $dot) ))) "r") "pandaproxy" (get (fromJson (include "redpanda.pandaProxyListener" (dict "a" (list $dot) ))) "r") "pandaproxy_client" (get (fromJson (include "redpanda.kafkaClient" (dict "a" (list $dot) ))) "r") "rpk" (get (fromJson (include "redpanda.rpkConfiguration" (dict "a" (list $dot) ))) "r") "config_file" "/etc/redpanda/redpanda.yaml" ) -}} +{{- if (and (and (get (fromJson (include "redpanda.RedpandaAtLeast_23_3_0" (dict "a" (list $dot) ))) "r") $values.auditLogging.enabled) (get (fromJson (include "redpanda.Auth.IsSASLEnabled" (dict "a" (list $values.auth) ))) "r")) -}} +{{- $_ := (set $redpandaYaml "audit_log_client" (get (fromJson (include "redpanda.kafkaClient" (dict "a" (list $dot) ))) "r")) -}} +{{- end -}} +{{- $redpandaYaml = (merge (dict ) $redpandaYaml (get (fromJson (include "redpanda.Storage.Translate" (dict "a" (list $values.storage) ))) "r")) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (toYaml $redpandaYaml)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.RPKProfile" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (not $values.external.enabled) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) ) (mustMergeOverwrite (dict ) (dict "kind" "ConfigMap" "apiVersion" "v1" )) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "name" (printf "%s-rpk" (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r")) "namespace" $dot.Release.Namespace "labels" (get (fromJson (include "redpanda.FullLabels" (dict "a" (list $dot) ))) "r") )) "data" (dict "profile" (toYaml (get (fromJson (include "redpanda.rpkProfile" (dict "a" (list $dot) ))) "r")) ) )))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.rpkProfile" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $brokerList := (list ) -}} +{{- range $_, $i := untilStep (((0 | int) | int)|int) (($values.statefulset.replicas | int)|int) (1|int) -}} +{{- $brokerList = (concat (default (list ) $brokerList) (list (printf "%s:%d" (get (fromJson (include "redpanda.advertisedHost" (dict "a" (list $dot $i) ))) "r") (((get (fromJson (include "redpanda.advertisedKafkaPort" (dict "a" (list $dot $i) ))) "r") | int) | int)))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $adminAdvertisedList := (list ) -}} +{{- range $_, $i := untilStep (((0 | int) | int)|int) (($values.statefulset.replicas | int)|int) (1|int) -}} +{{- $adminAdvertisedList = (concat (default (list ) $adminAdvertisedList) (list (printf "%s:%d" (get (fromJson (include "redpanda.advertisedHost" (dict "a" (list $dot $i) ))) "r") (((get (fromJson (include "redpanda.advertisedAdminPort" (dict "a" (list $dot $i) ))) "r") | int) | int)))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $kafkaTLS := (get (fromJson (include "redpanda.brokersTLSConfiguration" (dict "a" (list $dot) ))) "r") -}} +{{- $tmp_tuple_1 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.dicttest" (dict "a" (list $kafkaTLS "truststore_file" (coalesce nil)) ))) "r")) ))) "r") -}} +{{- $ok_1 := $tmp_tuple_1.T2 -}} +{{- if $ok_1 -}} +{{- $_ := (set $kafkaTLS "ca_file" "ca.crt") -}} +{{- $_ := (unset $kafkaTLS "truststore_file") -}} +{{- end -}} +{{- $adminTLS := (get (fromJson (include "redpanda.adminTLSConfiguration" (dict "a" (list $dot) ))) "r") -}} +{{- $tmp_tuple_2 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.dicttest" (dict "a" (list $adminTLS "truststore_file" (coalesce nil)) ))) "r")) ))) "r") -}} +{{- $ok_2 := $tmp_tuple_2.T2 -}} +{{- if $ok_2 -}} +{{- $_ := (set $adminTLS "ca_file" "ca.crt") -}} +{{- $_ := (unset $adminTLS "truststore_file") -}} +{{- end -}} +{{- $ka := (dict "brokers" $brokerList "tls" (coalesce nil) ) -}} +{{- if (gt ((get (fromJson (include "_shims.len" (dict "a" (list $kafkaTLS) ))) "r") | int) (0 | int)) -}} +{{- $_ := (set $ka "tls" $kafkaTLS) -}} +{{- end -}} +{{- $aa := (dict "addresses" $adminAdvertisedList "tls" (coalesce nil) ) -}} +{{- if (gt ((get (fromJson (include "_shims.len" (dict "a" (list $adminTLS) ))) "r") | int) (0 | int)) -}} +{{- $_ := (set $aa "tls" $adminTLS) -}} +{{- end -}} +{{- $result := (dict "name" (get (fromJson (include "redpanda.getFirstExternalKafkaListener" (dict "a" (list $dot) ))) "r") "kafka_api" $ka "admin_api" $aa ) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $result) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.advertisedKafkaPort" -}} +{{- $dot := (index .a 0) -}} +{{- $i := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $externalKafkaListenerName := (get (fromJson (include "redpanda.getFirstExternalKafkaListener" (dict "a" (list $dot) ))) "r") -}} +{{- $listener := (index $values.listeners.kafka.external $externalKafkaListenerName) -}} +{{- $port := (($values.listeners.kafka.port | int) | int) -}} +{{- if (gt (($listener.port | int) | int) ((1 | int) | int)) -}} +{{- $port = (($listener.port | int) | int) -}} +{{- end -}} +{{- if (gt ((get (fromJson (include "_shims.len" (dict "a" (list $listener.advertisedPorts) ))) "r") | int) (1 | int)) -}} +{{- $port = ((index $listener.advertisedPorts $i) | int) -}} +{{- else -}}{{- if (eq ((get (fromJson (include "_shims.len" (dict "a" (list $listener.advertisedPorts) ))) "r") | int) (1 | int)) -}} +{{- $port = ((index $listener.advertisedPorts (0 | int)) | int) -}} +{{- end -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $port) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.advertisedAdminPort" -}} +{{- $dot := (index .a 0) -}} +{{- $i := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $keys := (keys $values.listeners.admin.external) -}} +{{- $_ := (sortAlpha $keys) -}} +{{- $externalAdminListenerName := (first $keys) -}} +{{- $listener := (index $values.listeners.admin.external (get (fromJson (include "_shims.typeassertion" (dict "a" (list "string" $externalAdminListenerName) ))) "r")) -}} +{{- $port := (($values.listeners.admin.port | int) | int) -}} +{{- if (gt (($listener.port | int) | int) (1 | int)) -}} +{{- $port = (($listener.port | int) | int) -}} +{{- end -}} +{{- if (gt ((get (fromJson (include "_shims.len" (dict "a" (list $listener.advertisedPorts) ))) "r") | int) (1 | int)) -}} +{{- $port = ((index $listener.advertisedPorts $i) | int) -}} +{{- else -}}{{- if (eq ((get (fromJson (include "_shims.len" (dict "a" (list $listener.advertisedPorts) ))) "r") | int) (1 | int)) -}} +{{- $port = ((index $listener.advertisedPorts (0 | int)) | int) -}} +{{- end -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $port) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.advertisedHost" -}} +{{- $dot := (index .a 0) -}} +{{- $i := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $address := (printf "%s-%d" (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r") ($i | int)) -}} +{{- if (ne (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $values.external.domain "") ))) "r") "") -}} +{{- $address = (printf "%s.%s" $address (tpl $values.external.domain $dot)) -}} +{{- end -}} +{{- if (le ((get (fromJson (include "_shims.len" (dict "a" (list $values.external.addresses) ))) "r") | int) (0 | int)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $address) | toJson -}} +{{- break -}} +{{- end -}} +{{- if (eq ((get (fromJson (include "_shims.len" (dict "a" (list $values.external.addresses) ))) "r") | int) (1 | int)) -}} +{{- $address = (index $values.external.addresses (0 | int)) -}} +{{- else -}} +{{- $address = (index $values.external.addresses $i) -}} +{{- end -}} +{{- if (ne (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $values.external.domain "") ))) "r") "") -}} +{{- $address = (printf "%s.%s" $address $values.external.domain) -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $address) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.getFirstExternalKafkaListener" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $keys := (keys $values.listeners.kafka.external) -}} +{{- $_ := (sortAlpha $keys) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (get (fromJson (include "_shims.typeassertion" (dict "a" (list "string" (first $keys)) ))) "r")) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.BrokerList" -}} +{{- $dot := (index .a 0) -}} +{{- $replicas := (index .a 1) -}} +{{- $port := (index .a 2) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $bl := (coalesce nil) -}} +{{- range $_, $i := untilStep (((0 | int) | int)|int) ($replicas|int) (1|int) -}} +{{- $bl = (concat (default (list ) $bl) (list (printf "%s-%d.%s:%d" (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r") $i (get (fromJson (include "redpanda.InternalDomain" (dict "a" (list $dot) ))) "r") $port))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $bl) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.rpkConfiguration" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $brokerList := (get (fromJson (include "redpanda.BrokerList" (dict "a" (list $dot ($values.statefulset.replicas | int) ($values.listeners.kafka.port | int)) ))) "r") -}} +{{- $adminTLS := (coalesce nil) -}} +{{- $tls_3 := (get (fromJson (include "redpanda.adminTLSConfiguration" (dict "a" (list $dot) ))) "r") -}} +{{- if (gt ((get (fromJson (include "_shims.len" (dict "a" (list $tls_3) ))) "r") | int) (0 | int)) -}} +{{- $adminTLS = $tls_3 -}} +{{- end -}} +{{- $brokerTLS := (coalesce nil) -}} +{{- $tls_4 := (get (fromJson (include "redpanda.brokersTLSConfiguration" (dict "a" (list $dot) ))) "r") -}} +{{- if (gt ((get (fromJson (include "_shims.len" (dict "a" (list $tls_4) ))) "r") | int) (0 | int)) -}} +{{- $brokerTLS = $tls_4 -}} +{{- end -}} +{{- $result := (dict "overprovisioned" (get (fromJson (include "redpanda.RedpandaResources.GetOverProvisionValue" (dict "a" (list $values.resources) ))) "r") "enable_memory_locking" (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $values.resources.memory.enable_memory_locking false) ))) "r") "additional_start_flags" (get (fromJson (include "redpanda.RedpandaAdditionalStartFlags" (dict "a" (list $dot ((get (fromJson (include "redpanda.RedpandaSMP" (dict "a" (list $dot) ))) "r") | int64)) ))) "r") "kafka_api" (dict "brokers" $brokerList "tls" $brokerTLS ) "admin_api" (dict "addresses" (get (fromJson (include "redpanda.Listeners.AdminList" (dict "a" (list $values.listeners ($values.statefulset.replicas | int) (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r") (get (fromJson (include "redpanda.InternalDomain" (dict "a" (list $dot) ))) "r")) ))) "r") "tls" $adminTLS ) ) -}} +{{- $result = (merge (dict ) $result (get (fromJson (include "redpanda.Tuning.Translate" (dict "a" (list $values.tuning) ))) "r")) -}} +{{- $result = (merge (dict ) $result (get (fromJson (include "redpanda.Config.CreateRPKConfiguration" (dict "a" (list $values.config) ))) "r")) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $result) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.brokersTLSConfiguration" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (not (get (fromJson (include "redpanda.InternalTLS.IsEnabled" (dict "a" (list $values.listeners.kafka.tls $values.tls) ))) "r")) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (dict )) | toJson -}} +{{- break -}} +{{- end -}} +{{- $result := (dict ) -}} +{{- $truststore_5 := (get (fromJson (include "redpanda.InternalTLS.TrustStoreFilePath" (dict "a" (list $values.listeners.kafka.tls $values.tls) ))) "r") -}} +{{- if (ne $truststore_5 "/etc/ssl/certs/ca-certificates.crt") -}} +{{- $_ := (set $result "truststore_file" $truststore_5) -}} +{{- end -}} +{{- if $values.listeners.kafka.tls.requireClientAuth -}} +{{- $_ := (set $result "cert_file" (printf "/etc/tls/certs/%s-client/tls.crt" (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r"))) -}} +{{- $_ := (set $result "key_file" (printf "/etc/tls/certs/%s-client/tls.key" (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r"))) -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $result) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.adminTLSConfiguration" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $result := (dict ) -}} +{{- if (not (get (fromJson (include "redpanda.InternalTLS.IsEnabled" (dict "a" (list $values.listeners.admin.tls $values.tls) ))) "r")) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $result) | toJson -}} +{{- break -}} +{{- end -}} +{{- $truststore_6 := (get (fromJson (include "redpanda.InternalTLS.TrustStoreFilePath" (dict "a" (list $values.listeners.admin.tls $values.tls) ))) "r") -}} +{{- if (ne $truststore_6 "/etc/ssl/certs/ca-certificates.crt") -}} +{{- $_ := (set $result "truststore_file" $truststore_6) -}} +{{- end -}} +{{- if $values.listeners.admin.tls.requireClientAuth -}} +{{- $_ := (set $result "cert_file" (printf "/etc/tls/certs/%s-client/tls.crt" (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r"))) -}} +{{- $_ := (set $result "key_file" (printf "/etc/tls/certs/%s-client/tls.key" (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r"))) -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $result) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.kafkaClient" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $brokerList := (list ) -}} +{{- range $_, $i := untilStep (((0 | int) | int)|int) (($values.statefulset.replicas | int)|int) (1|int) -}} +{{- $brokerList = (concat (default (list ) $brokerList) (list (dict "address" (printf "%s-%d.%s" (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r") $i (get (fromJson (include "redpanda.InternalDomain" (dict "a" (list $dot) ))) "r")) "port" ($values.listeners.kafka.port | int) ))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $kafkaTLS := $values.listeners.kafka.tls -}} +{{- $brokerTLS := (coalesce nil) -}} +{{- if (get (fromJson (include "redpanda.InternalTLS.IsEnabled" (dict "a" (list $values.listeners.kafka.tls $values.tls) ))) "r") -}} +{{- $brokerTLS = (dict "enabled" true "cert_file" (printf "/etc/tls/certs/%s/tls.crt" $kafkaTLS.cert) "key_file" (printf "/etc/tls/certs/%s/tls.key" $kafkaTLS.cert) "require_client_auth" $kafkaTLS.requireClientAuth "truststore_file" (get (fromJson (include "redpanda.InternalTLS.TrustStoreFilePath" (dict "a" (list $kafkaTLS $values.tls) ))) "r") ) -}} +{{- end -}} +{{- $cfg := (dict "brokers" $brokerList ) -}} +{{- if (gt ((get (fromJson (include "_shims.len" (dict "a" (list $brokerTLS) ))) "r") | int) (0 | int)) -}} +{{- $_ := (set $cfg "broker_tls" $brokerTLS) -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $cfg) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.configureListeners" -}} +{{- $redpanda := (index .a 0) -}} +{{- $dot := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $_ := (set $redpanda "admin" (get (fromJson (include "redpanda.AdminListeners.Listeners" (dict "a" (list $values.listeners.admin) ))) "r")) -}} +{{- $_ := (set $redpanda "kafka_api" (get (fromJson (include "redpanda.KafkaListeners.Listeners" (dict "a" (list $values.listeners.kafka $values.auth) ))) "r")) -}} +{{- $_ := (set $redpanda "rpc_server" (get (fromJson (include "redpanda.rpcListeners" (dict "a" (list $dot) ))) "r")) -}} +{{- $_ := (set $redpanda "admin_api_tls" (coalesce nil)) -}} +{{- $tls_7 := (get (fromJson (include "redpanda.AdminListeners.ListenersTLS" (dict "a" (list $values.listeners.admin $values.tls) ))) "r") -}} +{{- if (gt ((get (fromJson (include "_shims.len" (dict "a" (list $tls_7) ))) "r") | int) (0 | int)) -}} +{{- $_ := (set $redpanda "admin_api_tls" $tls_7) -}} +{{- end -}} +{{- $_ := (set $redpanda "kafka_api_tls" (coalesce nil)) -}} +{{- $tls_8 := (get (fromJson (include "redpanda.KafkaListeners.ListenersTLS" (dict "a" (list $values.listeners.kafka $values.tls) ))) "r") -}} +{{- if (gt ((get (fromJson (include "_shims.len" (dict "a" (list $tls_8) ))) "r") | int) (0 | int)) -}} +{{- $_ := (set $redpanda "kafka_api_tls" $tls_8) -}} +{{- end -}} +{{- $tls_9 := (get (fromJson (include "redpanda.rpcListenersTLS" (dict "a" (list $dot) ))) "r") -}} +{{- if (gt ((get (fromJson (include "_shims.len" (dict "a" (list $tls_9) ))) "r") | int) (0 | int)) -}} +{{- $_ := (set $redpanda "rpc_server_tls" $tls_9) -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.pandaProxyListener" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $pandaProxy := (dict ) -}} +{{- $_ := (set $pandaProxy "pandaproxy_api" (get (fromJson (include "redpanda.HTTPListeners.Listeners" (dict "a" (list $values.listeners.http (get (fromJson (include "redpanda.Auth.IsSASLEnabled" (dict "a" (list $values.auth) ))) "r")) ))) "r")) -}} +{{- $_ := (set $pandaProxy "pandaproxy_api_tls" (coalesce nil)) -}} +{{- $tls_10 := (get (fromJson (include "redpanda.HTTPListeners.ListenersTLS" (dict "a" (list $values.listeners.http $values.tls) ))) "r") -}} +{{- if (gt ((get (fromJson (include "_shims.len" (dict "a" (list $tls_10) ))) "r") | int) (0 | int)) -}} +{{- $_ := (set $pandaProxy "pandaproxy_api_tls" $tls_10) -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $pandaProxy) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.schemaRegistry" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $schemaReg := (dict ) -}} +{{- $_ := (set $schemaReg "schema_registry_api" (get (fromJson (include "redpanda.SchemaRegistryListeners.Listeners" (dict "a" (list $values.listeners.schemaRegistry (get (fromJson (include "redpanda.Auth.IsSASLEnabled" (dict "a" (list $values.auth) ))) "r")) ))) "r")) -}} +{{- $_ := (set $schemaReg "schema_registry_api_tls" (coalesce nil)) -}} +{{- $tls_11 := (get (fromJson (include "redpanda.SchemaRegistryListeners.ListenersTLS" (dict "a" (list $values.listeners.schemaRegistry $values.tls) ))) "r") -}} +{{- if (gt ((get (fromJson (include "_shims.len" (dict "a" (list $tls_11) ))) "r") | int) (0 | int)) -}} +{{- $_ := (set $schemaReg "schema_registry_api_tls" $tls_11) -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $schemaReg) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.rpcListenersTLS" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $r := $values.listeners.rpc -}} +{{- if (and (not ((or (or (get (fromJson (include "redpanda.RedpandaAtLeast_22_2_atleast_22_2_10" (dict "a" (list $dot) ))) "r") (get (fromJson (include "redpanda.RedpandaAtLeast_22_3_atleast_22_3_13" (dict "a" (list $dot) ))) "r")) (get (fromJson (include "redpanda.RedpandaAtLeast_23_1_2" (dict "a" (list $dot) ))) "r")))) ((or (and (eq $r.tls.enabled (coalesce nil)) $values.tls.enabled) (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $r.tls.enabled false) ))) "r")))) -}} +{{- $_ := (fail (printf "Redpanda version v%s does not support TLS on the RPC port. Please upgrade. See technical service bulletin 2023-01." (trimPrefix "v" (get (fromJson (include "redpanda.Tag" (dict "a" (list $dot) ))) "r")))) -}} +{{- end -}} +{{- if (not (get (fromJson (include "redpanda.InternalTLS.IsEnabled" (dict "a" (list $r.tls $values.tls) ))) "r")) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (dict )) | toJson -}} +{{- break -}} +{{- end -}} +{{- $certName := $r.tls.cert -}} +{{- $_is_returning = true -}} +{{- (dict "r" (dict "enabled" true "cert_file" (printf "/etc/tls/certs/%s/tls.crt" $certName) "key_file" (printf "/etc/tls/certs/%s/tls.key" $certName) "require_client_auth" $r.tls.requireClientAuth "truststore_file" (get (fromJson (include "redpanda.InternalTLS.TrustStoreFilePath" (dict "a" (list $r.tls $values.tls) ))) "r") )) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.rpcListeners" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $_is_returning = true -}} +{{- (dict "r" (dict "address" "0.0.0.0" "port" ($values.listeners.rpc.port | int) )) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.createInternalListenerTLSCfg" -}} +{{- $tls := (index .a 0) -}} +{{- $internal := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (not (get (fromJson (include "redpanda.InternalTLS.IsEnabled" (dict "a" (list $internal $tls) ))) "r")) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (dict )) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (dict "name" "internal" "enabled" true "cert_file" (printf "/etc/tls/certs/%s/tls.crt" $internal.cert) "key_file" (printf "/etc/tls/certs/%s/tls.key" $internal.cert) "require_client_auth" $internal.requireClientAuth "truststore_file" (get (fromJson (include "redpanda.InternalTLS.TrustStoreFilePath" (dict "a" (list $internal $tls) ))) "r") )) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.createInternalListenerCfg" -}} +{{- $port := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $_is_returning = true -}} +{{- (dict "r" (dict "name" "internal" "address" "0.0.0.0" "port" $port )) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.RedpandaAdditionalStartFlags" -}} +{{- $dot := (index .a 0) -}} +{{- $smp := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $chartFlags := (dict "smp" (printf "%d" ($smp | int)) "memory" (printf "%dM" (((get (fromJson (include "redpanda.RedpandaMemory" (dict "a" (list $dot) ))) "r") | int64) | int)) "reserve-memory" (printf "%dM" (((get (fromJson (include "redpanda.RedpandaReserveMemory" (dict "a" (list $dot) ))) "r") | int64) | int)) "default-log-level" $values.logging.logLevel ) -}} +{{- if (eq (index $values.config.node "developer_mode") true) -}} +{{- $_ := (unset $chartFlags "reserve-memory") -}} +{{- end -}} +{{- range $flag, $_ := $chartFlags -}} +{{- range $_, $userFlag := $values.statefulset.additionalRedpandaCmdFlags -}} +{{- if (regexMatch (printf "^--%s" $flag) $userFlag) -}} +{{- $_ := (unset $chartFlags $flag) -}} +{{- end -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $keys := (keys $chartFlags) -}} +{{- $_ := (sortAlpha $keys) -}} +{{- $flags := (list ) -}} +{{- range $_, $key := $keys -}} +{{- $flags = (concat (default (list ) $flags) (list (printf "--%s=%s" $key (index $chartFlags $key)))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (concat (default (list ) $flags) (default (list ) $values.statefulset.additionalRedpandaCmdFlags))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + diff --git a/charts/redpanda/redpanda/5.9.2/templates/_console.go.tpl b/charts/redpanda/redpanda/5.9.2/templates/_console.go.tpl new file mode 100644 index 0000000000..f8498e9986 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/_console.go.tpl @@ -0,0 +1,60 @@ +{{- /* Generated from "console.tpl.go" */ -}} + +{{- define "redpanda.ConsoleConfig" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $schemaURLs := (coalesce nil) -}} +{{- if $values.listeners.schemaRegistry.enabled -}} +{{- $schema := "http" -}} +{{- if (get (fromJson (include "redpanda.InternalTLS.IsEnabled" (dict "a" (list $values.listeners.schemaRegistry.tls $values.tls) ))) "r") -}} +{{- $schema = "https" -}} +{{- end -}} +{{- range $_, $i := untilStep (((0 | int) | int)|int) (($values.statefulset.replicas | int)|int) (1|int) -}} +{{- $schemaURLs = (concat (default (list ) $schemaURLs) (list (printf "%s://%s-%d.%s:%d" $schema (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r") $i (get (fromJson (include "redpanda.InternalDomain" (dict "a" (list $dot) ))) "r") ($values.listeners.schemaRegistry.port | int)))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- end -}} +{{- $schema := "http" -}} +{{- if (get (fromJson (include "redpanda.InternalTLS.IsEnabled" (dict "a" (list $values.listeners.admin.tls $values.tls) ))) "r") -}} +{{- $schema = "https" -}} +{{- end -}} +{{- $c := (dict "kafka" (dict "brokers" (get (fromJson (include "redpanda.BrokerList" (dict "a" (list $dot ($values.statefulset.replicas | int) ($values.listeners.kafka.port | int)) ))) "r") "sasl" (dict "enabled" (get (fromJson (include "redpanda.Auth.IsSASLEnabled" (dict "a" (list $values.auth) ))) "r") ) "tls" (get (fromJson (include "redpanda.KafkaListeners.ConsolemTLS" (dict "a" (list $values.listeners.kafka $values.tls) ))) "r") "schemaRegistry" (dict "enabled" $values.listeners.schemaRegistry.enabled "urls" $schemaURLs "tls" (get (fromJson (include "redpanda.SchemaRegistryListeners.ConsoleTLS" (dict "a" (list $values.listeners.schemaRegistry $values.tls) ))) "r") ) ) "redpanda" (dict "adminApi" (dict "enabled" true "urls" (list (printf "%s://%s:%d" $schema (get (fromJson (include "redpanda.InternalDomain" (dict "a" (list $dot) ))) "r") ($values.listeners.admin.port | int))) "tls" (get (fromJson (include "redpanda.AdminListeners.ConsoleTLS" (dict "a" (list $values.listeners.admin $values.tls) ))) "r") ) ) ) -}} +{{- if $values.connectors.enabled -}} +{{- $port := (dig "connectors" "connectors" "restPort" (8083 | int) $dot.Values.AsMap) -}} +{{- $tmp_tuple_1 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.asintegral" (dict "a" (list $port) ))) "r")) ))) "r") -}} +{{- $ok := $tmp_tuple_1.T2 -}} +{{- $p := ($tmp_tuple_1.T1 | int) -}} +{{- if (not $ok) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $c) | toJson -}} +{{- break -}} +{{- end -}} +{{- $connectorsURL := (printf "http://%s.%s.svc.%s:%d" (get (fromJson (include "redpanda.ConnectorsFullName" (dict "a" (list $dot) ))) "r") $dot.Release.Namespace (trimSuffix "." $values.clusterDomain) $p) -}} +{{- $_ := (set $c "connect" (mustMergeOverwrite (dict "enabled" false "clusters" (coalesce nil) "connectTimeout" 0 "readTimeout" 0 "requestTimeout" 0 ) (dict "enabled" $values.connectors.enabled "clusters" (list (mustMergeOverwrite (dict "name" "" "url" "" "tls" (dict "enabled" false "caFilepath" "" "certFilepath" "" "keyFilepath" "" "insecureSkipTlsVerify" false ) "username" "" "password" "" "token" "" ) (dict "name" "connectors" "url" $connectorsURL "tls" (mustMergeOverwrite (dict "enabled" false "caFilepath" "" "certFilepath" "" "keyFilepath" "" "insecureSkipTlsVerify" false ) (dict "enabled" false "caFilepath" "" "certFilepath" "" "keyFilepath" "" "insecureSkipTlsVerify" false )) "username" "" "password" "" "token" "" ))) ))) -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (merge (dict ) $values.console.console.config $c)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.ConnectorsFullName" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (ne (dig "connectors" "connectors" "fullnameOverwrite" "" $dot.Values.AsMap) "") -}} +{{- $_is_returning = true -}} +{{- (dict "r" (get (fromJson (include "redpanda.cleanForK8s" (dict "a" (list $values.connectors.connectors.fullnameOverwrite) ))) "r")) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (get (fromJson (include "redpanda.cleanForK8s" (dict "a" (list (printf "%s-connectors" $dot.Release.Name)) ))) "r")) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + diff --git a/charts/redpanda/redpanda/5.9.2/templates/_example-commands.tpl b/charts/redpanda/redpanda/5.9.2/templates/_example-commands.tpl new file mode 100644 index 0000000000..9a5c695e32 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/_example-commands.tpl @@ -0,0 +1,58 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You 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. +*/}} + + +{{/* +Any rpk command that's given to the user in NOTES.txt must be defined in this template file +and tested in a test. +*/}} + +{{/* tested in tests/test-kafka-sasl-status.yaml */}} +{{- define "rpk-acl-user-create" -}} +{{- $cmd := (get ((include "redpanda.RpkACLUserCreate" (dict "a" (list .))) | fromJson) "r") }} +{{- $cmd }} +{{- end -}} + +{{/* tested in tests/test-kafka-sasl-status.yaml */}} +{{- define "rpk-acl-create" -}} +{{- $cmd := (get ((include "redpanda.RpkACLCreate" (dict "a" (list .))) | fromJson) "r") }} +{{- $cmd }} +{{- end -}} + +{{/* tested in tests/test-kafka-sasl-status.yaml */}} +{{- define "rpk-cluster-info" -}} +{{- $cmd := (get ((include "redpanda.RpkClusterInfo" (dict "a" (list .))) | fromJson) "r") }} +{{- $cmd }} +{{- end -}} + +{{/* tested in tests/test-kafka-sasl-status.yaml */}} +{{- define "rpk-topic-create" -}} +{{- $cmd := (get ((include "redpanda.RpkTopicCreate" (dict "a" (list .))) | fromJson) "r") }} +{{- $cmd }} +{{- end -}} + +{{/* tested in tests/test-kafka-sasl-status.yaml */}} +{{- define "rpk-topic-describe" -}} +{{- $cmd := (get ((include "redpanda.RpkTopicDescribe" (dict "a" (list .))) | fromJson) "r") }} +{{- $cmd }} +{{- end -}} + +{{/* tested in tests/test-kafka-sasl-status.yaml */}} +{{- define "rpk-topic-delete" -}} +{{- $cmd := (get ((include "redpanda.RpkTopicDelete" (dict "a" (list .))) | fromJson) "r") }} +{{- $cmd }} +{{- end -}} \ No newline at end of file diff --git a/charts/redpanda/redpanda/5.9.2/templates/_helpers.go.tpl b/charts/redpanda/redpanda/5.9.2/templates/_helpers.go.tpl new file mode 100644 index 0000000000..c910f646ad --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/_helpers.go.tpl @@ -0,0 +1,535 @@ +{{- /* Generated from "helpers.go" */ -}} + +{{- define "redpanda.Chart" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $_is_returning = true -}} +{{- (dict "r" (get (fromJson (include "redpanda.cleanForK8s" (dict "a" (list (replace "+" "_" (printf "%s-%s" $dot.Chart.Name $dot.Chart.Version))) ))) "r")) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.Name" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $tmp_tuple_1 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.typetest" (dict "a" (list "string" (index $dot.Values "nameOverride") "") ))) "r")) ))) "r") -}} +{{- $ok_2 := $tmp_tuple_1.T2 -}} +{{- $override_1 := $tmp_tuple_1.T1 -}} +{{- if (and $ok_2 (ne $override_1 "")) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (get (fromJson (include "redpanda.cleanForK8s" (dict "a" (list $override_1) ))) "r")) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (get (fromJson (include "redpanda.cleanForK8s" (dict "a" (list $dot.Chart.Name) ))) "r")) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.Fullname" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $tmp_tuple_2 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.typetest" (dict "a" (list "string" (index $dot.Values "fullnameOverride") "") ))) "r")) ))) "r") -}} +{{- $ok_4 := $tmp_tuple_2.T2 -}} +{{- $override_3 := $tmp_tuple_2.T1 -}} +{{- if (and $ok_4 (ne $override_3 "")) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (get (fromJson (include "redpanda.cleanForK8s" (dict "a" (list $override_3) ))) "r")) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (get (fromJson (include "redpanda.cleanForK8s" (dict "a" (list $dot.Release.Name) ))) "r")) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.FullLabels" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $labels := (dict ) -}} +{{- if (ne $values.commonLabels (coalesce nil)) -}} +{{- $labels = $values.commonLabels -}} +{{- end -}} +{{- $defaults := (dict "helm.sh/chart" (get (fromJson (include "redpanda.Chart" (dict "a" (list $dot) ))) "r") "app.kubernetes.io/name" (get (fromJson (include "redpanda.Name" (dict "a" (list $dot) ))) "r") "app.kubernetes.io/instance" $dot.Release.Name "app.kubernetes.io/managed-by" $dot.Release.Service "app.kubernetes.io/component" (get (fromJson (include "redpanda.Name" (dict "a" (list $dot) ))) "r") ) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (merge (dict ) $labels $defaults)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.ServiceAccountName" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $serviceAccount := $values.serviceAccount -}} +{{- if (and $serviceAccount.create (ne $serviceAccount.name "")) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $serviceAccount.name) | toJson -}} +{{- break -}} +{{- else -}}{{- if $serviceAccount.create -}} +{{- $_is_returning = true -}} +{{- (dict "r" (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r")) | toJson -}} +{{- break -}} +{{- else -}}{{- if (ne $serviceAccount.name "") -}} +{{- $_is_returning = true -}} +{{- (dict "r" $serviceAccount.name) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" "default") | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.Tag" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $tag := (toString $values.image.tag) -}} +{{- if (eq $tag "") -}} +{{- $tag = $dot.Chart.AppVersion -}} +{{- end -}} +{{- $pattern := "^v(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$" -}} +{{- if (not (regexMatch $pattern $tag)) -}} +{{- $_ := (fail "image.tag must start with a 'v' and be a valid semver") -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $tag) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.ServiceName" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (and (ne $values.service (coalesce nil)) (ne $values.service.name (coalesce nil))) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (get (fromJson (include "redpanda.cleanForK8s" (dict "a" (list $values.service.name) ))) "r")) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r")) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.InternalDomain" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $service := (get (fromJson (include "redpanda.ServiceName" (dict "a" (list $dot) ))) "r") -}} +{{- $ns := $dot.Release.Namespace -}} +{{- $domain := (trimSuffix "." $values.clusterDomain) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (printf "%s.%s.svc.%s." $service $ns $domain)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.TLSEnabled" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if $values.tls.enabled -}} +{{- $_is_returning = true -}} +{{- (dict "r" true) | toJson -}} +{{- break -}} +{{- end -}} +{{- $listeners := (list "kafka" "admin" "schemaRegistry" "rpc" "http") -}} +{{- range $_, $listener := $listeners -}} +{{- $tlsCert := (dig "listeners" $listener "tls" "cert" false $dot.Values.AsMap) -}} +{{- $tlsEnabled := (dig "listeners" $listener "tls" "enabled" false $dot.Values.AsMap) -}} +{{- if (and (not (empty $tlsEnabled)) (not (empty $tlsCert))) -}} +{{- $_is_returning = true -}} +{{- (dict "r" true) | toJson -}} +{{- break -}} +{{- end -}} +{{- $external := (dig "listeners" $listener "external" false $dot.Values.AsMap) -}} +{{- if (empty $external) -}} +{{- continue -}} +{{- end -}} +{{- $keys := (keys (get (fromJson (include "_shims.typeassertion" (dict "a" (list (printf "map[%s]%s" "string" "interface {}") $external) ))) "r")) -}} +{{- range $_, $key := $keys -}} +{{- $enabled := (dig "listeners" $listener "external" $key "enabled" false $dot.Values.AsMap) -}} +{{- $tlsCert := (dig "listeners" $listener "external" $key "tls" "cert" false $dot.Values.AsMap) -}} +{{- $tlsEnabled := (dig "listeners" $listener "external" $key "tls" "enabled" false $dot.Values.AsMap) -}} +{{- if (and (and (not (empty $enabled)) (not (empty $tlsCert))) (not (empty $tlsEnabled))) -}} +{{- $_is_returning = true -}} +{{- (dict "r" true) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" false) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.ClientAuthRequired" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $listeners := (list "kafka" "admin" "schemaRegistry" "rpc" "http") -}} +{{- range $_, $listener := $listeners -}} +{{- $required := (dig "listeners" $listener "tls" "requireClientAuth" false $dot.Values.AsMap) -}} +{{- if (not (empty $required)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" true) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" false) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.DefaultMounts" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $_is_returning = true -}} +{{- (dict "r" (concat (default (list ) (list (mustMergeOverwrite (dict "name" "" "mountPath" "" ) (dict "name" "config" "mountPath" "/etc/redpanda" )))) (default (list ) (get (fromJson (include "redpanda.CommonMounts" (dict "a" (list $dot) ))) "r")))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.CommonMounts" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $mounts := (list ) -}} +{{- $sasl_5 := $values.auth.sasl -}} +{{- if (and $sasl_5.enabled (ne $sasl_5.secretRef "")) -}} +{{- $mounts = (concat (default (list ) $mounts) (list (mustMergeOverwrite (dict "name" "" "mountPath" "" ) (dict "name" "users" "mountPath" "/etc/secrets/users" "readOnly" true )))) -}} +{{- end -}} +{{- if (get (fromJson (include "redpanda.TLSEnabled" (dict "a" (list $dot) ))) "r") -}} +{{- $certNames := (keys $values.tls.certs) -}} +{{- $_ := (sortAlpha $certNames) -}} +{{- range $_, $name := $certNames -}} +{{- $cert := (index $values.tls.certs $name) -}} +{{- if (not (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $cert.enabled true) ))) "r")) -}} +{{- continue -}} +{{- end -}} +{{- $mounts = (concat (default (list ) $mounts) (list (mustMergeOverwrite (dict "name" "" "mountPath" "" ) (dict "name" (printf "redpanda-%s-cert" $name) "mountPath" (printf "/etc/tls/certs/%s" $name) )))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $adminTLS := $values.listeners.admin.tls -}} +{{- if $adminTLS.requireClientAuth -}} +{{- $mounts = (concat (default (list ) $mounts) (list (mustMergeOverwrite (dict "name" "" "mountPath" "" ) (dict "name" "mtls-client" "mountPath" (printf "/etc/tls/certs/%s-client" (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r")) )))) -}} +{{- end -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $mounts) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.DefaultVolumes" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $_is_returning = true -}} +{{- (dict "r" (concat (default (list ) (list (mustMergeOverwrite (dict "name" "" ) (mustMergeOverwrite (dict ) (dict "configMap" (mustMergeOverwrite (dict ) (mustMergeOverwrite (dict ) (dict "name" (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r") )) (dict )) )) (dict "name" "config" )))) (default (list ) (get (fromJson (include "redpanda.CommonVolumes" (dict "a" (list $dot) ))) "r")))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.CommonVolumes" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $volumes := (list ) -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (get (fromJson (include "redpanda.TLSEnabled" (dict "a" (list $dot) ))) "r") -}} +{{- $certNames := (keys $values.tls.certs) -}} +{{- $_ := (sortAlpha $certNames) -}} +{{- range $_, $name := $certNames -}} +{{- $cert := (index $values.tls.certs $name) -}} +{{- if (not (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $cert.enabled true) ))) "r")) -}} +{{- continue -}} +{{- end -}} +{{- $volumes = (concat (default (list ) $volumes) (list (mustMergeOverwrite (dict "name" "" ) (mustMergeOverwrite (dict ) (dict "secret" (mustMergeOverwrite (dict ) (dict "secretName" (get (fromJson (include "redpanda.CertSecretName" (dict "a" (list $dot $name $cert) ))) "r") "defaultMode" (0o440 | int) )) )) (dict "name" (printf "redpanda-%s-cert" $name) )))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $adminTLS := $values.listeners.admin.tls -}} +{{- $cert := (index $values.tls.certs $adminTLS.cert) -}} +{{- if $adminTLS.requireClientAuth -}} +{{- $secretName := (printf "%s-client" (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r")) -}} +{{- if (ne $cert.clientSecretRef (coalesce nil)) -}} +{{- $secretName = $cert.clientSecretRef.name -}} +{{- end -}} +{{- $volumes = (concat (default (list ) $volumes) (list (mustMergeOverwrite (dict "name" "" ) (mustMergeOverwrite (dict ) (dict "secret" (mustMergeOverwrite (dict ) (dict "secretName" $secretName "defaultMode" (0o440 | int) )) )) (dict "name" "mtls-client" )))) -}} +{{- end -}} +{{- end -}} +{{- $sasl_6 := $values.auth.sasl -}} +{{- if (and $sasl_6.enabled (ne $sasl_6.secretRef "")) -}} +{{- $volumes = (concat (default (list ) $volumes) (list (mustMergeOverwrite (dict "name" "" ) (mustMergeOverwrite (dict ) (dict "secret" (mustMergeOverwrite (dict ) (dict "secretName" $sasl_6.secretRef )) )) (dict "name" "users" )))) -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $volumes) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.CertSecretName" -}} +{{- $dot := (index .a 0) -}} +{{- $certName := (index .a 1) -}} +{{- $cert := (index .a 2) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (ne $cert.secretRef (coalesce nil)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $cert.secretRef.name) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (printf "%s-%s-cert" (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r") $certName)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.PodSecurityContext" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $sc := (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $values.statefulset.podSecurityContext $values.statefulset.securityContext) ))) "r") -}} +{{- $_is_returning = true -}} +{{- (dict "r" (mustMergeOverwrite (dict ) (dict "fsGroup" $sc.fsGroup "fsGroupChangePolicy" $sc.fsGroupChangePolicy ))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.ContainerSecurityContext" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $sc := (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $values.statefulset.podSecurityContext $values.statefulset.securityContext) ))) "r") -}} +{{- $_is_returning = true -}} +{{- (dict "r" (mustMergeOverwrite (dict ) (dict "runAsUser" $sc.runAsUser "runAsGroup" (get (fromJson (include "redpanda.coalesce" (dict "a" (list (list $sc.runAsGroup $sc.fsGroup)) ))) "r") "allowPrivilegeEscalation" (get (fromJson (include "redpanda.coalesce" (dict "a" (list (list $sc.allowPrivilegeEscalation $sc.allowPriviledgeEscalation)) ))) "r") "runAsNonRoot" $sc.runAsNonRoot ))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.RedpandaAtLeast_22_2_0" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $_is_returning = true -}} +{{- (dict "r" (get (fromJson (include "redpanda.redpandaAtLeast" (dict "a" (list $dot ">=22.2.0-0 || <0.0.1-0") ))) "r")) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.RedpandaAtLeast_22_3_0" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $_is_returning = true -}} +{{- (dict "r" (get (fromJson (include "redpanda.redpandaAtLeast" (dict "a" (list $dot ">=22.3.0-0 || <0.0.1-0") ))) "r")) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.RedpandaAtLeast_23_1_1" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $_is_returning = true -}} +{{- (dict "r" (get (fromJson (include "redpanda.redpandaAtLeast" (dict "a" (list $dot ">=23.1.1-0 || <0.0.1-0") ))) "r")) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.RedpandaAtLeast_23_1_2" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $_is_returning = true -}} +{{- (dict "r" (get (fromJson (include "redpanda.redpandaAtLeast" (dict "a" (list $dot ">=23.1.2-0 || <0.0.1-0") ))) "r")) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.RedpandaAtLeast_22_3_atleast_22_3_13" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $_is_returning = true -}} +{{- (dict "r" (get (fromJson (include "redpanda.redpandaAtLeast" (dict "a" (list $dot ">=22.3.13-0,<22.4") ))) "r")) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.RedpandaAtLeast_22_2_atleast_22_2_10" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $_is_returning = true -}} +{{- (dict "r" (get (fromJson (include "redpanda.redpandaAtLeast" (dict "a" (list $dot ">=22.2.10-0,<22.3") ))) "r")) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.RedpandaAtLeast_23_2_1" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $_is_returning = true -}} +{{- (dict "r" (get (fromJson (include "redpanda.redpandaAtLeast" (dict "a" (list $dot ">=23.2.1-0 || <0.0.1-0") ))) "r")) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.RedpandaAtLeast_23_3_0" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $_is_returning = true -}} +{{- (dict "r" (get (fromJson (include "redpanda.redpandaAtLeast" (dict "a" (list $dot ">=23.3.0-0 || <0.0.1-0") ))) "r")) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.redpandaAtLeast" -}} +{{- $dot := (index .a 0) -}} +{{- $constraint := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $version := (trimPrefix "v" (get (fromJson (include "redpanda.Tag" (dict "a" (list $dot) ))) "r")) -}} +{{- $tmp_tuple_3 := (get (fromJson (include "_shims.compact" (dict "a" (list (list (semverCompare $constraint $version) nil)) ))) "r") -}} +{{- $err := $tmp_tuple_3.T2 -}} +{{- $result := $tmp_tuple_3.T1 -}} +{{- if (ne $err (coalesce nil)) -}} +{{- $_ := (fail $err) -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $result) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.cleanForK8s" -}} +{{- $in := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $_is_returning = true -}} +{{- (dict "r" (trimSuffix "-" (trunc (63 | int) $in))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.RedpandaSMP" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $coresInMillies := ((get (fromJson (include "_shims.resource_MilliValue" (dict "a" (list $values.resources.cpu.cores) ))) "r") | int64) -}} +{{- if (lt $coresInMillies (1000 | int64)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (1 | int64)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" ((get (fromJson (include "_shims.resource_Value" (dict "a" (list $values.resources.cpu.cores) ))) "r") | int64)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.coalesce" -}} +{{- $values := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- range $_, $v := $values -}} +{{- if (ne $v (coalesce nil)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $v) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.StrategicMergePatch" -}} +{{- $overrides := (index .a 0) -}} +{{- $original := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (ne $overrides.labels (coalesce nil)) -}} +{{- $_ := (set $original.metadata "labels" (merge (dict ) $overrides.labels (default (dict ) $original.metadata.labels))) -}} +{{- end -}} +{{- if (ne $overrides.annotations (coalesce nil)) -}} +{{- $_ := (set $original.metadata "annotations" (merge (dict ) $overrides.annotations (default (dict ) $original.metadata.annotations))) -}} +{{- end -}} +{{- if (ne $overrides.spec.securityContext (coalesce nil)) -}} +{{- $_ := (set $original.spec "securityContext" (merge (dict ) $overrides.spec.securityContext (default (mustMergeOverwrite (dict ) (dict )) $original.spec.securityContext))) -}} +{{- end -}} +{{- $overrideContainers := (dict ) -}} +{{- range $i, $_ := $overrides.spec.containers -}} +{{- $container := (index $overrides.spec.containers $i) -}} +{{- $_ := (set $overrideContainers (toString $container.name) $container) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $merged := (coalesce nil) -}} +{{- range $_, $container := $original.spec.containers -}} +{{- $tmp_tuple_4 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.dicttest" (dict "a" (list $overrideContainers $container.name (coalesce nil)) ))) "r")) ))) "r") -}} +{{- $ok_8 := $tmp_tuple_4.T2 -}} +{{- $override_7 := $tmp_tuple_4.T1 -}} +{{- if $ok_8 -}} +{{- $env := (concat (default (list ) $container.env) (default (list ) $override_7.env)) -}} +{{- $container = (merge (dict ) $override_7 $container) -}} +{{- $_ := (set $container "env" $env) -}} +{{- end -}} +{{- if (eq $container.env (coalesce nil)) -}} +{{- $_ := (set $container "env" (list )) -}} +{{- end -}} +{{- $merged = (concat (default (list ) $merged) (list $container)) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_ := (set $original.spec "containers" $merged) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $original) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + diff --git a/charts/redpanda/redpanda/5.9.2/templates/_helpers.tpl b/charts/redpanda/redpanda/5.9.2/templates/_helpers.tpl new file mode 100644 index 0000000000..a885f9dcd3 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/_helpers.tpl @@ -0,0 +1,368 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You 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. +*/}} +{{/* +Expand the name of the chart. +*/}} +{{- define "redpanda.name" -}} +{{- get ((include "redpanda.Name" (dict "a" (list .))) | fromJson) "r" }} +{{- 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 "redpanda.fullname" -}} +{{- get ((include "redpanda.Fullname" (dict "a" (list .))) | fromJson) "r" }} +{{- end -}} + +{{/* +Create a default service name +*/}} +{{- define "redpanda.servicename" -}} +{{- get ((include "redpanda.ServiceName" (dict "a" (list .))) | fromJson) "r" }} +{{- end -}} + +{{/* +full helm labels + common labels +*/}} +{{- define "full.labels" -}} +{{- (get ((include "redpanda.FullLabels" (dict "a" (list .))) | fromJson) "r") | toYaml }} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "redpanda.chart" -}} +{{- get ((include "redpanda.Chart" (dict "a" (list .))) | fromJson) "r" }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "redpanda.serviceAccountName" -}} +{{- get ((include "redpanda.ServiceAccountName" (dict "a" (list .))) | fromJson) "r" }} +{{- end }} + +{{/* +Use AppVersion if image.tag is not set +*/}} +{{- define "redpanda.tag" -}} +{{- get ((include "redpanda.Tag" (dict "a" (list .))) | fromJson) "r" }} +{{- end -}} + +{{/* Generate internal fqdn */}} +{{- define "redpanda.internal.domain" -}} +{{- get ((include "redpanda.InternalDomain" (dict "a" (list .))) | fromJson) "r" }} +{{- end -}} + +{{/* ConfigMap variables */}} +{{- define "admin-internal-tls-enabled" -}} +{{- toJson (dict "bool" (get ((include "redpanda.InternalTLS.IsEnabled" (dict "a" (list .Values.listeners.admin.tls .Values.tls))) | fromJson) "r")) -}} +{{- end -}} + +{{- define "kafka-internal-tls-enabled" -}} +{{- $listener := .Values.listeners.kafka -}} +{{- toJson (dict "bool" (and (dig "tls" "enabled" .Values.tls.enabled $listener) (not (empty (dig "tls" "cert" "" $listener))))) -}} +{{- end -}} + +{{- define "kafka-external-tls-cert" -}} +{{- dig "tls" "cert" .Values.listeners.kafka.tls.cert .listener -}} +{{- end -}} + +{{- define "http-internal-tls-enabled" -}} +{{- $listener := .Values.listeners.http -}} +{{- toJson (dict "bool" (and (dig "tls" "enabled" .Values.tls.enabled $listener) (not (empty (dig "tls" "cert" "" $listener))))) -}} +{{- end -}} + +{{- define "schemaRegistry-internal-tls-enabled" -}} +{{- $listener := .Values.listeners.schemaRegistry -}} +{{- toJson (dict "bool" (and (dig "tls" "enabled" .Values.tls.enabled $listener) (not (empty (dig "tls" "cert" "" $listener))))) -}} +{{- end -}} + +{{- define "tls-enabled" -}} +{{- $tlsenabled := get ((include "redpanda.TLSEnabled" (dict "a" (list .))) | fromJson) "r" }} +{{- toJson (dict "bool" $tlsenabled) -}} +{{- end -}} + +{{- define "sasl-enabled" -}} +{{- toJson (dict "bool" (dig "enabled" false .Values.auth.sasl)) -}} +{{- end -}} + +{{- define "admin-api-urls" -}} +{{ printf "${SERVICE_NAME}.%s" (include "redpanda.internal.domain" .) }}:{{.Values.listeners.admin.port }} +{{- end -}} + +{{- define "admin-api-service-url" -}} +{{ include "redpanda.internal.domain" .}}:{{.Values.listeners.admin.port }} +{{- end -}} + +{{- define "sasl-mechanism" -}} +{{- dig "sasl" "mechanism" "SCRAM-SHA-512" .Values.auth -}} +{{- end -}} + +{{- define "fail-on-insecure-sasl-logging" -}} +{{- if (include "sasl-enabled" .|fromJson).bool -}} + {{- $check := list + (include "redpanda-atleast-23-1-1" .|fromJson).bool + (include "redpanda-22-3-atleast-22-3-13" .|fromJson).bool + (include "redpanda-22-2-atleast-22-2-10" .|fromJson).bool + -}} + {{- if not (mustHas true $check) -}} + {{- fail "SASL is enabled and the redpanda version specified leaks secrets to the logs. Please choose a newer version of redpanda." -}} + {{- end -}} +{{- end -}} +{{- end -}} + +{{- define "fail-on-unsupported-helm-version" -}} + {{- $helmVer := (fromYaml (toYaml .Capabilities.HelmVersion)).version -}} + {{- if semverCompare "<3.8.0-0" $helmVer -}} + {{- fail (printf "helm version %s is not supported. Please use helm version v3.8.0 or newer." $helmVer) -}} + {{- end -}} +{{- end -}} + +{{- define "redpanda-atleast-22-2-0" -}} +{{- toJson (dict "bool" (get ((include "redpanda.RedpandaAtLeast_22_2_0" (dict "a" (list .))) | fromJson) "r")) }} +{{- end -}} +{{- define "redpanda-atleast-22-3-0" -}} +{{- toJson (dict "bool" (get ((include "redpanda.RedpandaAtLeast_22_3_0" (dict "a" (list .))) | fromJson) "r")) }} +{{- end -}} +{{- define "redpanda-atleast-23-1-1" -}} +{{- toJson (dict "bool" (get ((include "redpanda.RedpandaAtLeast_23_1_1" (dict "a" (list .))) | fromJson) "r")) }} +{{- end -}} +{{- define "redpanda-atleast-23-1-2" -}} +{{- toJson (dict "bool" (get ((include "redpanda.RedpandaAtLeast_23_1_2" (dict "a" (list .))) | fromJson) "r")) }} +{{- end -}} +{{- define "redpanda-22-3-atleast-22-3-13" -}} +{{- toJson (dict "bool" (get ((include "redpanda.RedpandaAtLeast_22_3_atleast_22_3_13" (dict "a" (list .))) | fromJson) "r")) }} +{{- end -}} +{{- define "redpanda-22-2-atleast-22-2-10" -}} +{{- toJson (dict "bool" (get ((include "redpanda.RedpandaAtLeast_22_2_atleast_22_2_10" (dict "a" (list .))) | fromJson) "r")) }} +{{- end -}} +{{- define "redpanda-atleast-23-2-1" -}} +{{- toJson (dict "bool" (get ((include "redpanda.RedpandaAtLeast_23_2_1" (dict "a" (list .))) | fromJson) "r")) }} +{{- end -}} +{{- define "redpanda-atleast-23-3-0" -}} +{{- toJson (dict "bool" (get ((include "redpanda.RedpandaAtLeast_23_3_0" (dict "a" (list .))) | fromJson) "r")) }} +{{- end -}} + +{{- define "redpanda-22-2-x-without-sasl" -}} +{{- $result := (include "redpanda-atleast-22-3-0" . | fromJson).bool -}} +{{- if or (include "sasl-enabled" . | fromJson).bool .Values.listeners.kafka.authenticationMethod -}} +{{- $result := false -}} +{{- end -}} +{{- toJson (dict "bool" $result) -}} +{{- end -}} + +{{- define "pod-security-context" -}} +{{- get ((include "redpanda.PodSecurityContext" (dict "a" (list .))) | fromJson) "r" | toYaml }} +{{- end -}} + +{{- define "container-security-context" -}} +{{- get ((include "redpanda.ContainerSecurityContext" (dict "a" (list .))) | fromJson) "r" | toYaml }} +{{- end -}} + +{{- define "admin-tls-curl-flags" -}} + {{- $result := "" -}} + {{- if (include "admin-internal-tls-enabled" . | fromJson).bool -}} + {{- $path := (printf "/etc/tls/certs/%s" .Values.listeners.admin.tls.cert) -}} + {{- $result = (printf "--cacert %s/tls.crt" $path) -}} + {{- if .Values.listeners.admin.tls.requireClientAuth -}} + {{- $result = (printf "--cacert %s/ca.crt --cert %s/tls.crt --key %s/tls.key" $path $path $path) -}} + {{- end -}} + {{- end -}} + {{- $result -}} +{{- end -}} + +{{- define "admin-http-protocol" -}} + {{- $result := "http" -}} + {{- if (include "admin-internal-tls-enabled" . | fromJson).bool -}} + {{- $result = "https" -}} + {{- end -}} + {{- $result -}} +{{- end -}} + +{{- /* +advertised-port returns either the only advertised port if only one is specified, +or the port specified for this pod ordinal when there is a full list provided. + +This will return a string int or panic if there is more than one port provided, +but not enough ports for the number of replicas requested. +*/ -}} +{{- define "advertised-port" -}} + {{- $port := dig "port" .listenerVals.port .externalVals -}} + {{- if .externalVals.advertisedPorts -}} + {{- if eq (len .externalVals.advertisedPorts) 1 -}} + {{- $port = mustFirst .externalVals.advertisedPorts -}} + {{- else -}} + {{- $port = index .externalVals.advertisedPorts .replicaIndex -}} + {{- end -}} + {{- end -}} + {{ $port }} +{{- end -}} + +{{- /* +advertised-host returns a json string with the data needed for configuring the advertised listener +*/ -}} +{{- define "advertised-host" -}} + {{- $host := dict "name" .externalName "address" .externalAdvertiseAddress "port" .port -}} + {{- if .values.external.addresses -}} + {{- $address := "" -}} + {{- if gt (len .values.external.addresses) 1 -}} + {{- $address = (index .values.external.addresses .replicaIndex) -}} + {{- else -}} + {{- $address = (index .values.external.addresses 0) -}} + {{- end -}} + {{- if ( .values.external.domain | default "" ) }} + {{- $host = dict "name" .externalName "address" (printf "%s.%s" $address .values.external.domain) "port" .port -}} + {{- else -}} + {{- $host = dict "name" .externalName "address" $address "port" .port -}} + {{- end -}} + {{- end -}} + {{- toJson $host -}} +{{- end -}} + +{{- define "is-licensed" -}} +{{- toJson (dict "bool" (or (not (empty (include "enterprise-license" . ))) (not (empty (include "enterprise-secret" . ))))) -}} +{{- end -}} + +{{- define "seed-server-list" -}} + {{- $brokers := list -}} + {{- range $ordinal := until (.Values.statefulset.replicas | int) -}} + {{- $brokers = append $brokers (printf "%s-%d.%s" + (include "redpanda.fullname" $) + $ordinal + (include "redpanda.internal.domain" $)) + -}} + {{- end -}} + {{- toJson $brokers -}} +{{- end -}} + +{{/* +return license checks deprecated values if current values is empty +*/}} +{{- define "enterprise-license" -}} +{{- if dig "license" dict .Values.enterprise -}} + {{- .Values.enterprise.license -}} +{{- else -}} + {{- .Values.license_key -}} +{{- end -}} +{{- end -}} + +{{/* +return licenseSecretRef checks deprecated values entry if current values empty +*/}} +{{- define "enterprise-secret" -}} +{{- if ( dig "licenseSecretRef" dict .Values.enterprise ) -}} + {{- .Values.enterprise.licenseSecretRef -}} +{{- else if not (empty .Values.license_secret_ref ) -}} + {{- .Values.license_secret_ref -}} +{{- end -}} +{{- end -}} + +{{/* +return licenseSecretRef.name checks deprecated values entry if current values empty +*/}} +{{- define "enterprise-secret-name" -}} +{{- if ( dig "licenseSecretRef" dict .Values.enterprise ) -}} + {{- dig "name" "" .Values.enterprise.licenseSecretRef -}} +{{- else if not (empty .Values.license_secret_ref ) -}} + {{- dig "secret_name" "" .Values.license_secret_ref -}} +{{- end -}} +{{- end -}} + +{{/* +return licenseSecretRef.key checks deprecated values entry if current values empty +*/}} +{{- define "enterprise-secret-key" -}} +{{- if ( dig "licenseSecretRef" dict .Values.enterprise ) -}} + {{- dig "key" "" .Values.enterprise.licenseSecretRef -}} +{{- else if not (empty .Values.license_secret_ref ) -}} + {{- dig "secret_key" "" .Values.license_secret_ref -}} +{{- end -}} +{{- end -}} + +{{/* mounts that are common to all containers */}} +{{- define "common-mounts" -}} +{{- $mounts := get ((include "redpanda.CommonMounts" (dict "a" (list .))) | fromJson) "r" }} +{{- if $mounts -}} +{{- toYaml $mounts -}} +{{- end -}} +{{- end -}} + +{{/* mounts that are common to most containers */}} +{{- define "default-mounts" -}} +{{- $mounts := get ((include "redpanda.DefaultMounts" (dict "a" (list .))) | fromJson) "r" }} +{{- if $mounts -}} +{{- toYaml $mounts -}} +{{- end -}} +{{- end -}} + +{{/* volumes that are common to all pods */}} +{{- define "common-volumes" -}} +{{- $volumes := get ((include "redpanda.CommonVolumes" (dict "a" (list .))) | fromJson) "r" }} +{{- if $volumes -}} +{{- toYaml $volumes -}} +{{- end -}} +{{- end -}} + +{{/* the default set of volumes for most pods, except the sts pod */}} +{{- define "default-volumes" -}} +{{- $volumes := get ((include "redpanda.DefaultVolumes" (dict "a" (list .))) | fromJson) "r" }} +{{- if $volumes -}} +{{- toYaml $volumes -}} +{{- end -}} +{{- end -}} + +{{/* support legacy storage.tieredConfig */}} +{{- define "storage-tiered-config" -}} +{{- $cfg := get ((include "redpanda.StorageTieredConfig" (dict "a" (list .))) | fromJson) "r" }} +{{- if $cfg -}} +{{- toYaml $cfg -}} +{{- end -}} +{{- end -}} + +{{/* + rpk sasl environment variables + + this will return a string with the correct environment variables to use for SASL based on the + version of the redpada container being used +*/}} +{{- define "rpk-sasl-environment-variables" -}} +{{- if (include "redpanda-atleast-23-2-1" . | fromJson).bool -}} +RPK_USER RPK_PASS RPK_SASL_MECHANISM +{{- else -}} +REDPANDA_SASL_USERNAME REDPANDA_SASL_PASSWORD REDPANDA_SASL_MECHANISM +{{- end -}} +{{- end -}} + +{{- define "curl-options" -}} +{{- print " -svm3 --fail --retry \"120\" --retry-max-time \"120\" --retry-all-errors -o - -w \"\\nstatus=%{http_code} %{redirect_url} size=%{size_download} time=%{time_total} content-type=\\\"%{content_type}\\\"\\n\" "}} +{{- end -}} + +{{- define "advertised-address-template" -}} + {{- $prefixTemplate := dig "prefixTemplate" "" .externalListener -}} + {{- if empty $prefixTemplate -}} + {{- $prefixTemplate = dig "prefixTemplate" "" .externalVals -}} + {{- end -}} + {{ quote $prefixTemplate }} +{{- end -}} + +{{/* check if client auth is enabled for any of the listeners */}} +{{- define "client-auth-required" -}} +{{- $requireClientAuth := get ((include "redpanda.ClientAuthRequired" (dict "a" (list .))) | fromJson) "r" }} +{{- toJson (dict "bool" $requireClientAuth) -}} +{{- end -}} diff --git a/charts/redpanda/redpanda/5.9.2/templates/_memory.go.tpl b/charts/redpanda/redpanda/5.9.2/templates/_memory.go.tpl new file mode 100644 index 0000000000..9f839e66b2 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/_memory.go.tpl @@ -0,0 +1,63 @@ +{{- /* Generated from "memory.go" */ -}} + +{{- define "redpanda.RedpandaReserveMemory" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $rpMem_1 := $values.resources.memory.redpanda -}} +{{- if (and (ne $rpMem_1 (coalesce nil)) (ne $rpMem_1.reserveMemory (coalesce nil))) -}} +{{- $_is_returning = true -}} +{{- (dict "r" ((div ((get (fromJson (include "_shims.resource_Value" (dict "a" (list $rpMem_1.reserveMemory) ))) "r") | int64) ((mul (1024 | int) (1024 | int)))) | int64)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" ((add (((mulf (((get (fromJson (include "redpanda.ContainerMemory" (dict "a" (list $dot) ))) "r") | int64) | float64) 0.002) | float64) | int64) (200 | int64)) | int64)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.RedpandaMemory" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $memory := ((0 | int64) | int64) -}} +{{- $containerMemory := ((get (fromJson (include "redpanda.ContainerMemory" (dict "a" (list $dot) ))) "r") | int64) -}} +{{- $rpMem_2 := $values.resources.memory.redpanda -}} +{{- if (and (ne $rpMem_2 (coalesce nil)) (ne $rpMem_2.memory (coalesce nil))) -}} +{{- $memory = ((div ((get (fromJson (include "_shims.resource_Value" (dict "a" (list $rpMem_2.memory) ))) "r") | int64) ((mul (1024 | int) (1024 | int)))) | int64) -}} +{{- else -}} +{{- $memory = (((mulf ($containerMemory | float64) 0.8) | float64) | int64) -}} +{{- end -}} +{{- if (eq $memory (0 | int64)) -}} +{{- $_ := (fail "unable to get memory value redpanda-memory") -}} +{{- end -}} +{{- if (lt $memory (256 | int64)) -}} +{{- $_ := (fail (printf "%d is below the minimum value for Redpanda" $memory)) -}} +{{- end -}} +{{- if (gt ((add $memory ((get (fromJson (include "redpanda.RedpandaReserveMemory" (dict "a" (list $dot) ))) "r") | int64)) | int64) $containerMemory) -}} +{{- $_ := (fail (printf "Not enough container memory for Redpanda memory values where Redpanda: %d, reserve: %d, container: %d" $memory ((get (fromJson (include "redpanda.RedpandaReserveMemory" (dict "a" (list $dot) ))) "r") | int64) $containerMemory)) -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $memory) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.ContainerMemory" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (ne $values.resources.memory.container.min (coalesce nil)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" ((div ((get (fromJson (include "_shims.resource_Value" (dict "a" (list $values.resources.memory.container.min) ))) "r") | int64) ((mul (1024 | int) (1024 | int)))) | int64)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" ((div ((get (fromJson (include "_shims.resource_Value" (dict "a" (list $values.resources.memory.container.max) ))) "r") | int64) ((mul (1024 | int) (1024 | int)))) | int64)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + diff --git a/charts/redpanda/redpanda/5.9.2/templates/_notes.go.tpl b/charts/redpanda/redpanda/5.9.2/templates/_notes.go.tpl new file mode 100644 index 0000000000..6c1e88a618 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/_notes.go.tpl @@ -0,0 +1,167 @@ +{{- /* Generated from "notes.go" */ -}} + +{{- define "redpanda.Warnings" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $warnings := (coalesce nil) -}} +{{- $w_1 := (get (fromJson (include "redpanda.cpuWarning" (dict "a" (list $dot) ))) "r") -}} +{{- if (ne $w_1 "") -}} +{{- $warnings = (concat (default (list ) $warnings) (list (printf `**Warning**: %s` $w_1))) -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $warnings) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.cpuWarning" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $coresInMillis := ((get (fromJson (include "_shims.resource_MilliValue" (dict "a" (list $values.resources.cpu.cores) ))) "r") | int64) -}} +{{- if (lt $coresInMillis (1000 | int64)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (printf "%dm is below the minimum recommended CPU value for Redpanda" $coresInMillis)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" "") | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.Notes" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $anySASL := (get (fromJson (include "redpanda.Auth.IsSASLEnabled" (dict "a" (list $values.auth) ))) "r") -}} +{{- $notes := (coalesce nil) -}} +{{- $notes = (concat (default (list ) $notes) (list `` `` `` `` (printf `Congratulations on installing %s!` $dot.Chart.Name) `` `The pods will rollout in a few seconds. To check the status:` `` (printf ` kubectl -n %s rollout status statefulset %s --watch` $dot.Release.Namespace (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r")))) -}} +{{- if (and $values.external.enabled (eq $values.external.type "LoadBalancer")) -}} +{{- $notes = (concat (default (list ) $notes) (list `` `If you are using the load balancer service with a cloud provider, the services will likely have automatically-generated addresses. In this scenario the advertised listeners must be updated in order for external access to work. Run the following command once Redpanda is deployed:` `` (printf ` helm upgrade %s redpanda/redpanda --reuse-values -n %s --set $(kubectl get svc -n %s -o jsonpath='{"external.addresses={"}{ range .items[*]}{.status.loadBalancer.ingress[0].ip }{.status.loadBalancer.ingress[0].hostname}{","}{ end }{"}\n"}')` (get (fromJson (include "redpanda.Name" (dict "a" (list $dot) ))) "r") $dot.Release.Namespace $dot.Release.Namespace))) -}} +{{- end -}} +{{- $profiles := (keys $values.listeners.kafka.external) -}} +{{- $_ := (sortAlpha $profiles) -}} +{{- $profileName := (index $profiles (0 | int)) -}} +{{- $notes = (concat (default (list ) $notes) (list `` `Set up rpk for access to your external listeners:`)) -}} +{{- $profile := (index $values.listeners.kafka.external $profileName) -}} +{{- if (get (fromJson (include "redpanda.TLSEnabled" (dict "a" (list $dot) ))) "r") -}} +{{- $external := "" -}} +{{- if (and (ne $profile.tls (coalesce nil)) (ne $profile.tls.cert (coalesce nil))) -}} +{{- $external = $profile.tls.cert -}} +{{- else -}} +{{- $external = $values.listeners.kafka.tls.cert -}} +{{- end -}} +{{- $notes = (concat (default (list ) $notes) (list (printf ` kubectl get secret -n %s %s-%s-cert -o go-template='{{ index .data "ca.crt" | base64decode }}' > ca.crt` $dot.Release.Namespace (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r") $external))) -}} +{{- if (or $values.listeners.kafka.tls.requireClientAuth $values.listeners.admin.tls.requireClientAuth) -}} +{{- $notes = (concat (default (list ) $notes) (list (printf ` kubectl get secret -n %s %s-client -o go-template='{{ index .data "tls.crt" | base64decode }}' > tls.crt` $dot.Release.Namespace (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r")) (printf ` kubectl get secret -n %s %s-client -o go-template='{{ index .data "tls.key" | base64decode }}' > tls.key` $dot.Release.Namespace (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r")))) -}} +{{- end -}} +{{- end -}} +{{- $notes = (concat (default (list ) $notes) (list (printf ` rpk profile create --from-profile <(kubectl get configmap -n %s %s-rpk -o go-template='{{ .data.profile }}') %s` $dot.Release.Namespace (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r") $profileName) `` `Set up dns to look up the pods on their Kubernetes Nodes. You can use this query to get the list of short-names to IP addresses. Add your external domain to the hostnames and you could test by adding these to your /etc/hosts:` `` (printf ` kubectl get pod -n %s -o custom-columns=node:.status.hostIP,name:.metadata.name --no-headers -l app.kubernetes.io/name=redpanda,app.kubernetes.io/component=redpanda-statefulset` $dot.Release.Namespace))) -}} +{{- if $anySASL -}} +{{- $notes = (concat (default (list ) $notes) (list `` `Set the credentials in the environment:` `` (printf ` kubectl -n %s get secret %s -o go-template="{{ range .data }}{{ . | base64decode }}{{ end }}" | IFS=: read -r %s` $dot.Release.Namespace $values.auth.sasl.secretRef (get (fromJson (include "redpanda.RpkSASLEnvironmentVariables" (dict "a" (list $dot) ))) "r")) (printf ` export %s` (get (fromJson (include "redpanda.RpkSASLEnvironmentVariables" (dict "a" (list $dot) ))) "r")))) -}} +{{- end -}} +{{- $notes = (concat (default (list ) $notes) (list `` `Try some sample commands:`)) -}} +{{- if $anySASL -}} +{{- $notes = (concat (default (list ) $notes) (list `Create a user:` `` (printf ` %s` (get (fromJson (include "redpanda.RpkACLUserCreate" (dict "a" (list $dot) ))) "r")) `` `Give the user permissions:` `` (printf ` %s` (get (fromJson (include "redpanda.RpkACLCreate" (dict "a" (list $dot) ))) "r")))) -}} +{{- end -}} +{{- $notes = (concat (default (list ) $notes) (list `` `Get the api status:` `` (printf ` %s` (get (fromJson (include "redpanda.RpkClusterInfo" (dict "a" (list $dot) ))) "r")) `` `Create a topic` `` (printf ` %s` (get (fromJson (include "redpanda.RpkTopicCreate" (dict "a" (list $dot) ))) "r")) `` `Describe the topic:` `` (printf ` %s` (get (fromJson (include "redpanda.RpkTopicDescribe" (dict "a" (list $dot) ))) "r")) `` `Delete the topic:` `` (printf ` %s` (get (fromJson (include "redpanda.RpkTopicDelete" (dict "a" (list $dot) ))) "r")))) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $notes) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.RpkACLUserCreate" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $_is_returning = true -}} +{{- (dict "r" (printf `rpk acl user create myuser --new-password changeme --mechanism %s` (get (fromJson (include "redpanda.SASLMechanism" (dict "a" (list $dot) ))) "r"))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.SASLMechanism" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (ne $values.auth.sasl (coalesce nil)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $values.auth.sasl.mechanism) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" "SCRAM-SHA-512") | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.RpkACLCreate" -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $_is_returning = true -}} +{{- (dict "r" `rpk acl create --allow-principal 'myuser' --allow-host '*' --operation all --topic 'test-topic'`) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.RpkClusterInfo" -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $_is_returning = true -}} +{{- (dict "r" `rpk cluster info`) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.RpkTopicCreate" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $_is_returning = true -}} +{{- (dict "r" (printf `rpk topic create test-topic -p 3 -r %d` (min (3 | int64) (($values.statefulset.replicas | int) | int64)))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.RpkTopicDescribe" -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $_is_returning = true -}} +{{- (dict "r" `rpk topic describe test-topic`) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.RpkTopicDelete" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $_is_returning = true -}} +{{- (dict "r" `rpk topic delete test-topic`) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.RpkSASLEnvironmentVariables" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (get (fromJson (include "redpanda.RedpandaAtLeast_23_2_1" (dict "a" (list $dot) ))) "r") -}} +{{- $_is_returning = true -}} +{{- (dict "r" `RPK_USER RPK_PASS RPK_SASL_MECHANISM`) | toJson -}} +{{- break -}} +{{- else -}} +{{- $_is_returning = true -}} +{{- (dict "r" `REDPANDA_SASL_USERNAME REDPANDA_SASL_PASSWORD REDPANDA_SASL_MECHANISM`) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} +{{- end -}} + diff --git a/charts/redpanda/redpanda/5.9.2/templates/_poddisruptionbudget.go.tpl b/charts/redpanda/redpanda/5.9.2/templates/_poddisruptionbudget.go.tpl new file mode 100644 index 0000000000..763b7b0bdf --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/_poddisruptionbudget.go.tpl @@ -0,0 +1,21 @@ +{{- /* Generated from "poddisruptionbudget.go" */ -}} + +{{- define "redpanda.PodDisruptionBudget" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $budget := ($values.statefulset.budget.maxUnavailable | int) -}} +{{- $minReplicas := ((div ($values.statefulset.replicas | int) (2 | int)) | int) -}} +{{- if (and (gt $budget (1 | int)) (gt $budget $minReplicas)) -}} +{{- $_ := (fail (printf "statefulset.budget.maxUnavailable is set too high to maintain quorum: %d > %d" $budget $minReplicas)) -}} +{{- end -}} +{{- $maxUnavailable := ($budget | int) -}} +{{- $matchLabels := (get (fromJson (include "redpanda.StatefulSetPodLabelsSelector" (dict "a" (list $dot) ))) "r") -}} +{{- $_ := (set $matchLabels "redpanda.com/poddisruptionbudget" (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r")) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "spec" (dict ) "status" (dict "disruptionsAllowed" 0 "currentHealthy" 0 "desiredHealthy" 0 "expectedPods" 0 ) ) (mustMergeOverwrite (dict ) (dict "apiVersion" "policy/v1" "kind" "PodDisruptionBudget" )) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "name" (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r") "namespace" $dot.Release.Namespace "labels" (get (fromJson (include "redpanda.FullLabels" (dict "a" (list $dot) ))) "r") )) "spec" (mustMergeOverwrite (dict ) (dict "selector" (mustMergeOverwrite (dict ) (dict "matchLabels" $matchLabels )) "maxUnavailable" $maxUnavailable )) ))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + diff --git a/charts/redpanda/redpanda/5.9.2/templates/_post-install-upgrade-job.go.tpl b/charts/redpanda/redpanda/5.9.2/templates/_post-install-upgrade-job.go.tpl new file mode 100644 index 0000000000..0d5635d3e1 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/_post-install-upgrade-job.go.tpl @@ -0,0 +1,233 @@ +{{- /* Generated from "post_install_upgrade_job.go" */ -}} + +{{- define "redpanda.PostInstallUpgradeJob" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (not $values.post_install_job.enabled) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $job := (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "spec" (dict "template" (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "spec" (dict "containers" (coalesce nil) ) ) ) "status" (dict ) ) (mustMergeOverwrite (dict ) (dict "apiVersion" "batch/v1" "kind" "Job" )) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "name" (printf "%s-configuration" (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r")) "namespace" $dot.Release.Namespace "labels" (merge (dict ) (get (fromJson (include "redpanda.FullLabels" (dict "a" (list $dot) ))) "r") (default (dict ) $values.post_install_job.labels)) "annotations" (merge (dict ) (dict "helm.sh/hook" "post-install,post-upgrade" "helm.sh/hook-delete-policy" "before-hook-creation" "helm.sh/hook-weight" "-5" ) (default (dict ) $values.post_install_job.annotations)) )) "spec" (mustMergeOverwrite (dict "template" (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "spec" (dict "containers" (coalesce nil) ) ) ) (dict "template" (get (fromJson (include "redpanda.StrategicMergePatch" (dict "a" (list $values.post_install_job.podTemplate (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "spec" (dict "containers" (coalesce nil) ) ) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "generateName" (printf "%s-post-" $dot.Release.Name) "labels" (merge (dict ) (dict "app.kubernetes.io/name" (get (fromJson (include "redpanda.Name" (dict "a" (list $dot) ))) "r") "app.kubernetes.io/instance" $dot.Release.Name "app.kubernetes.io/component" (printf "%.50s-post-install" (get (fromJson (include "redpanda.Name" (dict "a" (list $dot) ))) "r")) ) (default (dict ) $values.commonLabels)) )) "spec" (mustMergeOverwrite (dict "containers" (coalesce nil) ) (dict "nodeSelector" $values.nodeSelector "affinity" (get (fromJson (include "redpanda.postInstallJobAffinity" (dict "a" (list $dot) ))) "r") "tolerations" (get (fromJson (include "redpanda.tolerations" (dict "a" (list $dot) ))) "r") "restartPolicy" "Never" "securityContext" (get (fromJson (include "redpanda.PodSecurityContext" (dict "a" (list $dot) ))) "r") "imagePullSecrets" (default (coalesce nil) $values.imagePullSecrets) "containers" (list (mustMergeOverwrite (dict "name" "" "resources" (dict ) ) (dict "name" "post-install" "image" (printf "%s:%s" $values.image.repository (get (fromJson (include "redpanda.Tag" (dict "a" (list $dot) ))) "r")) "env" (get (fromJson (include "redpanda.PostInstallUpgradeEnvironmentVariables" (dict "a" (list $dot) ))) "r") "command" (list "bash" "-c") "args" (list ) "resources" (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $values.post_install_job.resources (mustMergeOverwrite (dict ) (dict ))) ))) "r") "securityContext" (merge (dict ) (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $values.post_install_job.securityContext (mustMergeOverwrite (dict ) (dict ))) ))) "r") (get (fromJson (include "redpanda.ContainerSecurityContext" (dict "a" (list $dot) ))) "r")) "volumeMounts" (get (fromJson (include "redpanda.DefaultMounts" (dict "a" (list $dot) ))) "r") ))) "volumes" (get (fromJson (include "redpanda.DefaultVolumes" (dict "a" (list $dot) ))) "r") "serviceAccountName" (get (fromJson (include "redpanda.ServiceAccountName" (dict "a" (list $dot) ))) "r") )) ))) ))) "r") )) )) -}} +{{- $script := (coalesce nil) -}} +{{- $script = (concat (default (list ) $script) (list `set -e`)) -}} +{{- if (get (fromJson (include "redpanda.RedpandaAtLeast_22_2_0" (dict "a" (list $dot) ))) "r") -}} +{{- $script = (concat (default (list ) $script) (list `if [[ -n "$REDPANDA_LICENSE" ]] then` ` rpk cluster license set "$REDPANDA_LICENSE"` `fi`)) -}} +{{- end -}} +{{- $script = (concat (default (list ) $script) (list `` `` `` `` `rpk cluster config export -f /tmp/cfg.yml` `` `` `for KEY in "${!RPK_@}"; do` ` config="${KEY#*RPK_}"` ` rpk redpanda config set --config /tmp/cfg.yml "${config,,}" "${!KEY}"` `done` `` `` `rpk cluster config import -f /tmp/cfg.yml` ``)) -}} +{{- $_ := (set (index $job.spec.template.spec.containers (0 | int)) "args" (concat (default (list ) (index $job.spec.template.spec.containers (0 | int)).args) (list (join "\n" $script)))) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $job) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.postInstallJobAffinity" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (not (empty $values.post_install_job.affinity)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $values.post_install_job.affinity) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (merge (dict ) $values.post_install_job.affinity $values.affinity)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.tolerations" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $result := (coalesce nil) -}} +{{- range $_, $t := $values.tolerations -}} +{{- $result = (concat (default (list ) $result) (list (merge (dict ) $t))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $result) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.PostInstallUpgradeEnvironmentVariables" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $envars := (list ) -}} +{{- $license_1 := (get (fromJson (include "redpanda.GetLicenseLiteral" (dict "a" (list $dot) ))) "r") -}} +{{- $secretReference_2 := (get (fromJson (include "redpanda.GetLicenseSecretReference" (dict "a" (list $dot) ))) "r") -}} +{{- if (ne $license_1 "") -}} +{{- $envars = (concat (default (list ) $envars) (list (mustMergeOverwrite (dict "name" "" ) (dict "name" "REDPANDA_LICENSE" "value" $license_1 )))) -}} +{{- else -}}{{- if (ne $secretReference_2 (coalesce nil)) -}} +{{- $envars = (concat (default (list ) $envars) (list (mustMergeOverwrite (dict "name" "" ) (dict "name" "REDPANDA_LICENSE" "valueFrom" (mustMergeOverwrite (dict ) (dict "secretKeyRef" $secretReference_2 )) )))) -}} +{{- end -}} +{{- end -}} +{{- if (not (get (fromJson (include "redpanda.Storage.IsTieredStorageEnabled" (dict "a" (list $values.storage) ))) "r")) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $envars) | toJson -}} +{{- break -}} +{{- end -}} +{{- $tieredStorageConfig := (get (fromJson (include "redpanda.Storage.GetTieredStorageConfig" (dict "a" (list $values.storage) ))) "r") -}} +{{- $tmp_tuple_1 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.dicttest" (dict "a" (list $tieredStorageConfig "cloud_storage_azure_container" (coalesce nil)) ))) "r")) ))) "r") -}} +{{- $azureContainerExists := $tmp_tuple_1.T2 -}} +{{- $ac := $tmp_tuple_1.T1 -}} +{{- $tmp_tuple_2 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.dicttest" (dict "a" (list $tieredStorageConfig "cloud_storage_azure_storage_account" (coalesce nil)) ))) "r")) ))) "r") -}} +{{- $azureStorageAccountExists := $tmp_tuple_2.T2 -}} +{{- $asa := $tmp_tuple_2.T1 -}} +{{- if (and (and (and $azureContainerExists (ne $ac (coalesce nil))) $azureStorageAccountExists) (ne $asa (coalesce nil))) -}} +{{- $envars = (concat (default (list ) $envars) (default (list ) (get (fromJson (include "redpanda.addAzureSharedKey" (dict "a" (list $tieredStorageConfig $values) ))) "r"))) -}} +{{- else -}} +{{- $envars = (concat (default (list ) $envars) (default (list ) (get (fromJson (include "redpanda.addCloudStorageSecretKey" (dict "a" (list $tieredStorageConfig $values) ))) "r"))) -}} +{{- end -}} +{{- $envars = (concat (default (list ) $envars) (default (list ) (get (fromJson (include "redpanda.addCloudStorageAccessKey" (dict "a" (list $tieredStorageConfig $values) ))) "r"))) -}} +{{- range $k, $v := $tieredStorageConfig -}} +{{- if (or (or (eq $k "cloud_storage_access_key") (eq $k "cloud_storage_secret_key")) (eq $k "cloud_storage_azure_shared_key")) -}} +{{- continue -}} +{{- end -}} +{{- if (or (eq $v (coalesce nil)) (empty $v)) -}} +{{- continue -}} +{{- end -}} +{{- if (and (eq $k "cloud_storage_cache_size") (ne $v (coalesce nil))) -}} +{{- $envars = (concat (default (list ) $envars) (list (mustMergeOverwrite (dict "name" "" ) (dict "name" (printf "RPK_%s" (upper $k)) "value" (toJson ((get (fromJson (include "_shims.resource_Value" (dict "a" (list $v) ))) "r") | int64)) )))) -}} +{{- continue -}} +{{- end -}} +{{- $tmp_tuple_3 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.typetest" (dict "a" (list "string" $v "") ))) "r")) ))) "r") -}} +{{- $ok_4 := $tmp_tuple_3.T2 -}} +{{- $str_3 := $tmp_tuple_3.T1 -}} +{{- if $ok_4 -}} +{{- $envars = (concat (default (list ) $envars) (list (mustMergeOverwrite (dict "name" "" ) (dict "name" (printf "RPK_%s" (upper $k)) "value" $str_3 )))) -}} +{{- else -}} +{{- $envars = (concat (default (list ) $envars) (list (mustMergeOverwrite (dict "name" "" ) (dict "name" (printf "RPK_%s" (upper $k)) "value" (mustToJson $v) )))) -}} +{{- end -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $envars) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.addCloudStorageAccessKey" -}} +{{- $tieredStorageConfig := (index .a 0) -}} +{{- $values := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $tmp_tuple_4 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.dicttest" (dict "a" (list $tieredStorageConfig "cloud_storage_access_key" (coalesce nil)) ))) "r")) ))) "r") -}} +{{- $ok_6 := $tmp_tuple_4.T2 -}} +{{- $v_5 := $tmp_tuple_4.T1 -}} +{{- $ak_7 := $values.storage.tiered.credentialsSecretRef.accessKey -}} +{{- if (and $ok_6 (ne $v_5 "")) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list (mustMergeOverwrite (dict "name" "" ) (dict "name" "RPK_CLOUD_STORAGE_ACCESS_KEY" "value" (get (fromJson (include "_shims.typeassertion" (dict "a" (list "string" $v_5) ))) "r") )))) | toJson -}} +{{- break -}} +{{- else -}}{{- if (get (fromJson (include "redpanda.SecretRef.IsValid" (dict "a" (list $ak_7) ))) "r") -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list (mustMergeOverwrite (dict "name" "" ) (dict "name" "RPK_CLOUD_STORAGE_ACCESS_KEY" "valueFrom" (mustMergeOverwrite (dict ) (dict "secretKeyRef" (mustMergeOverwrite (dict "key" "" ) (mustMergeOverwrite (dict ) (dict "name" $ak_7.name )) (dict "key" $ak_7.key )) )) )))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list )) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.addCloudStorageSecretKey" -}} +{{- $tieredStorageConfig := (index .a 0) -}} +{{- $values := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $tmp_tuple_5 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.dicttest" (dict "a" (list $tieredStorageConfig "cloud_storage_secret_key" (coalesce nil)) ))) "r")) ))) "r") -}} +{{- $ok_9 := $tmp_tuple_5.T2 -}} +{{- $v_8 := $tmp_tuple_5.T1 -}} +{{- $sk_10 := $values.storage.tiered.credentialsSecretRef.secretKey -}} +{{- if (and $ok_9 (ne $v_8 "")) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list (mustMergeOverwrite (dict "name" "" ) (dict "name" "RPK_CLOUD_STORAGE_SECRET_KEY" "value" (get (fromJson (include "_shims.typeassertion" (dict "a" (list "string" $v_8) ))) "r") )))) | toJson -}} +{{- break -}} +{{- else -}}{{- if (get (fromJson (include "redpanda.SecretRef.IsValid" (dict "a" (list $sk_10) ))) "r") -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list (mustMergeOverwrite (dict "name" "" ) (dict "name" "RPK_CLOUD_STORAGE_SECRET_KEY" "valueFrom" (mustMergeOverwrite (dict ) (dict "secretKeyRef" (mustMergeOverwrite (dict "key" "" ) (mustMergeOverwrite (dict ) (dict "name" $sk_10.name )) (dict "key" $sk_10.key )) )) )))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list )) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.addAzureSharedKey" -}} +{{- $tieredStorageConfig := (index .a 0) -}} +{{- $values := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $tmp_tuple_6 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.dicttest" (dict "a" (list $tieredStorageConfig "cloud_storage_azure_shared_key" (coalesce nil)) ))) "r")) ))) "r") -}} +{{- $ok_12 := $tmp_tuple_6.T2 -}} +{{- $v_11 := $tmp_tuple_6.T1 -}} +{{- $sk_13 := $values.storage.tiered.credentialsSecretRef.secretKey -}} +{{- if (and $ok_12 (ne $v_11 "")) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list (mustMergeOverwrite (dict "name" "" ) (dict "name" "RPK_CLOUD_STORAGE_AZURE_SHARED_KEY" "value" (get (fromJson (include "_shims.typeassertion" (dict "a" (list "string" $v_11) ))) "r") )))) | toJson -}} +{{- break -}} +{{- else -}}{{- if (get (fromJson (include "redpanda.SecretRef.IsValid" (dict "a" (list $sk_13) ))) "r") -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list (mustMergeOverwrite (dict "name" "" ) (dict "name" "RPK_CLOUD_STORAGE_AZURE_SHARED_KEY" "valueFrom" (mustMergeOverwrite (dict ) (dict "secretKeyRef" (mustMergeOverwrite (dict "key" "" ) (mustMergeOverwrite (dict ) (dict "name" $sk_13.name )) (dict "key" $sk_13.key )) )) )))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list )) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.GetLicenseLiteral" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (ne $values.enterprise.license "") -}} +{{- $_is_returning = true -}} +{{- (dict "r" $values.enterprise.license) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $values.license_key) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.GetLicenseSecretReference" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (not (empty $values.enterprise.licenseSecretRef)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (mustMergeOverwrite (dict "key" "" ) (mustMergeOverwrite (dict ) (dict "name" $values.enterprise.licenseSecretRef.name )) (dict "key" $values.enterprise.licenseSecretRef.key ))) | toJson -}} +{{- break -}} +{{- else -}}{{- if (not (empty $values.license_secret_ref)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (mustMergeOverwrite (dict "key" "" ) (mustMergeOverwrite (dict ) (dict "name" $values.license_secret_ref.secret_name )) (dict "key" $values.license_secret_ref.secret_key ))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + diff --git a/charts/redpanda/redpanda/5.9.2/templates/_secrets.go.tpl b/charts/redpanda/redpanda/5.9.2/templates/_secrets.go.tpl new file mode 100644 index 0000000000..09a32e197b --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/_secrets.go.tpl @@ -0,0 +1,385 @@ +{{- /* Generated from "secrets.go" */ -}} + +{{- define "redpanda.Secrets" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $secrets := (coalesce nil) -}} +{{- $secrets = (concat (default (list ) $secrets) (list (get (fromJson (include "redpanda.SecretSTSLifecycle" (dict "a" (list $dot) ))) "r"))) -}} +{{- $saslUsers_1 := (get (fromJson (include "redpanda.SecretSASLUsers" (dict "a" (list $dot) ))) "r") -}} +{{- if (ne $saslUsers_1 (coalesce nil)) -}} +{{- $secrets = (concat (default (list ) $secrets) (list $saslUsers_1)) -}} +{{- end -}} +{{- $configWatcher_2 := (get (fromJson (include "redpanda.SecretConfigWatcher" (dict "a" (list $dot) ))) "r") -}} +{{- if (ne $configWatcher_2 (coalesce nil)) -}} +{{- $secrets = (concat (default (list ) $secrets) (list $configWatcher_2)) -}} +{{- end -}} +{{- $secrets = (concat (default (list ) $secrets) (list (get (fromJson (include "redpanda.SecretConfigurator" (dict "a" (list $dot) ))) "r"))) -}} +{{- $fsValidator_3 := (get (fromJson (include "redpanda.SecretFSValidator" (dict "a" (list $dot) ))) "r") -}} +{{- if (ne $fsValidator_3 (coalesce nil)) -}} +{{- $secrets = (concat (default (list ) $secrets) (list $fsValidator_3)) -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $secrets) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.SecretSTSLifecycle" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $secret := (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) ) (mustMergeOverwrite (dict ) (dict "apiVersion" "v1" "kind" "Secret" )) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "name" (printf "%s-sts-lifecycle" (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r")) "namespace" $dot.Release.Namespace "labels" (get (fromJson (include "redpanda.FullLabels" (dict "a" (list $dot) ))) "r") )) "type" "Opaque" "stringData" (dict ) )) -}} +{{- $adminCurlFlags := (get (fromJson (include "redpanda.adminTLSCurlFlags" (dict "a" (list $dot) ))) "r") -}} +{{- $_ := (set $secret.stringData "common.sh" (join "\n" (list `#!/usr/bin/env bash` `` `# the SERVICE_NAME comes from the metadata.name of the pod, essentially the POD_NAME` (printf `CURL_URL="%s"` (get (fromJson (include "redpanda.adminInternalURL" (dict "a" (list $dot) ))) "r")) `` `# commands used throughout` (printf `CURL_NODE_ID_CMD="curl --silent --fail %s ${CURL_URL}/v1/node_config"` $adminCurlFlags) `` `CURL_MAINTENANCE_DELETE_CMD_PREFIX='curl -X DELETE --silent -o /dev/null -w "%{http_code}"'` `CURL_MAINTENANCE_PUT_CMD_PREFIX='curl -X PUT --silent -o /dev/null -w "%{http_code}"'` (printf `CURL_MAINTENANCE_GET_CMD="curl -X GET --silent %s ${CURL_URL}/v1/maintenance"` $adminCurlFlags)))) -}} +{{- $postStartSh := (list `#!/usr/bin/env bash` `# This code should be similar if not exactly the same as that found in the panda-operator, see` `# https://github.com/redpanda-data/redpanda/blob/e51d5b7f2ef76d5160ca01b8c7a8cf07593d29b6/src/go/k8s/pkg/resources/secret.go` `` `# path below should match the path defined on the statefulset` `source /var/lifecycle/common.sh` `` `postStartHook () {` ` set -x` `` ` touch /tmp/postStartHookStarted` `` ` until NODE_ID=$(${CURL_NODE_ID_CMD} | grep -o '\"node_id\":[^,}]*' | grep -o '[^: ]*$'); do` ` sleep 0.5` ` done` `` ` echo "Clearing maintenance mode on node ${NODE_ID}"` (printf ` CURL_MAINTENANCE_DELETE_CMD="${CURL_MAINTENANCE_DELETE_CMD_PREFIX} %s ${CURL_URL}/v1/brokers/${NODE_ID}/maintenance"` $adminCurlFlags) ` # a 400 here would mean not in maintenance mode` ` until [ "${status:-}" = '"200"' ] || [ "${status:-}" = '"400"' ]; do` ` status=$(${CURL_MAINTENANCE_DELETE_CMD})` ` sleep 0.5` ` done`) -}} +{{- if (and $values.auth.sasl.enabled (ne $values.auth.sasl.secretRef "")) -}} +{{- $postStartSh = (concat (default (list ) $postStartSh) (list ` # Setup and export SASL bootstrap-user` ` IFS=":" read -r USER_NAME PASSWORD MECHANISM < <(grep "" $(find /etc/secrets/users/* -print))` (printf ` MECHANISM=${MECHANISM:-%s}` (dig "auth" "sasl" "mechanism" "SCRAM-SHA-512" $dot.Values.AsMap)) ` rpk acl user create ${USER_NAME} --password=${PASSWORD} --mechanism ${MECHANISM} || true`)) -}} +{{- end -}} +{{- $postStartSh = (concat (default (list ) $postStartSh) (list `` ` touch /tmp/postStartHookFinished` `}` `` `postStartHook` `true`)) -}} +{{- $_ := (set $secret.stringData "postStart.sh" (join "\n" $postStartSh)) -}} +{{- $preStopSh := (list `#!/usr/bin/env bash` `# This code should be similar if not exactly the same as that found in the panda-operator, see` `# https://github.com/redpanda-data/redpanda/blob/e51d5b7f2ef76d5160ca01b8c7a8cf07593d29b6/src/go/k8s/pkg/resources/secret.go` `` `touch /tmp/preStopHookStarted` `` `# path below should match the path defined on the statefulset` `source /var/lifecycle/common.sh` `` `set -x` `` `preStopHook () {` ` until NODE_ID=$(${CURL_NODE_ID_CMD} | grep -o '\"node_id\":[^,}]*' | grep -o '[^: ]*$'); do` ` sleep 0.5` ` done` `` ` echo "Setting maintenance mode on node ${NODE_ID}"` (printf ` CURL_MAINTENANCE_PUT_CMD="${CURL_MAINTENANCE_PUT_CMD_PREFIX} %s ${CURL_URL}/v1/brokers/${NODE_ID}/maintenance"` $adminCurlFlags) ` until [ "${status:-}" = '"200"' ]; do` ` status=$(${CURL_MAINTENANCE_PUT_CMD})` ` sleep 0.5` ` done` `` ` until [ "${finished:-}" = "true" ] || [ "${draining:-}" = "false" ]; do` ` res=$(${CURL_MAINTENANCE_GET_CMD})` ` finished=$(echo $res | grep -o '\"finished\":[^,}]*' | grep -o '[^: ]*$')` ` draining=$(echo $res | grep -o '\"draining\":[^,}]*' | grep -o '[^: ]*$')` ` sleep 0.5` ` done` `` ` touch /tmp/preStopHookFinished` `}`) -}} +{{- if (and (gt ($values.statefulset.replicas | int) (2 | int)) (not (get (fromJson (include "_shims.typeassertion" (dict "a" (list "bool" (dig "recovery_mode_enabled" false $values.config.node)) ))) "r"))) -}} +{{- $preStopSh = (concat (default (list ) $preStopSh) (list `preStopHook`)) -}} +{{- else -}} +{{- $preStopSh = (concat (default (list ) $preStopSh) (list `touch /tmp/preStopHookFinished` `echo "Not enough replicas or in recovery mode, cannot put a broker into maintenance mode."`)) -}} +{{- end -}} +{{- $preStopSh = (concat (default (list ) $preStopSh) (list `true`)) -}} +{{- $_ := (set $secret.stringData "preStop.sh" (join "\n" $preStopSh)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $secret) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.SecretSASLUsers" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (and (and (ne $values.auth.sasl.secretRef "") $values.auth.sasl.enabled) (gt ((get (fromJson (include "_shims.len" (dict "a" (list $values.auth.sasl.users) ))) "r") | int) (0 | int))) -}} +{{- $secret := (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) ) (mustMergeOverwrite (dict ) (dict "apiVersion" "v1" "kind" "Secret" )) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "name" $values.auth.sasl.secretRef "namespace" $dot.Release.Namespace "labels" (get (fromJson (include "redpanda.FullLabels" (dict "a" (list $dot) ))) "r") )) "type" "Opaque" "stringData" (dict ) )) -}} +{{- $usersTxt := (list ) -}} +{{- range $_, $user := $values.auth.sasl.users -}} +{{- if (empty $user.mechanism) -}} +{{- $usersTxt = (concat (default (list ) $usersTxt) (list (printf "%s:%s" $user.name $user.password))) -}} +{{- else -}} +{{- $usersTxt = (concat (default (list ) $usersTxt) (list (printf "%s:%s:%s" $user.name $user.password $user.mechanism))) -}} +{{- end -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_ := (set $secret.stringData "users.txt" (join "\n" $usersTxt)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $secret) | toJson -}} +{{- break -}} +{{- else -}}{{- if (and $values.auth.sasl.enabled (eq $values.auth.sasl.secretRef "")) -}} +{{- $_ := (fail "auth.sasl.secretRef cannot be empty when auth.sasl.enabled=true") -}} +{{- else -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.SecretConfigWatcher" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (not $values.statefulset.sideCars.configWatcher.enabled) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $sasl := $values.auth.sasl -}} +{{- $secret := (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) ) (mustMergeOverwrite (dict ) (dict "apiVersion" "v1" "kind" "Secret" )) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "name" (printf "%s-config-watcher" (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r")) "namespace" $dot.Release.Namespace "labels" (get (fromJson (include "redpanda.FullLabels" (dict "a" (list $dot) ))) "r") )) "type" "Opaque" "stringData" (dict ) )) -}} +{{- $saslUserSh := (coalesce nil) -}} +{{- $saslUserSh = (concat (default (list ) $saslUserSh) (list `#!/usr/bin/env bash` `` `trap 'error_handler $? $LINENO' ERR` `` `error_handler() {` ` echo "Error: ($1) occurred at line $2"` `}` `` `set -e` `` `# rpk cluster health can exit non-zero if it's unable to dial brokers. This` `# can happen for many reasons but we never want this script to crash as it` `# would take down yet another broker and make a bad situation worse.` `# Instead, just wait for the command to eventually exit zero.` `echo "Waiting for cluster to be ready"` `until rpk cluster health --watch --exit-when-healthy; do` ` echo "rpk cluster health failed. Waiting 5 seconds before trying again..."` ` sleep 5` `done`)) -}} +{{- if (and $sasl.enabled (ne $sasl.secretRef "")) -}} +{{- $saslUserSh = (concat (default (list ) $saslUserSh) (list `while true; do` ` echo "RUNNING: Monitoring and Updating SASL users"` ` USERS_DIR="/etc/secrets/users"` `` ` new_users_list(){` ` LIST=$1` ` NEW_USER=$2` ` if [[ -n "${LIST}" ]]; then` ` LIST="${NEW_USER},${LIST}"` ` else` ` LIST="${NEW_USER}"` ` fi` `` ` echo "${LIST}"` ` }` `` ` process_users() {` ` USERS_DIR=${1-"/etc/secrets/users"}` ` USERS_FILE=$(find ${USERS_DIR}/* -print)` ` USERS_LIST=""` ` READ_LIST_SUCCESS=0` ` # Read line by line, handle a missing EOL at the end of file` ` while read p || [ -n "$p" ] ; do` ` IFS=":" read -r USER_NAME PASSWORD MECHANISM <<< $p` ` # Do not process empty lines` ` if [ -z "$USER_NAME" ]; then` ` continue` ` fi` ` if [[ "${USER_NAME// /}" != "$USER_NAME" ]]; then` ` continue` ` fi` ` echo "Creating user ${USER_NAME}..."` (printf ` MECHANISM=${MECHANISM:-%s}` (dig "auth" "sasl" "mechanism" "SCRAM-SHA-512" $dot.Values.AsMap)) ` creation_result=$(rpk acl user create ${USER_NAME} --password=${PASSWORD} --mechanism ${MECHANISM} 2>&1) && creation_result_exit_code=$? || creation_result_exit_code=$? # On a non-success exit code` ` if [[ $creation_result_exit_code -ne 0 ]]; then` ` # Check if the stderr contains "User already exists"` ` # this error occurs when password has changed` ` if [[ $creation_result == *"User already exists"* ]]; then` ` echo "Update user ${USER_NAME}"` ` # we will try to update by first deleting` ` deletion_result=$(rpk acl user delete ${USER_NAME} 2>&1) && deletion_result_exit_code=$? || deletion_result_exit_code=$?` ` if [[ $deletion_result_exit_code -ne 0 ]]; then` ` echo "deletion of user ${USER_NAME} failed: ${deletion_result}"` ` READ_LIST_SUCCESS=1` ` break` ` fi` ` # Now we update the user` ` update_result=$(rpk acl user create ${USER_NAME} --password=${PASSWORD} --mechanism ${MECHANISM} 2>&1) && update_result_exit_code=$? || update_result_exit_code=$? # On a non-success exit code` ` if [[ $update_result_exit_code -ne 0 ]]; then` ` echo "updating user ${USER_NAME} failed: ${update_result}"` ` READ_LIST_SUCCESS=1` ` break` ` else` ` echo "Updated user ${USER_NAME}..."` ` USERS_LIST=$(new_users_list "${USERS_LIST}" "${USER_NAME}")` ` fi` ` else` ` # Another error occurred, so output the original message and exit code` ` echo "error creating user ${USER_NAME}: ${creation_result}"` ` READ_LIST_SUCCESS=1` ` break` ` fi` ` # On a success, the user was created so output that` ` else` ` echo "Created user ${USER_NAME}..."` ` USERS_LIST=$(new_users_list "${USERS_LIST}" "${USER_NAME}")` ` fi` ` done < $USERS_FILE` `` ` if [[ -n "${USERS_LIST}" && ${READ_LIST_SUCCESS} ]]; then` ` echo "Setting superusers configurations with users [${USERS_LIST}]"` ` superuser_result=$(rpk cluster config set superusers [${USERS_LIST}] 2>&1) && superuser_result_exit_code=$? || superuser_result_exit_code=$?` ` if [[ $superuser_result_exit_code -ne 0 ]]; then` ` echo "Setting superusers configurations failed: ${superuser_result}"` ` else` ` echo "Completed setting superusers configurations"` ` fi` ` fi` ` }` `` ` # first time processing` ` process_users $USERS_DIR` `` ` # subsequent changes detected here` ` # watching delete_self as documented in https://ahmet.im/blog/kubernetes-inotify/` ` USERS_FILE=$(find ${USERS_DIR}/* -print)` ` while RES=$(inotifywait -q -e delete_self ${USERS_FILE}); do` ` process_users $USERS_DIR` ` done` `done`)) -}} +{{- else -}} +{{- $saslUserSh = (concat (default (list ) $saslUserSh) (list `echo "Nothing to do. Sleeping..."` `sleep infinity`)) -}} +{{- end -}} +{{- $_ := (set $secret.stringData "sasl-user.sh" (join "\n" $saslUserSh)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $secret) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.SecretFSValidator" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (not $values.statefulset.initContainers.fsValidator.enabled) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $secret := (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) ) (mustMergeOverwrite (dict ) (dict "apiVersion" "v1" "kind" "Secret" )) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "name" (printf "%s-fs-validator" (substr 0 (49 | int) (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r"))) "namespace" $dot.Release.Namespace "labels" (get (fromJson (include "redpanda.FullLabels" (dict "a" (list $dot) ))) "r") )) "type" "Opaque" "stringData" (dict ) )) -}} +{{- $_ := (set $secret.stringData "fsValidator.sh" `set -e +EXPECTED_FS_TYPE=$1 + +DATA_DIR="/var/lib/redpanda/data" +TEST_FILE="testfile" + +echo "checking data directory exist..." +if [ ! -d "${DATA_DIR}" ]; then + echo "data directory does not exists, exiting" + exit 1 +fi + +echo "checking filesystem type..." +FS_TYPE=$(df -T $DATA_DIR | tail -n +2 | awk '{print $2}') + +if [ "${FS_TYPE}" != "${EXPECTED_FS_TYPE}" ]; then + echo "file system found to be ${FS_TYPE} when expected ${EXPECTED_FS_TYPE}" + exit 1 +fi + +echo "checking if able to create a test file..." + +touch ${DATA_DIR}/${TEST_FILE} +result=$(touch ${DATA_DIR}/${TEST_FILE} 2> /dev/null; echo $?) +if [ "${result}" != "0" ]; then + echo "could not write testfile, may not have write permission" + exit 1 +fi + +echo "checking if able to delete a test file..." + +result=$(rm ${DATA_DIR}/${TEST_FILE} 2> /dev/null; echo $?) +if [ "${result}" != "0" ]; then + echo "could not delete testfile" + exit 1 +fi + +echo "passed"`) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $secret) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.SecretConfigurator" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $secret := (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) ) (mustMergeOverwrite (dict ) (dict "apiVersion" "v1" "kind" "Secret" )) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "name" (printf "%.51s-configurator" (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r")) "namespace" $dot.Release.Namespace "labels" (get (fromJson (include "redpanda.FullLabels" (dict "a" (list $dot) ))) "r") )) "type" "Opaque" "stringData" (dict ) )) -}} +{{- $configuratorSh := (list ) -}} +{{- $configuratorSh = (concat (default (list ) $configuratorSh) (list `set -xe` `SERVICE_NAME=$1` `KUBERNETES_NODE_NAME=$2` `POD_ORDINAL=${SERVICE_NAME##*-}` "BROKER_INDEX=`expr $POD_ORDINAL + 1`" `` `CONFIG=/etc/redpanda/redpanda.yaml` `` `# Setup config files` `cp /tmp/base-config/redpanda.yaml "${CONFIG}"` `cp /tmp/base-config/bootstrap.yaml /etc/redpanda/.bootstrap.yaml`)) -}} +{{- if (not (get (fromJson (include "redpanda.RedpandaAtLeast_22_3_0" (dict "a" (list $dot) ))) "r")) -}} +{{- $configuratorSh = (concat (default (list ) $configuratorSh) (list `` `# Configure bootstrap` `## Not used for Redpanda v22.3.0+` `rpk --config "${CONFIG}" redpanda config set redpanda.node_id "${POD_ORDINAL}"` `if [ "${POD_ORDINAL}" = "0" ]; then` ` rpk --config "${CONFIG}" redpanda config set redpanda.seed_servers '[]' --format yaml` `fi`)) -}} +{{- end -}} +{{- $kafkaSnippet := (get (fromJson (include "redpanda.secretConfiguratorKafkaConfig" (dict "a" (list $dot) ))) "r") -}} +{{- $configuratorSh = (concat (default (list ) $configuratorSh) (default (list ) $kafkaSnippet)) -}} +{{- $httpSnippet := (get (fromJson (include "redpanda.secretConfiguratorHTTPConfig" (dict "a" (list $dot) ))) "r") -}} +{{- $configuratorSh = (concat (default (list ) $configuratorSh) (default (list ) $httpSnippet)) -}} +{{- if (and (get (fromJson (include "redpanda.RedpandaAtLeast_22_3_0" (dict "a" (list $dot) ))) "r") $values.rackAwareness.enabled) -}} +{{- $configuratorSh = (concat (default (list ) $configuratorSh) (list `` `# Configure Rack Awareness` `set +x` (printf `RACK=$(curl --silent --cacert /run/secrets/kubernetes.io/serviceaccount/ca.crt --fail -H 'Authorization: Bearer '$(cat /run/secrets/kubernetes.io/serviceaccount/token) "https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT_HTTPS}/api/v1/nodes/${KUBERNETES_NODE_NAME}?pretty=true" | grep %s | grep -v '\"key\":' | sed 's/.*": "\([^"]\+\).*/\1/')` (squote (quote $values.rackAwareness.nodeAnnotation))) `set -x` `rpk --config "$CONFIG" redpanda config set redpanda.rack "${RACK}"`)) -}} +{{- end -}} +{{- $_ := (set $secret.stringData "configurator.sh" (join "\n" $configuratorSh)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $secret) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.secretConfiguratorKafkaConfig" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $internalAdvertiseAddress := (printf "%s.%s" "${SERVICE_NAME}" (get (fromJson (include "redpanda.InternalDomain" (dict "a" (list $dot) ))) "r")) -}} +{{- $snippet := (coalesce nil) -}} +{{- $listenerName := "kafka" -}} +{{- $listenerAdvertisedName := $listenerName -}} +{{- $redpandaConfigPart := "redpanda" -}} +{{- $snippet = (concat (default (list ) $snippet) (list `` (printf `LISTENER=%s` (quote (toJson (dict "name" "internal" "address" $internalAdvertiseAddress "port" ($values.listeners.kafka.port | int) )))) (printf `rpk redpanda config --config "$CONFIG" set %s.advertised_%s_api[0] "$LISTENER"` $redpandaConfigPart $listenerAdvertisedName))) -}} +{{- if (gt ((get (fromJson (include "_shims.len" (dict "a" (list $values.listeners.kafka.external) ))) "r") | int) (0 | int)) -}} +{{- $externalCounter := (0 | int) -}} +{{- range $externalName, $externalVals := $values.listeners.kafka.external -}} +{{- $externalCounter = ((add $externalCounter (1 | int)) | int) -}} +{{- $snippet = (concat (default (list ) $snippet) (list `` (printf `ADVERTISED_%s_ADDRESSES=()` (upper $listenerName)))) -}} +{{- range $_, $replicaIndex := (until (($values.statefulset.replicas | int) | int)) -}} +{{- $port := ($externalVals.port | int) -}} +{{- if (gt ((get (fromJson (include "_shims.len" (dict "a" (list $externalVals.advertisedPorts) ))) "r") | int) (0 | int)) -}} +{{- if (eq ((get (fromJson (include "_shims.len" (dict "a" (list $externalVals.advertisedPorts) ))) "r") | int) (1 | int)) -}} +{{- $port = (index $externalVals.advertisedPorts (0 | int)) -}} +{{- else -}} +{{- $port = (index $externalVals.advertisedPorts $replicaIndex) -}} +{{- end -}} +{{- end -}} +{{- $host := (get (fromJson (include "redpanda.advertisedHostJSON" (dict "a" (list $dot $externalName $port $replicaIndex) ))) "r") -}} +{{- $address := (toJson $host) -}} +{{- $prefixTemplate := (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $externalVals.prefixTemplate "") ))) "r") -}} +{{- if (eq $prefixTemplate "") -}} +{{- $prefixTemplate = (default "" $values.external.prefixTemplate) -}} +{{- end -}} +{{- $snippet = (concat (default (list ) $snippet) (list `` (printf `PREFIX_TEMPLATE=%s` (quote $prefixTemplate)) (printf `ADVERTISED_%s_ADDRESSES+=(%s)` (upper $listenerName) (quote $address)))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $snippet = (concat (default (list ) $snippet) (list `` (printf `rpk redpanda config --config "$CONFIG" set %s.advertised_%s_api[%d] "${ADVERTISED_%s_ADDRESSES[$POD_ORDINAL]}"` $redpandaConfigPart $listenerAdvertisedName $externalCounter (upper $listenerName)))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $snippet) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.secretConfiguratorHTTPConfig" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $internalAdvertiseAddress := (printf "%s.%s" "${SERVICE_NAME}" (get (fromJson (include "redpanda.InternalDomain" (dict "a" (list $dot) ))) "r")) -}} +{{- $snippet := (coalesce nil) -}} +{{- $listenerName := "http" -}} +{{- $listenerAdvertisedName := "pandaproxy" -}} +{{- $redpandaConfigPart := "pandaproxy" -}} +{{- $snippet = (concat (default (list ) $snippet) (list `` (printf `LISTENER=%s` (quote (toJson (dict "name" "internal" "address" $internalAdvertiseAddress "port" ($values.listeners.http.port | int) )))) (printf `rpk redpanda config --config "$CONFIG" set %s.advertised_%s_api[0] "$LISTENER"` $redpandaConfigPart $listenerAdvertisedName))) -}} +{{- if (gt ((get (fromJson (include "_shims.len" (dict "a" (list $values.listeners.http.external) ))) "r") | int) (0 | int)) -}} +{{- $externalCounter := (0 | int) -}} +{{- range $externalName, $externalVals := $values.listeners.http.external -}} +{{- $externalCounter = ((add $externalCounter (1 | int)) | int) -}} +{{- $snippet = (concat (default (list ) $snippet) (list `` (printf `ADVERTISED_%s_ADDRESSES=()` (upper $listenerName)))) -}} +{{- range $_, $replicaIndex := (until (($values.statefulset.replicas | int) | int)) -}} +{{- $port := ($externalVals.port | int) -}} +{{- if (gt ((get (fromJson (include "_shims.len" (dict "a" (list $externalVals.advertisedPorts) ))) "r") | int) (0 | int)) -}} +{{- if (eq ((get (fromJson (include "_shims.len" (dict "a" (list $externalVals.advertisedPorts) ))) "r") | int) (1 | int)) -}} +{{- $port = (index $externalVals.advertisedPorts (0 | int)) -}} +{{- else -}} +{{- $port = (index $externalVals.advertisedPorts $replicaIndex) -}} +{{- end -}} +{{- end -}} +{{- $host := (get (fromJson (include "redpanda.advertisedHostJSON" (dict "a" (list $dot $externalName $port $replicaIndex) ))) "r") -}} +{{- $address := (toJson $host) -}} +{{- $prefixTemplate := (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $externalVals.prefixTemplate "") ))) "r") -}} +{{- if (eq $prefixTemplate "") -}} +{{- $prefixTemplate = (default "" $values.external.prefixTemplate) -}} +{{- end -}} +{{- $snippet = (concat (default (list ) $snippet) (list `` (printf `PREFIX_TEMPLATE=%s` (quote $prefixTemplate)) (printf `ADVERTISED_%s_ADDRESSES+=(%s)` (upper $listenerName) (quote $address)))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $snippet = (concat (default (list ) $snippet) (list `` (printf `rpk redpanda config --config "$CONFIG" set %s.advertised_%s_api[%d] "${ADVERTISED_%s_ADDRESSES[$POD_ORDINAL]}"` $redpandaConfigPart $listenerAdvertisedName $externalCounter (upper $listenerName)))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $snippet) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.adminTLSCurlFlags" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (not (get (fromJson (include "redpanda.InternalTLS.IsEnabled" (dict "a" (list $values.listeners.admin.tls $values.tls) ))) "r")) -}} +{{- $_is_returning = true -}} +{{- (dict "r" "") | toJson -}} +{{- break -}} +{{- end -}} +{{- $path := (printf "/etc/tls/certs/%s" $values.listeners.admin.tls.cert) -}} +{{- if $values.listeners.admin.tls.requireClientAuth -}} +{{- $_is_returning = true -}} +{{- (dict "r" (printf "--cacert %s/ca.crt --cert %s/tls.crt --key %s/tls.key" $path $path $path)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (printf "--cacert %s/ca.crt" $path)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.externalAdvertiseAddress" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $eaa := "${SERVICE_NAME}" -}} +{{- $externalDomainTemplate := (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $values.external.domain "") ))) "r") -}} +{{- $expanded := (tpl $externalDomainTemplate $dot) -}} +{{- if (not (empty $expanded)) -}} +{{- $eaa = (printf "%s.%s" "${SERVICE_NAME}" $expanded) -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $eaa) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.advertisedHostJSON" -}} +{{- $dot := (index .a 0) -}} +{{- $externalName := (index .a 1) -}} +{{- $port := (index .a 2) -}} +{{- $replicaIndex := (index .a 3) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $host := (dict "name" $externalName "address" (get (fromJson (include "redpanda.externalAdvertiseAddress" (dict "a" (list $dot) ))) "r") "port" $port ) -}} +{{- if (gt ((get (fromJson (include "_shims.len" (dict "a" (list $values.external.addresses) ))) "r") | int) (0 | int)) -}} +{{- $address := "" -}} +{{- if (gt ((get (fromJson (include "_shims.len" (dict "a" (list $values.external.addresses) ))) "r") | int) (1 | int)) -}} +{{- $address = (index $values.external.addresses $replicaIndex) -}} +{{- else -}} +{{- $address = (index $values.external.addresses (0 | int)) -}} +{{- end -}} +{{- $domain_4 := (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $values.external.domain "") ))) "r") -}} +{{- if (ne $domain_4 "") -}} +{{- $host = (dict "name" $externalName "address" (printf "%s.%s" $address $domain_4) "port" $port ) -}} +{{- else -}} +{{- $host = (dict "name" $externalName "address" $address "port" $port ) -}} +{{- end -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $host) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.adminInternalHTTPProtocol" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (get (fromJson (include "redpanda.InternalTLS.IsEnabled" (dict "a" (list $values.listeners.admin.tls $values.tls) ))) "r") -}} +{{- $_is_returning = true -}} +{{- (dict "r" "https") | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" "http") | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.adminInternalURL" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $_is_returning = true -}} +{{- (dict "r" (printf "%s://%s.%s.%s.svc.%s:%d" (get (fromJson (include "redpanda.adminInternalHTTPProtocol" (dict "a" (list $dot) ))) "r") `${SERVICE_NAME}` (get (fromJson (include "redpanda.ServiceName" (dict "a" (list $dot) ))) "r") $dot.Release.Namespace (trimSuffix "." $values.clusterDomain) ($values.listeners.admin.port | int))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + diff --git a/charts/redpanda/redpanda/5.9.2/templates/_service.internal.go.tpl b/charts/redpanda/redpanda/5.9.2/templates/_service.internal.go.tpl new file mode 100644 index 0000000000..9c63aac1cb --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/_service.internal.go.tpl @@ -0,0 +1,38 @@ +{{- /* Generated from "service_internal.go" */ -}} + +{{- define "redpanda.MonitoringEnabledLabel" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $_is_returning = true -}} +{{- (dict "r" (dict "monitoring.redpanda.com/enabled" (printf "%t" $values.monitoring.enabled) )) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.ServiceInternal" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $ports := (list ) -}} +{{- $ports = (concat (default (list ) $ports) (list (mustMergeOverwrite (dict "port" 0 "targetPort" 0 ) (dict "name" "admin" "protocol" "TCP" "appProtocol" $values.listeners.admin.appProtocol "port" ($values.listeners.admin.port | int) "targetPort" ($values.listeners.admin.port | int) )))) -}} +{{- if $values.listeners.http.enabled -}} +{{- $ports = (concat (default (list ) $ports) (list (mustMergeOverwrite (dict "port" 0 "targetPort" 0 ) (dict "name" "http" "protocol" "TCP" "port" ($values.listeners.http.port | int) "targetPort" ($values.listeners.http.port | int) )))) -}} +{{- end -}} +{{- $ports = (concat (default (list ) $ports) (list (mustMergeOverwrite (dict "port" 0 "targetPort" 0 ) (dict "name" "kafka" "protocol" "TCP" "port" ($values.listeners.kafka.port | int) "targetPort" ($values.listeners.kafka.port | int) )))) -}} +{{- $ports = (concat (default (list ) $ports) (list (mustMergeOverwrite (dict "port" 0 "targetPort" 0 ) (dict "name" "rpc" "protocol" "TCP" "port" ($values.listeners.rpc.port | int) "targetPort" ($values.listeners.rpc.port | int) )))) -}} +{{- if $values.listeners.schemaRegistry.enabled -}} +{{- $ports = (concat (default (list ) $ports) (list (mustMergeOverwrite (dict "port" 0 "targetPort" 0 ) (dict "name" "schemaregistry" "protocol" "TCP" "port" ($values.listeners.schemaRegistry.port | int) "targetPort" ($values.listeners.schemaRegistry.port | int) )))) -}} +{{- end -}} +{{- $annotations := (dict ) -}} +{{- if (ne $values.service (coalesce nil)) -}} +{{- $annotations = $values.service.internal.annotations -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "spec" (dict ) "status" (dict "loadBalancer" (dict ) ) ) (mustMergeOverwrite (dict ) (dict "apiVersion" "v1" "kind" "Service" )) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "name" (get (fromJson (include "redpanda.ServiceName" (dict "a" (list $dot) ))) "r") "namespace" $dot.Release.Namespace "labels" (merge (dict ) (get (fromJson (include "redpanda.FullLabels" (dict "a" (list $dot) ))) "r") (get (fromJson (include "redpanda.MonitoringEnabledLabel" (dict "a" (list $dot) ))) "r")) "annotations" $annotations )) "spec" (mustMergeOverwrite (dict ) (dict "type" "ClusterIP" "publishNotReadyAddresses" true "clusterIP" "None" "selector" (get (fromJson (include "redpanda.StatefulSetPodLabelsSelector" (dict "a" (list $dot) ))) "r") "ports" $ports )) ))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + diff --git a/charts/redpanda/redpanda/5.9.2/templates/_service.loadbalancer.go.tpl b/charts/redpanda/redpanda/5.9.2/templates/_service.loadbalancer.go.tpl new file mode 100644 index 0000000000..dbc7547509 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/_service.loadbalancer.go.tpl @@ -0,0 +1,101 @@ +{{- /* Generated from "service.loadbalancer.go" */ -}} + +{{- define "redpanda.LoadBalancerServices" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (or (not $values.external.enabled) (not $values.external.service.enabled)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- if (ne $values.external.type "LoadBalancer") -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $externalDNS := (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $values.external.externalDns (mustMergeOverwrite (dict "enabled" false ) (dict ))) ))) "r") -}} +{{- $labels := (get (fromJson (include "redpanda.FullLabels" (dict "a" (list $dot) ))) "r") -}} +{{- $_ := (set $labels "repdanda.com/type" "loadbalancer") -}} +{{- $selector := (get (fromJson (include "redpanda.StatefulSetPodLabelsSelector" (dict "a" (list $dot) ))) "r") -}} +{{- $services := (coalesce nil) -}} +{{- $replicas := ($values.statefulset.replicas | int) -}} +{{- range $_, $i := untilStep (((0 | int) | int)|int) (($values.statefulset.replicas | int)|int) (1|int) -}} +{{- $podname := (printf "%s-%d" (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r") $i) -}} +{{- $annotations := (dict ) -}} +{{- range $k, $v := $values.external.annotations -}} +{{- $_ := (set $annotations $k $v) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- if $externalDNS.enabled -}} +{{- $prefix := $podname -}} +{{- if (gt ((get (fromJson (include "_shims.len" (dict "a" (list $values.external.addresses) ))) "r") | int) ($i | int)) -}} +{{- $prefix = (index $values.external.addresses $i) -}} +{{- end -}} +{{- $address := (printf "%s.%s" $prefix (tpl $values.external.domain $dot)) -}} +{{- $_ := (set $annotations "external-dns.alpha.kubernetes.io/hostname" $address) -}} +{{- end -}} +{{- $podSelector := (dict ) -}} +{{- range $k, $v := $selector -}} +{{- $_ := (set $podSelector $k $v) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_ := (set $podSelector "statefulset.kubernetes.io/pod-name" $podname) -}} +{{- $ports := (coalesce nil) -}} +{{- range $name, $listener := $values.listeners.admin.external -}} +{{- if (not (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $listener.enabled $values.external.enabled) ))) "r")) -}} +{{- continue -}} +{{- end -}} +{{- $fallbackPorts := (concat (default (list ) $listener.advertisedPorts) (list ($values.listeners.admin.port | int))) -}} +{{- $ports = (concat (default (list ) $ports) (list (mustMergeOverwrite (dict "port" 0 "targetPort" 0 ) (dict "name" (printf "admin-%s" $name) "protocol" "TCP" "targetPort" ($listener.port | int) "port" ((get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $listener.nodePort (index $fallbackPorts (0 | int))) ))) "r") | int) )))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- range $name, $listener := $values.listeners.kafka.external -}} +{{- if (not (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $listener.enabled $values.external.enabled) ))) "r")) -}} +{{- continue -}} +{{- end -}} +{{- $fallbackPorts := (concat (default (list ) $listener.advertisedPorts) (list ($listener.port | int))) -}} +{{- $ports = (concat (default (list ) $ports) (list (mustMergeOverwrite (dict "port" 0 "targetPort" 0 ) (dict "name" (printf "kafka-%s" $name) "protocol" "TCP" "targetPort" ($listener.port | int) "port" ((get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $listener.nodePort (index $fallbackPorts (0 | int))) ))) "r") | int) )))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- range $name, $listener := $values.listeners.http.external -}} +{{- if (not (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $listener.enabled $values.external.enabled) ))) "r")) -}} +{{- continue -}} +{{- end -}} +{{- $fallbackPorts := (concat (default (list ) $listener.advertisedPorts) (list ($listener.port | int))) -}} +{{- $ports = (concat (default (list ) $ports) (list (mustMergeOverwrite (dict "port" 0 "targetPort" 0 ) (dict "name" (printf "http-%s" $name) "protocol" "TCP" "targetPort" ($listener.port | int) "port" ((get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $listener.nodePort (index $fallbackPorts (0 | int))) ))) "r") | int) )))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- range $name, $listener := $values.listeners.schemaRegistry.external -}} +{{- if (not (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $listener.enabled $values.external.enabled) ))) "r")) -}} +{{- continue -}} +{{- end -}} +{{- $fallbackPorts := (concat (default (list ) $listener.advertisedPorts) (list ($listener.port | int))) -}} +{{- $ports = (concat (default (list ) $ports) (list (mustMergeOverwrite (dict "port" 0 "targetPort" 0 ) (dict "name" (printf "schema-%s" $name) "protocol" "TCP" "targetPort" ($listener.port | int) "port" ((get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $listener.nodePort (index $fallbackPorts (0 | int))) ))) "r") | int) )))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $svc := (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "spec" (dict ) "status" (dict "loadBalancer" (dict ) ) ) (mustMergeOverwrite (dict ) (dict "apiVersion" "v1" "kind" "Service" )) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "name" (printf "lb-%s" $podname) "namespace" $dot.Release.Namespace "labels" $labels "annotations" $annotations )) "spec" (mustMergeOverwrite (dict ) (dict "externalTrafficPolicy" "Local" "loadBalancerSourceRanges" $values.external.sourceRanges "ports" $ports "publishNotReadyAddresses" true "selector" $podSelector "sessionAffinity" "None" "type" "LoadBalancer" )) )) -}} +{{- $services = (concat (default (list ) $services) (list $svc)) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $services) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + diff --git a/charts/redpanda/redpanda/5.9.2/templates/_service.nodeport.go.tpl b/charts/redpanda/redpanda/5.9.2/templates/_service.nodeport.go.tpl new file mode 100644 index 0000000000..5bec96af51 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/_service.nodeport.go.tpl @@ -0,0 +1,80 @@ +{{- /* Generated from "service.nodeport.go" */ -}} + +{{- define "redpanda.NodePortService" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (or (not $values.external.enabled) (not $values.external.service.enabled)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- if (ne $values.external.type "NodePort") -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $ports := (coalesce nil) -}} +{{- range $name, $listener := $values.listeners.admin.external -}} +{{- if (not (get (fromJson (include "redpanda.AdminExternal.IsEnabled" (dict "a" (list $listener) ))) "r")) -}} +{{- continue -}} +{{- end -}} +{{- $nodePort := ($listener.port | int) -}} +{{- if (gt ((get (fromJson (include "_shims.len" (dict "a" (list $listener.advertisedPorts) ))) "r") | int) (0 | int)) -}} +{{- $nodePort = (index $listener.advertisedPorts (0 | int)) -}} +{{- end -}} +{{- $ports = (concat (default (list ) $ports) (list (mustMergeOverwrite (dict "port" 0 "targetPort" 0 ) (dict "name" (printf "admin-%s" $name) "protocol" "TCP" "port" ($listener.port | int) "nodePort" $nodePort )))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- range $name, $listener := $values.listeners.kafka.external -}} +{{- if (not (get (fromJson (include "redpanda.KafkaExternal.IsEnabled" (dict "a" (list $listener) ))) "r")) -}} +{{- continue -}} +{{- end -}} +{{- $nodePort := ($listener.port | int) -}} +{{- if (gt ((get (fromJson (include "_shims.len" (dict "a" (list $listener.advertisedPorts) ))) "r") | int) (0 | int)) -}} +{{- $nodePort = (index $listener.advertisedPorts (0 | int)) -}} +{{- end -}} +{{- $ports = (concat (default (list ) $ports) (list (mustMergeOverwrite (dict "port" 0 "targetPort" 0 ) (dict "name" (printf "kafka-%s" $name) "protocol" "TCP" "port" ($listener.port | int) "nodePort" $nodePort )))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- range $name, $listener := $values.listeners.http.external -}} +{{- if (not (get (fromJson (include "redpanda.HTTPExternal.IsEnabled" (dict "a" (list $listener) ))) "r")) -}} +{{- continue -}} +{{- end -}} +{{- $nodePort := ($listener.port | int) -}} +{{- if (gt ((get (fromJson (include "_shims.len" (dict "a" (list $listener.advertisedPorts) ))) "r") | int) (0 | int)) -}} +{{- $nodePort = (index $listener.advertisedPorts (0 | int)) -}} +{{- end -}} +{{- $ports = (concat (default (list ) $ports) (list (mustMergeOverwrite (dict "port" 0 "targetPort" 0 ) (dict "name" (printf "http-%s" $name) "protocol" "TCP" "port" ($listener.port | int) "nodePort" $nodePort )))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- range $name, $listener := $values.listeners.schemaRegistry.external -}} +{{- if (not (get (fromJson (include "redpanda.SchemaRegistryExternal.IsEnabled" (dict "a" (list $listener) ))) "r")) -}} +{{- continue -}} +{{- end -}} +{{- $nodePort := ($listener.port | int) -}} +{{- if (gt ((get (fromJson (include "_shims.len" (dict "a" (list $listener.advertisedPorts) ))) "r") | int) (0 | int)) -}} +{{- $nodePort = (index $listener.advertisedPorts (0 | int)) -}} +{{- end -}} +{{- $ports = (concat (default (list ) $ports) (list (mustMergeOverwrite (dict "port" 0 "targetPort" 0 ) (dict "name" (printf "schema-%s" $name) "protocol" "TCP" "port" ($listener.port | int) "nodePort" $nodePort )))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $annotations := $values.external.annotations -}} +{{- if (eq $annotations (coalesce nil)) -}} +{{- $annotations = (dict ) -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "spec" (dict ) "status" (dict "loadBalancer" (dict ) ) ) (mustMergeOverwrite (dict ) (dict "apiVersion" "v1" "kind" "Service" )) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "name" (printf "%s-external" (get (fromJson (include "redpanda.ServiceName" (dict "a" (list $dot) ))) "r")) "namespace" $dot.Release.Namespace "labels" (get (fromJson (include "redpanda.FullLabels" (dict "a" (list $dot) ))) "r") "annotations" $annotations )) "spec" (mustMergeOverwrite (dict ) (dict "externalTrafficPolicy" "Local" "ports" $ports "publishNotReadyAddresses" true "selector" (get (fromJson (include "redpanda.StatefulSetPodLabelsSelector" (dict "a" (list $dot) ))) "r") "sessionAffinity" "None" "type" "NodePort" )) ))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + diff --git a/charts/redpanda/redpanda/5.9.2/templates/_serviceaccount.go.tpl b/charts/redpanda/redpanda/5.9.2/templates/_serviceaccount.go.tpl new file mode 100644 index 0000000000..9122cbd2a4 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/_serviceaccount.go.tpl @@ -0,0 +1,18 @@ +{{- /* Generated from "serviceaccount.go" */ -}} + +{{- define "redpanda.ServiceAccount" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (not $values.serviceAccount.create) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) ) (mustMergeOverwrite (dict ) (dict "apiVersion" "v1" "kind" "ServiceAccount" )) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "name" (get (fromJson (include "redpanda.ServiceAccountName" (dict "a" (list $dot) ))) "r") "namespace" $dot.Release.Namespace "labels" (get (fromJson (include "redpanda.FullLabels" (dict "a" (list $dot) ))) "r") "annotations" $values.serviceAccount.annotations )) ))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + diff --git a/charts/redpanda/redpanda/5.9.2/templates/_servicemonitor.go.tpl b/charts/redpanda/redpanda/5.9.2/templates/_servicemonitor.go.tpl new file mode 100644 index 0000000000..97d3f3325e --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/_servicemonitor.go.tpl @@ -0,0 +1,26 @@ +{{- /* Generated from "servicemonitor.go" */ -}} + +{{- define "redpanda.ServiceMonitor" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (not $values.monitoring.enabled) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $endpoint := (mustMergeOverwrite (dict ) (dict "interval" $values.monitoring.scrapeInterval "path" "/public_metrics" "port" "admin" "enableHttp2" $values.monitoring.enableHttp2 "scheme" "http" )) -}} +{{- if (or (get (fromJson (include "redpanda.InternalTLS.IsEnabled" (dict "a" (list $values.listeners.admin.tls $values.tls) ))) "r") (ne $values.monitoring.tlsConfig (coalesce nil))) -}} +{{- $_ := (set $endpoint "scheme" "https") -}} +{{- $_ := (set $endpoint "tlsConfig" $values.monitoring.tlsConfig) -}} +{{- if (eq $endpoint.tlsConfig (coalesce nil)) -}} +{{- $_ := (set $endpoint "tlsConfig" (mustMergeOverwrite (dict "ca" (dict ) "cert" (dict ) ) (mustMergeOverwrite (dict "ca" (dict ) "cert" (dict ) ) (dict "insecureSkipVerify" true )) (dict ))) -}} +{{- end -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "spec" (dict "endpoints" (coalesce nil) "selector" (dict ) "namespaceSelector" (dict ) ) ) (mustMergeOverwrite (dict ) (dict "apiVersion" "monitoring.coreos.com/v1" "kind" "ServiceMonitor" )) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "name" (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r") "namespace" $dot.Release.Namespace "labels" (merge (dict ) (get (fromJson (include "redpanda.FullLabels" (dict "a" (list $dot) ))) "r") $values.monitoring.labels) )) "spec" (mustMergeOverwrite (dict "endpoints" (coalesce nil) "selector" (dict ) "namespaceSelector" (dict ) ) (dict "endpoints" (list $endpoint) "selector" (mustMergeOverwrite (dict ) (dict "matchLabels" (dict "monitoring.redpanda.com/enabled" "true" "app.kubernetes.io/name" (get (fromJson (include "redpanda.Name" (dict "a" (list $dot) ))) "r") "app.kubernetes.io/instance" $dot.Release.Name ) )) )) ))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + diff --git a/charts/redpanda/redpanda/5.9.2/templates/_shims.tpl b/charts/redpanda/redpanda/5.9.2/templates/_shims.tpl new file mode 100644 index 0000000000..e3bb40e415 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/_shims.tpl @@ -0,0 +1,289 @@ +{{- /* Generated from "bootstrap.go" */ -}} + +{{- define "_shims.typetest" -}} +{{- $typ := (index .a 0) -}} +{{- $value := (index .a 1) -}} +{{- $zero := (index .a 2) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (typeIs $typ $value) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list $value true)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list $zero false)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.typeassertion" -}} +{{- $typ := (index .a 0) -}} +{{- $value := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (not (typeIs $typ $value)) -}} +{{- $_ := (fail (printf "expected type of %q got: %T" $typ $value)) -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $value) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.dicttest" -}} +{{- $m := (index .a 0) -}} +{{- $key := (index .a 1) -}} +{{- $zero := (index .a 2) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (hasKey $m $key) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list (index $m $key) true)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list $zero false)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.compact" -}} +{{- $args := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $out := (dict ) -}} +{{- range $i, $e := $args -}} +{{- $_ := (set $out (printf "T%d" ((add (1 | int) $i) | int)) $e) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $out) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.deref" -}} +{{- $ptr := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (eq $ptr (coalesce nil)) -}} +{{- $_ := (fail "nil dereference") -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $ptr) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.len" -}} +{{- $m := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (eq $m (coalesce nil)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (0 | int)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (len $m)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.ptr_Deref" -}} +{{- $ptr := (index .a 0) -}} +{{- $def := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (ne $ptr (coalesce nil)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $ptr) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $def) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.ptr_Equal" -}} +{{- $a := (index .a 0) -}} +{{- $b := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (and (eq $a (coalesce nil)) (eq $b (coalesce nil))) -}} +{{- $_is_returning = true -}} +{{- (dict "r" true) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (eq $a $b)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.lookup" -}} +{{- $apiVersion := (index .a 0) -}} +{{- $kind := (index .a 1) -}} +{{- $namespace := (index .a 2) -}} +{{- $name := (index .a 3) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $result := (lookup $apiVersion $kind $namespace $name) -}} +{{- if (empty $result) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list (coalesce nil) false)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list $result true)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.asnumeric" -}} +{{- $value := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (typeIs "float64" $value) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list $value true)) | toJson -}} +{{- break -}} +{{- end -}} +{{- if (typeIs "int64" $value) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list $value true)) | toJson -}} +{{- break -}} +{{- end -}} +{{- if (typeIs "int" $value) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list $value true)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list (0 | int) false)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.asintegral" -}} +{{- $value := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (or (typeIs "int64" $value) (typeIs "int" $value)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list $value true)) | toJson -}} +{{- break -}} +{{- end -}} +{{- if (and (typeIs "float64" $value) (eq (floor $value) $value)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list $value true)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list (0 | int) false)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.parseResource" -}} +{{- $repr := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (typeIs "float64" $repr) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list (float64 $repr) 1.0)) | toJson -}} +{{- break -}} +{{- end -}} +{{- if (not (typeIs "string" $repr)) -}} +{{- $_ := (fail (printf "invalid Quantity expected string or float64 got: %T (%v)" $repr $repr)) -}} +{{- end -}} +{{- if (not (regexMatch `^[0-9]+(\.[0-9]{0,6})?(k|m|M|G|T|P|Ki|Mi|Gi|Ti|Pi)?$` $repr)) -}} +{{- $_ := (fail (printf "invalid Quantity: %q" $repr)) -}} +{{- end -}} +{{- $reprStr := (toString $repr) -}} +{{- $unit := (regexFind "(k|m|M|G|T|P|Ki|Mi|Gi|Ti|Pi)$" $repr) -}} +{{- $numeric := (float64 (substr (0 | int) ((sub ((get (fromJson (include "_shims.len" (dict "a" (list $reprStr) ))) "r") | int) ((get (fromJson (include "_shims.len" (dict "a" (list $unit) ))) "r") | int)) | int) $reprStr)) -}} +{{- $tmp_tuple_1 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.dicttest" (dict "a" (list (dict "" 1.0 "m" 0.001 "k" (1000 | int) "M" (1000000 | int) "G" (1000000000 | int) "T" (1000000000000 | int) "P" (1000000000000000 | int) "Ki" (1024 | int) "Mi" (1048576 | int) "Gi" (1073741824 | int) "Ti" (1099511627776 | int) "Pi" (1125899906842624 | int) ) $unit (coalesce nil)) ))) "r")) ))) "r") -}} +{{- $ok := $tmp_tuple_1.T2 -}} +{{- $scale := ($tmp_tuple_1.T1 | float64) -}} +{{- if (not $ok) -}} +{{- $_ := (fail (printf "unknown unit: %q" $unit)) -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list $numeric $scale)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.resource_MustParse" -}} +{{- $repr := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $tmp_tuple_2 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.parseResource" (dict "a" (list $repr) ))) "r")) ))) "r") -}} +{{- $scale := ($tmp_tuple_2.T2 | float64) -}} +{{- $numeric := ($tmp_tuple_2.T1 | float64) -}} +{{- $strs := (list "" "m" "k" "M" "G" "T" "P" "Ki" "Mi" "Gi" "Ti" "Pi") -}} +{{- $scales := (list 1.0 0.001 (1000 | int) (1000000 | int) (1000000000 | int) (1000000000000 | int) (1000000000000000 | int) (1024 | int) (1048576 | int) (1073741824 | int) (1099511627776 | int) (1125899906842624 | int)) -}} +{{- $idx := -1 -}} +{{- range $i, $s := $scales -}} +{{- if (eq ($s | float64) ($scale | float64)) -}} +{{- $idx = $i -}} +{{- break -}} +{{- end -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- if (eq $idx -1) -}} +{{- $_ := (fail (printf "unknown scale: %v" $scale)) -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (printf "%s%s" (toString $numeric) (index $strs $idx))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.resource_Value" -}} +{{- $repr := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $tmp_tuple_3 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.parseResource" (dict "a" (list $repr) ))) "r")) ))) "r") -}} +{{- $scale := ($tmp_tuple_3.T2 | float64) -}} +{{- $numeric := ($tmp_tuple_3.T1 | float64) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (int64 (ceil ((mulf $numeric $scale) | float64)))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.resource_MilliValue" -}} +{{- $repr := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $tmp_tuple_4 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.parseResource" (dict "a" (list $repr) ))) "r")) ))) "r") -}} +{{- $scale := ($tmp_tuple_4.T2 | float64) -}} +{{- $numeric := ($tmp_tuple_4.T1 | float64) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (int64 (ceil ((mulf ((mulf $numeric 1000.0) | float64) $scale) | float64)))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "_shims.render-manifest" -}} +{{- $tpl := (index . 0) -}} +{{- $dot := (index . 1) -}} +{{- $manifests := (get ((include $tpl (dict "a" (list $dot))) | fromJson) "r") -}} +{{- if not (typeIs "[]interface {}" $manifests) -}} +{{- $manifests = (list $manifests) -}} +{{- end -}} +{{- range $_, $manifest := $manifests -}} +{{- if ne $manifest nil }} +--- +{{toYaml (unset (unset $manifest "status") "creationTimestamp")}} +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/charts/redpanda/redpanda/5.9.2/templates/_statefulset.go.tpl b/charts/redpanda/redpanda/5.9.2/templates/_statefulset.go.tpl new file mode 100644 index 0000000000..a7b73c98a4 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/_statefulset.go.tpl @@ -0,0 +1,677 @@ +{{- /* Generated from "statefulset.go" */ -}} + +{{- define "redpanda.statefulSetRedpandaEnv" -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list (mustMergeOverwrite (dict "name" "" ) (dict "name" "SERVICE_NAME" "valueFrom" (mustMergeOverwrite (dict ) (dict "fieldRef" (mustMergeOverwrite (dict "fieldPath" "" ) (dict "fieldPath" "metadata.name" )) )) )) (mustMergeOverwrite (dict "name" "" ) (dict "name" "POD_IP" "valueFrom" (mustMergeOverwrite (dict ) (dict "fieldRef" (mustMergeOverwrite (dict "fieldPath" "" ) (dict "fieldPath" "status.podIP" )) )) )) (mustMergeOverwrite (dict "name" "" ) (dict "name" "HOST_IP" "valueFrom" (mustMergeOverwrite (dict ) (dict "fieldRef" (mustMergeOverwrite (dict "fieldPath" "" ) (dict "fieldPath" "status.hostIP" )) )) )))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.StatefulSetPodLabelsSelector" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if $dot.Release.IsUpgrade -}} +{{- $tmp_tuple_1 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.lookup" (dict "a" (list "apps/v1" "StatefulSet" $dot.Release.Namespace (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r")) ))) "r")) ))) "r") -}} +{{- $ok_2 := $tmp_tuple_1.T2 -}} +{{- $existing_1 := $tmp_tuple_1.T1 -}} +{{- if (and $ok_2 (gt ((get (fromJson (include "_shims.len" (dict "a" (list $existing_1.spec.selector.matchLabels) ))) "r") | int) (0 | int))) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $existing_1.spec.selector.matchLabels) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} +{{- $values := $dot.Values.AsMap -}} +{{- $additionalSelectorLabels := (dict ) -}} +{{- if (ne $values.statefulset.additionalSelectorLabels (coalesce nil)) -}} +{{- $additionalSelectorLabels = $values.statefulset.additionalSelectorLabels -}} +{{- end -}} +{{- $component := (printf "%s-statefulset" (trimSuffix "-" (trunc (51 | int) (get (fromJson (include "redpanda.Name" (dict "a" (list $dot) ))) "r")))) -}} +{{- $defaults := (dict "app.kubernetes.io/component" $component "app.kubernetes.io/instance" $dot.Release.Name "app.kubernetes.io/name" (get (fromJson (include "redpanda.Name" (dict "a" (list $dot) ))) "r") ) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (merge (dict ) $additionalSelectorLabels $defaults)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.StatefulSetPodLabels" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if $dot.Release.IsUpgrade -}} +{{- $tmp_tuple_2 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.lookup" (dict "a" (list "apps/v1" "StatefulSet" $dot.Release.Namespace (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r")) ))) "r")) ))) "r") -}} +{{- $ok_4 := $tmp_tuple_2.T2 -}} +{{- $existing_3 := $tmp_tuple_2.T1 -}} +{{- if (and $ok_4 (gt ((get (fromJson (include "_shims.len" (dict "a" (list $existing_3.spec.template.metadata.labels) ))) "r") | int) (0 | int))) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $existing_3.spec.template.metadata.labels) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} +{{- $values := $dot.Values.AsMap -}} +{{- $statefulSetLabels := (dict ) -}} +{{- if (ne $values.statefulset.podTemplate.labels (coalesce nil)) -}} +{{- $statefulSetLabels = $values.statefulset.podTemplate.labels -}} +{{- end -}} +{{- $defaults := (dict "redpanda.com/poddisruptionbudget" (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r") ) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (merge (dict ) $statefulSetLabels (get (fromJson (include "redpanda.StatefulSetPodLabelsSelector" (dict "a" (list $dot) ))) "r") $defaults (get (fromJson (include "redpanda.FullLabels" (dict "a" (list $dot) ))) "r"))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.StatefulSetPodAnnotations" -}} +{{- $dot := (index .a 0) -}} +{{- $configMapChecksum := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $configMapChecksumAnnotation := (dict "config.redpanda.com/checksum" $configMapChecksum ) -}} +{{- if (ne $values.statefulset.podTemplate.annotations (coalesce nil)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (merge (dict ) $values.statefulset.podTemplate.annotations $configMapChecksumAnnotation)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (merge (dict ) $values.statefulset.annotations $configMapChecksumAnnotation)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.StatefulSetVolumes" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $fullname := (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r") -}} +{{- $volumes := (get (fromJson (include "redpanda.CommonVolumes" (dict "a" (list $dot) ))) "r") -}} +{{- $values := $dot.Values.AsMap -}} +{{- $volumes = (concat (default (list ) $volumes) (default (list ) (list (mustMergeOverwrite (dict "name" "" ) (mustMergeOverwrite (dict ) (dict "secret" (mustMergeOverwrite (dict ) (dict "secretName" (printf "%.50s-sts-lifecycle" $fullname) "defaultMode" (0o775 | int) )) )) (dict "name" "lifecycle-scripts" )) (mustMergeOverwrite (dict "name" "" ) (mustMergeOverwrite (dict ) (dict "configMap" (mustMergeOverwrite (dict ) (mustMergeOverwrite (dict ) (dict "name" $fullname )) (dict )) )) (dict "name" $fullname )) (mustMergeOverwrite (dict "name" "" ) (mustMergeOverwrite (dict ) (dict "emptyDir" (mustMergeOverwrite (dict ) (dict )) )) (dict "name" "config" )) (mustMergeOverwrite (dict "name" "" ) (mustMergeOverwrite (dict ) (dict "secret" (mustMergeOverwrite (dict ) (dict "secretName" (printf "%.51s-configurator" $fullname) "defaultMode" (0o775 | int) )) )) (dict "name" (printf "%.51s-configurator" $fullname) )) (mustMergeOverwrite (dict "name" "" ) (mustMergeOverwrite (dict ) (dict "secret" (mustMergeOverwrite (dict ) (dict "secretName" (printf "%s-config-watcher" $fullname) "defaultMode" (0o775 | int) )) )) (dict "name" (printf "%s-config-watcher" $fullname) ))))) -}} +{{- if $values.statefulset.initContainers.fsValidator.enabled -}} +{{- $volumes = (concat (default (list ) $volumes) (list (mustMergeOverwrite (dict "name" "" ) (mustMergeOverwrite (dict ) (dict "secret" (mustMergeOverwrite (dict ) (dict "secretName" (printf "%.49s-fs-validator" $fullname) "defaultMode" (0o775 | int) )) )) (dict "name" (printf "%.49s-fs-validator" $fullname) )))) -}} +{{- end -}} +{{- $vol_5 := (get (fromJson (include "redpanda.Listeners.TrustStoreVolume" (dict "a" (list $values.listeners $values.tls) ))) "r") -}} +{{- if (ne $vol_5 (coalesce nil)) -}} +{{- $volumes = (concat (default (list ) $volumes) (list $vol_5)) -}} +{{- end -}} +{{- $volumes = (concat (default (list ) $volumes) (default (list ) (get (fromJson (include "redpanda.templateToVolumes" (dict "a" (list $dot $values.statefulset.extraVolumes) ))) "r"))) -}} +{{- $volumes = (concat (default (list ) $volumes) (list (get (fromJson (include "redpanda.statefulSetVolumeDataDir" (dict "a" (list $dot) ))) "r"))) -}} +{{- $v_6 := (get (fromJson (include "redpanda.statefulSetVolumeTieredStorageDir" (dict "a" (list $dot) ))) "r") -}} +{{- if (ne $v_6 (coalesce nil)) -}} +{{- $volumes = (concat (default (list ) $volumes) (list $v_6)) -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $volumes) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.statefulSetVolumeDataDir" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $datadirSource := (mustMergeOverwrite (dict ) (dict "emptyDir" (mustMergeOverwrite (dict ) (dict )) )) -}} +{{- if $values.storage.persistentVolume.enabled -}} +{{- $datadirSource = (mustMergeOverwrite (dict ) (dict "persistentVolumeClaim" (mustMergeOverwrite (dict "claimName" "" ) (dict "claimName" "datadir" )) )) -}} +{{- else -}}{{- if (ne $values.storage.hostPath "") -}} +{{- $datadirSource = (mustMergeOverwrite (dict ) (dict "hostPath" (mustMergeOverwrite (dict "path" "" ) (dict "path" $values.storage.hostPath )) )) -}} +{{- end -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (mustMergeOverwrite (dict "name" "" ) $datadirSource (dict "name" "datadir" ))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.statefulSetVolumeTieredStorageDir" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (not (get (fromJson (include "redpanda.Storage.IsTieredStorageEnabled" (dict "a" (list $values.storage) ))) "r")) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $tieredType := (get (fromJson (include "redpanda.Storage.TieredMountType" (dict "a" (list $values.storage) ))) "r") -}} +{{- if (or (eq $tieredType "none") (eq $tieredType "persistentVolume")) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- if (eq $tieredType "hostPath") -}} +{{- $_is_returning = true -}} +{{- (dict "r" (mustMergeOverwrite (dict "name" "" ) (mustMergeOverwrite (dict ) (dict "hostPath" (mustMergeOverwrite (dict "path" "" ) (dict "path" (get (fromJson (include "redpanda.Storage.GetTieredStorageHostPath" (dict "a" (list $values.storage) ))) "r") )) )) (dict "name" "tiered-storage-dir" ))) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (mustMergeOverwrite (dict "name" "" ) (mustMergeOverwrite (dict ) (dict "emptyDir" (mustMergeOverwrite (dict ) (dict "sizeLimit" (get (fromJson (include "redpanda.Storage.CloudStorageCacheSize" (dict "a" (list $values.storage) ))) "r") )) )) (dict "name" "tiered-storage-dir" ))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.StatefulSetVolumeMounts" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $mounts := (get (fromJson (include "redpanda.CommonMounts" (dict "a" (list $dot) ))) "r") -}} +{{- $values := $dot.Values.AsMap -}} +{{- $mounts = (concat (default (list ) $mounts) (default (list ) (list (mustMergeOverwrite (dict "name" "" "mountPath" "" ) (dict "name" "config" "mountPath" "/etc/redpanda" )) (mustMergeOverwrite (dict "name" "" "mountPath" "" ) (dict "name" (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r") "mountPath" "/tmp/base-config" )) (mustMergeOverwrite (dict "name" "" "mountPath" "" ) (dict "name" "lifecycle-scripts" "mountPath" "/var/lifecycle" )) (mustMergeOverwrite (dict "name" "" "mountPath" "" ) (dict "name" "datadir" "mountPath" "/var/lib/redpanda/data" ))))) -}} +{{- if (gt ((get (fromJson (include "_shims.len" (dict "a" (list (get (fromJson (include "redpanda.Listeners.TrustStores" (dict "a" (list $values.listeners $values.tls) ))) "r")) ))) "r") | int) (0 | int)) -}} +{{- $mounts = (concat (default (list ) $mounts) (list (mustMergeOverwrite (dict "name" "" "mountPath" "" ) (dict "name" "truststores" "mountPath" "/etc/truststores" "readOnly" true )))) -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $mounts) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.StatefulSetInitContainers" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $containers := (coalesce nil) -}} +{{- $c_7 := (get (fromJson (include "redpanda.statefulSetInitContainerTuning" (dict "a" (list $dot) ))) "r") -}} +{{- if (ne $c_7 (coalesce nil)) -}} +{{- $containers = (concat (default (list ) $containers) (list $c_7)) -}} +{{- end -}} +{{- $c_8 := (get (fromJson (include "redpanda.statefulSetInitContainerSetDataDirOwnership" (dict "a" (list $dot) ))) "r") -}} +{{- if (ne $c_8 (coalesce nil)) -}} +{{- $containers = (concat (default (list ) $containers) (list $c_8)) -}} +{{- end -}} +{{- $c_9 := (get (fromJson (include "redpanda.statefulSetInitContainerFSValidator" (dict "a" (list $dot) ))) "r") -}} +{{- if (ne $c_9 (coalesce nil)) -}} +{{- $containers = (concat (default (list ) $containers) (list $c_9)) -}} +{{- end -}} +{{- $c_10 := (get (fromJson (include "redpanda.statefulSetInitContainerSetTieredStorageCacheDirOwnership" (dict "a" (list $dot) ))) "r") -}} +{{- if (ne $c_10 (coalesce nil)) -}} +{{- $containers = (concat (default (list ) $containers) (list $c_10)) -}} +{{- end -}} +{{- $containers = (concat (default (list ) $containers) (list (get (fromJson (include "redpanda.statefulSetInitContainerConfigurator" (dict "a" (list $dot) ))) "r"))) -}} +{{- $containers = (concat (default (list ) $containers) (default (list ) (get (fromJson (include "redpanda.templateToContainers" (dict "a" (list $dot $values.statefulset.initContainers.extraInitContainers) ))) "r"))) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $containers) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.statefulSetInitContainerTuning" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (not $values.tuning.tune_aio_events) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (mustMergeOverwrite (dict "name" "" "resources" (dict ) ) (dict "name" "tuning" "image" (printf "%s:%s" $values.image.repository (get (fromJson (include "redpanda.Tag" (dict "a" (list $dot) ))) "r")) "command" (list `/bin/bash` `-c` `rpk redpanda tune all`) "securityContext" (mustMergeOverwrite (dict ) (dict "capabilities" (mustMergeOverwrite (dict ) (dict "add" (list `SYS_RESOURCE`) )) "privileged" true "runAsUser" ((0 | int64) | int64) "runAsGroup" ((0 | int64) | int64) )) "volumeMounts" (concat (default (list ) (concat (default (list ) (get (fromJson (include "redpanda.CommonMounts" (dict "a" (list $dot) ))) "r")) (default (list ) (get (fromJson (include "redpanda.templateToVolumeMounts" (dict "a" (list $dot $values.statefulset.initContainers.tuning.extraVolumeMounts) ))) "r")))) (list (mustMergeOverwrite (dict "name" "" "mountPath" "" ) (dict "name" (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r") "mountPath" "/etc/redpanda" )))) "resources" $values.statefulset.initContainers.tuning.resources ))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.statefulSetInitContainerSetDataDirOwnership" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (not $values.statefulset.initContainers.setDataDirOwnership.enabled) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $tmp_tuple_3 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "redpanda.securityContextUidGid" (dict "a" (list $dot "set-datadir-ownership") ))) "r")) ))) "r") -}} +{{- $gid := ($tmp_tuple_3.T2 | int64) -}} +{{- $uid := ($tmp_tuple_3.T1 | int64) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (mustMergeOverwrite (dict "name" "" "resources" (dict ) ) (dict "name" "set-datadir-ownership" "image" (printf "%s:%s" $values.statefulset.initContainerImage.repository $values.statefulset.initContainerImage.tag) "command" (list `/bin/sh` `-c` (printf `chown %d:%d -R /var/lib/redpanda/data` $uid $gid)) "volumeMounts" (concat (default (list ) (concat (default (list ) (get (fromJson (include "redpanda.CommonMounts" (dict "a" (list $dot) ))) "r")) (default (list ) (get (fromJson (include "redpanda.templateToVolumeMounts" (dict "a" (list $dot $values.statefulset.initContainers.setDataDirOwnership.extraVolumeMounts) ))) "r")))) (list (mustMergeOverwrite (dict "name" "" "mountPath" "" ) (dict "name" `datadir` "mountPath" `/var/lib/redpanda/data` )))) "resources" $values.statefulset.initContainers.setDataDirOwnership.resources ))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.securityContextUidGid" -}} +{{- $dot := (index .a 0) -}} +{{- $containerName := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $uid := $values.statefulset.securityContext.runAsUser -}} +{{- if (and (ne $values.statefulset.podSecurityContext (coalesce nil)) (ne $values.statefulset.podSecurityContext.runAsUser (coalesce nil))) -}} +{{- $uid = $values.statefulset.podSecurityContext.runAsUser -}} +{{- end -}} +{{- if (eq $uid (coalesce nil)) -}} +{{- $_ := (fail (printf `%s container requires runAsUser to be specified` $containerName)) -}} +{{- end -}} +{{- $gid := $values.statefulset.securityContext.fsGroup -}} +{{- if (and (ne $values.statefulset.podSecurityContext (coalesce nil)) (ne $values.statefulset.podSecurityContext.fsGroup (coalesce nil))) -}} +{{- $gid = $values.statefulset.podSecurityContext.fsGroup -}} +{{- end -}} +{{- if (eq $gid (coalesce nil)) -}} +{{- $_ := (fail (printf `%s container requires fsGroup to be specified` $containerName)) -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (list $uid $gid)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.statefulSetInitContainerFSValidator" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (not $values.statefulset.initContainers.fsValidator.enabled) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (mustMergeOverwrite (dict "name" "" "resources" (dict ) ) (dict "name" "fs-validator" "image" (printf "%s:%s" $values.image.repository (get (fromJson (include "redpanda.Tag" (dict "a" (list $dot) ))) "r")) "command" (list `/bin/sh`) "args" (list `-c` (printf `trap "exit 0" TERM; exec /etc/secrets/fs-validator/scripts/fsValidator.sh %s & wait $!` $values.statefulset.initContainers.fsValidator.expectedFS)) "securityContext" (get (fromJson (include "redpanda.ContainerSecurityContext" (dict "a" (list $dot) ))) "r") "volumeMounts" (concat (default (list ) (concat (default (list ) (get (fromJson (include "redpanda.CommonMounts" (dict "a" (list $dot) ))) "r")) (default (list ) (get (fromJson (include "redpanda.templateToVolumeMounts" (dict "a" (list $dot $values.statefulset.initContainers.fsValidator.extraVolumeMounts) ))) "r")))) (list (mustMergeOverwrite (dict "name" "" "mountPath" "" ) (dict "name" (printf `%.49s-fs-validator` (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r")) "mountPath" `/etc/secrets/fs-validator/scripts/` )) (mustMergeOverwrite (dict "name" "" "mountPath" "" ) (dict "name" `datadir` "mountPath" `/var/lib/redpanda/data` )))) "resources" $values.statefulset.initContainers.fsValidator.resources ))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.statefulSetInitContainerSetTieredStorageCacheDirOwnership" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (not (get (fromJson (include "redpanda.Storage.IsTieredStorageEnabled" (dict "a" (list $values.storage) ))) "r")) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $tmp_tuple_4 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "redpanda.securityContextUidGid" (dict "a" (list $dot "set-tiered-storage-cache-dir-ownership") ))) "r")) ))) "r") -}} +{{- $gid := ($tmp_tuple_4.T2 | int64) -}} +{{- $uid := ($tmp_tuple_4.T1 | int64) -}} +{{- $cacheDir := (get (fromJson (include "redpanda.Storage.TieredCacheDirectory" (dict "a" (list $values.storage $dot) ))) "r") -}} +{{- $mounts := (get (fromJson (include "redpanda.CommonMounts" (dict "a" (list $dot) ))) "r") -}} +{{- $mounts = (concat (default (list ) $mounts) (list (mustMergeOverwrite (dict "name" "" "mountPath" "" ) (dict "name" "datadir" "mountPath" "/var/lib/redpanda/data" )))) -}} +{{- if (ne (get (fromJson (include "redpanda.Storage.TieredMountType" (dict "a" (list $values.storage) ))) "r") "none") -}} +{{- $name := "tiered-storage-dir" -}} +{{- if (and (ne $values.storage.persistentVolume (coalesce nil)) (ne $values.storage.persistentVolume.nameOverwrite "")) -}} +{{- $name = $values.storage.persistentVolume.nameOverwrite -}} +{{- end -}} +{{- $mounts = (concat (default (list ) $mounts) (list (mustMergeOverwrite (dict "name" "" "mountPath" "" ) (dict "name" $name "mountPath" $cacheDir )))) -}} +{{- end -}} +{{- $mounts = (concat (default (list ) $mounts) (default (list ) (get (fromJson (include "redpanda.templateToVolumeMounts" (dict "a" (list $dot $values.statefulset.initContainers.setTieredStorageCacheDirOwnership.extraVolumeMounts) ))) "r"))) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (mustMergeOverwrite (dict "name" "" "resources" (dict ) ) (dict "name" `set-tiered-storage-cache-dir-ownership` "image" (printf `%s:%s` $values.statefulset.initContainerImage.repository $values.statefulset.initContainerImage.tag) "command" (list `/bin/sh` `-c` (printf `mkdir -p %s; chown %d:%d -R %s` $cacheDir $uid $gid $cacheDir)) "volumeMounts" $mounts "resources" $values.statefulset.initContainers.setTieredStorageCacheDirOwnership.resources ))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.statefulSetInitContainerConfigurator" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $_is_returning = true -}} +{{- (dict "r" (mustMergeOverwrite (dict "name" "" "resources" (dict ) ) (dict "name" (printf `%.51s-configurator` (get (fromJson (include "redpanda.Name" (dict "a" (list $dot) ))) "r")) "image" (printf `%s:%s` $values.image.repository (get (fromJson (include "redpanda.Tag" (dict "a" (list $dot) ))) "r")) "command" (list `/bin/bash` `-c` `trap "exit 0" TERM; exec $CONFIGURATOR_SCRIPT "${SERVICE_NAME}" "${KUBERNETES_NODE_NAME}" & wait $!`) "env" (list (mustMergeOverwrite (dict "name" "" ) (dict "name" "CONFIGURATOR_SCRIPT" "value" "/etc/secrets/configurator/scripts/configurator.sh" )) (mustMergeOverwrite (dict "name" "" ) (dict "name" "SERVICE_NAME" "valueFrom" (mustMergeOverwrite (dict ) (dict "fieldRef" (mustMergeOverwrite (dict "fieldPath" "" ) (dict "fieldPath" "metadata.name" )) "resourceFieldRef" (coalesce nil) "configMapKeyRef" (coalesce nil) "secretKeyRef" (coalesce nil) )) )) (mustMergeOverwrite (dict "name" "" ) (dict "name" "KUBERNETES_NODE_NAME" "valueFrom" (mustMergeOverwrite (dict ) (dict "fieldRef" (mustMergeOverwrite (dict "fieldPath" "" ) (dict "fieldPath" "spec.nodeName" )) )) )) (mustMergeOverwrite (dict "name" "" ) (dict "name" "HOST_IP_ADDRESS" "valueFrom" (mustMergeOverwrite (dict ) (dict "fieldRef" (mustMergeOverwrite (dict "fieldPath" "" ) (dict "apiVersion" "v1" "fieldPath" "status.hostIP" )) )) ))) "securityContext" (get (fromJson (include "redpanda.ContainerSecurityContext" (dict "a" (list $dot) ))) "r") "volumeMounts" (concat (default (list ) (concat (default (list ) (get (fromJson (include "redpanda.CommonMounts" (dict "a" (list $dot) ))) "r")) (default (list ) (get (fromJson (include "redpanda.templateToVolumeMounts" (dict "a" (list $dot $values.statefulset.initContainers.configurator.extraVolumeMounts) ))) "r")))) (list (mustMergeOverwrite (dict "name" "" "mountPath" "" ) (dict "name" "config" "mountPath" "/etc/redpanda" )) (mustMergeOverwrite (dict "name" "" "mountPath" "" ) (dict "name" (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r") "mountPath" "/tmp/base-config" )) (mustMergeOverwrite (dict "name" "" "mountPath" "" ) (dict "name" (printf `%.51s-configurator` (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r")) "mountPath" "/etc/secrets/configurator/scripts/" )))) "resources" $values.statefulset.initContainers.configurator.resources ))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.StatefulSetContainers" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $containers := (coalesce nil) -}} +{{- $containers = (concat (default (list ) $containers) (list (get (fromJson (include "redpanda.statefulSetContainerRedpanda" (dict "a" (list $dot) ))) "r"))) -}} +{{- $c_11 := (get (fromJson (include "redpanda.statefulSetContainerConfigWatcher" (dict "a" (list $dot) ))) "r") -}} +{{- if (ne $c_11 (coalesce nil)) -}} +{{- $containers = (concat (default (list ) $containers) (list $c_11)) -}} +{{- end -}} +{{- $c_12 := (get (fromJson (include "redpanda.statefulSetContainerControllers" (dict "a" (list $dot) ))) "r") -}} +{{- if (ne $c_12 (coalesce nil)) -}} +{{- $containers = (concat (default (list ) $containers) (list $c_12)) -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $containers) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.statefulSetContainerRedpanda" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $internalAdvertiseAddress := (printf "%s.%s" "$(SERVICE_NAME)" (get (fromJson (include "redpanda.InternalDomain" (dict "a" (list $dot) ))) "r")) -}} +{{- $container := (mustMergeOverwrite (dict "name" "" "resources" (dict ) ) (dict "name" (get (fromJson (include "redpanda.Name" (dict "a" (list $dot) ))) "r") "image" (printf `%s:%s` $values.image.repository (get (fromJson (include "redpanda.Tag" (dict "a" (list $dot) ))) "r")) "env" (get (fromJson (include "redpanda.statefulSetRedpandaEnv" (dict "a" (list ) ))) "r") "lifecycle" (mustMergeOverwrite (dict ) (dict "postStart" (mustMergeOverwrite (dict ) (dict "exec" (mustMergeOverwrite (dict ) (dict "command" (list `/bin/bash` `-c` (join "\n" (list (printf `timeout -v %d bash -x /var/lifecycle/postStart.sh` ((div ($values.statefulset.terminationGracePeriodSeconds | int64) (2 | int64)) | int64)) `true` ``))) )) )) "preStop" (mustMergeOverwrite (dict ) (dict "exec" (mustMergeOverwrite (dict ) (dict "command" (list `/bin/bash` `-c` (join "\n" (list (printf `timeout -v %d bash -x /var/lifecycle/preStop.sh` ((div ($values.statefulset.terminationGracePeriodSeconds | int64) (2 | int64)) | int64)) `true # do not fail and cause the pod to terminate` ``))) )) )) )) "startupProbe" (mustMergeOverwrite (dict ) (mustMergeOverwrite (dict ) (dict "exec" (mustMergeOverwrite (dict ) (dict "command" (list `/bin/sh` `-c` (join "\n" (list `set -e` (printf `RESULT=$(curl --silent --fail -k -m 5 %s "%s://%s/v1/status/ready")` (get (fromJson (include "redpanda.adminTLSCurlFlags" (dict "a" (list $dot) ))) "r") (get (fromJson (include "redpanda.adminInternalHTTPProtocol" (dict "a" (list $dot) ))) "r") (get (fromJson (include "redpanda.adminApiURLs" (dict "a" (list $dot) ))) "r")) `echo $RESULT` `echo $RESULT | grep ready` ``))) )) )) (dict "initialDelaySeconds" ($values.statefulset.startupProbe.initialDelaySeconds | int) "periodSeconds" ($values.statefulset.startupProbe.periodSeconds | int) "failureThreshold" ($values.statefulset.startupProbe.failureThreshold | int) )) "livenessProbe" (mustMergeOverwrite (dict ) (mustMergeOverwrite (dict ) (dict "exec" (mustMergeOverwrite (dict ) (dict "command" (list `/bin/sh` `-c` (printf `curl --silent --fail -k -m 5 %s "%s://%s/v1/status/ready"` (get (fromJson (include "redpanda.adminTLSCurlFlags" (dict "a" (list $dot) ))) "r") (get (fromJson (include "redpanda.adminInternalHTTPProtocol" (dict "a" (list $dot) ))) "r") (get (fromJson (include "redpanda.adminApiURLs" (dict "a" (list $dot) ))) "r"))) )) )) (dict "initialDelaySeconds" ($values.statefulset.livenessProbe.initialDelaySeconds | int) "periodSeconds" ($values.statefulset.livenessProbe.periodSeconds | int) "failureThreshold" ($values.statefulset.livenessProbe.failureThreshold | int) )) "command" (list `rpk` `redpanda` `start` (printf `--advertise-rpc-addr=%s:%d` $internalAdvertiseAddress ($values.listeners.rpc.port | int))) "volumeMounts" (concat (default (list ) (get (fromJson (include "redpanda.StatefulSetVolumeMounts" (dict "a" (list $dot) ))) "r")) (default (list ) (get (fromJson (include "redpanda.templateToVolumeMounts" (dict "a" (list $dot $values.statefulset.extraVolumeMounts) ))) "r"))) "securityContext" (get (fromJson (include "redpanda.ContainerSecurityContext" (dict "a" (list $dot) ))) "r") "resources" (mustMergeOverwrite (dict ) (dict )) )) -}} +{{- if (not (get (fromJson (include "_shims.typeassertion" (dict "a" (list "bool" (dig `recovery_mode_enabled` false $values.config.node)) ))) "r")) -}} +{{- $_ := (set $container "readinessProbe" (mustMergeOverwrite (dict ) (mustMergeOverwrite (dict ) (dict "exec" (mustMergeOverwrite (dict ) (dict "command" (list `/bin/sh` `-c` (join "\n" (list `set -x` `RESULT=$(rpk cluster health)` `echo $RESULT` `echo $RESULT | grep 'Healthy:.*true'` ``))) )) )) (dict "initialDelaySeconds" ($values.statefulset.readinessProbe.initialDelaySeconds | int) "timeoutSeconds" ($values.statefulset.readinessProbe.timeoutSeconds | int) "periodSeconds" ($values.statefulset.readinessProbe.periodSeconds | int) "successThreshold" ($values.statefulset.readinessProbe.successThreshold | int) "failureThreshold" ($values.statefulset.readinessProbe.failureThreshold | int) ))) -}} +{{- end -}} +{{- $_ := (set $container "ports" (concat (default (list ) $container.ports) (list (mustMergeOverwrite (dict "containerPort" 0 ) (dict "name" "admin" "containerPort" ($values.listeners.admin.port | int) ))))) -}} +{{- range $externalName, $external := $values.listeners.admin.external -}} +{{- if (get (fromJson (include "redpanda.AdminExternal.IsEnabled" (dict "a" (list $external) ))) "r") -}} +{{- $_ := (set $container "ports" (concat (default (list ) $container.ports) (list (mustMergeOverwrite (dict "containerPort" 0 ) (dict "name" (printf "admin-%.8s" (lower $externalName)) "containerPort" ($external.port | int) ))))) -}} +{{- end -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_ := (set $container "ports" (concat (default (list ) $container.ports) (list (mustMergeOverwrite (dict "containerPort" 0 ) (dict "name" "http" "containerPort" ($values.listeners.http.port | int) ))))) -}} +{{- range $externalName, $external := $values.listeners.http.external -}} +{{- if (get (fromJson (include "redpanda.HTTPExternal.IsEnabled" (dict "a" (list $external) ))) "r") -}} +{{- $_ := (set $container "ports" (concat (default (list ) $container.ports) (list (mustMergeOverwrite (dict "containerPort" 0 ) (dict "name" (printf "http-%.8s" (lower $externalName)) "containerPort" ($external.port | int) ))))) -}} +{{- end -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_ := (set $container "ports" (concat (default (list ) $container.ports) (list (mustMergeOverwrite (dict "containerPort" 0 ) (dict "name" "kafka" "containerPort" ($values.listeners.kafka.port | int) ))))) -}} +{{- range $externalName, $external := $values.listeners.kafka.external -}} +{{- if (get (fromJson (include "redpanda.KafkaExternal.IsEnabled" (dict "a" (list $external) ))) "r") -}} +{{- $_ := (set $container "ports" (concat (default (list ) $container.ports) (list (mustMergeOverwrite (dict "containerPort" 0 ) (dict "name" (printf "kafka-%.8s" (lower $externalName)) "containerPort" ($external.port | int) ))))) -}} +{{- end -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_ := (set $container "ports" (concat (default (list ) $container.ports) (list (mustMergeOverwrite (dict "containerPort" 0 ) (dict "name" "rpc" "containerPort" ($values.listeners.rpc.port | int) ))))) -}} +{{- $_ := (set $container "ports" (concat (default (list ) $container.ports) (list (mustMergeOverwrite (dict "containerPort" 0 ) (dict "name" "schemaregistry" "containerPort" ($values.listeners.schemaRegistry.port | int) ))))) -}} +{{- range $externalName, $external := $values.listeners.schemaRegistry.external -}} +{{- if (get (fromJson (include "redpanda.SchemaRegistryExternal.IsEnabled" (dict "a" (list $external) ))) "r") -}} +{{- $_ := (set $container "ports" (concat (default (list ) $container.ports) (list (mustMergeOverwrite (dict "containerPort" 0 ) (dict "name" (printf "schema-%.8s" (lower $externalName)) "containerPort" ($external.port | int) ))))) -}} +{{- end -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- if (and (get (fromJson (include "redpanda.Storage.IsTieredStorageEnabled" (dict "a" (list $values.storage) ))) "r") (ne (get (fromJson (include "redpanda.Storage.TieredMountType" (dict "a" (list $values.storage) ))) "r") "none")) -}} +{{- $name := "tiered-storage-dir" -}} +{{- if (and (ne $values.storage.persistentVolume (coalesce nil)) (ne $values.storage.persistentVolume.nameOverwrite "")) -}} +{{- $name = $values.storage.persistentVolume.nameOverwrite -}} +{{- end -}} +{{- $_ := (set $container "volumeMounts" (concat (default (list ) $container.volumeMounts) (list (mustMergeOverwrite (dict "name" "" "mountPath" "" ) (dict "name" $name "mountPath" (get (fromJson (include "redpanda.Storage.TieredCacheDirectory" (dict "a" (list $values.storage $dot) ))) "r") ))))) -}} +{{- end -}} +{{- $_ := (set $container.resources "limits" (dict "cpu" $values.resources.cpu.cores "memory" $values.resources.memory.container.max )) -}} +{{- if (ne $values.resources.memory.container.min (coalesce nil)) -}} +{{- $_ := (set $container.resources "requests" (dict "cpu" $values.resources.cpu.cores "memory" $values.resources.memory.container.min )) -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $container) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.adminApiURLs" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $_is_returning = true -}} +{{- (dict "r" (printf `${SERVICE_NAME}.%s:%d` (get (fromJson (include "redpanda.InternalDomain" (dict "a" (list $dot) ))) "r") ($values.listeners.admin.port | int))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.statefulSetContainerConfigWatcher" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (not $values.statefulset.sideCars.configWatcher.enabled) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (mustMergeOverwrite (dict "name" "" "resources" (dict ) ) (dict "name" "config-watcher" "image" (printf `%s:%s` $values.image.repository (get (fromJson (include "redpanda.Tag" (dict "a" (list $dot) ))) "r")) "command" (list `/bin/sh`) "args" (list `-c` `trap "exit 0" TERM; exec /etc/secrets/config-watcher/scripts/sasl-user.sh & wait $!`) "resources" $values.statefulset.sideCars.configWatcher.resources "securityContext" $values.statefulset.sideCars.configWatcher.securityContext "volumeMounts" (concat (default (list ) (concat (default (list ) (get (fromJson (include "redpanda.CommonMounts" (dict "a" (list $dot) ))) "r")) (list (mustMergeOverwrite (dict "name" "" "mountPath" "" ) (dict "name" "config" "mountPath" "/etc/redpanda" )) (mustMergeOverwrite (dict "name" "" "mountPath" "" ) (dict "name" (printf `%s-config-watcher` (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r")) "mountPath" "/etc/secrets/config-watcher/scripts" ))))) (default (list ) (get (fromJson (include "redpanda.templateToVolumeMounts" (dict "a" (list $dot $values.statefulset.sideCars.configWatcher.extraVolumeMounts) ))) "r"))) ))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.statefulSetContainerControllers" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (or (not $values.rbac.enabled) (not $values.statefulset.sideCars.controllers.enabled)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (mustMergeOverwrite (dict "name" "" "resources" (dict ) ) (dict "name" "redpanda-controllers" "image" (printf `%s:%s` $values.statefulset.sideCars.controllers.image.repository $values.statefulset.sideCars.controllers.image.tag) "command" (list `/manager`) "args" (list `--operator-mode=false` (printf `--namespace=%s` $dot.Release.Namespace) (printf `--health-probe-bind-address=%s` $values.statefulset.sideCars.controllers.healthProbeAddress) (printf `--metrics-bind-address=%s` $values.statefulset.sideCars.controllers.metricsAddress) (printf `--additional-controllers=%s` (join "," $values.statefulset.sideCars.controllers.run))) "env" (list (mustMergeOverwrite (dict "name" "" ) (dict "name" "REDPANDA_HELM_RELEASE_NAME" "value" $dot.Release.Name ))) "resources" $values.statefulset.sideCars.controllers.resources "securityContext" $values.statefulset.sideCars.controllers.securityContext ))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.templateToVolumeMounts" -}} +{{- $dot := (index .a 0) -}} +{{- $template := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $result := (tpl $template $dot) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (fromYamlArray $result)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.templateToVolumes" -}} +{{- $dot := (index .a 0) -}} +{{- $template := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $result := (tpl $template $dot) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (fromYamlArray $result)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.templateToContainers" -}} +{{- $dot := (index .a 0) -}} +{{- $template := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $result := (tpl $template $dot) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (fromYamlArray $result)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.StatefulSet" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (and (not (get (fromJson (include "redpanda.RedpandaAtLeast_22_2_0" (dict "a" (list $dot) ))) "r")) (not $values.force)) -}} +{{- $sv := (get (fromJson (include "redpanda.semver" (dict "a" (list $dot) ))) "r") -}} +{{- $_ := (fail (printf "Error: The Redpanda version (%s) is no longer supported \nTo accept this risk, run the upgrade again adding `--force=true`\n" $sv)) -}} +{{- end -}} +{{- $ss := (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "spec" (dict "selector" (coalesce nil) "template" (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "spec" (dict "containers" (coalesce nil) ) ) "serviceName" "" "updateStrategy" (dict ) ) "status" (dict "replicas" 0 "availableReplicas" 0 ) ) (mustMergeOverwrite (dict ) (dict "apiVersion" "apps/v1" "kind" "StatefulSet" )) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "name" (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r") "namespace" $dot.Release.Namespace "labels" (get (fromJson (include "redpanda.FullLabels" (dict "a" (list $dot) ))) "r") )) "spec" (mustMergeOverwrite (dict "selector" (coalesce nil) "template" (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "spec" (dict "containers" (coalesce nil) ) ) "serviceName" "" "updateStrategy" (dict ) ) (dict "selector" (mustMergeOverwrite (dict ) (dict "matchLabels" (get (fromJson (include "redpanda.StatefulSetPodLabelsSelector" (dict "a" (list $dot) ))) "r") )) "serviceName" (get (fromJson (include "redpanda.ServiceName" (dict "a" (list $dot) ))) "r") "replicas" ($values.statefulset.replicas | int) "updateStrategy" $values.statefulset.updateStrategy "podManagementPolicy" "Parallel" "template" (get (fromJson (include "redpanda.StrategicMergePatch" (dict "a" (list $values.statefulset.podTemplate (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "spec" (dict "containers" (coalesce nil) ) ) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "labels" (get (fromJson (include "redpanda.StatefulSetPodLabels" (dict "a" (list $dot) ))) "r") "annotations" (get (fromJson (include "redpanda.StatefulSetPodAnnotations" (dict "a" (list $dot (get (fromJson (include "redpanda.statefulSetChecksumAnnotation" (dict "a" (list $dot) ))) "r")) ))) "r") )) "spec" (mustMergeOverwrite (dict "containers" (coalesce nil) ) (dict "terminationGracePeriodSeconds" ($values.statefulset.terminationGracePeriodSeconds | int64) "securityContext" (get (fromJson (include "redpanda.PodSecurityContext" (dict "a" (list $dot) ))) "r") "serviceAccountName" (get (fromJson (include "redpanda.ServiceAccountName" (dict "a" (list $dot) ))) "r") "imagePullSecrets" (default (coalesce nil) $values.imagePullSecrets) "initContainers" (get (fromJson (include "redpanda.StatefulSetInitContainers" (dict "a" (list $dot) ))) "r") "containers" (get (fromJson (include "redpanda.StatefulSetContainers" (dict "a" (list $dot) ))) "r") "volumes" (get (fromJson (include "redpanda.StatefulSetVolumes" (dict "a" (list $dot) ))) "r") "topologySpreadConstraints" (get (fromJson (include "redpanda.statefulSetTopologySpreadConstraints" (dict "a" (list $dot) ))) "r") "nodeSelector" (get (fromJson (include "redpanda.statefulSetNodeSelectors" (dict "a" (list $dot) ))) "r") "affinity" (get (fromJson (include "redpanda.statefulSetAffinity" (dict "a" (list $dot) ))) "r") "priorityClassName" $values.statefulset.priorityClassName "tolerations" (get (fromJson (include "redpanda.statefulSetTolerations" (dict "a" (list $dot) ))) "r") )) ))) ))) "r") "volumeClaimTemplates" (coalesce nil) )) )) -}} +{{- if (or $values.storage.persistentVolume.enabled ((and (get (fromJson (include "redpanda.Storage.IsTieredStorageEnabled" (dict "a" (list $values.storage) ))) "r") (eq (get (fromJson (include "redpanda.Storage.TieredMountType" (dict "a" (list $values.storage) ))) "r") "persistentVolume")))) -}} +{{- $t_13 := (get (fromJson (include "redpanda.volumeClaimTemplateDatadir" (dict "a" (list $dot) ))) "r") -}} +{{- if (ne $t_13 (coalesce nil)) -}} +{{- $_ := (set $ss.spec "volumeClaimTemplates" (concat (default (list ) $ss.spec.volumeClaimTemplates) (list $t_13))) -}} +{{- end -}} +{{- $t_14 := (get (fromJson (include "redpanda.volumeClaimTemplateTieredStorageDir" (dict "a" (list $dot) ))) "r") -}} +{{- if (ne $t_14 (coalesce nil)) -}} +{{- $_ := (set $ss.spec "volumeClaimTemplates" (concat (default (list ) $ss.spec.volumeClaimTemplates) (list $t_14))) -}} +{{- end -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $ss) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.semver" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $_is_returning = true -}} +{{- (dict "r" (trimPrefix "v" (get (fromJson (include "redpanda.Tag" (dict "a" (list $dot) ))) "r"))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.statefulSetChecksumAnnotation" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $dependencies := (coalesce nil) -}} +{{- $dependencies = (concat (default (list ) $dependencies) (list (get (fromJson (include "redpanda.ConfigMapsWithoutSeedServer" (dict "a" (list $dot) ))) "r"))) -}} +{{- if $values.external.enabled -}} +{{- $dependencies = (concat (default (list ) $dependencies) (list (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $values.external.domain "") ))) "r"))) -}} +{{- if (empty $values.external.addresses) -}} +{{- $dependencies = (concat (default (list ) $dependencies) (list "")) -}} +{{- else -}} +{{- $dependencies = (concat (default (list ) $dependencies) (list $values.external.addresses)) -}} +{{- end -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (sha256sum (toJson $dependencies))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.statefulSetTolerations" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $_is_returning = true -}} +{{- (dict "r" (default $values.tolerations $values.statefulset.tolerations)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.statefulSetNodeSelectors" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $_is_returning = true -}} +{{- (dict "r" (default $values.statefulset.nodeSelector $values.nodeSelector)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.statefulSetAffinity" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $affinity := (mustMergeOverwrite (dict ) (dict )) -}} +{{- if (not (empty $values.statefulset.nodeAffinity)) -}} +{{- $_ := (set $affinity "nodeAffinity" $values.statefulset.nodeAffinity) -}} +{{- else -}}{{- if (not (empty $values.affinity.nodeAffinity)) -}} +{{- $_ := (set $affinity "nodeAffinity" $values.affinity.nodeAffinity) -}} +{{- end -}} +{{- end -}} +{{- if (not (empty $values.statefulset.podAffinity)) -}} +{{- $_ := (set $affinity "podAffinity" $values.statefulset.podAffinity) -}} +{{- else -}}{{- if (not (empty $values.affinity.podAffinity)) -}} +{{- $_ := (set $affinity "podAffinity" $values.affinity.podAffinity) -}} +{{- end -}} +{{- end -}} +{{- if (not (empty $values.statefulset.podAntiAffinity)) -}} +{{- $_ := (set $affinity "podAntiAffinity" (mustMergeOverwrite (dict ) (dict ))) -}} +{{- if (eq $values.statefulset.podAntiAffinity.type "hard") -}} +{{- $_ := (set $affinity.podAntiAffinity "requiredDuringSchedulingIgnoredDuringExecution" (list (mustMergeOverwrite (dict "topologyKey" "" ) (dict "topologyKey" $values.statefulset.podAntiAffinity.topologyKey "labelSelector" (mustMergeOverwrite (dict ) (dict "matchLabels" (get (fromJson (include "redpanda.StatefulSetPodLabelsSelector" (dict "a" (list $dot) ))) "r") )) )))) -}} +{{- else -}}{{- if (eq $values.statefulset.podAntiAffinity.type "soft") -}} +{{- $_ := (set $affinity.podAntiAffinity "preferredDuringSchedulingIgnoredDuringExecution" (list (mustMergeOverwrite (dict "weight" 0 "podAffinityTerm" (dict "topologyKey" "" ) ) (dict "weight" ($values.statefulset.podAntiAffinity.weight | int) "podAffinityTerm" (mustMergeOverwrite (dict "topologyKey" "" ) (dict "topologyKey" $values.statefulset.podAntiAffinity.topologyKey "labelSelector" (mustMergeOverwrite (dict ) (dict "matchLabels" (get (fromJson (include "redpanda.StatefulSetPodLabelsSelector" (dict "a" (list $dot) ))) "r") )) )) )))) -}} +{{- else -}}{{- if (eq $values.statefulset.podAntiAffinity.type "custom") -}} +{{- $_ := (set $affinity "podAntiAffinity" $values.statefulset.podAntiAffinity.custom) -}} +{{- end -}} +{{- end -}} +{{- end -}} +{{- else -}}{{- if (not (empty $values.affinity.podAntiAffinity)) -}} +{{- $_ := (set $affinity "podAntiAffinity" $values.affinity.podAntiAffinity) -}} +{{- end -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $affinity) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.volumeClaimTemplateDatadir" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (not $values.storage.persistentVolume.enabled) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $pvc := (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "spec" (dict "resources" (dict ) ) "status" (dict ) ) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "name" "datadir" "labels" (merge (dict ) (dict `app.kubernetes.io/name` (get (fromJson (include "redpanda.Name" (dict "a" (list $dot) ))) "r") `app.kubernetes.io/instance` $dot.Release.Name `app.kubernetes.io/component` (get (fromJson (include "redpanda.Name" (dict "a" (list $dot) ))) "r") ) $values.storage.persistentVolume.labels $values.commonLabels) "annotations" (default (coalesce nil) $values.storage.persistentVolume.annotations) )) "spec" (mustMergeOverwrite (dict "resources" (dict ) ) (dict "accessModes" (list "ReadWriteOnce") "resources" (mustMergeOverwrite (dict ) (dict "requests" (dict "storage" $values.storage.persistentVolume.size ) )) )) )) -}} +{{- if (not (empty $values.storage.persistentVolume.storageClass)) -}} +{{- if (eq $values.storage.persistentVolume.storageClass "-") -}} +{{- $_ := (set $pvc.spec "storageClassName" "") -}} +{{- else -}} +{{- $_ := (set $pvc.spec "storageClassName" $values.storage.persistentVolume.storageClass) -}} +{{- end -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $pvc) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.volumeClaimTemplateTieredStorageDir" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (or (not (get (fromJson (include "redpanda.Storage.IsTieredStorageEnabled" (dict "a" (list $values.storage) ))) "r")) (ne (get (fromJson (include "redpanda.Storage.TieredMountType" (dict "a" (list $values.storage) ))) "r") "persistentVolume")) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $pvc := (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "spec" (dict "resources" (dict ) ) "status" (dict ) ) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "name" (default "tiered-storage-dir" $values.storage.persistentVolume.nameOverwrite) "labels" (merge (dict ) (dict `app.kubernetes.io/name` (get (fromJson (include "redpanda.Name" (dict "a" (list $dot) ))) "r") `app.kubernetes.io/instance` $dot.Release.Name `app.kubernetes.io/component` (get (fromJson (include "redpanda.Name" (dict "a" (list $dot) ))) "r") ) (get (fromJson (include "redpanda.Storage.TieredPersistentVolumeLabels" (dict "a" (list $values.storage) ))) "r") $values.commonLabels) "annotations" (default (coalesce nil) (get (fromJson (include "redpanda.Storage.TieredPersistentVolumeAnnotations" (dict "a" (list $values.storage) ))) "r")) )) "spec" (mustMergeOverwrite (dict "resources" (dict ) ) (dict "accessModes" (list "ReadWriteOnce") "resources" (mustMergeOverwrite (dict ) (dict "requests" (dict "storage" (index (get (fromJson (include "redpanda.Storage.GetTieredStorageConfig" (dict "a" (list $values.storage) ))) "r") `cloud_storage_cache_size`) ) )) )) )) -}} +{{- $sc_15 := (get (fromJson (include "redpanda.Storage.TieredPersistentVolumeStorageClass" (dict "a" (list $values.storage) ))) "r") -}} +{{- if (eq $sc_15 "-") -}} +{{- $_ := (set $pvc.spec "storageClassName" "") -}} +{{- else -}}{{- if (not (empty $sc_15)) -}} +{{- $_ := (set $pvc.spec "storageClassName" $sc_15) -}} +{{- end -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $pvc) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.statefulSetTopologySpreadConstraints" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $result := (coalesce nil) -}} +{{- $labelSelector := (mustMergeOverwrite (dict ) (dict "matchLabels" (get (fromJson (include "redpanda.StatefulSetPodLabelsSelector" (dict "a" (list $dot) ))) "r") )) -}} +{{- range $_, $v := $values.statefulset.topologySpreadConstraints -}} +{{- $result = (concat (default (list ) $result) (list (mustMergeOverwrite (dict "maxSkew" 0 "topologyKey" "" "whenUnsatisfiable" "" ) (dict "maxSkew" ($v.maxSkew | int) "topologyKey" $v.topologyKey "whenUnsatisfiable" $v.whenUnsatisfiable "labelSelector" $labelSelector )))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $result) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.StorageTieredConfig" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $_is_returning = true -}} +{{- (dict "r" (get (fromJson (include "redpanda.Storage.GetTieredStorageConfig" (dict "a" (list $values.storage) ))) "r")) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + diff --git a/charts/redpanda/redpanda/5.9.2/templates/_values.go.tpl b/charts/redpanda/redpanda/5.9.2/templates/_values.go.tpl new file mode 100644 index 0000000000..1d0eb030f0 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/_values.go.tpl @@ -0,0 +1,1258 @@ +{{- /* Generated from "values.go" */ -}} + +{{- define "redpanda.AuditLogging.Translate" -}} +{{- $a := (index .a 0) -}} +{{- $dot := (index .a 1) -}} +{{- $isSASLEnabled := (index .a 2) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $result := (dict ) -}} +{{- if (not (get (fromJson (include "redpanda.RedpandaAtLeast_23_3_0" (dict "a" (list $dot) ))) "r")) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $result) | toJson -}} +{{- break -}} +{{- end -}} +{{- $enabled := (and $a.enabled $isSASLEnabled) -}} +{{- $_ := (set $result "audit_enabled" $enabled) -}} +{{- if (not $enabled) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $result) | toJson -}} +{{- break -}} +{{- end -}} +{{- if (ne (($a.clientMaxBufferSize | int) | int) (16777216 | int)) -}} +{{- $_ := (set $result "audit_client_max_buffer_size" ($a.clientMaxBufferSize | int)) -}} +{{- end -}} +{{- if (ne (($a.queueDrainIntervalMs | int) | int) (500 | int)) -}} +{{- $_ := (set $result "audit_queue_drain_interval_ms" ($a.queueDrainIntervalMs | int)) -}} +{{- end -}} +{{- if (ne (($a.queueMaxBufferSizePerShard | int) | int) (1048576 | int)) -}} +{{- $_ := (set $result "audit_queue_max_buffer_size_per_shard" ($a.queueMaxBufferSizePerShard | int)) -}} +{{- end -}} +{{- if (ne (($a.partitions | int) | int) (12 | int)) -}} +{{- $_ := (set $result "audit_log_num_partitions" ($a.partitions | int)) -}} +{{- end -}} +{{- if (ne ($a.replicationFactor | int) (0 | int)) -}} +{{- $_ := (set $result "audit_log_replication_factor" ($a.replicationFactor | int)) -}} +{{- end -}} +{{- if (gt ((get (fromJson (include "_shims.len" (dict "a" (list $a.enabledEventTypes) ))) "r") | int) (0 | int)) -}} +{{- $_ := (set $result "audit_enabled_event_types" $a.enabledEventTypes) -}} +{{- end -}} +{{- if (gt ((get (fromJson (include "_shims.len" (dict "a" (list $a.excludedTopics) ))) "r") | int) (0 | int)) -}} +{{- $_ := (set $result "audit_excluded_topics" $a.excludedTopics) -}} +{{- end -}} +{{- if (gt ((get (fromJson (include "_shims.len" (dict "a" (list $a.excludedPrincipals) ))) "r") | int) (0 | int)) -}} +{{- $_ := (set $result "audit_excluded_principals" $a.excludedPrincipals) -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $result) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.Auth.IsSASLEnabled" -}} +{{- $a := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (eq $a.sasl (coalesce nil)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" false) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $a.sasl.enabled) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.Auth.Translate" -}} +{{- $a := (index .a 0) -}} +{{- $isSASLEnabled := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (not $isSASLEnabled) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- if (eq ((get (fromJson (include "_shims.len" (dict "a" (list $a.sasl.users) ))) "r") | int) (0 | int)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $users := (list ) -}} +{{- range $_, $u := $a.sasl.users -}} +{{- $users = (concat (default (list ) $users) (list $u.name)) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (dict "superusers" $users )) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.Logging.Translate" -}} +{{- $l := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $result := (dict ) -}} +{{- $clusterID_1 := (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $l.usageStats.clusterId "") ))) "r") -}} +{{- if (ne $clusterID_1 "") -}} +{{- $_ := (set $result "cluster_id" $clusterID_1) -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $result) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.RedpandaResources.GetOverProvisionValue" -}} +{{- $rr := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (lt ((get (fromJson (include "_shims.resource_MilliValue" (dict "a" (list $rr.cpu.cores) ))) "r") | int64) (1000 | int64)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" true) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $rr.cpu.overprovisioned false) ))) "r")) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.Storage.IsTieredStorageEnabled" -}} +{{- $s := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $conf := (get (fromJson (include "redpanda.Storage.GetTieredStorageConfig" (dict "a" (list $s) ))) "r") -}} +{{- $tmp_tuple_3 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.dicttest" (dict "a" (list $conf "cloud_storage_enabled" (coalesce nil)) ))) "r")) ))) "r") -}} +{{- $ok := $tmp_tuple_3.T2 -}} +{{- $b := $tmp_tuple_3.T1 -}} +{{- $_is_returning = true -}} +{{- (dict "r" (and $ok (get (fromJson (include "_shims.typeassertion" (dict "a" (list "bool" $b) ))) "r"))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.Storage.GetTieredStorageConfig" -}} +{{- $s := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (gt ((get (fromJson (include "_shims.len" (dict "a" (list $s.tieredConfig) ))) "r") | int) (0 | int)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $s.tieredConfig) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $s.tiered.config) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.Storage.GetTieredStorageHostPath" -}} +{{- $s := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $hp := $s.tieredStorageHostPath -}} +{{- if (and (empty $hp) (ne $s.tiered (coalesce nil))) -}} +{{- $hp = $s.tiered.hostPath -}} +{{- end -}} +{{- if (empty $hp) -}} +{{- $_ := (fail (printf `storage.tiered.mountType is "%s" but storage.tiered.hostPath is empty` $s.tiered.mountType)) -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $hp) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.Storage.CloudStorageCacheSize" -}} +{{- $s := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $tmp_tuple_4 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.dicttest" (dict "a" (list (get (fromJson (include "redpanda.Storage.GetTieredStorageConfig" (dict "a" (list $s) ))) "r") `cloud_storage_cache_size` (coalesce nil)) ))) "r")) ))) "r") -}} +{{- $ok := $tmp_tuple_4.T2 -}} +{{- $value := $tmp_tuple_4.T1 -}} +{{- if (not $ok) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $value) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.Storage.TieredCacheDirectory" -}} +{{- $s := (index .a 0) -}} +{{- $dot := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $config := (get (fromJson (include "redpanda.Storage.GetTieredStorageConfig" (dict "a" (list $s) ))) "r") -}} +{{- $dir := (get (fromJson (include "_shims.typeassertion" (dict "a" (list "string" (dig `cloud_storage_cache_directory` "/var/lib/redpanda/data/cloud_storage_cache" $config)) ))) "r") -}} +{{- if (eq $dir "") -}} +{{- $_is_returning = true -}} +{{- (dict "r" "/var/lib/redpanda/data/cloud_storage_cache") | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $dir) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.Storage.TieredMountType" -}} +{{- $s := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (and (ne $s.tieredStoragePersistentVolume (coalesce nil)) $s.tieredStoragePersistentVolume.enabled) -}} +{{- $_is_returning = true -}} +{{- (dict "r" "persistentVolume") | toJson -}} +{{- break -}} +{{- end -}} +{{- if (not (empty $s.tieredStorageHostPath)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" "hostPath") | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $s.tiered.mountType) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.Storage.TieredPersistentVolumeLabels" -}} +{{- $s := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (ne $s.tieredStoragePersistentVolume (coalesce nil)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $s.tieredStoragePersistentVolume.labels) | toJson -}} +{{- break -}} +{{- end -}} +{{- if (ne $s.tiered (coalesce nil)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $s.tiered.persistentVolume.labels) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_ := (fail `storage.tiered.mountType is "persistentVolume" but storage.tiered.persistentVolume is not configured`) -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.Storage.TieredPersistentVolumeAnnotations" -}} +{{- $s := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (ne $s.tieredStoragePersistentVolume (coalesce nil)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $s.tieredStoragePersistentVolume.annotations) | toJson -}} +{{- break -}} +{{- end -}} +{{- if (ne $s.tiered (coalesce nil)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $s.tiered.persistentVolume.annotations) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_ := (fail `storage.tiered.mountType is "persistentVolume" but storage.tiered.persistentVolume is not configured`) -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.Storage.TieredPersistentVolumeStorageClass" -}} +{{- $s := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (ne $s.tieredStoragePersistentVolume (coalesce nil)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $s.tieredStoragePersistentVolume.storageClass) | toJson -}} +{{- break -}} +{{- end -}} +{{- if (ne $s.tiered (coalesce nil)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $s.tiered.persistentVolume.storageClass) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_ := (fail `storage.tiered.mountType is "persistentVolume" but storage.tiered.persistentVolume is not configured`) -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.Storage.Translate" -}} +{{- $s := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $result := (dict ) -}} +{{- if (not (get (fromJson (include "redpanda.Storage.IsTieredStorageEnabled" (dict "a" (list $s) ))) "r")) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $result) | toJson -}} +{{- break -}} +{{- end -}} +{{- $tieredStorageConfig := (get (fromJson (include "redpanda.Storage.GetTieredStorageConfig" (dict "a" (list $s) ))) "r") -}} +{{- range $k, $v := $tieredStorageConfig -}} +{{- if (or (eq $v (coalesce nil)) (empty $v)) -}} +{{- continue -}} +{{- end -}} +{{- if (and (eq $k "cloud_storage_cache_size") (ne $v (coalesce nil))) -}} +{{- $_ := (set $result $k (printf "%d" ((get (fromJson (include "_shims.resource_Value" (dict "a" (list $v) ))) "r") | int64))) -}} +{{- continue -}} +{{- end -}} +{{- $tmp_tuple_6 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.typetest" (dict "a" (list "string" $v "") ))) "r")) ))) "r") -}} +{{- $ok_3 := $tmp_tuple_6.T2 -}} +{{- $str_2 := $tmp_tuple_6.T1 -}} +{{- $tmp_tuple_7 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.typetest" (dict "a" (list "bool" $v false) ))) "r")) ))) "r") -}} +{{- $ok_5 := $tmp_tuple_7.T2 -}} +{{- $b_4 := $tmp_tuple_7.T1 -}} +{{- $tmp_tuple_8 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.asnumeric" (dict "a" (list $v) ))) "r")) ))) "r") -}} +{{- $isFloat_7 := $tmp_tuple_8.T2 -}} +{{- $f_6 := ($tmp_tuple_8.T1 | float64) -}} +{{- if $ok_3 -}} +{{- $_ := (set $result $k $str_2) -}} +{{- else -}}{{- if $ok_5 -}} +{{- $_ := (set $result $k $b_4) -}} +{{- else -}}{{- if $isFloat_7 -}} +{{- $_ := (set $result $k ($f_6 | int)) -}} +{{- else -}} +{{- $_ := (set $result $k (mustToJson $v)) -}} +{{- end -}} +{{- end -}} +{{- end -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $result) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.Storage.StorageMinFreeBytes" -}} +{{- $s := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (and (ne $s.persistentVolume (coalesce nil)) (not $s.persistentVolume.enabled)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (5368709120 | int)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $minimumFreeBytes := ((mulf (((get (fromJson (include "_shims.resource_Value" (dict "a" (list $s.persistentVolume.size) ))) "r") | int64) | float64) 0.05) | float64) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (min (5368709120 | int) ($minimumFreeBytes | int64))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.Tuning.Translate" -}} +{{- $t := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $result := (dict ) -}} +{{- $s := (toJson $t) -}} +{{- $tune := (fromJson $s) -}} +{{- $tmp_tuple_9 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.typetest" (dict "a" (list (printf "map[%s]%s" "string" "interface {}") $tune (coalesce nil)) ))) "r")) ))) "r") -}} +{{- $ok := $tmp_tuple_9.T2 -}} +{{- $m := $tmp_tuple_9.T1 -}} +{{- if (not $ok) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (dict )) | toJson -}} +{{- break -}} +{{- end -}} +{{- range $k, $v := $m -}} +{{- $_ := (set $result $k $v) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $result) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.Listeners.CreateSeedServers" -}} +{{- $l := (index .a 0) -}} +{{- $replicas := (index .a 1) -}} +{{- $fullname := (index .a 2) -}} +{{- $internalDomain := (index .a 3) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $result := (coalesce nil) -}} +{{- range $_, $i := untilStep (((0 | int) | int)|int) ($replicas|int) (1|int) -}} +{{- $result = (concat (default (list ) $result) (list (dict "host" (dict "address" (printf "%s-%d.%s" $fullname $i $internalDomain) "port" ($l.rpc.port | int) ) ))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $result) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.Listeners.AdminList" -}} +{{- $l := (index .a 0) -}} +{{- $replicas := (index .a 1) -}} +{{- $fullname := (index .a 2) -}} +{{- $internalDomain := (index .a 3) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $_is_returning = true -}} +{{- (dict "r" (get (fromJson (include "redpanda.ServerList" (dict "a" (list $replicas "" $fullname $internalDomain ($l.admin.port | int)) ))) "r")) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.ServerList" -}} +{{- $replicas := (index .a 0) -}} +{{- $prefix := (index .a 1) -}} +{{- $fullname := (index .a 2) -}} +{{- $internalDomain := (index .a 3) -}} +{{- $port := (index .a 4) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $result := (coalesce nil) -}} +{{- range $_, $i := untilStep (((0 | int) | int)|int) ($replicas|int) (1|int) -}} +{{- $result = (concat (default (list ) $result) (list (printf "%s%s-%d.%s:%d" $prefix $fullname $i $internalDomain ($port | int)))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $result) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.Listeners.TrustStoreVolume" -}} +{{- $l := (index .a 0) -}} +{{- $tls := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $cmSources := (dict ) -}} +{{- $secretSources := (dict ) -}} +{{- range $_, $ts := (get (fromJson (include "redpanda.Listeners.TrustStores" (dict "a" (list $l $tls) ))) "r") -}} +{{- $projection := (get (fromJson (include "redpanda.TrustStore.VolumeProjection" (dict "a" (list $ts) ))) "r") -}} +{{- if (ne $projection.secret (coalesce nil)) -}} +{{- $_ := (set $secretSources $projection.secret.name (concat (default (list ) (index $secretSources $projection.secret.name)) (default (list ) $projection.secret.items))) -}} +{{- else -}} +{{- $_ := (set $cmSources $projection.configMap.name (concat (default (list ) (index $cmSources $projection.configMap.name)) (default (list ) $projection.configMap.items))) -}} +{{- end -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $sources := (coalesce nil) -}} +{{- range $_, $name := (sortAlpha (keys $cmSources)) -}} +{{- $keys := (index $cmSources $name) -}} +{{- $sources = (concat (default (list ) $sources) (list (mustMergeOverwrite (dict ) (dict "configMap" (mustMergeOverwrite (dict ) (mustMergeOverwrite (dict ) (dict "name" $name )) (dict "items" (get (fromJson (include "redpanda.dedupKeyToPaths" (dict "a" (list $keys) ))) "r") )) )))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- range $_, $name := (sortAlpha (keys $secretSources)) -}} +{{- $keys := (index $secretSources $name) -}} +{{- $sources = (concat (default (list ) $sources) (list (mustMergeOverwrite (dict ) (dict "secret" (mustMergeOverwrite (dict ) (mustMergeOverwrite (dict ) (dict "name" $name )) (dict "items" (get (fromJson (include "redpanda.dedupKeyToPaths" (dict "a" (list $keys) ))) "r") )) )))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- if (lt ((get (fromJson (include "_shims.len" (dict "a" (list $sources) ))) "r") | int) (1 | int)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (mustMergeOverwrite (dict "name" "" ) (mustMergeOverwrite (dict ) (dict "projected" (mustMergeOverwrite (dict "sources" (coalesce nil) ) (dict "sources" $sources )) )) (dict "name" "truststores" ))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.dedupKeyToPaths" -}} +{{- $items := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $seen := (dict ) -}} +{{- $deduped := (coalesce nil) -}} +{{- range $_, $item := $items -}} +{{- $tmp_tuple_10 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.dicttest" (dict "a" (list $seen $item.key (coalesce nil)) ))) "r")) ))) "r") -}} +{{- $ok_8 := $tmp_tuple_10.T2 -}} +{{- if $ok_8 -}} +{{- continue -}} +{{- end -}} +{{- $deduped = (concat (default (list ) $deduped) (list $item)) -}} +{{- $_ := (set $seen $item.key true) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $deduped) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.Listeners.TrustStores" -}} +{{- $l := (index .a 0) -}} +{{- $tls := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $tss := (get (fromJson (include "redpanda.KafkaListeners.TrustStores" (dict "a" (list $l.kafka $tls) ))) "r") -}} +{{- $tss = (concat (default (list ) $tss) (default (list ) (get (fromJson (include "redpanda.AdminListeners.TrustStores" (dict "a" (list $l.admin $tls) ))) "r"))) -}} +{{- $tss = (concat (default (list ) $tss) (default (list ) (get (fromJson (include "redpanda.HTTPListeners.TrustStores" (dict "a" (list $l.http $tls) ))) "r"))) -}} +{{- $tss = (concat (default (list ) $tss) (default (list ) (get (fromJson (include "redpanda.SchemaRegistryListeners.TrustStores" (dict "a" (list $l.schemaRegistry $tls) ))) "r"))) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $tss) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.Config.CreateRPKConfiguration" -}} +{{- $c := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $result := (dict ) -}} +{{- range $k, $v := $c.rpk -}} +{{- $_ := (set $result $k $v) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $result) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.TLSCertMap.MustGet" -}} +{{- $m := (index .a 0) -}} +{{- $name := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $tmp_tuple_11 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.dicttest" (dict "a" (list $m $name (coalesce nil)) ))) "r")) ))) "r") -}} +{{- $ok := $tmp_tuple_11.T2 -}} +{{- $cert := $tmp_tuple_11.T1 -}} +{{- if (not $ok) -}} +{{- $_ := (fail (printf "Certificate %q referenced, but not found in the tls.certs map" $name)) -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $cert) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.TrustStore.TrustStoreFilePath" -}} +{{- $t := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $_is_returning = true -}} +{{- (dict "r" (printf "%s/%s" "/etc/truststores" (get (fromJson (include "redpanda.TrustStore.RelativePath" (dict "a" (list $t) ))) "r"))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.TrustStore.RelativePath" -}} +{{- $t := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (ne $t.configMapKeyRef (coalesce nil)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (printf "configmaps/%s-%s" $t.configMapKeyRef.name $t.configMapKeyRef.key)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (printf "secrets/%s-%s" $t.secretKeyRef.name $t.secretKeyRef.key)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.TrustStore.VolumeProjection" -}} +{{- $t := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (ne $t.configMapKeyRef (coalesce nil)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (mustMergeOverwrite (dict ) (dict "configMap" (mustMergeOverwrite (dict ) (mustMergeOverwrite (dict ) (dict "name" $t.configMapKeyRef.name )) (dict "items" (list (mustMergeOverwrite (dict "key" "" "path" "" ) (dict "key" $t.configMapKeyRef.key "path" (get (fromJson (include "redpanda.TrustStore.RelativePath" (dict "a" (list $t) ))) "r") ))) )) ))) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (mustMergeOverwrite (dict ) (dict "secret" (mustMergeOverwrite (dict ) (mustMergeOverwrite (dict ) (dict "name" $t.secretKeyRef.name )) (dict "items" (list (mustMergeOverwrite (dict "key" "" "path" "" ) (dict "key" $t.secretKeyRef.key "path" (get (fromJson (include "redpanda.TrustStore.RelativePath" (dict "a" (list $t) ))) "r") ))) )) ))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.InternalTLS.IsEnabled" -}} +{{- $t := (index .a 0) -}} +{{- $tls := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $_is_returning = true -}} +{{- (dict "r" (and (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $t.enabled $tls.enabled) ))) "r") (ne $t.cert ""))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.InternalTLS.TrustStoreFilePath" -}} +{{- $t := (index .a 0) -}} +{{- $tls := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (ne $t.trustStore (coalesce nil)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (get (fromJson (include "redpanda.TrustStore.TrustStoreFilePath" (dict "a" (list $t.trustStore) ))) "r")) | toJson -}} +{{- break -}} +{{- end -}} +{{- if (get (fromJson (include "redpanda.TLSCertMap.MustGet" (dict "a" (list (deepCopy $tls.certs) $t.cert) ))) "r").caEnabled -}} +{{- $_is_returning = true -}} +{{- (dict "r" (printf "/etc/tls/certs/%s/ca.crt" $t.cert)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" "/etc/ssl/certs/ca-certificates.crt") | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.ExternalTLS.GetCert" -}} +{{- $t := (index .a 0) -}} +{{- $i := (index .a 1) -}} +{{- $tls := (index .a 2) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $_is_returning = true -}} +{{- (dict "r" (get (fromJson (include "redpanda.TLSCertMap.MustGet" (dict "a" (list (deepCopy $tls.certs) (get (fromJson (include "redpanda.ExternalTLS.GetCertName" (dict "a" (list $t $i) ))) "r")) ))) "r")) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.ExternalTLS.GetCertName" -}} +{{- $t := (index .a 0) -}} +{{- $i := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $_is_returning = true -}} +{{- (dict "r" (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $t.cert $i.cert) ))) "r")) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.ExternalTLS.TrustStoreFilePath" -}} +{{- $t := (index .a 0) -}} +{{- $i := (index .a 1) -}} +{{- $tls := (index .a 2) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (ne $t.trustStore (coalesce nil)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (get (fromJson (include "redpanda.TrustStore.TrustStoreFilePath" (dict "a" (list $t.trustStore) ))) "r")) | toJson -}} +{{- break -}} +{{- end -}} +{{- if (get (fromJson (include "redpanda.ExternalTLS.GetCert" (dict "a" (list $t $i $tls) ))) "r").caEnabled -}} +{{- $_is_returning = true -}} +{{- (dict "r" (printf "/etc/tls/certs/%s/ca.crt" (get (fromJson (include "redpanda.ExternalTLS.GetCertName" (dict "a" (list $t $i) ))) "r"))) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" "/etc/ssl/certs/ca-certificates.crt") | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.ExternalTLS.IsEnabled" -}} +{{- $t := (index .a 0) -}} +{{- $i := (index .a 1) -}} +{{- $tls := (index .a 2) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (eq $t (coalesce nil)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" false) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" (and (ne (get (fromJson (include "redpanda.ExternalTLS.GetCertName" (dict "a" (list $t $i) ))) "r") "") (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $t.enabled (get (fromJson (include "redpanda.InternalTLS.IsEnabled" (dict "a" (list $i $tls) ))) "r")) ))) "r"))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.AdminListeners.ConsoleTLS" -}} +{{- $l := (index .a 0) -}} +{{- $tls := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $t := (mustMergeOverwrite (dict "enabled" false "caFilepath" "" "certFilepath" "" "keyFilepath" "" "insecureSkipTlsVerify" false ) (dict "enabled" (get (fromJson (include "redpanda.InternalTLS.IsEnabled" (dict "a" (list $l.tls $tls) ))) "r") )) -}} +{{- if (not $t.enabled) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $t) | toJson -}} +{{- break -}} +{{- end -}} +{{- $adminAPIPrefix := "/mnt/cert/adminapi" -}} +{{- $_ := (set $t "caFilepath" (printf "%s/%s/ca.crt" $adminAPIPrefix $l.tls.cert)) -}} +{{- if (not $l.tls.requireClientAuth) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $t) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_ := (set $t "certFilepath" (printf "%s/%s/tls.crt" $adminAPIPrefix $l.tls.cert)) -}} +{{- $_ := (set $t "keyFilepath" (printf "%s/%s/tls.key" $adminAPIPrefix $l.tls.cert)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $t) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.AdminListeners.Listeners" -}} +{{- $l := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $admin := (list (get (fromJson (include "redpanda.createInternalListenerCfg" (dict "a" (list ($l.port | int)) ))) "r")) -}} +{{- range $k, $lis := $l.external -}} +{{- if (not (get (fromJson (include "redpanda.AdminExternal.IsEnabled" (dict "a" (list $lis) ))) "r")) -}} +{{- continue -}} +{{- end -}} +{{- $admin = (concat (default (list ) $admin) (list (dict "name" $k "port" ($lis.port | int) "address" "0.0.0.0" ))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $admin) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.AdminListeners.ListenersTLS" -}} +{{- $l := (index .a 0) -}} +{{- $tls := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $admin := (list ) -}} +{{- $internal := (get (fromJson (include "redpanda.createInternalListenerTLSCfg" (dict "a" (list $tls $l.tls) ))) "r") -}} +{{- if (gt ((get (fromJson (include "_shims.len" (dict "a" (list $internal) ))) "r") | int) (0 | int)) -}} +{{- $admin = (concat (default (list ) $admin) (list $internal)) -}} +{{- end -}} +{{- range $k, $lis := $l.external -}} +{{- if (or (not (get (fromJson (include "redpanda.AdminExternal.IsEnabled" (dict "a" (list $lis) ))) "r")) (not (get (fromJson (include "redpanda.ExternalTLS.IsEnabled" (dict "a" (list $lis.tls $l.tls $tls) ))) "r"))) -}} +{{- continue -}} +{{- end -}} +{{- $certName := (get (fromJson (include "redpanda.ExternalTLS.GetCertName" (dict "a" (list $lis.tls $l.tls) ))) "r") -}} +{{- $admin = (concat (default (list ) $admin) (list (dict "name" $k "enabled" true "cert_file" (printf "/etc/tls/certs/%s/tls.crt" $certName) "key_file" (printf "/etc/tls/certs/%s/tls.key" $certName) "require_client_auth" (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $lis.tls.requireClientAuth false) ))) "r") "truststore_file" (get (fromJson (include "redpanda.ExternalTLS.TrustStoreFilePath" (dict "a" (list $lis.tls $l.tls $tls) ))) "r") ))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $admin) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.AdminListeners.TrustStores" -}} +{{- $l := (index .a 0) -}} +{{- $tls := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $tss := (list ) -}} +{{- if (and (get (fromJson (include "redpanda.InternalTLS.IsEnabled" (dict "a" (list $l.tls $tls) ))) "r") (ne $l.tls.trustStore (coalesce nil))) -}} +{{- $tss = (concat (default (list ) $tss) (list $l.tls.trustStore)) -}} +{{- end -}} +{{- range $_, $key := (sortAlpha (keys $l.external)) -}} +{{- $lis := (index $l.external $key) -}} +{{- if (or (or (not (get (fromJson (include "redpanda.AdminExternal.IsEnabled" (dict "a" (list $lis) ))) "r")) (not (get (fromJson (include "redpanda.ExternalTLS.IsEnabled" (dict "a" (list $lis.tls $l.tls $tls) ))) "r"))) (eq $lis.tls.trustStore (coalesce nil))) -}} +{{- continue -}} +{{- end -}} +{{- $tss = (concat (default (list ) $tss) (list $lis.tls.trustStore)) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $tss) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.AdminExternal.IsEnabled" -}} +{{- $l := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $_is_returning = true -}} +{{- (dict "r" (and (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $l.enabled true) ))) "r") (gt ($l.port | int) (0 | int)))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.HTTPListeners.Listeners" -}} +{{- $l := (index .a 0) -}} +{{- $saslEnabled := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $internal := (get (fromJson (include "redpanda.createInternalListenerCfg" (dict "a" (list ($l.port | int)) ))) "r") -}} +{{- if $saslEnabled -}} +{{- $_ := (set $internal "authentication_method" "http_basic") -}} +{{- end -}} +{{- $am_9 := (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $l.authenticationMethod "") ))) "r") -}} +{{- if (ne $am_9 "") -}} +{{- $_ := (set $internal "authentication_method" $am_9) -}} +{{- end -}} +{{- $result := (list $internal) -}} +{{- range $k, $l := $l.external -}} +{{- if (not (get (fromJson (include "redpanda.HTTPExternal.IsEnabled" (dict "a" (list $l) ))) "r")) -}} +{{- continue -}} +{{- end -}} +{{- $listener := (dict "name" $k "port" ($l.port | int) "address" "0.0.0.0" ) -}} +{{- if $saslEnabled -}} +{{- $_ := (set $listener "authentication_method" "http_basic") -}} +{{- end -}} +{{- $am_10 := (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $l.authenticationMethod "") ))) "r") -}} +{{- if (ne $am_10 "") -}} +{{- $_ := (set $listener "authentication_method" $am_10) -}} +{{- end -}} +{{- $result = (concat (default (list ) $result) (list $listener)) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $result) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.HTTPListeners.ListenersTLS" -}} +{{- $l := (index .a 0) -}} +{{- $tls := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $pp := (list ) -}} +{{- $internal := (get (fromJson (include "redpanda.createInternalListenerTLSCfg" (dict "a" (list $tls $l.tls) ))) "r") -}} +{{- if (gt ((get (fromJson (include "_shims.len" (dict "a" (list $internal) ))) "r") | int) (0 | int)) -}} +{{- $pp = (concat (default (list ) $pp) (list $internal)) -}} +{{- end -}} +{{- range $k, $lis := $l.external -}} +{{- if (or (not (get (fromJson (include "redpanda.HTTPExternal.IsEnabled" (dict "a" (list $lis) ))) "r")) (not (get (fromJson (include "redpanda.ExternalTLS.IsEnabled" (dict "a" (list $lis.tls $l.tls $tls) ))) "r"))) -}} +{{- continue -}} +{{- end -}} +{{- $certName := (get (fromJson (include "redpanda.ExternalTLS.GetCertName" (dict "a" (list $lis.tls $l.tls) ))) "r") -}} +{{- $pp = (concat (default (list ) $pp) (list (dict "name" $k "enabled" true "cert_file" (printf "/etc/tls/certs/%s/tls.crt" $certName) "key_file" (printf "/etc/tls/certs/%s/tls.key" $certName) "require_client_auth" (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $lis.tls.requireClientAuth false) ))) "r") "truststore_file" (get (fromJson (include "redpanda.ExternalTLS.TrustStoreFilePath" (dict "a" (list $lis.tls $l.tls $tls) ))) "r") ))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $pp) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.HTTPListeners.TrustStores" -}} +{{- $l := (index .a 0) -}} +{{- $tls := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $tss := (coalesce nil) -}} +{{- if (and (get (fromJson (include "redpanda.InternalTLS.IsEnabled" (dict "a" (list $l.tls $tls) ))) "r") (ne $l.tls.trustStore (coalesce nil))) -}} +{{- $tss = (concat (default (list ) $tss) (list $l.tls.trustStore)) -}} +{{- end -}} +{{- range $_, $key := (sortAlpha (keys $l.external)) -}} +{{- $lis := (index $l.external $key) -}} +{{- if (or (or (not (get (fromJson (include "redpanda.HTTPExternal.IsEnabled" (dict "a" (list $lis) ))) "r")) (not (get (fromJson (include "redpanda.ExternalTLS.IsEnabled" (dict "a" (list $lis.tls $l.tls $tls) ))) "r"))) (eq $lis.tls.trustStore (coalesce nil))) -}} +{{- continue -}} +{{- end -}} +{{- $tss = (concat (default (list ) $tss) (list $lis.tls.trustStore)) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $tss) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.HTTPExternal.IsEnabled" -}} +{{- $l := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $_is_returning = true -}} +{{- (dict "r" (and (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $l.enabled true) ))) "r") (gt ($l.port | int) (0 | int)))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.KafkaListeners.Listeners" -}} +{{- $l := (index .a 0) -}} +{{- $auth := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $internal := (get (fromJson (include "redpanda.createInternalListenerCfg" (dict "a" (list ($l.port | int)) ))) "r") -}} +{{- if (get (fromJson (include "redpanda.Auth.IsSASLEnabled" (dict "a" (list $auth) ))) "r") -}} +{{- $_ := (set $internal "authentication_method" "sasl") -}} +{{- end -}} +{{- $am_11 := (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $l.authenticationMethod "") ))) "r") -}} +{{- if (ne $am_11 "") -}} +{{- $_ := (set $internal "authentication_method" $am_11) -}} +{{- end -}} +{{- $kafka := (list $internal) -}} +{{- range $k, $l := $l.external -}} +{{- if (not (get (fromJson (include "redpanda.KafkaExternal.IsEnabled" (dict "a" (list $l) ))) "r")) -}} +{{- continue -}} +{{- end -}} +{{- $listener := (dict "name" $k "port" ($l.port | int) "address" "0.0.0.0" ) -}} +{{- if (get (fromJson (include "redpanda.Auth.IsSASLEnabled" (dict "a" (list $auth) ))) "r") -}} +{{- $_ := (set $listener "authentication_method" "sasl") -}} +{{- end -}} +{{- $am_12 := (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $l.authenticationMethod "") ))) "r") -}} +{{- if (ne $am_12 "") -}} +{{- $_ := (set $listener "authentication_method" $am_12) -}} +{{- end -}} +{{- $kafka = (concat (default (list ) $kafka) (list $listener)) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $kafka) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.KafkaListeners.ListenersTLS" -}} +{{- $l := (index .a 0) -}} +{{- $tls := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $kafka := (list ) -}} +{{- $internal := (get (fromJson (include "redpanda.createInternalListenerTLSCfg" (dict "a" (list $tls $l.tls) ))) "r") -}} +{{- if (gt ((get (fromJson (include "_shims.len" (dict "a" (list $internal) ))) "r") | int) (0 | int)) -}} +{{- $kafka = (concat (default (list ) $kafka) (list $internal)) -}} +{{- end -}} +{{- range $k, $lis := $l.external -}} +{{- if (or (not (get (fromJson (include "redpanda.KafkaExternal.IsEnabled" (dict "a" (list $lis) ))) "r")) (not (get (fromJson (include "redpanda.ExternalTLS.IsEnabled" (dict "a" (list $lis.tls $l.tls $tls) ))) "r"))) -}} +{{- continue -}} +{{- end -}} +{{- $certName := (get (fromJson (include "redpanda.ExternalTLS.GetCertName" (dict "a" (list $lis.tls $l.tls) ))) "r") -}} +{{- $kafka = (concat (default (list ) $kafka) (list (dict "name" $k "enabled" true "cert_file" (printf "/etc/tls/certs/%s/tls.crt" $certName) "key_file" (printf "/etc/tls/certs/%s/tls.key" $certName) "require_client_auth" (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $lis.tls.requireClientAuth false) ))) "r") "truststore_file" (get (fromJson (include "redpanda.ExternalTLS.TrustStoreFilePath" (dict "a" (list $lis.tls $l.tls $tls) ))) "r") ))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $kafka) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.KafkaListeners.TrustStores" -}} +{{- $l := (index .a 0) -}} +{{- $tls := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $tss := (coalesce nil) -}} +{{- if (and (get (fromJson (include "redpanda.InternalTLS.IsEnabled" (dict "a" (list $l.tls $tls) ))) "r") (ne $l.tls.trustStore (coalesce nil))) -}} +{{- $tss = (concat (default (list ) $tss) (list $l.tls.trustStore)) -}} +{{- end -}} +{{- range $_, $key := (sortAlpha (keys $l.external)) -}} +{{- $lis := (index $l.external $key) -}} +{{- if (or (or (not (get (fromJson (include "redpanda.KafkaExternal.IsEnabled" (dict "a" (list $lis) ))) "r")) (not (get (fromJson (include "redpanda.ExternalTLS.IsEnabled" (dict "a" (list $lis.tls $l.tls $tls) ))) "r"))) (eq $lis.tls.trustStore (coalesce nil))) -}} +{{- continue -}} +{{- end -}} +{{- $tss = (concat (default (list ) $tss) (list $lis.tls.trustStore)) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $tss) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.KafkaListeners.ConsolemTLS" -}} +{{- $k := (index .a 0) -}} +{{- $tls := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $t := (mustMergeOverwrite (dict "enabled" false "caFilepath" "" "certFilepath" "" "keyFilepath" "" "insecureSkipTlsVerify" false ) (dict "enabled" (get (fromJson (include "redpanda.InternalTLS.IsEnabled" (dict "a" (list $k.tls $tls) ))) "r") )) -}} +{{- if (not $t.enabled) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $t) | toJson -}} +{{- break -}} +{{- end -}} +{{- $kafkaPathPrefix := "/mnt/cert/kafka" -}} +{{- $_ := (set $t "caFilepath" (printf "%s/%s/ca.crt" $kafkaPathPrefix $k.tls.cert)) -}} +{{- if (not $k.tls.requireClientAuth) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $t) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_ := (set $t "certFilepath" (printf "%s/%s/tls.crt" $kafkaPathPrefix $k.tls.cert)) -}} +{{- $_ := (set $t "keyFilepath" (printf "%s/%s/tls.key" $kafkaPathPrefix $k.tls.cert)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $t) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.KafkaExternal.IsEnabled" -}} +{{- $l := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $_is_returning = true -}} +{{- (dict "r" (and (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $l.enabled true) ))) "r") (gt ($l.port | int) (0 | int)))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.SchemaRegistryListeners.Listeners" -}} +{{- $sr := (index .a 0) -}} +{{- $saslEnabled := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $internal := (get (fromJson (include "redpanda.createInternalListenerCfg" (dict "a" (list ($sr.port | int)) ))) "r") -}} +{{- if $saslEnabled -}} +{{- $_ := (set $internal "authentication_method" "http_basic") -}} +{{- end -}} +{{- $am_13 := (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $sr.authenticationMethod "") ))) "r") -}} +{{- if (ne $am_13 "") -}} +{{- $_ := (set $internal "authentication_method" $am_13) -}} +{{- end -}} +{{- $result := (list $internal) -}} +{{- range $k, $l := $sr.external -}} +{{- if (not (get (fromJson (include "redpanda.SchemaRegistryExternal.IsEnabled" (dict "a" (list $l) ))) "r")) -}} +{{- continue -}} +{{- end -}} +{{- $listener := (dict "name" $k "port" ($l.port | int) "address" "0.0.0.0" ) -}} +{{- if $saslEnabled -}} +{{- $_ := (set $listener "authentication_method" "http_basic") -}} +{{- end -}} +{{- $am_14 := (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $l.authenticationMethod "") ))) "r") -}} +{{- if (ne $am_14 "") -}} +{{- $_ := (set $listener "authentication_method" $am_14) -}} +{{- end -}} +{{- $result = (concat (default (list ) $result) (list $listener)) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $result) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.SchemaRegistryListeners.ListenersTLS" -}} +{{- $l := (index .a 0) -}} +{{- $tls := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $listeners := (list ) -}} +{{- $internal := (get (fromJson (include "redpanda.createInternalListenerTLSCfg" (dict "a" (list $tls $l.tls) ))) "r") -}} +{{- if (gt ((get (fromJson (include "_shims.len" (dict "a" (list $internal) ))) "r") | int) (0 | int)) -}} +{{- $listeners = (concat (default (list ) $listeners) (list $internal)) -}} +{{- end -}} +{{- range $k, $lis := $l.external -}} +{{- if (or (not (get (fromJson (include "redpanda.SchemaRegistryExternal.IsEnabled" (dict "a" (list $lis) ))) "r")) (not (get (fromJson (include "redpanda.ExternalTLS.IsEnabled" (dict "a" (list $lis.tls $l.tls $tls) ))) "r"))) -}} +{{- continue -}} +{{- end -}} +{{- $certName := (get (fromJson (include "redpanda.ExternalTLS.GetCertName" (dict "a" (list $lis.tls $l.tls) ))) "r") -}} +{{- $listeners = (concat (default (list ) $listeners) (list (dict "name" $k "enabled" true "cert_file" (printf "/etc/tls/certs/%s/tls.crt" $certName) "key_file" (printf "/etc/tls/certs/%s/tls.key" $certName) "require_client_auth" (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $lis.tls.requireClientAuth false) ))) "r") "truststore_file" (get (fromJson (include "redpanda.ExternalTLS.TrustStoreFilePath" (dict "a" (list $lis.tls $l.tls $tls) ))) "r") ))) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $listeners) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.SchemaRegistryListeners.TrustStores" -}} +{{- $l := (index .a 0) -}} +{{- $tls := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $tss := (coalesce nil) -}} +{{- if (and (get (fromJson (include "redpanda.InternalTLS.IsEnabled" (dict "a" (list $l.tls $tls) ))) "r") (ne $l.tls.trustStore (coalesce nil))) -}} +{{- $tss = (concat (default (list ) $tss) (list $l.tls.trustStore)) -}} +{{- end -}} +{{- range $_, $key := (sortAlpha (keys $l.external)) -}} +{{- $lis := (index $l.external $key) -}} +{{- if (or (or (not (get (fromJson (include "redpanda.SchemaRegistryExternal.IsEnabled" (dict "a" (list $lis) ))) "r")) (not (get (fromJson (include "redpanda.ExternalTLS.IsEnabled" (dict "a" (list $lis.tls $l.tls $tls) ))) "r"))) (eq $lis.tls.trustStore (coalesce nil))) -}} +{{- continue -}} +{{- end -}} +{{- $tss = (concat (default (list ) $tss) (list $lis.tls.trustStore)) -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $tss) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.SchemaRegistryListeners.ConsoleTLS" -}} +{{- $sr := (index .a 0) -}} +{{- $tls := (index .a 1) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $t := (mustMergeOverwrite (dict "enabled" false "caFilepath" "" "certFilepath" "" "keyFilepath" "" "insecureSkipTlsVerify" false ) (dict "enabled" (get (fromJson (include "redpanda.InternalTLS.IsEnabled" (dict "a" (list $sr.tls $tls) ))) "r") )) -}} +{{- if (not $t.enabled) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $t) | toJson -}} +{{- break -}} +{{- end -}} +{{- $schemaRegistryPrefix := "/mnt/cert/schemaregistry" -}} +{{- $_ := (set $t "caFilepath" (printf "%s/%s/ca.crt" $schemaRegistryPrefix $sr.tls.cert)) -}} +{{- if (not $sr.tls.requireClientAuth) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $t) | toJson -}} +{{- break -}} +{{- end -}} +{{- $_ := (set $t "certFilepath" (printf "%s/%s/tls.crt" $schemaRegistryPrefix $sr.tls.cert)) -}} +{{- $_ := (set $t "keyFilepath" (printf "%s/%s/tls.key" $schemaRegistryPrefix $sr.tls.cert)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $t) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.SchemaRegistryExternal.IsEnabled" -}} +{{- $l := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $_is_returning = true -}} +{{- (dict "r" (and (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $l.enabled true) ))) "r") (gt ($l.port | int) (0 | int)))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.TunableConfig.Translate" -}} +{{- $c := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- if (eq $c (coalesce nil)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $result := (dict ) -}} +{{- range $k, $v := $c -}} +{{- if (not (empty $v)) -}} +{{- $_ := (set $result $k $v) -}} +{{- end -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $result) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.NodeConfig.Translate" -}} +{{- $c := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $result := (dict ) -}} +{{- range $k, $v := $c -}} +{{- if (not (empty $v)) -}} +{{- $tmp_tuple_14 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.asnumeric" (dict "a" (list $v) ))) "r")) ))) "r") -}} +{{- $ok_15 := $tmp_tuple_14.T2 -}} +{{- if $ok_15 -}} +{{- $_ := (set $result $k $v) -}} +{{- else -}}{{- if (kindIs "bool" $v) -}} +{{- $_ := (set $result $k $v) -}} +{{- else -}} +{{- $_ := (set $result $k (toYaml $v)) -}} +{{- end -}} +{{- end -}} +{{- end -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $result) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.ClusterConfig.Translate" -}} +{{- $c := (index .a 0) -}} +{{- $replicas := (index .a 1) -}} +{{- $skipDefaultTopic := (index .a 2) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $result := (dict ) -}} +{{- range $k, $v := $c -}} +{{- if (and (eq $k "default_topic_replications") (not $skipDefaultTopic)) -}} +{{- $r := ($replicas | int) -}} +{{- $input := ($r | int) -}} +{{- $tmp_tuple_15 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.asintegral" (dict "a" (list $v) ))) "r")) ))) "r") -}} +{{- $ok_17 := $tmp_tuple_15.T2 -}} +{{- $num_16 := ($tmp_tuple_15.T1 | int) -}} +{{- if $ok_17 -}} +{{- $input = $num_16 -}} +{{- end -}} +{{- $tmp_tuple_16 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.asnumeric" (dict "a" (list $v) ))) "r")) ))) "r") -}} +{{- $ok_19 := $tmp_tuple_16.T2 -}} +{{- $f_18 := ($tmp_tuple_16.T1 | float64) -}} +{{- if $ok_19 -}} +{{- $input = ($f_18 | int) -}} +{{- end -}} +{{- $_ := (set $result $k (min ($input | int64) (((sub ((add $r (((mod $r (2 | int)) | int))) | int) (1 | int)) | int) | int64))) -}} +{{- continue -}} +{{- end -}} +{{- $tmp_tuple_17 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.typetest" (dict "a" (list "bool" $v false) ))) "r")) ))) "r") -}} +{{- $ok_21 := $tmp_tuple_17.T2 -}} +{{- $b_20 := $tmp_tuple_17.T1 -}} +{{- if $ok_21 -}} +{{- $_ := (set $result $k $b_20) -}} +{{- continue -}} +{{- end -}} +{{- if (not (empty $v)) -}} +{{- $_ := (set $result $k $v) -}} +{{- end -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $_is_returning = true -}} +{{- (dict "r" $result) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.SecretRef.IsValid" -}} +{{- $sr := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $_is_returning = true -}} +{{- (dict "r" (and (and (ne $sr (coalesce nil)) (not (empty $sr.key))) (not (empty $sr.name)))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.TieredStorageCredentials.IsAccessKeyReferenceValid" -}} +{{- $tsc := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $_is_returning = true -}} +{{- (dict "r" (and (and (ne $tsc.accessKey (coalesce nil)) (ne $tsc.accessKey.name "")) (ne $tsc.accessKey.key ""))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.TieredStorageCredentials.IsSecretKeyReferenceValid" -}} +{{- $tsc := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $_is_returning = true -}} +{{- (dict "r" (and (and (ne $tsc.secretKey (coalesce nil)) (ne $tsc.secretKey.name "")) (ne $tsc.secretKey.key ""))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + diff --git a/charts/redpanda/redpanda/5.9.2/templates/cert-issuers.yaml b/charts/redpanda/redpanda/5.9.2/templates/cert-issuers.yaml new file mode 100644 index 0000000000..f5c9667526 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/cert-issuers.yaml @@ -0,0 +1,18 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You 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. +*/}} +{{- include "_shims.render-manifest" (list "redpanda.CertIssuers" .) -}} +{{- include "_shims.render-manifest" (list "redpanda.RootCAs" .) -}} diff --git a/charts/redpanda/redpanda/5.9.2/templates/certs.yaml b/charts/redpanda/redpanda/5.9.2/templates/certs.yaml new file mode 100644 index 0000000000..08437f58ec --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/certs.yaml @@ -0,0 +1,17 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You 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. +*/}} +{{- include "_shims.render-manifest" (list "redpanda.ClientCerts" .) -}} diff --git a/charts/redpanda/redpanda/5.9.2/templates/configmap.yaml b/charts/redpanda/redpanda/5.9.2/templates/configmap.yaml new file mode 100644 index 0000000000..8c33ab3378 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/configmap.yaml @@ -0,0 +1,17 @@ +{{- /* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You 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. +*/}} +{{- include "_shims.render-manifest" (list "redpanda.ConfigMaps" .) -}} diff --git a/charts/redpanda/redpanda/5.9.2/templates/connectors/connectors.yaml b/charts/redpanda/redpanda/5.9.2/templates/connectors/connectors.yaml new file mode 100644 index 0000000000..c7dfe6b893 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/connectors/connectors.yaml @@ -0,0 +1,108 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/}} +{{ if and .Values.connectors.enabled (not .Values.connectors.deployment.create) }} + +{{ $values := .Values }} + +{{/* brokers */}} +{{ $kafkaBrokers := list }} +{{ range (include "seed-server-list" . | mustFromJson) }} + {{ $kafkaBrokers = append $kafkaBrokers (printf "%s:%d" . (int $values.listeners.kafka.port)) }} +{{ end }} + +{{ $connectorsValues := dict + "Values" (dict + "connectors" (dict + "bootstrapServers" (join "," $kafkaBrokers) + "brokerTLS" (dict + "enabled" (include "kafka-internal-tls-enabled" . | fromJson).bool + "ca" (dict + "secretRef" (ternary (printf "%s-default-cert" (include "redpanda.fullname" .)) "" (include "kafka-internal-tls-enabled" . | fromJson).bool) + ) + ) + ) + ) +}} + +{{ $extraVolumes := list }} +{{ $extraVolumeMounts := list }} +{{ $extraEnv := .Values.connectors.deployment.extraEnv }} +{{ $command := list }} +{{ if (include "sasl-enabled" . | fromJson).bool }} + {{ $command = concat $command (list "bash" "-c") }} + {{ $consoleSASLConfig := (printf "set -e; IFS=':' read -r CONNECT_SASL_USERNAME CONNECT_SASL_PASSWORD CONNECT_SASL_MECHANISM < <(grep \"\" $(find /mnt/users/* -print)); CONNECT_SASL_MECHANISM=${CONNECT_SASL_MECHANISM:-%s}; export CONNECT_SASL_USERNAME CONNECT_SASL_PASSWORD CONNECT_SASL_MECHANISM;" ( include "sasl-mechanism" . | lower )) }} + {{ $consoleSASLConfig = cat $consoleSASLConfig " [[ $CONNECT_SASL_MECHANISM == \"SCRAM-SHA-256\" ]] && CONNECT_SASL_MECHANISM=scram-sha-256;" }} + {{ $consoleSASLConfig = cat $consoleSASLConfig " [[ $CONNECT_SASL_MECHANISM == \"SCRAM-SHA-512\" ]] && CONNECT_SASL_MECHANISM=scram-sha-512;" }} + {{ $consoleSASLConfig = cat $consoleSASLConfig " export CONNECT_SASL_MECHANISM;" }} + {{ $consoleSASLConfig = cat $consoleSASLConfig " echo $CONNECT_SASL_PASSWORD > /opt/kafka/connect-password/rc-credentials/password;" }} + {{ $consoleSASLConfig = cat $consoleSASLConfig " exec /opt/kafka/bin/kafka_connect_run.sh" }} + {{ $command = append $command $consoleSASLConfig }} + + {{ $extraVolumes = concat $extraVolumes .Values.connectors.storage.volume }} + + {{ $extraVolumes = append $extraVolumes (dict + "name" (printf "%s-users" (include "redpanda.fullname" .)) + "secret" (dict + "secretName" .Values.auth.sasl.secretRef + ) + )}} + + {{ $extraVolumeMounts = concat $extraVolumeMounts .Values.connectors.storage.volumeMounts }} + + {{ $extraVolumeMounts = append $extraVolumeMounts (dict + "name" (printf "%s-users" (include "redpanda.fullname" .)) + "mountPath" "/mnt/users" + "readOnly" true + )}} + {{ $extraVolumes = append $extraVolumes (dict + "name" (printf "%s-user-password" ((include "redpanda.fullname" .)) | trunc 49) + "emptyDir" (dict) + )}} + {{ $extraVolumeMounts = append $extraVolumeMounts (dict + "name" (printf "%s-user-password" ((include "redpanda.fullname" .)) | trunc 49) + "mountPath" "/opt/kafka/connect-password/rc-credentials" + )}} + {{ $extraEnv = append $extraEnv (dict + "name" "CONNECT_SASL_PASSWORD_FILE" + "value" "rc-credentials/password" + )}} + {{ $connectorsValues := merge $connectorsValues (dict + "Values" (dict + "storage" (dict + "volumeMounts" $extraVolumeMounts + "volume" $extraVolumes + ) + "auth" (dict + "sasl" (dict + "enabled" .Values.auth.sasl.enabled + ) + ) + "deployment" (dict + "command" $command + "extraEnv" $extraEnv + ) + ) + )}} +{{ end }} + +{{ $connectorsValues := merge $connectorsValues (dict "Values" (dict "deployment" (dict "create" (not .Values.connectors.deployment.create)))) }} +{{ $connectorsValues := merge $connectorsValues (dict "Values" (dict "test" (dict "create" (not .Values.connectors.test.create)))) }} +{{ $helmVars := merge $connectorsValues .Subcharts.connectors }} +{{ include (print .Subcharts.connectors.Template.BasePath "/deployment.yaml") $helmVars }} +--- +{{ include (print .Subcharts.connectors.Template.BasePath "/tests/01-mm2-values.yaml") $helmVars }} +{{ end }} diff --git a/charts/redpanda/redpanda/5.9.2/templates/console/configmap-and-deployment.yaml b/charts/redpanda/redpanda/5.9.2/templates/console/configmap-and-deployment.yaml new file mode 100644 index 0000000000..358c17ddc8 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/console/configmap-and-deployment.yaml @@ -0,0 +1,231 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You 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. +*/}} + +{{/* Secret */}} +{{ $secretConfig := dict ( dict + "create" $.Values.console.secret.create + ) +}} +{{/* if the console chart has the creation of the secret disabled, create it here instead if needed */}} +{{ if and .Values.console.enabled (not .Values.console.secret.create) }} +{{ $licenseKey := ( include "enterprise-license" . ) }} +# before license changes, this was not printing a secret, so we gather in which case to print +# for now only if we have a license do we print, however, this may be an issue for some +# since if we do include a license we MUST also print all secret items. + {{ if ( not (empty $licenseKey ) ) }} +{{ $secretConfig = ( dict + "create" true + "enterprise" ( dict "license" $licenseKey) + ) +}} + +{{ $config := dict + "Values" (dict + "secret" $secretConfig + )}} + +{{ $secretValues := merge $config .Subcharts.console }} +{{ $wrappedSecretValues := (dict "Chart" .Subcharts.console.Chart "Release" .Release "Values" (dict "AsMap" $secretValues.Values)) }} +--- +{{- include "_shims.render-manifest" (list "console.Secret" $wrappedSecretValues) -}} + {{ end }} +{{ end }} + +{{ $configmap := dict }} +{{/* if the console chart has the creation of the configmap disabled, create it here instead */}} +{{ if and .Values.console.enabled (not .Values.console.configmap.create) }} +{{ $consoleConfigmap := dict "create" true }} + +{{ $consoleConfig := merge .Values.console.config (get ((include "redpanda.ConsoleConfig" (dict "a" (list .))) | fromJson) "r") }} + +{{ $config := dict + "Values" (dict + "console" (dict "config" $consoleConfig) + "configmap" $consoleConfigmap + "secret" $secretConfig + ) +}} + +{{ $configMapValues := merge $config .Subcharts.console }} +--- +{{ $wrappedSecretValues := (dict "Chart" .Subcharts.console.Chart "Release" .Release "Values" (dict "AsMap" $configMapValues.Values)) }} +{{- include "_shims.render-manifest" (list "console.ConfigMap" $wrappedSecretValues) -}} +{{ $configmap = include "_shims.render-manifest" (list "console.ConfigMap" $wrappedSecretValues) }} +{{ end }} + +{{/* Deployment */}} +{{ if and .Values.console.enabled (not .Values.console.deployment.create) }} + +{{ $extraVolumes := list }} +{{ $extraVolumeMounts := list }} +{{ $command := list }} +{{ if (include "sasl-enabled" . | fromJson).bool }} + {{ $command = concat $command (list "sh" "-c") }} + {{ $consoleSASLConfig := (printf "set -e; IFS=':' read -r KAFKA_SASL_USERNAME KAFKA_SASL_PASSWORD KAFKA_SASL_MECHANISM < <(grep \"\" $(find /mnt/users/* -print)); KAFKA_SASL_MECHANISM=${KAFKA_SASL_MECHANISM:-%s}; export KAFKA_SASL_USERNAME KAFKA_SASL_PASSWORD KAFKA_SASL_MECHANISM;" ( include "sasl-mechanism" . )) }} + {{ $consoleSASLConfig = cat $consoleSASLConfig " export KAFKA_SCHEMAREGISTRY_USERNAME=$KAFKA_SASL_USERNAME;" }} + {{ $consoleSASLConfig = cat $consoleSASLConfig " export KAFKA_SCHEMAREGISTRY_PASSWORD=$KAFKA_SASL_PASSWORD;" }} + {{ $consoleSASLConfig = cat $consoleSASLConfig " /app/console $@" }} + {{ $command = append $command $consoleSASLConfig }} + {{ $command = append $command "--" }} + {{ $extraVolumes = append $extraVolumes (dict + "name" (printf "%s-users" (include "redpanda.fullname" .)) + "secret" (dict + "secretName" .Values.auth.sasl.secretRef + ) + )}} + {{ $extraVolumeMounts = append $extraVolumeMounts (dict + "name" (printf "%s-users" (include "redpanda.fullname" .)) + "mountPath" "/mnt/users" + "readOnly" true + ) }} +{{ end }} + +{{ $kafkaTLS := list }} +{{ if (include "kafka-internal-tls-enabled" . | fromJson).bool }} + {{ $service := .Values.listeners.kafka }} + {{ $cert := get .Values.tls.certs $service.tls.cert }} + {{- $secretName := (printf "%s-%s-cert" (include "redpanda.fullname" .) $service.tls.cert) }} + {{- if $cert.secretRef }} + {{- $secretName = $cert.secretRef.name }} + {{- end }} + {{ if $cert.caEnabled }} + {{ $kafkaTLS = append $kafkaTLS (dict + "name" "KAFKA_TLS_CAFILEPATH" + "value" (printf "/mnt/cert/kafka/%s/ca.crt" $service.tls.cert) + )}} + {{ $extraVolumes = append $extraVolumes (dict + "name" (printf "kafka-%s-cert" $service.tls.cert) + "secret" (dict + "defaultMode" 0420 + "secretName" ( $secretName ) + ))}} + {{ $extraVolumeMounts = append $extraVolumeMounts (dict + "name" (printf "kafka-%s-cert" $service.tls.cert) + "mountPath" (printf "/mnt/cert/kafka/%s" $service.tls.cert) + "readOnly" true + )}} + {{ end }} +{{ end }} + +{{ $schemaRegistryTLS := list }} +{{ if (include "schemaRegistry-internal-tls-enabled" . | fromJson).bool }} + {{ $service := .Values.listeners.schemaRegistry }} + {{ $cert := get .Values.tls.certs $service.tls.cert }} + {{- $secretName := (printf "%s-%s-cert" (include "redpanda.fullname" .) $service.tls.cert) }} + {{- if $cert.secretRef }} + {{- $secretName = $cert.secretRef.name }} + {{- end }} + {{ if $cert.caEnabled }} + {{ $schemaRegistryTLS = append $schemaRegistryTLS (dict + "name" "KAFKA_SCHEMAREGISTRY_TLS_CAFILEPATH" + "value" (printf "/mnt/cert/schemaregistry/%s/ca.crt" $service.tls.cert) + )}} + {{ $extraVolumes = append $extraVolumes (dict + "name" (printf "schemaregistry-%s-cert" $service.tls.cert) + "secret" (dict + "defaultMode" 0420 + "secretName" ( $secretName ) + ))}} + {{ $extraVolumeMounts = append $extraVolumeMounts (dict + "name" (printf "schemaregistry-%s-cert" $service.tls.cert) + "mountPath" (printf "/mnt/cert/schemaregistry/%s" $service.tls.cert) + "readOnly" true + )}} + {{ end }} +{{ end }} + +{{ $adminAPI := list }} +{{ if (include "admin-internal-tls-enabled" . | fromJson).bool }} + {{ $service := .Values.listeners.admin }} + {{ $cert := get .Values.tls.certs $service.tls.cert }} + {{- $secretName := (printf "%s-%s-cert" (include "redpanda.fullname" .) $service.tls.cert) }} + {{- if $cert.secretRef }} + {{- $secretName = $cert.secretRef.name }} + {{- end }} + {{ if $cert.caEnabled }} + {{ $extraVolumes = append $extraVolumes (dict + "name" (printf "adminapi-%s-cert" $service.tls.cert) + "secret" (dict + "defaultMode" 0420 + "secretName" ( $secretName ) + ))}} + {{ $extraVolumeMounts = append $extraVolumeMounts (dict + "name" (printf "adminapi-%s-cert" $service.tls.cert) + "mountPath" (printf "/mnt/cert/adminapi/%s" $service.tls.cert) + "readOnly" true + )}} + {{ end }} +{{ end }} + +{{ $enterprise := dict }} +{{ if ( include "enterprise-secret" .) }} + {{ $enterprise = dict + "licenseSecretRef" ( dict + "name" ( include "enterprise-secret-name" . ) + "key" ( include "enterprise-secret-key" . ) + ) + }} +{{ end }} + +{{ $extraEnv := concat $kafkaTLS $schemaRegistryTLS $adminAPI .Values.console.extraEnv }} +{{ $extraVolumes = concat $extraVolumes .Values.console.extraVolumes }} +{{ $extraVolumeMounts = concat $extraVolumeMounts .Values.console.extraVolumeMounts }} +{{ $consoleValues := dict + "Values" (dict + "extraVolumes" $extraVolumes + "extraVolumeMounts" $extraVolumeMounts + "extraEnv" $extraEnv + "secret" $secretConfig + "enterprise" $enterprise + "image" $.Values.console.image + "autoscaling" .Values.console.autoscaling + "replicaCount" .Values.console.replicaCount + "strategy" .Values.console.strategy + "podAnnotations" .Values.console.podAnnotations + "podLabels" .Values.console.podLabels + "imagePullSecrets" .Values.console.imagePullSecrets + "podSecurityContext" .Values.console.podSecurityContext + "secretMounts" .Values.console.secretMounts + "initContainers" .Values.console.initContainers + "extraArgs" .Values.console.extraArgs + "securityContext" .Values.console.securityContext + "livenessProbe" .Values.console.livenessProbe + "readinessProbe" .Values.console.readinessProbe + "resources" .Values.console.resources + "extraContainers" .Values.console.extraContainers + "nodeSelector" .Values.console.nodeSelector + "affinity" .Values.console.affinity + "topologySpreadConstraints" .Values.console.topologySpreadConstraints + "priorityClassName" .Values.console.priorityClassName + "tolerations" .Values.console.tolerations +)}} + +{{ if not (empty $command) }} + {{ $consoleValues := merge $consoleValues (dict "Values" (dict "deployment" (dict "command" $command))) }} +{{ end }} +{{ $consoleValues := merge $consoleValues (dict "Values" (dict "deployment" (dict "create" (not .Values.console.deployment.create)))) }} + +{{ if and .Values.console.enabled (not .Values.console.configmap.create) }} +{{ $consoleValues := merge $consoleValues (dict "Values" (dict "podAnnotations" (dict "checksum-redpanda-chart/config" ( $configmap | toYaml | sha256sum )))) }} +{{ end }} + +{{ $deploymentValues := merge $consoleValues .Subcharts.console }} +{{ $wrappedDeploymentValues := (dict "Chart" .Subcharts.console.Chart "Release" .Release "Values" (dict "AsMap" $deploymentValues.Values)) }} + +--- +{{- include "_shims.render-manifest" (list "console.Deployment" $wrappedDeploymentValues) -}} +{{ end }} diff --git a/charts/redpanda/redpanda/5.9.2/templates/poddisruptionbudget.yaml b/charts/redpanda/redpanda/5.9.2/templates/poddisruptionbudget.yaml new file mode 100644 index 0000000000..28688dd27d --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/poddisruptionbudget.yaml @@ -0,0 +1,17 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You 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. +*/}} +{{- include "_shims.render-manifest" (list "redpanda.PodDisruptionBudget" .) -}} diff --git a/charts/redpanda/redpanda/5.9.2/templates/post-install-upgrade-job.yaml b/charts/redpanda/redpanda/5.9.2/templates/post-install-upgrade-job.yaml new file mode 100644 index 0000000000..106872e05f --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/post-install-upgrade-job.yaml @@ -0,0 +1,17 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You 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. +*/}} +{{- include "_shims.render-manifest" (list "redpanda.PostInstallUpgradeJob" .) -}} diff --git a/charts/redpanda/redpanda/5.9.2/templates/post-upgrade.yaml b/charts/redpanda/redpanda/5.9.2/templates/post-upgrade.yaml new file mode 100644 index 0000000000..e4775a7d0c --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/post-upgrade.yaml @@ -0,0 +1,17 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You 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. +*/}} +{{- include "_shims.render-manifest" (list "redpanda.PostUpgrade" .) -}} diff --git a/charts/redpanda/redpanda/5.9.2/templates/post_upgrade_job.yaml b/charts/redpanda/redpanda/5.9.2/templates/post_upgrade_job.yaml new file mode 100644 index 0000000000..0de92dd696 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/post_upgrade_job.yaml @@ -0,0 +1,90 @@ +{{- /* Generated from "post_upgrade_job.go" */ -}} + +{{- define "redpanda.PostUpgrade" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (not $values.post_upgrade_job.enabled) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $labels := (default (dict ) $values.post_upgrade_job.labels) -}} +{{- $annotations := (default (dict ) $values.post_upgrade_job.annotations) -}} +{{- $annotations = (merge (dict ) (dict "helm.sh/hook" "post-upgrade" "helm.sh/hook-delete-policy" "before-hook-creation" "helm.sh/hook-weight" "-10" ) $annotations) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "spec" (dict "template" (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "spec" (dict "containers" (coalesce nil) ) ) ) "status" (dict ) ) (mustMergeOverwrite (dict ) (dict "apiVersion" "batch/v1" "kind" "Job" )) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "name" (printf "%s-post-upgrade" (get (fromJson (include "redpanda.Name" (dict "a" (list $dot) ))) "r")) "namespace" $dot.Release.Namespace "labels" (merge (dict ) (get (fromJson (include "redpanda.FullLabels" (dict "a" (list $dot) ))) "r") $labels) "annotations" $annotations )) "spec" (mustMergeOverwrite (dict "template" (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "spec" (dict "containers" (coalesce nil) ) ) ) (dict "backoffLimit" $values.post_upgrade_job.backoffLimit "template" (get (fromJson (include "redpanda.StrategicMergePatch" (dict "a" (list $values.post_upgrade_job.podTemplate (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "spec" (dict "containers" (coalesce nil) ) ) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "name" $dot.Release.Name "labels" (merge (dict ) (dict "app.kubernetes.io/name" (get (fromJson (include "redpanda.Name" (dict "a" (list $dot) ))) "r") "app.kubernetes.io/instance" $dot.Release.Name "app.kubernetes.io/component" (printf "%s-post-upgrade" (trunc (50 | int) (get (fromJson (include "redpanda.Name" (dict "a" (list $dot) ))) "r"))) ) $values.commonLabels) )) "spec" (mustMergeOverwrite (dict "containers" (coalesce nil) ) (dict "nodeSelector" $values.nodeSelector "affinity" (merge (dict ) $values.post_upgrade_job.affinity $values.affinity) "tolerations" $values.tolerations "restartPolicy" "Never" "securityContext" (get (fromJson (include "redpanda.PodSecurityContext" (dict "a" (list $dot) ))) "r") "serviceAccountName" (get (fromJson (include "redpanda.ServiceAccountName" (dict "a" (list $dot) ))) "r") "imagePullSecrets" (default (coalesce nil) $values.imagePullSecrets) "containers" (list (mustMergeOverwrite (dict "name" "" "resources" (dict ) ) (dict "name" "post-upgrade" "image" (printf "%s:%s" $values.image.repository (get (fromJson (include "redpanda.Tag" (dict "a" (list $dot) ))) "r")) "command" (list "/bin/bash" "-c") "args" (list (get (fromJson (include "redpanda.PostUpgradeJobScript" (dict "a" (list $dot) ))) "r")) "env" $values.post_upgrade_job.extraEnv "envFrom" $values.post_upgrade_job.extraEnvFrom "securityContext" (merge (dict ) (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $values.post_upgrade_job.securityContext (mustMergeOverwrite (dict ) (dict ))) ))) "r") (get (fromJson (include "redpanda.ContainerSecurityContext" (dict "a" (list $dot) ))) "r")) "resources" $values.post_upgrade_job.resources "volumeMounts" (get (fromJson (include "redpanda.DefaultMounts" (dict "a" (list $dot) ))) "r") ))) "volumes" (get (fromJson (include "redpanda.DefaultVolumes" (dict "a" (list $dot) ))) "r") )) ))) ))) "r") )) ))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.PostUpgradeJobScript" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $script := (list `set -e` ``) -}} +{{- range $key, $value := $values.config.cluster -}} +{{- $tmp_tuple_1 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.asintegral" (dict "a" (list $value) ))) "r")) ))) "r") -}} +{{- $isInt64 := $tmp_tuple_1.T2 -}} +{{- $asInt64 := ($tmp_tuple_1.T1 | int64) -}} +{{- if (and (eq $key "default_topic_replications") $isInt64) -}} +{{- $r := (($values.statefulset.replicas | int) | int64) -}} +{{- $r = ((sub (((add $r (((mod $r (2 | int64)) | int64))) | int64)) (1 | int64)) | int64) -}} +{{- $asInt64 = (min $asInt64 ($r | int64)) -}} +{{- end -}} +{{- $tmp_tuple_2 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.typetest" (dict "a" (list "bool" $value false) ))) "r")) ))) "r") -}} +{{- $ok_2 := $tmp_tuple_2.T2 -}} +{{- $asBool_1 := $tmp_tuple_2.T1 -}} +{{- $tmp_tuple_3 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.typetest" (dict "a" (list "string" $value "") ))) "r")) ))) "r") -}} +{{- $ok_4 := $tmp_tuple_3.T2 -}} +{{- $asStr_3 := $tmp_tuple_3.T1 -}} +{{- $tmp_tuple_4 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.typetest" (dict "a" (list (printf "[]%s" "interface {}") $value (coalesce nil)) ))) "r")) ))) "r") -}} +{{- $ok_6 := $tmp_tuple_4.T2 -}} +{{- $asSlice_5 := $tmp_tuple_4.T1 -}} +{{- if (and $ok_2 $asBool_1) -}} +{{- $script = (concat (default (list ) $script) (list (printf "rpk cluster config set %s %t" $key $asBool_1))) -}} +{{- else -}}{{- if (and $ok_4 (ne $asStr_3 "")) -}} +{{- $script = (concat (default (list ) $script) (list (printf "rpk cluster config set %s %s" $key $asStr_3))) -}} +{{- else -}}{{- if (and $isInt64 (gt $asInt64 (0 | int64))) -}} +{{- $script = (concat (default (list ) $script) (list (printf "rpk cluster config set %s %d" $key $asInt64))) -}} +{{- else -}}{{- if (and $ok_6 (gt ((get (fromJson (include "_shims.len" (dict "a" (list $asSlice_5) ))) "r") | int) (0 | int))) -}} +{{- $script = (concat (default (list ) $script) (list (printf `rpk cluster config set %s "[ %s ]"` $key (join "," $asSlice_5)))) -}} +{{- else -}}{{- if (not (empty $value)) -}} +{{- $script = (concat (default (list ) $script) (list (printf "rpk cluster config set %s %v" $key $value))) -}} +{{- end -}} +{{- end -}} +{{- end -}} +{{- end -}} +{{- end -}} +{{- end -}} +{{- if $_is_returning -}} +{{- break -}} +{{- end -}} +{{- $tmp_tuple_5 := (get (fromJson (include "_shims.compact" (dict "a" (list (get (fromJson (include "_shims.dicttest" (dict "a" (list $values.config.cluster "storage_min_free_bytes" (coalesce nil)) ))) "r")) ))) "r") -}} +{{- $ok_7 := $tmp_tuple_5.T2 -}} +{{- if (not $ok_7) -}} +{{- $script = (concat (default (list ) $script) (list (printf "rpk cluster config set storage_min_free_bytes %d" ((get (fromJson (include "redpanda.Storage.StorageMinFreeBytes" (dict "a" (list $values.storage) ))) "r") | int64)))) -}} +{{- end -}} +{{- if (get (fromJson (include "redpanda.RedpandaAtLeast_23_2_1" (dict "a" (list $dot) ))) "r") -}} +{{- $service := $values.listeners.admin -}} +{{- $caCert := "" -}} +{{- $scheme := "http" -}} +{{- if (get (fromJson (include "redpanda.InternalTLS.IsEnabled" (dict "a" (list $service.tls $values.tls) ))) "r") -}} +{{- $scheme = "https" -}} +{{- $cert := (get (fromJson (include "redpanda.TLSCertMap.MustGet" (dict "a" (list (deepCopy $values.tls.certs) $service.tls.cert) ))) "r") -}} +{{- if $cert.caEnabled -}} +{{- $caCert = (printf "--cacert /etc/tls/certs/%s/ca.crt" $service.tls.cert) -}} +{{- end -}} +{{- end -}} +{{- $url := (printf "%s://%s:%d/v1/debug/restart_service?service=schema-registry" $scheme (get (fromJson (include "redpanda.InternalDomain" (dict "a" (list $dot) ))) "r") (($service.port | int) | int64)) -}} +{{- $script = (concat (default (list ) $script) (list `if [ -d "/etc/secrets/users/" ]; then` ` IFS=":" read -r USER_NAME PASSWORD MECHANISM < <(grep "" $(find /etc/secrets/users/* -print))` ` curl -svm3 --fail --retry "120" --retry-max-time "120" --retry-all-errors --ssl-reqd \` (printf ` %s \` $caCert) ` -X PUT -u ${USER_NAME}:${PASSWORD} \` (printf ` %s || true` $url) `fi`)) -}} +{{- end -}} +{{- $script = (concat (default (list ) $script) (list "")) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (join "\n" $script)) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + diff --git a/charts/redpanda/redpanda/5.9.2/templates/rbac.go.tpl b/charts/redpanda/redpanda/5.9.2/templates/rbac.go.tpl new file mode 100644 index 0000000000..38fe5363f8 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/rbac.go.tpl @@ -0,0 +1,116 @@ +{{- /* Generated from "rbac.go" */ -}} + +{{- define "redpanda.ClusterRoles" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $crs := (coalesce nil) -}} +{{- $cr_1 := (get (fromJson (include "redpanda.SidecarControllersClusterRole" (dict "a" (list $dot) ))) "r") -}} +{{- if (ne $cr_1 (coalesce nil)) -}} +{{- $crs = (concat (default (list ) $crs) (list $cr_1)) -}} +{{- end -}} +{{- if (not $values.rbac.enabled) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $crs) | toJson -}} +{{- break -}} +{{- end -}} +{{- $rpkBundleName := (printf "%s-rpk-bundle" (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r")) -}} +{{- $crs = (concat (default (list ) $crs) (default (list ) (list (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "rules" (coalesce nil) ) (mustMergeOverwrite (dict ) (dict "apiVersion" "rbac.authorization.k8s.io/v1" "kind" "ClusterRole" )) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "name" (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r") "labels" (get (fromJson (include "redpanda.FullLabels" (dict "a" (list $dot) ))) "r") "annotations" $values.serviceAccount.annotations )) "rules" (list (mustMergeOverwrite (dict "verbs" (coalesce nil) ) (dict "apiGroups" (list "") "resources" (list "nodes") "verbs" (list "get" "list") ))) )) (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "rules" (coalesce nil) ) (mustMergeOverwrite (dict ) (dict "apiVersion" "rbac.authorization.k8s.io/v1" "kind" "ClusterRole" )) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "name" $rpkBundleName "labels" (get (fromJson (include "redpanda.FullLabels" (dict "a" (list $dot) ))) "r") "annotations" $values.serviceAccount.annotations )) "rules" (list (mustMergeOverwrite (dict "verbs" (coalesce nil) ) (dict "apiGroups" (list "") "resources" (list "configmaps" "endpoints" "events" "limitranges" "persistentvolumeclaims" "pods" "pods/log" "replicationcontrollers" "resourcequotas" "serviceaccounts" "services") "verbs" (list "get" "list") ))) ))))) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $crs) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.ClusterRoleBindings" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- $crbs := (coalesce nil) -}} +{{- $crb_2 := (get (fromJson (include "redpanda.SidecarControllersClusterRoleBinding" (dict "a" (list $dot) ))) "r") -}} +{{- if (ne $crb_2 (coalesce nil)) -}} +{{- $crbs = (concat (default (list ) $crbs) (list $crb_2)) -}} +{{- end -}} +{{- if (not $values.rbac.enabled) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $crbs) | toJson -}} +{{- break -}} +{{- end -}} +{{- $rpkBundleName := (printf "%s-rpk-bundle" (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r")) -}} +{{- $crbs = (concat (default (list ) $crbs) (default (list ) (list (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "roleRef" (dict "apiGroup" "" "kind" "" "name" "" ) ) (mustMergeOverwrite (dict ) (dict "apiVersion" "rbac.authorization.k8s.io/v1" "kind" "ClusterRoleBinding" )) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "name" (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r") "labels" (get (fromJson (include "redpanda.FullLabels" (dict "a" (list $dot) ))) "r") "annotations" $values.serviceAccount.annotations )) "roleRef" (mustMergeOverwrite (dict "apiGroup" "" "kind" "" "name" "" ) (dict "apiGroup" "rbac.authorization.k8s.io" "kind" "ClusterRole" "name" (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r") )) "subjects" (list (mustMergeOverwrite (dict "kind" "" "name" "" ) (dict "kind" "ServiceAccount" "name" (get (fromJson (include "redpanda.ServiceAccountName" (dict "a" (list $dot) ))) "r") "namespace" $dot.Release.Namespace ))) )) (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "roleRef" (dict "apiGroup" "" "kind" "" "name" "" ) ) (mustMergeOverwrite (dict ) (dict "apiVersion" "rbac.authorization.k8s.io/v1" "kind" "ClusterRoleBinding" )) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "name" $rpkBundleName "labels" (get (fromJson (include "redpanda.FullLabels" (dict "a" (list $dot) ))) "r") "annotations" $values.serviceAccount.annotations )) "roleRef" (mustMergeOverwrite (dict "apiGroup" "" "kind" "" "name" "" ) (dict "apiGroup" "rbac.authorization.k8s.io" "kind" "ClusterRole" "name" $rpkBundleName )) "subjects" (list (mustMergeOverwrite (dict "kind" "" "name" "" ) (dict "kind" "ServiceAccount" "name" (get (fromJson (include "redpanda.ServiceAccountName" (dict "a" (list $dot) ))) "r") "namespace" $dot.Release.Namespace ))) ))))) -}} +{{- $_is_returning = true -}} +{{- (dict "r" $crbs) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.SidecarControllersClusterRole" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (or (not $values.statefulset.sideCars.controllers.enabled) (not $values.statefulset.sideCars.controllers.createRBAC)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $sidecarControllerName := (printf "%s-sidecar-controllers" (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r")) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "rules" (coalesce nil) ) (mustMergeOverwrite (dict ) (dict "apiVersion" "rbac.authorization.k8s.io/v1" "kind" "ClusterRole" )) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "name" $sidecarControllerName "labels" (get (fromJson (include "redpanda.FullLabels" (dict "a" (list $dot) ))) "r") "annotations" $values.serviceAccount.annotations )) "rules" (list (mustMergeOverwrite (dict "verbs" (coalesce nil) ) (dict "apiGroups" (list "") "resources" (list "nodes") "verbs" (list "get" "list" "watch") )) (mustMergeOverwrite (dict "verbs" (coalesce nil) ) (dict "apiGroups" (list "") "resources" (list "persistentvolumes") "verbs" (list "delete" "get" "list" "patch" "update" "watch") ))) ))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.SidecarControllersClusterRoleBinding" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (or (not $values.statefulset.sideCars.controllers.enabled) (not $values.statefulset.sideCars.controllers.createRBAC)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $sidecarControllerName := (printf "%s-sidecar-controllers" (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r")) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "roleRef" (dict "apiGroup" "" "kind" "" "name" "" ) ) (mustMergeOverwrite (dict ) (dict "apiVersion" "rbac.authorization.k8s.io/v1" "kind" "ClusterRoleBinding" )) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "name" $sidecarControllerName "labels" (get (fromJson (include "redpanda.FullLabels" (dict "a" (list $dot) ))) "r") "annotations" $values.serviceAccount.annotations )) "roleRef" (mustMergeOverwrite (dict "apiGroup" "" "kind" "" "name" "" ) (dict "apiGroup" "rbac.authorization.k8s.io" "kind" "ClusterRole" "name" $sidecarControllerName )) "subjects" (list (mustMergeOverwrite (dict "kind" "" "name" "" ) (dict "kind" "ServiceAccount" "name" (get (fromJson (include "redpanda.ServiceAccountName" (dict "a" (list $dot) ))) "r") "namespace" $dot.Release.Namespace ))) ))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.SidecarControllersRole" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (or (not $values.statefulset.sideCars.controllers.enabled) (not $values.statefulset.sideCars.controllers.createRBAC)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $sidecarControllerName := (printf "%s-sidecar-controllers" (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r")) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "rules" (coalesce nil) ) (mustMergeOverwrite (dict ) (dict "apiVersion" "rbac.authorization.k8s.io/v1" "kind" "Role" )) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "name" $sidecarControllerName "namespace" $dot.Release.Namespace "labels" (get (fromJson (include "redpanda.FullLabels" (dict "a" (list $dot) ))) "r") "annotations" $values.serviceAccount.annotations )) "rules" (list (mustMergeOverwrite (dict "verbs" (coalesce nil) ) (dict "apiGroups" (list "apps") "resources" (list "statefulsets/status") "verbs" (list "patch" "update") )) (mustMergeOverwrite (dict "verbs" (coalesce nil) ) (dict "apiGroups" (list "") "resources" (list "secrets" "pods") "verbs" (list "get" "list" "watch") )) (mustMergeOverwrite (dict "verbs" (coalesce nil) ) (dict "apiGroups" (list "apps") "resources" (list "statefulsets") "verbs" (list "get" "patch" "update" "list" "watch") )) (mustMergeOverwrite (dict "verbs" (coalesce nil) ) (dict "apiGroups" (list "") "resources" (list "persistentvolumeclaims") "verbs" (list "delete" "get" "list" "patch" "update" "watch") ))) ))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + +{{- define "redpanda.SidecarControllersRoleBinding" -}} +{{- $dot := (index .a 0) -}} +{{- range $_ := (list 1) -}} +{{- $_is_returning := false -}} +{{- $values := $dot.Values.AsMap -}} +{{- if (or (not $values.statefulset.sideCars.controllers.enabled) (not $values.statefulset.sideCars.controllers.createRBAC)) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (coalesce nil)) | toJson -}} +{{- break -}} +{{- end -}} +{{- $sidecarControllerName := (printf "%s-sidecar-controllers" (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r")) -}} +{{- $_is_returning = true -}} +{{- (dict "r" (mustMergeOverwrite (dict "metadata" (dict "creationTimestamp" (coalesce nil) ) "roleRef" (dict "apiGroup" "" "kind" "" "name" "" ) ) (mustMergeOverwrite (dict ) (dict "apiVersion" "rbac.authorization.k8s.io/v1" "kind" "RoleBinding" )) (dict "metadata" (mustMergeOverwrite (dict "creationTimestamp" (coalesce nil) ) (dict "name" $sidecarControllerName "namespace" $dot.Release.Namespace "labels" (get (fromJson (include "redpanda.FullLabels" (dict "a" (list $dot) ))) "r") "annotations" $values.serviceAccount.annotations )) "roleRef" (mustMergeOverwrite (dict "apiGroup" "" "kind" "" "name" "" ) (dict "apiGroup" "rbac.authorization.k8s.io" "kind" "Role" "name" $sidecarControllerName )) "subjects" (list (mustMergeOverwrite (dict "kind" "" "name" "" ) (dict "kind" "ServiceAccount" "name" (get (fromJson (include "redpanda.ServiceAccountName" (dict "a" (list $dot) ))) "r") "namespace" $dot.Release.Namespace ))) ))) | toJson -}} +{{- break -}} +{{- end -}} +{{- end -}} + diff --git a/charts/redpanda/redpanda/5.9.2/templates/rbac.yaml b/charts/redpanda/redpanda/5.9.2/templates/rbac.yaml new file mode 100644 index 0000000000..d746dda30b --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/rbac.yaml @@ -0,0 +1,20 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You 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. +*/}} +{{- include "_shims.render-manifest" (list "redpanda.ClusterRoles" .) -}} +{{- include "_shims.render-manifest" (list "redpanda.ClusterRoleBindings" .) -}} +{{- include "_shims.render-manifest" (list "redpanda.SidecarControllersRole" .) -}} +{{- include "_shims.render-manifest" (list "redpanda.SidecarControllersRoleBinding" .) -}} diff --git a/charts/redpanda/redpanda/5.9.2/templates/secrets.yaml b/charts/redpanda/redpanda/5.9.2/templates/secrets.yaml new file mode 100644 index 0000000000..7fa8524d21 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/secrets.yaml @@ -0,0 +1,17 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You 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. +*/}} +{{- include "_shims.render-manifest" (list "redpanda.Secrets" .) -}} diff --git a/charts/redpanda/redpanda/5.9.2/templates/service.internal.yaml b/charts/redpanda/redpanda/5.9.2/templates/service.internal.yaml new file mode 100644 index 0000000000..572550b7ad --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/service.internal.yaml @@ -0,0 +1,17 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You 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. +*/}} +{{- include "_shims.render-manifest" (list "redpanda.ServiceInternal" .) -}} diff --git a/charts/redpanda/redpanda/5.9.2/templates/service.loadbalancer.yaml b/charts/redpanda/redpanda/5.9.2/templates/service.loadbalancer.yaml new file mode 100644 index 0000000000..12a8562a0f --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/service.loadbalancer.yaml @@ -0,0 +1,17 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You 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. +*/}} +{{- include "_shims.render-manifest" (list "redpanda.LoadBalancerServices" .) -}} diff --git a/charts/redpanda/redpanda/5.9.2/templates/service.nodeport.yaml b/charts/redpanda/redpanda/5.9.2/templates/service.nodeport.yaml new file mode 100644 index 0000000000..da82c9e706 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/service.nodeport.yaml @@ -0,0 +1,17 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You 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. +*/}} +{{- include "_shims.render-manifest" (list "redpanda.NodePortService" .) -}} diff --git a/charts/redpanda/redpanda/5.9.2/templates/serviceaccount.yaml b/charts/redpanda/redpanda/5.9.2/templates/serviceaccount.yaml new file mode 100644 index 0000000000..5e62c0ec68 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/serviceaccount.yaml @@ -0,0 +1,17 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You 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. +*/}} +{{- include "_shims.render-manifest" (list "redpanda.ServiceAccount" .) -}} diff --git a/charts/redpanda/redpanda/5.9.2/templates/servicemonitor.yaml b/charts/redpanda/redpanda/5.9.2/templates/servicemonitor.yaml new file mode 100644 index 0000000000..cafedbf91d --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/servicemonitor.yaml @@ -0,0 +1,17 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. + */}} +{{- include "_shims.render-manifest" (list "redpanda.ServiceMonitor" .) -}} diff --git a/charts/redpanda/redpanda/5.9.2/templates/statefulset.yaml b/charts/redpanda/redpanda/5.9.2/templates/statefulset.yaml new file mode 100644 index 0000000000..d231e4b771 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/statefulset.yaml @@ -0,0 +1,21 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You 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. +*/}} + +{{- include "fail-on-unsupported-helm-version" . -}} +{{- include "fail-on-insecure-sasl-logging" . -}} + +{{- include "_shims.render-manifest" (list "redpanda.StatefulSet" .) -}} diff --git a/charts/redpanda/redpanda/5.9.2/templates/tests/test-api-status.yaml b/charts/redpanda/redpanda/5.9.2/templates/tests/test-api-status.yaml new file mode 100644 index 0000000000..330a2c4a4d --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/tests/test-api-status.yaml @@ -0,0 +1,52 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/}} +{{- if and .Values.tests.enabled (not (or (include "tls-enabled" . | fromJson).bool (include "sasl-enabled" . | fromJson).bool)) -}} +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "redpanda.fullname" . }}-test-api-status" + namespace: {{ .Release.Namespace | quote }} + labels: + {{- with include "full.labels" . }} + {{- . | nindent 4 }} + {{- end }} + annotations: + "helm.sh/hook": test + "helm.sh/hook-delete-policy": before-hook-creation +spec: + restartPolicy: Never + securityContext: {{ include "pod-security-context" . | nindent 4 }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: {{- toYaml . | nindent 4 }} + {{- end }} + containers: + - name: {{ template "redpanda.name" . }} + image: {{ .Values.image.repository }}:{{ template "redpanda.tag" . }} + command: + - /usr/bin/timeout + - "120" + - bash + - -c + - | + until rpk cluster info \ + --brokers {{ include "redpanda.fullname" . }}-0.{{ include "redpanda.internal.domain" . }}:{{ .Values.listeners.kafka.port }} + do sleep 2 + done + volumeMounts: {{ include "default-mounts" . | nindent 8 }} + securityContext: {{ include "container-security-context" . | nindent 8 }} + volumes: {{ include "default-volumes" . | nindent 4 }} +{{- end }} diff --git a/charts/redpanda/redpanda/5.9.2/templates/tests/test-auditLogging.yaml b/charts/redpanda/redpanda/5.9.2/templates/tests/test-auditLogging.yaml new file mode 100644 index 0000000000..b7d1d2581d --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/tests/test-auditLogging.yaml @@ -0,0 +1,91 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +*/}} +{{/* + This feature is gated by having a license, and it must have sasl enabled, we assume these conditions are met + as part of setting auditLogging being enabled. +*/}} +{{- if and .Values.tests.enabled .Values.auditLogging.enabled (include "redpanda-atleast-23-3-0" . | fromJson).bool }} +{{- $sasl := .Values.auth.sasl }} +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "redpanda.fullname" . }}-test-audit-logging" + namespace: {{ .Release.Namespace | quote }} + labels: + {{- with include "full.labels" . }} + {{- . | nindent 4 }} + {{- end }} + annotations: + "helm.sh/hook": test + "helm.sh/hook-delete-policy": before-hook-creation +spec: + restartPolicy: Never + securityContext: {{ include "pod-security-context" . | nindent 4 }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: { { - toYaml . | nindent 4 }} + {{- end }} + containers: + - name: {{ template "redpanda.name" . }} + image: {{ .Values.image.repository }}:{{ template "redpanda.tag" . }} + command: + - /usr/bin/timeout + - "120" + - bash + - -c + - | + set -xe + old_setting=${-//[^x]/} + audit_topic_name="_redpanda.audit_log" + expected_partitions={{ .Values.auditLogging.partitions }} + + # sasl configurations + set +x + IFS=":" read -r {{ include "rpk-sasl-environment-variables" . }} < <(grep "" $(find /etc/secrets/users/* -print)) + {{- if (include "redpanda-atleast-23-2-1" . | fromJson).bool }} + RPK_SASL_MECHANISM=${RPK_SASL_MECHANISM:-{{ .Values.auth.sasl.mechanism | upper }}} + {{- else }} + REDPANDA_SASL_MECHANISM=${REDPANDA_SASL_MECHANISM:-{{ .Values.auth.sasl.mechanism | upper }}} + {{- end }} + export {{ include "rpk-sasl-environment-variables" . }} + if [[ -n "$old_setting" ]]; then set -x; fi + + {{- $i := .Values.statefulset.replicas }} + {{- $default_topic_replicas := sub (add $i (mod $i 2)) 1 }} + # wait for post-upgrade job to update the default_topic_replications value + timeout 600 bash -c "until [[ $(rpk cluster config get default_topic_replications) = {{ $default_topic_replicas }} ]]; do sleep 1; done" + + # now run the to determine if we have the right results + # should describe topic without error + rpk topic describe ${audit_topic_name} + # should get the expected values + result=$(rpk topic list | grep ${audit_topic_name}) + name=$(echo $result | awk '{print $1}') + partitions=$(echo $result | awk '{print $2}') + if [ "${name}" != "${audit_topic_name}" ]; then + echo "expected topic name does not match" + exit 1 + fi + if [ ${partitions} != ${expected_partitions} ]; then + echo "expected partition size did not match" + exit 1 + fi + volumeMounts: {{ include "default-mounts" . | nindent 8 }} + resources: +{{- toYaml .Values.statefulset.resources | nindent 12 }} + securityContext: {{ include "container-security-context" . | nindent 8 }} + volumes: {{ include "default-volumes" . | nindent 4 }} +{{- end }} diff --git a/charts/redpanda/redpanda/5.9.2/templates/tests/test-connector-via-console.yaml b/charts/redpanda/redpanda/5.9.2/templates/tests/test-connector-via-console.yaml new file mode 100644 index 0000000000..c50958e54a --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/tests/test-connector-via-console.yaml @@ -0,0 +1,165 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/}} +{{- if and .Values.tests.enabled .Values.connectors.enabled .Values.console.enabled }} +{{- $sasl := .Values.auth.sasl }} +{{- $values := .Values }} +{{ $consoleValues := dict "Values" .Values.console "Release" .Release "Chart" .Subcharts.console.Chart }} +{{ $connectorsVars := dict "Values" .Values.connectors "Release" .Release "Chart" .Subcharts.connectors.Chart }} +{{/* brokers */}} +{{- $kafkaBrokers := list }} +{{- range (include "seed-server-list" . | mustFromJson) }} + {{- $kafkaBrokers = append $kafkaBrokers (printf "%s:%s" . ($values.listeners.kafka.port | toString)) }} +{{- end }} +{{- $brokersString := join "," $kafkaBrokers}} +apiVersion: v1 +kind: Pod +metadata: + name: {{ include "redpanda.fullname" . | trunc 54 }}-test-connectors-via-console + namespace: {{ .Release.Namespace | quote }} + labels: + {{- with include "full.labels" . }} + {{- . | nindent 4 }} + {{- end }} + test-name: test-connectors-via-console + annotations: + test-name: test-connectors-via-console + "helm.sh/hook": test + "helm.sh/hook-delete-policy": before-hook-creation +spec: + restartPolicy: Never + securityContext: {{ include "pod-security-context" . | nindent 4 }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: {{- toYaml . | nindent 4 }} + {{- end }} + containers: + - name: {{ template "redpanda.name" . }} + image: {{ .Values.image.repository }}:{{ template "redpanda.tag" . }} + env: + - name: TLS_ENABLED + value: {{ (include "kafka-internal-tls-enabled" . | fromJson).bool | quote }} + command: + - /bin/bash + - -c + - | + set -xe + + trap connectorsState ERR + + connectorsState () { + echo check connectors expand status + curl {{ template "curl-options" . }} http://{{ include "connectors.serviceName" $connectorsVars }}:{{ .Values.connectors.connectors.restPort }}/connectors?expand=status + echo check connectors expand info + curl {{ template "curl-options" . }} http://{{ include "connectors.serviceName" $connectorsVars }}:{{ .Values.connectors.connectors.restPort }}/connectors?expand=info + echo check connector configuration + curl {{ template "curl-options" . }} http://{{ include "connectors.serviceName" $connectorsVars }}:{{ .Values.connectors.connectors.restPort }}/connectors/$CONNECTOR_NAME + echo check connector topics + curl {{ template "curl-options" . }} http://{{ include "connectors.serviceName" $connectorsVars }}:{{ .Values.connectors.connectors.restPort }}/connectors/$CONNECTOR_NAME/topics + } + + {{- if .Values.auth.sasl.enabled }} + set -e + set +x + + echo "SASL enabled: reading credentials from $(find /etc/secrets/users/* -print)" + IFS=":" read -r {{ include "rpk-sasl-environment-variables" . }} < <(grep "" $(find /etc/secrets/users/* -print)) + {{- if (include "redpanda-atleast-23-2-1" . | fromJson).bool }} + RPK_SASL_MECHANISM=${RPK_SASL_MECHANISM:-{{ .Values.auth.sasl.mechanism | upper }}} + {{- else }} + REDPANDA_SASL_MECHANISM=${REDPANDA_SASL_MECHANISM:-{{ .Values.auth.sasl.mechanism | upper }}} + RPK_USER="${REDPANDA_SASL_USERNAME}" + RPK_PASS="${REDPANDA_SASL_PASSWORD}" + RPK_SASL_MECHANISM="${REDPANDA_SASL_MECHANISM}" + {{- end }} + export {{ include "rpk-sasl-environment-variables" . }} + + JAAS_CONFIG_SOURCE="\"source.cluster.sasl.jaas.config\": \"org.apache.kafka.common.security.scram.ScramLoginModule required username=\\\\"\"${RPK_USER}\\\\"\" password=\\\\"\"${RPK_PASS}\\\\"\";\"," + JAAS_CONFIG_TARGET="\"target.cluster.sasl.jaas.config\": \"org.apache.kafka.common.security.scram.ScramLoginModule required username=\\\\"\"${RPK_USER}\\\\"\" password=\\\\"\"${RPK_PASS}\\\\"\";\"," + set -x + set +e + {{- end }} + + {{- $testTopic := printf "test-topic-%s" (randNumeric 3) }} + rpk topic create {{ $testTopic }} + rpk topic list + echo "Test message!" | rpk topic produce {{ $testTopic }} + + SECURITY_PROTOCOL=PLAINTEXT + if [[ -n "$RPK_SASL_MECHANISM" && $TLS_ENABLED == "true" ]]; then + SECURITY_PROTOCOL="SASL_SSL" + elif [[ -n "$RPK_SASL_MECHANISM" ]]; then + SECURITY_PROTOCOL="SASL_PLAINTEXT" + elif [[ $TLS_ENABLED == "true" ]]; then + SECURITY_PROTOCOL="SSL" + fi + + CONNECTOR_NAME=mm2-$RANDOM + cat << 'EOF' > /tmp/mm2-conf.json + { + "connectorName": "CONNECTOR_NAME", + "config": { + "connector.class": "org.apache.kafka.connect.mirror.MirrorSourceConnector", + "topics": "{{ $testTopic }}", + "replication.factor": "1", + "tasks.max": "1", + "source.cluster.bootstrap.servers": {{ $brokersString | quote }}, + "target.cluster.bootstrap.servers": {{ $brokersString | quote }}, + "target.cluster.alias": "test-only-redpanda", + "source.cluster.alias": "source", + "key.converter": "org.apache.kafka.connect.converters.ByteArrayConverter", + "value.converter": "org.apache.kafka.connect.converters.ByteArrayConverter", + "source->target.enabled": "true", + "target->source.enabled": "false", + "sync.topic.configs.interval.seconds": "5", + "sync.topics.configs.enabled": "true", + "source.cluster.ssl.truststore.type": "PEM", + "target.cluster.ssl.truststore.type": "PEM", + "source.cluster.ssl.truststore.location": "/opt/kafka/connect-certs/ca/ca.crt", + "target.cluster.ssl.truststore.location": "/opt/kafka/connect-certs/ca/ca.crt", + JAAS_CONFIG_SOURCE + JAAS_CONFIG_TARGET + "source.cluster.security.protocol": "SECURITY_PROTOCOL", + "target.cluster.security.protocol": "SECURITY_PROTOCOL", + "source.cluster.sasl.mechanism": "SASL_MECHANISM", + "target.cluster.sasl.mechanism": "SASL_MECHANISM" + } + } + EOF + + sed -i "s/CONNECTOR_NAME/$CONNECTOR_NAME/g" /tmp/mm2-conf.json + sed -i "s/SASL_MECHANISM/$RPK_SASL_MECHANISM/g" /tmp/mm2-conf.json + sed -i "s/SECURITY_PROTOCOL/$SECURITY_PROTOCOL/g" /tmp/mm2-conf.json + set +x + sed -i "s/JAAS_CONFIG_SOURCE/$JAAS_CONFIG_SOURCE/g" /tmp/mm2-conf.json + sed -i "s/JAAS_CONFIG_TARGET/$JAAS_CONFIG_TARGET/g" /tmp/mm2-conf.json + set -x + + URL=http://{{ include "console.fullname" $consoleValues }}:{{ include "console.containerPort" $consoleValues }}/api/kafka-connect/clusters/connectors/connectors + {{/* outputting to /dev/null because the output contains the user password */}} + echo "Creating mm2 connector" + curl {{ template "curl-options" . }} -H 'Content-Type: application/json' "${URL}" -d @/tmp/mm2-conf.json + + rpk topic consume source.{{ $testTopic }} -n 1 + + echo "Destroying mm2 connector" + curl {{ template "curl-options" . }} -X DELETE "${URL}/${CONNECTOR_NAME}" + + rpk topic list + rpk topic delete {{ $testTopic }} source.{{ $testTopic }} mm2-offset-syncs.test-only-redpanda.internal + volumeMounts: {{ include "default-mounts" . | nindent 8 }} + securityContext: {{ include "container-security-context" . | nindent 8 }} + volumes: {{ include "default-volumes" . | nindent 4 }} +{{- end }} diff --git a/charts/redpanda/redpanda/5.9.2/templates/tests/test-console.yaml b/charts/redpanda/redpanda/5.9.2/templates/tests/test-console.yaml new file mode 100644 index 0000000000..aeef1117ac --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/tests/test-console.yaml @@ -0,0 +1,49 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/}} +{{- if and .Values.tests.enabled .Values.console.enabled -}} +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "redpanda.fullname" . }}-test-console" + namespace: {{ .Release.Namespace | quote }} + labels: + {{- with include "full.labels" . }} + {{- . | nindent 4 }} + {{- end }} + annotations: + "helm.sh/hook": test + "helm.sh/hook-delete-policy": before-hook-creation +spec: + restartPolicy: Never + securityContext: {{ include "pod-security-context" . | nindent 4 }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: {{- toYaml . | nindent 4 }} + {{- end }} + containers: + - name: {{ template "redpanda.name" . }} + image: {{ .Values.image.repository }}:{{ template "redpanda.tag" . }} + command: + - /usr/bin/timeout + - "120" + - bash + - -c + - | + curl {{ template "curl-options" . }} http://{{ include "redpanda.fullname" . }}-console.{{ .Release.Namespace }}.svc:{{ (get (fromJson (include "console.ContainerPort" (dict "a" (list (dict "Values" (dict "AsMap" .Values.console)) )))) "r" ) }}/api/cluster + volumeMounts: {{ include "default-mounts" . | nindent 8 }} + securityContext: {{ include "container-security-context" . | nindent 8 }} + volumes: {{ include "default-volumes" . | nindent 4 }} +{{- end }} diff --git a/charts/redpanda/redpanda/5.9.2/templates/tests/test-internal-external-tls-secrets.yaml b/charts/redpanda/redpanda/5.9.2/templates/tests/test-internal-external-tls-secrets.yaml new file mode 100644 index 0000000000..53d75bb1ba --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/tests/test-internal-external-tls-secrets.yaml @@ -0,0 +1,122 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/}} +{{- if and .Values.tests.enabled (include "tls-enabled" . | fromJson).bool ( eq .Values.external.type "NodePort" ) }} + {{- $values := .Values }} +apiVersion: v1 +kind: Pod +metadata: + name: {{ include "redpanda.fullname" . }}-test-internal-externals-cert-secrets + namespace: {{ .Release.Namespace | quote }} + labels: + {{- with include "full.labels" . }} + {{- . | nindent 4 }} + {{- end }} + annotations: + "helm.sh/hook": test + "helm.sh/hook-delete-policy": before-hook-creation +spec: + restartPolicy: Never + securityContext: {{ include "pod-security-context" . | nindent 4 }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: {{- toYaml . | nindent 4 }} + {{- end }} + containers: + - name: {{ template "redpanda.name" . }} + image: {{ .Values.image.repository }}:{{ template "redpanda.tag" . }} + command: + - bash + - -c + - | + set -x + + retry() { + local retries="$1" + local command="$2" + + # Run the command, and save the exit code + bash -c $command + local exit_code=$? + + # If the exit code is non-zero (i.e. command failed), and we have not + # reached the maximum number of retries, run the command again + if [[ $exit_code -ne 0 && $retries -gt 0 ]]; then + retry $(($retries - 1)) "$command" + else + # Return the exit code from the command + return $exit_code + fi + } + + {{- range $name, $cert := $values.tls.certs }} + {{- if $cert.secretRef }} + echo testing cert: {{ $name | quote }} + + {{- if eq $cert.secretRef.name "internal-tls-secret" }} + echo "---> testing internal tls" + retry 5 'openssl s_client -verify_return_error -prexit + {{- if $cert.caEnabled }} + -CAfile {{ printf "/etc/tls/certs/%s" $name }}/ca.crt + {{- end }} + -key {{ printf "/etc/tls/certs/%s" $name }}/tls.key + -connect {{ include "admin-api-urls" $ }}' + {{- end }} + + {{- if eq $cert.secretRef.name "external-tls-secret" }} + echo "---> testing external tls" + + {{- if eq $values.listeners.kafka.external.default.tls.cert $name }} + echo "-----> testing external tls: kafka api" + {{- $port := ( first $values.listeners.kafka.external.default.advertisedPorts ) }} + retry 5 'openssl s_client -verify_return_error -prexit + {{- if $cert.caEnabled }} + -CAfile {{ printf "/etc/tls/certs/%s" $name }}/ca.crt + {{- end }} + -key {{ printf "/etc/tls/certs/%s" $name }}/tls.key + -connect {{ $values.external.domain }}:{{ $port }}' + {{- end }} + + {{- if and (eq $values.listeners.schemaRegistry.external.default.tls.cert $name) (include "redpanda-22-2-x-without-sasl" $ | fromJson).bool }} + echo "-----> testing external tls: schema registry" + {{- $port := ( first $values.listeners.schemaRegistry.external.default.advertisedPorts ) }} + retry 5 'openssl s_client -verify_return_error -prexit + {{- if $cert.caEnabled }} + -CAfile {{ printf "/etc/tls/certs/%s" $name }}/ca.crt + {{- end }} + -key {{ printf "/etc/tls/certs/%s" $name }}/tls.key + -connect {{ $values.external.domain }}:{{ $port }}' + {{- end }} + + {{- if and (eq $values.listeners.http.external.default.tls.cert $name) (include "redpanda-22-2-x-without-sasl" $ | fromJson).bool }} + echo "-----> testing external tls: http api" + {{- $port := ( first $values.listeners.http.external.default.advertisedPorts ) }} + retry 5 'openssl s_client -verify_return_error -prexit + {{- if $cert.caEnabled }} + -CAfile {{ printf "/etc/tls/certs/%s" $name }}/ca.crt + {{- end }} + -key {{ printf "/etc/tls/certs/%s" $name }}/tls.key + -connect {{ $values.external.domain }}:{{ $port }}' + {{- end }} + + {{- end }} + echo "----" + + {{- end }} + {{- end }} + volumeMounts: {{ include "default-mounts" . | nindent 8 }} + securityContext: {{ include "container-security-context" . | nindent 8 }} + volumes: {{ include "default-volumes" . | nindent 4 }} +{{- end }} diff --git a/charts/redpanda/redpanda/5.9.2/templates/tests/test-kafka-internal-tls-status.yaml b/charts/redpanda/redpanda/5.9.2/templates/tests/test-kafka-internal-tls-status.yaml new file mode 100644 index 0000000000..dcfc02cbdc --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/tests/test-kafka-internal-tls-status.yaml @@ -0,0 +1,62 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/}} +{{- if and .Values.tests.enabled (include "kafka-internal-tls-enabled" . | fromJson).bool (not (include "sasl-enabled" . | fromJson).bool) -}} + {{- $service := .Values.listeners.kafka -}} + {{- $cert := get .Values.tls.certs $service.tls.cert -}} +apiVersion: v1 +kind: Pod +metadata: + name: {{ include "redpanda.fullname" . }}-test-kafka-internal-tls-status + namespace: {{ .Release.Namespace | quote }} + labels: + {{- with include "full.labels" . }} + {{- . | nindent 4 }} + {{- end }} + annotations: + "helm.sh/hook": test + "helm.sh/hook-delete-policy": before-hook-creation +spec: + restartPolicy: Never + securityContext: {{ include "pod-security-context" . | nindent 4 }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: {{- toYaml . | nindent 4 }} + {{- end }} + containers: + - name: {{ template "redpanda.name" . }} + image: {{ .Values.image.repository }}:{{ template "redpanda.tag" . }} + command: + - /usr/bin/timeout + - "120" + - bash + - -c + - | + until rpk cluster info \ + --brokers {{ include "redpanda.fullname" .}}-0.{{ include "redpanda.internal.domain" . }}:{{ $service.port }} \ + --tls-enabled \ + {{- if $cert.caEnabled }} + --tls-truststore /etc/tls/certs/{{ $service.tls.cert }}/ca.crt + {{- else }} + {{- /* This is a required field so we use the default in the redpanda debian container */}} + --tls-truststore /etc/ssl/certs/ca-certificates.crt + {{- end }} + do sleep 2 + done + resources: {{ toYaml .Values.statefulset.resources | nindent 12 }} + volumeMounts: {{ include "default-mounts" . | nindent 8 }} + securityContext: {{ include "container-security-context" . | nindent 8 }} + volumes: {{ include "default-volumes" . | nindent 4 }} +{{- end }} diff --git a/charts/redpanda/redpanda/5.9.2/templates/tests/test-kafka-nodelete.yaml b/charts/redpanda/redpanda/5.9.2/templates/tests/test-kafka-nodelete.yaml new file mode 100644 index 0000000000..188c2927a0 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/tests/test-kafka-nodelete.yaml @@ -0,0 +1,104 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/}} +{{- if and .Values.tests.enabled (dig "kafka_nodelete_topics" "[]" $.Values.config.cluster) }} +{{- $noDeleteTopics := .Values.config.cluster.kafka_nodelete_topics }} +{{- $sasl := .Values.auth.sasl }} +apiVersion: v1 +kind: Pod +metadata: + name: {{ include "redpanda.fullname" . }}-test-kafka-nodelete + namespace: {{ .Release.Namespace | quote }} + labels: +{{- with include "full.labels" . }} + {{- . | nindent 4 }} +{{- end }} + annotations: + "helm.sh/hook": test + "helm.sh/hook-delete-policy": before-hook-creation +spec: + restartPolicy: Never + securityContext: {{ include "pod-security-context" . | nindent 4 }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: {{- toYaml . | nindent 4 }} +{{- end }} + containers: + - name: {{ template "redpanda.name" . }} + image: {{ .Values.image.repository }}:{{ template "redpanda.tag" . }} + env: + - name: REDPANDA_BROKERS + value: "{{ include "redpanda.fullname" . }}.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain | trimSuffix "." }}:{{ .Values.listeners.kafka.port }}" + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + command: + - /usr/bin/timeout + - "120" + - bash + - -c + - | + set -e +{{- $cloudStorageFlags := "" }} +{{- if (include "storage-tiered-config" .|fromJson).cloud_storage_enabled }} + {{- $cloudStorageFlags = "-c retention.bytes=80 -c segment.bytes=40 -c redpanda.remote.read=true -c redpanda.remote.write=true"}} +{{- end }} +{{- if .Values.auth.sasl.enabled }} + old_setting=${-//[^x]/} + set +x + IFS=":" read -r {{ include "rpk-sasl-environment-variables" . }} < <(grep "" $(find /etc/secrets/users/* -print)) + {{- if (include "redpanda-atleast-23-2-1" . | fromJson).bool }} + RPK_SASL_MECHANISM=${RPK_SASL_MECHANISM:-{{ .Values.auth.sasl.mechanism | upper }}} + {{- else }} + REDPANDA_SASL_MECHANISM=${REDPANDA_SASL_MECHANISM:-{{ .Values.auth.sasl.mechanism | upper }}} + {{- end }} + export {{ include "rpk-sasl-environment-variables" . }} + if [[ -n "$old_setting" ]]; then set -x; fi +{{- end }} + {{- $i := .Values.statefulset.replicas }} + {{- $default_topic_replicas := sub (add $i (mod $i 2)) 1 }} + # wait for post-upgrade job to update the default_topic_replications value + timeout 120 bash -c "until [[ $(rpk cluster config get default_topic_replications) = {{ $default_topic_replicas }} ]]; do sleep 1; done" + + exists=$(rpk topic list | grep my_sample_topic | awk '{print $1}') + if [[ "$exists" != "my_sample_topic" ]]; then + until rpk topic create my_sample_topic {{ $cloudStorageFlags }} + do sleep 2 + done + fi + + {{- range $i := until 100 }} + echo "Pandas are awesome!" | rpk topic produce my_sample_topic + {{- end }} + sleep 2 + rpk topic consume my_sample_topic -n 1 | grep "Pandas are awesome!" + + # now check if we can delete the topic (we should not) + rpk topic delete my_sample_topic + + {{- if has "my_sample_topic" $noDeleteTopics }} + result=$(rpk topic list | grep my_sample_topic | awk '{print $1}') + if [[ "$result" != "my_sample_topic" ]]; then + echo "topic should not have been deleted" + exit 1 + fi + {{- end }} + + volumeMounts: {{ include "default-mounts" . | nindent 8 }} + resources: {{ toYaml .Values.statefulset.resources | nindent 12 }} + securityContext: {{ include "container-security-context" . | nindent 8 }} + volumes: {{ include "default-volumes" . | nindent 4 }} +{{- end }} diff --git a/charts/redpanda/redpanda/5.9.2/templates/tests/test-kafka-produce-consume.yaml b/charts/redpanda/redpanda/5.9.2/templates/tests/test-kafka-produce-consume.yaml new file mode 100644 index 0000000000..247acc57a5 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/tests/test-kafka-produce-consume.yaml @@ -0,0 +1,87 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/}} +{{- if .Values.tests.enabled }} +{{- $sasl := .Values.auth.sasl }} +apiVersion: v1 +kind: Pod +metadata: + name: {{ include "redpanda.fullname" . }}-test-kafka-produce-consume + namespace: {{ .Release.Namespace | quote }} + labels: +{{- with include "full.labels" . }} + {{- . | nindent 4 }} +{{- end }} + annotations: + "helm.sh/hook": test + "helm.sh/hook-delete-policy": before-hook-creation +spec: + restartPolicy: Never + securityContext: {{ include "pod-security-context" . | nindent 4 }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: {{- toYaml . | nindent 4 }} +{{- end }} + containers: + - name: {{ template "redpanda.name" . }} + image: {{ .Values.image.repository }}:{{ template "redpanda.tag" . }} + env: + - name: REDPANDA_BROKERS + value: "{{ include "redpanda.fullname" . }}.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain | trimSuffix "." }}:{{ .Values.listeners.kafka.port }}" + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + command: + - /usr/bin/timeout + - "120" + - bash + - -c + - | + set -e +{{- $cloudStorageFlags := "" }} +{{- if (include "storage-tiered-config" .|fromJson).cloud_storage_enabled }} + {{- $cloudStorageFlags = "-c retention.bytes=80 -c segment.bytes=40 -c redpanda.remote.read=true -c redpanda.remote.write=true"}} +{{- end }} +{{- if .Values.auth.sasl.enabled }} + old_setting=${-//[^x]/} + set +x + IFS=":" read -r {{ include "rpk-sasl-environment-variables" . }} < <(grep "" $(find /etc/secrets/users/* -print)) + {{- if (include "redpanda-atleast-23-2-1" . | fromJson).bool }} + RPK_SASL_MECHANISM=${RPK_SASL_MECHANISM:-{{ .Values.auth.sasl.mechanism | upper }}} + {{- else }} + REDPANDA_SASL_MECHANISM=${REDPANDA_SASL_MECHANISM:-{{ .Values.auth.sasl.mechanism | upper }}} + {{- end }} + export {{ include "rpk-sasl-environment-variables" . }} + if [[ -n "$old_setting" ]]; then set -x; fi +{{- end }} + {{- $i := .Values.statefulset.replicas }} + {{- $default_topic_replicas := sub (add $i (mod $i 2)) 1 }} + # wait for post-upgrade job to update the default_topic_replications value + timeout 600 bash -c "until [[ $(rpk cluster config get default_topic_replications) = {{ $default_topic_replicas }} ]]; do sleep 1; done" + until rpk topic create produce.consume.test.$POD_NAME {{ $cloudStorageFlags }} + do sleep 2 + done + {{- range $i := until 100 }} + echo "Pandas are awesome!" | rpk topic produce produce.consume.test.$POD_NAME + {{- end }} + sleep 2 + rpk topic consume produce.consume.test.$POD_NAME -n 1 | grep "Pandas are awesome!" + rpk topic delete produce.consume.test.$POD_NAME + volumeMounts: {{ include "default-mounts" . | nindent 8 }} + resources: {{ toYaml .Values.statefulset.resources | nindent 12 }} + securityContext: {{ include "container-security-context" . | nindent 8 }} + volumes: {{ include "default-volumes" . | nindent 4 }} +{{- end }} diff --git a/charts/redpanda/redpanda/5.9.2/templates/tests/test-kafka-sasl-status.yaml b/charts/redpanda/redpanda/5.9.2/templates/tests/test-kafka-sasl-status.yaml new file mode 100644 index 0000000000..0519c44bba --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/tests/test-kafka-sasl-status.yaml @@ -0,0 +1,79 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/}} +{{- if and .Values.tests.enabled (include "sasl-enabled" . | fromJson).bool }} +{{- $sasl := .Values.auth.sasl }} +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "redpanda.fullname" . }}-test-kafka-sasl-status" + namespace: {{ .Release.Namespace | quote }} + labels: +{{- with include "full.labels" . }} + {{- . | nindent 4 }} +{{- end }} + annotations: + "helm.sh/hook": test + "helm.sh/hook-delete-policy": before-hook-creation +spec: + restartPolicy: Never + securityContext: {{ include "pod-security-context" . | nindent 4 }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: {{- toYaml . | nindent 4 }} + {{- end }} + containers: + - name: {{ template "redpanda.name" . }} + image: {{ .Values.image.repository }}:{{ template "redpanda.tag" . }} + command: + - /usr/bin/timeout + - "120" + - bash + - -c + - | + set -xe + +{{- if .Values.auth.sasl.enabled }} + old_setting=${-//[^x]/} + set +x + IFS=":" read -r {{ include "rpk-sasl-environment-variables" . }} < <(grep "" $(find /etc/secrets/users/* -print)) + {{- if (include "redpanda-atleast-23-2-1" . | fromJson).bool }} + RPK_SASL_MECHANISM=${RPK_SASL_MECHANISM:-{{ .Values.auth.sasl.mechanism | upper }}} + {{- else }} + REDPANDA_SASL_MECHANISM=${REDPANDA_SASL_MECHANISM:-{{ .Values.auth.sasl.mechanism | upper }}} + {{- end }} + export {{ include "rpk-sasl-environment-variables" . }} + if [[ -n "$old_setting" ]]; then set -x; fi +{{- end }} + + until rpk acl user delete myuser + do sleep 2 + done + sleep 3 + + {{ include "rpk-cluster-info" $ }} + {{ include "rpk-acl-user-create" $ }} + {{ include "rpk-acl-create" $ }} + sleep 3 + {{ include "rpk-topic-create" $ }} + {{ include "rpk-topic-describe" $ }} + {{ include "rpk-topic-delete" $ }} + rpk acl user delete myuser + volumeMounts: {{ include "default-mounts" . | nindent 8 }} + resources: +{{- toYaml .Values.statefulset.resources | nindent 12 }} + securityContext: {{ include "container-security-context" . | nindent 8 }} + volumes: {{ include "default-volumes" . | nindent 4 }} +{{- end }} diff --git a/charts/redpanda/redpanda/5.9.2/templates/tests/test-license-with-console.yaml b/charts/redpanda/redpanda/5.9.2/templates/tests/test-license-with-console.yaml new file mode 100644 index 0000000000..1edf7a3507 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/tests/test-license-with-console.yaml @@ -0,0 +1,61 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/}} +{{- if and .Values.tests.enabled (include "is-licensed" . | fromJson).bool .Values.console.enabled }} +{{- $consolePort := (get (fromJson (include "console.ContainerPort" (dict "a" (list (dict "Values" (dict "AsMap" .Values.console)) )))) "r" ) }} +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "redpanda.fullname" . }}-test-license-with-console" + namespace: {{ .Release.Namespace | quote }} + labels: + {{- with include "full.labels" . }} + {{- . | nindent 4 }} + {{- end }} + annotations: + "helm.sh/hook": test + "helm.sh/hook-delete-policy": before-hook-creation +spec: + restartPolicy: Never + securityContext: + runAsUser: 65535 + runAsGroup: 65535 + {{- with .Values.imagePullSecrets }} + imagePullSecrets: {{- toYaml . | nindent 4 }} + {{- end }} + containers: + - name: {{ template "redpanda.name" . }} + image: mintel/docker-alpine-bash-curl-jq:latest + command: [ "/bin/bash", "-c" ] + args: + - | + echo "testing that we do NOT have an open source license" + set -xe + + max_iteration=10 + curl -vm3 --fail --retry "120" --retry-max-time "120" http://{{ include "redpanda.fullname" . }}-console.{{ .Release.Namespace }}.svc:{{$consolePort}}/api/cluster/overview | jq . + type=$(curl -svm3 --fail --retry "120" --retry-max-time "120" http://{{ include "redpanda.fullname" . }}-console.{{ .Release.Namespace }}.svc:{{$consolePort}}/api/cluster/overview | jq -r .console.license.type) + while [[ $max_iteration -gt 0 && ("$type" == "open_source" || "$type" == "") ]]; do + max_iteration=$(( max_iteration - 1 )) + type=$(curl -svm3 --fail --retry "120" --retry-max-time "120" http://{{ include "redpanda.fullname" . }}-console.{{ .Release.Namespace }}.svc:{{$consolePort}}/api/cluster/overview | jq -r .console.license.type) + done + if [[ "$type" == "open_source" || "$type" == "" ]]; then + curl -svm3 --fail --retry "120" --retry-max-time "120" http://{{ include "redpanda.fullname" . }}-console.{{ .Release.Namespace }}.svc:{{$consolePort}}/api/cluster/overview | jq . + exit 1 + fi + set +x + echo "license test passed." +{{- end }} diff --git a/charts/redpanda/redpanda/5.9.2/templates/tests/test-lifecycle-scripts.yaml b/charts/redpanda/redpanda/5.9.2/templates/tests/test-lifecycle-scripts.yaml new file mode 100644 index 0000000000..5c72e1d9fb --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/tests/test-lifecycle-scripts.yaml @@ -0,0 +1,66 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/}} +{{- if .Values.tests.enabled }} +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "redpanda.fullname" . }}-test-lifecycle" + namespace: {{ .Release.Namespace | quote }} + labels: + {{- with include "full.labels" . }} + {{- . | nindent 4 }} + {{- end }} + annotations: + helm.sh/hook: test + helm.sh/hook-delete-policy: before-hook-creation +spec: + restartPolicy: Never + securityContext: {{ include "pod-security-context" . | nindent 4 }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: {{- toYaml . | nindent 4 }} + {{- end }} + containers: + - name: {{ template "redpanda.name" . }} + image: {{ .Values.image.repository }}:{{ template "redpanda.tag" . }} + env: + - name: SERVICE_NAME + value: {{ include "redpanda.fullname" . }}-0 + command: + - /bin/timeout + - "{{ mul .Values.statefulset.terminationGracePeriodSeconds 2 }}" + - bash + - -xec + - | + /bin/timeout -v {{ div .Values.statefulset.terminationGracePeriodSeconds 2 }} bash -x /var/lifecycle/preStop.sh + ls -l /tmp/preStop* + test -f /tmp/preStopHookStarted + test -f /tmp/preStopHookFinished + + /bin/timeout -v {{ div .Values.statefulset.terminationGracePeriodSeconds 2 }} bash -x /var/lifecycle/postStart.sh + ls -l /tmp/postStart* + test -f /tmp/postStartHookStarted + test -f /tmp/postStartHookFinished + volumeMounts: {{ include "default-mounts" . | nindent 8 }} + - name: lifecycle-scripts + mountPath: /var/lifecycle + securityContext: {{ include "container-security-context" . | nindent 8 }} + volumes: {{ include "default-volumes" . | nindent 4 }} + - name: lifecycle-scripts + secret: + secretName: {{ (include "redpanda.fullname" . | trunc 50 ) }}-sts-lifecycle + defaultMode: 0o775 + {{- end }} \ No newline at end of file diff --git a/charts/redpanda/redpanda/5.9.2/templates/tests/test-loadbalancer-tls.yaml b/charts/redpanda/redpanda/5.9.2/templates/tests/test-loadbalancer-tls.yaml new file mode 100644 index 0000000000..4db3523d2b --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/tests/test-loadbalancer-tls.yaml @@ -0,0 +1,173 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */}} +{{- if and .Values.tests.enabled .Values.tls.enabled ( eq .Values.external.type "LoadBalancer" ) -}} + {{- $values := .Values }} +apiVersion: v1 +kind: Pod +metadata: + name: {{ include "redpanda.fullname" . }}-test-loadbalancer-tls + namespace: {{ .Release.Namespace | quote }} + labels: + {{- with include "full.labels" . }} + {{- . | nindent 4 }} + {{- end }} + annotations: + "helm.sh/hook": test + "helm.sh/hook-delete-policy": before-hook-creation +spec: + serviceAccountName: test-loadbalancer-tls-redpanda + restartPolicy: Never + securityContext: {{ include "pod-security-context" . | nindent 4 }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: {{- toYaml . | nindent 4 }} + {{- end }} + containers: + - name: {{ template "redpanda.name" . }} + image: mintel/docker-alpine-bash-curl-jq:latest + command: + - bash + - -c + - | + set -x + export APISERVER=https://kubernetes.default.svc + export SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount + export NAMESPACE=$(cat ${SERVICEACCOUNT}/namespace) + export TOKEN=$(cat ${SERVICEACCOUNT}/token) + export CACERT=${SERVICEACCOUNT}/ca.crt + + ip_list="" + + replicas={{ .Values.statefulset.replicas }} + if [ "${replicas}" -lt "1" ]; then + echo "replicas cannot be less than 1" + exit 1 + fi + + range=$(expr $replicas - 1) + ordinal_list=$(seq 0 $range) + + set -e + + for i in $ordinal_list + do + POD_DESC=$(curl --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" \ + -X GET ${APISERVER}/api/v1/namespaces/{{ .Release.Namespace }}/services/lb-{{ template "redpanda.fullname" . }}-$i) + ip=$(echo $POD_DESC | jq -r .status.loadBalancer.ingress[0].ip ) + ip_list="$ip $ip_list" + done + + echo test will be run against $ip_list + echo testing LoadBalancer connectivity + + {{- range $name, $cert := $values.tls.certs }} + {{- if $cert.secretRef }} + {{- if eq $cert.secretRef.name "external-tls-secret" }} + echo "---> testing external tls" + + {{- if eq $values.listeners.kafka.external.default.tls.cert $name }} + echo "-----> testing external tls: kafka api" + {{- $port := ( first $values.listeners.kafka.external.default.advertisedPorts ) }} + + for ip in $ip_list + do + openssl s_client -verify_return_error -prexit \ + {{- if $cert.caEnabled -}} + -CAfile {{ printf "/etc/tls/certs/%s" $name }}/ca.crt \ + {{- end -}} + -key {{ printf "/etc/tls/certs/%s" $name }}/tls.key -connect $ip:{{ $port }} + done + {{- end }} + + {{- if (include "redpanda-22-2-x-without-sasl" $ | fromJson).bool }} + {{- if eq $values.listeners.schemaRegistry.external.default.tls.cert $name }} + echo "-----> testing external tls: schema registry" + {{- $port := ( first $values.listeners.schemaRegistry.external.default.advertisedPorts ) }} + for ip in $ip_list + do + openssl s_client -verify_return_error -prexit \ + {{- if $cert.caEnabled -}} + -CAfile {{ printf "/etc/tls/certs/%s" $name }}/ca.crt \ + {{- end -}} + -key {{ printf "/etc/tls/certs/%s" $name }}/tls.key -connect $ip:{{ $port }} + done + {{- end }} + + {{- if eq $values.listeners.http.external.default.tls.cert $name }} + echo "-----> testing external tls: http api" + {{- $port := ( first $values.listeners.http.external.default.advertisedPorts ) }} + for ip in $ip_list + do + openssl s_client -verify_return_error -prexit \ + {{- if $cert.caEnabled -}} + -CAfile {{ printf "/etc/tls/certs/%s" $name }}/ca.crt \ + {{- end -}} + -key {{ printf "/etc/tls/certs/%s" $name }}/tls.key -connect $ip:{{ $port }} + done + {{- end }} + {{- end }} + + {{- end }} + {{- end }} + {{- end }} + volumeMounts: {{ include "default-mounts" . | nindent 8 }} + securityContext: {{ include "container-security-context" . | nindent 8 }} + volumes: {{ include "default-volumes" . | nindent 4 }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: test-loadbalancer-tls-redpanda + annotations: + helm.sh/hook-weight: "-100" + helm.sh/hook: test + helm.sh/hook-delete-policy: before-hook-creation +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: test-loadbalancer-tls-redpanda + annotations: + helm.sh/hook-weight: "-100" + helm.sh/hook: test + helm.sh/hook-delete-policy: before-hook-creation +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: test-loadbalancer-tls-redpanda +subjects: + - kind: ServiceAccount + name: test-loadbalancer-tls-redpanda + namespace: {{ .Release.Namespace }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: test-loadbalancer-tls-redpanda + annotations: + helm.sh/hook-weight: "-100" + helm.sh/hook: test + helm.sh/hook-delete-policy: before-hook-creation +rules: + - apiGroups: + - "" + resources: + - pods + - services + verbs: + - get + +{{- end -}} diff --git a/charts/redpanda/redpanda/5.9.2/templates/tests/test-nodeport-tls.yaml b/charts/redpanda/redpanda/5.9.2/templates/tests/test-nodeport-tls.yaml new file mode 100644 index 0000000000..4310eaf3a9 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/tests/test-nodeport-tls.yaml @@ -0,0 +1,173 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */}} +{{- if and .Values.tests.enabled .Values.tls.enabled ( eq .Values.external.type "NodePort" ) -}} + {{- $values := .Values }} +apiVersion: v1 +kind: Pod +metadata: + name: {{ include "redpanda.fullname" . }}-test-nodeport-tls + namespace: {{ .Release.Namespace | quote }} + labels: + {{- with include "full.labels" . }} + {{- . | nindent 4 }} + {{- end }} + annotations: + helm.sh/hook: test + helm.sh/hook-delete-policy: before-hook-creation +spec: + serviceAccountName: test-nodeport-tls-redpanda-no-a-test + restartPolicy: Never + securityContext: {{ include "pod-security-context" . | nindent 4 }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: {{- toYaml . | nindent 4 }} + {{- end }} + containers: + - name: {{ template "redpanda.name" . }} + image: mintel/docker-alpine-bash-curl-jq:latest + command: + - bash + - -c + - | + set -x + export APISERVER=https://kubernetes.default.svc + export SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount + export NAMESPACE=$(cat ${SERVICEACCOUNT}/namespace) + export TOKEN=$(cat ${SERVICEACCOUNT}/token) + export CACERT=${SERVICEACCOUNT}/ca.crt + + ip_list="" + + replicas={{ .Values.statefulset.replicas }} + if [ "${replicas}" -lt "1" ]; then + echo "replicas cannot be less than 1" + exit 1 + fi + + range=$(expr $replicas - 1) + ordinal_list=$(seq 0 $range) + + set -e + + for i in $ordinal_list + do + POD_DESC=$(curl --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" \ + -X GET ${APISERVER}/api/v1/namespaces/{{ .Release.Namespace }}/pods/{{ template "redpanda.fullname" . }}-$i) + ip=$(echo $POD_DESC | jq -r .status.hostIP ) + ip_list="$ip $ip_list" + done + + echo test will be run against $ip_list + echo testing NodePort connectivity + {{- range $name, $cert := $values.tls.certs }} + {{- if $cert.secretRef }} + {{- if eq $cert.secretRef.name "external-tls-secret" }} + echo "---> testing external tls" + + {{- if eq $values.listeners.kafka.external.default.tls.cert $name }} + echo "-----> testing external tls: kafka api" + {{- $port := ( first $values.listeners.kafka.external.default.advertisedPorts ) }} + for ip in $ip_list + do + openssl s_client -verify_return_error -prexit \ + {{- if $cert.caEnabled }} + -CAfile {{ printf "/etc/tls/certs/%s" $name }}/ca.crt \ + {{- end }} + -key {{ printf "/etc/tls/certs/%s" $name }}/tls.key \ + -connect ${ip}:{{ $port }} + done + {{- end }} + + {{- if (include "redpanda-22-2-x-without-sasl" $ | fromJson).bool }} + {{- if eq $values.listeners.schemaRegistry.external.default.tls.cert $name }} + echo "-----> testing external tls: schema registry" + {{- $port := ( first $values.listeners.schemaRegistry.external.default.advertisedPorts ) }} + for ip in $ip_list + do + openssl s_client -verify_return_error -prexit \ + {{- if $cert.caEnabled }} + -CAfile {{ printf "/etc/tls/certs/%s" $name }}/ca.crt \ + {{- end }} + -key {{ printf "/etc/tls/certs/%s" $name }}/tls.key \ + -connect ${ip}:{{ $port }} + done + {{- end }} + + {{- if eq $values.listeners.http.external.default.tls.cert $name }} + echo "-----> testing external tls: http api" + {{- $port := ( first $values.listeners.http.external.default.advertisedPorts ) }} + for ip in $ip_list + do + openssl s_client -verify_return_error -prexit \ + {{- if $cert.caEnabled }} + -CAfile {{ printf "/etc/tls/certs/%s" $name }}/ca.crt \ + {{- end }} + -key {{ printf "/etc/tls/certs/%s" $name }}/tls.key \ + -connect ${ip}:{{ $port }} + done + {{- end }} + {{- end }} + + {{- end }} + {{- end }} + {{- end }} + volumeMounts: {{ include "default-mounts" . | nindent 8 }} + securityContext: {{ include "container-security-context" . | nindent 8 }} + volumes: {{ include "default-volumes" . | nindent 4 }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: test-nodeport-tls-redpanda-no-a-test + annotations: + helm.sh/hook: test + helm.sh/hook-delete-policy: before-hook-creation + helm.sh/hook-weight: "-100" +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: test-nodeport-tls-redpanda-no-a-test + annotations: + helm.sh/hook: test + helm.sh/hook-delete-policy: before-hook-creation + helm.sh/hook-weight: "-100" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: test-nodeport-tls-redpanda-no-a-test +subjects: + - kind: ServiceAccount + name: test-nodeport-tls-redpanda-no-a-test + namespace: {{ .Release.Namespace }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: test-nodeport-tls-redpanda-no-a-test + annotations: + helm.sh/hook: test + helm.sh/hook-delete-policy: before-hook-creation + helm.sh/hook-weight: "-100" +rules: + - apiGroups: + - "" + resources: + - pods + - services + verbs: + - get +{{- end -}} diff --git a/charts/redpanda/redpanda/5.9.2/templates/tests/test-pandaproxy-internal-tls-status.yaml b/charts/redpanda/redpanda/5.9.2/templates/tests/test-pandaproxy-internal-tls-status.yaml new file mode 100644 index 0000000000..4cb6aaa0f6 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/tests/test-pandaproxy-internal-tls-status.yaml @@ -0,0 +1,81 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/}} +{{- if and .Values.tests.enabled (include "http-internal-tls-enabled" . | fromJson).bool .Values.listeners.http.enabled (include "redpanda-22-2-x-without-sasl" . | fromJson).bool -}} + {{- $service := .Values.listeners.http -}} + {{- $cert := get .Values.tls.certs $service.tls.cert -}} + {{- $sasl := .Values.auth.sasl }} +apiVersion: v1 +kind: Pod +metadata: + name: {{ include "redpanda.fullname" . }}-test-pandaproxy-internal-tls-status + namespace: {{ .Release.Namespace | quote }} + labels: + {{- with include "full.labels" . }} + {{- . | nindent 4 }} + {{- end }} + annotations: + "helm.sh/hook": test + "helm.sh/hook-delete-policy": before-hook-creation +spec: + restartPolicy: Never + securityContext: {{ include "pod-security-context" . | nindent 4 }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: {{- toYaml . | nindent 4 }} + {{- end }} + containers: + - name: {{ template "redpanda.name" . }} + image: {{ .Values.image.repository }}:{{ template "redpanda.tag" . }} + command: [ "/bin/bash", "-c" ] + args: + - | + {{- if .Values.auth.sasl.enabled }} + old_setting=${-//[^x]/} + set +x + IFS=":" read -r {{ include "rpk-sasl-environment-variables" . }} < <(grep "" $(find /etc/secrets/users/* -print)) + {{- if (include "redpanda-atleast-23-2-1" . | fromJson).bool }} + RPK_SASL_MECHANISM=${RPK_SASL_MECHANISM:-{{ .Values.auth.sasl.mechanism | upper }}} + {{- else }} + REDPANDA_SASL_MECHANISM=${REDPANDA_SASL_MECHANISM:-{{ .Values.auth.sasl.mechanism | upper }}} + {{- end }} + export {{ include "rpk-sasl-environment-variables" . }} + RPK_USER="${RPK_USER:-${REDPANDA_SASL_USERNAME}}" + RPK_PASS="${RPK_PASS:-${REDPANDA_SASL_PASSWORD}}" + if [[ -n "$old_setting" ]]; then set -x; fi + {{- end }} + + curl -svm3 --fail --retry "120" --retry-max-time "120" --retry-all-errors --ssl-reqd \ + {{- if or (include "sasl-enabled" .|fromJson).bool .Values.listeners.http.authenticationMethod }} + -u ${RPK_USER}:${RPK_PASS} \ + {{- end }} + {{- if $cert.caEnabled }} + --cacert /etc/tls/certs/{{ $service.tls.cert }}/ca.crt \ + {{- end }} + https://{{ include "redpanda.internal.domain" . }}:{{ .Values.listeners.http.port }}/brokers + + curl -svm3 --fail --retry "120" --retry-max-time "120" --retry-all-errors --ssl-reqd \ + {{- if or (include "sasl-enabled" .|fromJson).bool .Values.listeners.http.authenticationMethod }} + -u ${RPK_USER}:${RPK_PASS} \ + {{- end }} + {{- if $cert.caEnabled }} + --cacert /etc/tls/certs/{{ $service.tls.cert }}/ca.crt \ + {{- end }} + https://{{ include "redpanda.internal.domain" . }}:{{ .Values.listeners.http.port }}/topics + volumeMounts: {{ include "default-mounts" . | nindent 8 }} + resources: {{ toYaml .Values.statefulset.resources | nindent 12 }} + securityContext: {{ include "container-security-context" . | nindent 8 }} + volumes: {{ include "default-volumes" . | nindent 4 }} +{{- end -}} diff --git a/charts/redpanda/redpanda/5.9.2/templates/tests/test-pandaproxy-status.yaml b/charts/redpanda/redpanda/5.9.2/templates/tests/test-pandaproxy-status.yaml new file mode 100644 index 0000000000..4f5ee6bb71 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/tests/test-pandaproxy-status.yaml @@ -0,0 +1,72 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/}} +{{- if and .Values.tests.enabled (not (include "http-internal-tls-enabled" . | fromJson).bool) .Values.listeners.http.enabled (include "redpanda-22-2-x-without-sasl" . | fromJson).bool -}} + {{- $sasl := .Values.auth.sasl }} +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "redpanda.fullname" . }}-test-pandaproxy-status" + namespace: {{ .Release.Namespace | quote }} + labels: + {{- with include "full.labels" . }} + {{- . | nindent 4 }} + {{- end }} + annotations: + "helm.sh/hook": test + "helm.sh/hook-delete-policy": before-hook-creation +spec: + restartPolicy: Never + securityContext: {{ include "pod-security-context" . | nindent 4 }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: {{- toYaml . | nindent 4 }} + {{- end }} + containers: + - name: {{ template "redpanda.name" . }} + image: {{ .Values.image.repository }}:{{ template "redpanda.tag" . }} + command: [ "/bin/bash", "-c" ] + args: + - | + {{- if .Values.auth.sasl.enabled }} + old_setting=${-//[^x]/} + set +x + IFS=: read -r {{ include "rpk-sasl-environment-variables" . }} < <(grep "" $(find /etc/secrets/users/* -print)) + {{- if (include "redpanda-atleast-23-2-1" . | fromJson).bool }} + RPK_SASL_MECHANISM=${RPK_SASL_MECHANISM:-{{ .Values.auth.sasl.mechanism | upper }}} + {{- else }} + REDPANDA_SASL_MECHANISM=${REDPANDA_SASL_MECHANISM:-{{ .Values.auth.sasl.mechanism | upper }}} + {{- end }} + export {{ include "rpk-sasl-environment-variables" . }} + RPK_USER="${RPK_USER:-${REDPANDA_SASL_USERNAME}}" + RPK_PASS="${RPK_PASS:-${REDPANDA_SASL_PASSWORD}}" + if [[ -n "$old_setting" ]]; then set -x; fi + {{- end }} + + curl {{ template "curl-options" . }} \ + {{- if or (include "sasl-enabled" .|fromJson).bool .Values.listeners.http.authenticationMethod }} + -u ${RPK_USER}:${RPK_PASS} \ + {{- end }} + http://{{ include "redpanda.servicename" . }}:{{ .Values.listeners.http.port }}/brokers + + curl {{ template "curl-options" . }} \ + {{- if or (include "sasl-enabled" .|fromJson).bool .Values.listeners.http.authenticationMethod }} + -u ${RPK_USER}:${RPK_PASS} \ + {{- end }} + http://{{ include "redpanda.servicename" . }}:{{ .Values.listeners.http.port }}/topics + volumeMounts: {{ include "default-mounts" . | nindent 8 }} + securityContext: {{ include "container-security-context" . | nindent 8 }} + volumes: {{ include "default-volumes" . | nindent 4 }} +{{- end }} diff --git a/charts/redpanda/redpanda/5.9.2/templates/tests/test-prometheus-targets.yaml b/charts/redpanda/redpanda/5.9.2/templates/tests/test-prometheus-targets.yaml new file mode 100644 index 0000000000..81f83a34e2 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/tests/test-prometheus-targets.yaml @@ -0,0 +1,84 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */}} + +{{- if and .Values.tests.enabled .Values.monitoring.enabled }} +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "redpanda.fullname" . }}-test-prometheus-targets" + namespace: {{ .Release.Namespace | quote }} + labels: + {{- with include "full.labels" . }} + {{- . | nindent 4 }} + {{- end }} + annotations: + "helm.sh/hook": test + "helm.sh/hook-delete-policy": before-hook-creation +spec: + restartPolicy: Never + securityContext: {{ include "pod-security-context" . | nindent 4 }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: {{- toYaml . | nindent 4 }} + {{- end }} + containers: + - name: {{ template "redpanda.name" . }} + image: registry.gitlab.com/gitlab-ci-utils/curl-jq:latest + command: [ "/bin/bash", "-c" ] + args: + - | + set -xe + + HEALTHY=$( curl {{ template "curl-options" . }} http://prometheus-operated.prometheus.svc.cluster.local:9090/-/healthy) + if [ $HEALTHY != 200 ]; then + echo "prometheus is not healthy, exiting" + exit 1 + fi + + echo "prometheus is healthy, checking if ready..." + + READY=$( curl {{ template "curl-options" . }} http://prometheus-operated.prometheus.svc.cluster.local:9090/-/ready) + if [ $READY != 200 ]; then + echo "prometheus is not ready, exiting" + exit 1 + fi + + echo "prometheus is ready, requesting target information..." + + + curl_prometheus() { + + # Run the command, and save the exit code + # from: https://prometheus.io/docs/prometheus/latest/querying/api/ + local RESULT=$( curl {{ template "curl-options" . }} http://prometheus-operated.prometheus.svc.cluster.local:9090/api/v1/targets?scrapePool=serviceMonitor/{{ .Release.Namespace }}/{{ include "redpanda.fullname" . }}/0 | jq '.data.activeTargets[].health | select(. == "up")' | wc -l ) + + echo $RESULT + } + for d in $(seq 1 30); do + RESULT=$(curl_prometheus) + if [ $RESULT == {{ .Values.statefulset.replicas }} ]; then + break + fi + sleep 15 + done + + set +x + if [ $RESULT != {{ .Values.statefulset.replicas }} ]; then + curl --fail http://prometheus-operated.prometheus.svc.cluster.local:9090/api/v1/targets?scrapePool=serviceMonitor/{{ .Release.Namespace }}/{{ include "redpanda.fullname" . }}/0 | jq . + echo "the number of targets unexpected; got ${RESULT} targets 'up', but was expecting {{ .Values.statefulset.replicas }}" + exit 1 + fi +{{- end }} diff --git a/charts/redpanda/redpanda/5.9.2/templates/tests/test-rack-awareness.yaml b/charts/redpanda/redpanda/5.9.2/templates/tests/test-rack-awareness.yaml new file mode 100644 index 0000000000..82a31937f5 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/tests/test-rack-awareness.yaml @@ -0,0 +1,61 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/}} +{{- if .Values.tests.enabled }} +apiVersion: v1 +kind: Pod +metadata: + name: {{ include "redpanda.fullname" . }}-test-rack-awareness + namespace: {{ .Release.Namespace | quote }} +{{- with include "full.labels" . }} + labels: {{- . | nindent 4 }} +{{- end }} + annotations: + "helm.sh/hook": test + "helm.sh/hook-delete-policy": before-hook-creation +spec: + restartPolicy: Never + securityContext: {{ include "pod-security-context" . | nindent 4 }} +{{- with .Values.imagePullSecrets }} + imagePullSecrets: {{- toYaml . | nindent 4 }} +{{- end }} + containers: + - name: {{ template "redpanda.name" . }} + image: {{ .Values.image.repository }}:{{ template "redpanda.tag" . }} + command: + - /bin/bash + - -c + - | + set -e +{{- if and .Values.rackAwareness.enabled (include "redpanda-atleast-22-3-0" . | fromJson).bool }} + curl {{ template "curl-options" . }} \ + {{- if (include "tls-enabled" . | fromJson).bool }} + {{- if (dig "default" "caEnabled" false .Values.tls.certs) }} + --cacert "/etc/tls/certs/default/ca.crt" \ + {{- end }} + https://{{ include "redpanda.internal.domain" . }}:{{ .Values.listeners.admin.port }}/v1/node_config | grep '"rack":"rack[1-4]"' + {{- else }} + http://{{ include "redpanda.internal.domain" . }}:{{ .Values.listeners.admin.port }}/v1/node_config | grep '"rack":"rack[1-4]"' + {{- end }} +{{- end }} + + rpk redpanda admin config print --host {{ include "redpanda.internal.domain" . }}:{{ .Values.listeners.admin.port }} | grep '"enable_rack_awareness": {{ .Values.rackAwareness.enabled }}' + + rpk cluster config get enable_rack_awareness + volumeMounts: {{ include "default-mounts" . | nindent 8 }} + securityContext: {{ include "container-security-context" . | nindent 8 }} + volumes: {{ include "default-volumes" . | nindent 4 }} +{{- end }} \ No newline at end of file diff --git a/charts/redpanda/redpanda/5.9.2/templates/tests/test-rpk-debug-bundle.yaml b/charts/redpanda/redpanda/5.9.2/templates/tests/test-rpk-debug-bundle.yaml new file mode 100644 index 0000000000..3230f08817 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/tests/test-rpk-debug-bundle.yaml @@ -0,0 +1,104 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You 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. +*/}} + +{{/* + +This test currently fails because of a bug where when multiple containers exist +The api returns an error. We should be requesting logs from each container. + + +{{- if and .Values.tests.enabled .Values.rbac.enabled (include "redpanda-atleast-23-1-1" .|fromJson).bool -}} + {{- $sasl := .Values.auth.sasl }} + {{- $useSaslSecret := and $sasl.enabled (not (empty $sasl.secretRef )) }} + + +apiVersion: v1 +kind: Pod +metadata: + name: {{ include "redpanda.fullname" . }}-test-rpk-debug-bundle + namespace: {{ .Release.Namespace | quote }} + labels: +{{- with include "full.labels" . }} + {{- . | nindent 4 }} +{{- end }} + annotations: + "helm.sh/hook": test + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +spec: + restartPolicy: Never + securityContext: {{ include "pod-security-context" . | nindent 4 }} + affinity: + podAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + statefulset.kubernetes.io/pod-name: {{ include "redpanda.fullname" . }}-0 + topologyKey: kubernetes.io/hostname + {{- with .Values.imagePullSecrets }} + imagePullSecrets: {{- toYaml . | nindent 4 }} + {{- end }} + initContainers: + - name: {{ template "redpanda.name" . }} + image: {{ .Values.image.repository}}:{{ template "redpanda.tag" . }} + volumeMounts: {{ include "default-mounts" . | nindent 8 }} + - name: shared-data + mountPath: /usr/share/redpanda/test + - name: datadir + mountPath: /var/lib/redpanda/data + command: + - /bin/bash + - -c + - | + set -e + {{- if .Values.auth.sasl.enabled }} + old_setting=${-//[^x]/} + set +x + IFS=: read -r {{ include "rpk-sasl-environment-variables" . }} < <(grep "" $(find /etc/secrets/users/* -print)) + {{- if (include "redpanda-atleast-23-2-1" . | fromJson).bool }} + RPK_SASL_MECHANISM=${RPK_SASL_MECHANISM:-{{ .Values.auth.sasl.mechanism | upper }}} + {{- else }} + REDPANDA_SASL_MECHANISM=${REDPANDA_SASL_MECHANISM:-{{ .Values.auth.sasl.mechanism | upper }}} + {{- end }} + export {{ include "rpk-sasl-environment-variables" . }} + if [[ -n "$old_setting" ]]; then set -x; fi + {{- end }} + rpk debug bundle -o /usr/share/redpanda/test/debug-test.zip -n {{ .Release.Namespace }} + containers: + - name: {{ template "redpanda.name" . }}-tester + image: busybox:latest + volumeMounts: {{ include "default-mounts" . | nindent 8 }} + - name: shared-data + mountPath: /test + command: + - /bin/ash + - -c + - | + set -e + unzip /test/debug-test.zip -d /tmp/bundle + + test -f /tmp/bundle/logs/{{ .Release.Namespace }}-0.txt + test -f /tmp/bundle/logs/{{ .Release.Namespace }}-1.txt + test -f /tmp/bundle/logs/{{ .Release.Namespace }}-2.txt + + test -d /tmp/bundle/controller + + test -f /tmp/bundle/k8s/pods.json + test -f /tmp/bundle/k8s/configmaps.json + securityContext: {{ include "container-security-context" . | nindent 8 }} + volumes: {{ include "default-volumes" . | nindent 4 }} +{{- end -}} +*/}} \ No newline at end of file diff --git a/charts/redpanda/redpanda/5.9.2/templates/tests/test-sasl-updated.yaml b/charts/redpanda/redpanda/5.9.2/templates/tests/test-sasl-updated.yaml new file mode 100644 index 0000000000..5f61be552e --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/templates/tests/test-sasl-updated.yaml @@ -0,0 +1,71 @@ +{{/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/}} + +{{- if and .Values.tests.enabled (include "sasl-enabled" . | fromJson).bool (eq .Values.auth.sasl.secretRef "some-users") -}} +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "redpanda.fullname" . }}-test-update-sasl-users" + namespace: {{ .Release.Namespace | quote }} + labels: +{{- with include "full.labels" . }} + {{- . | nindent 4 }} +{{- end }} + annotations: + "helm.sh/hook": test + "helm.sh/hook-delete-policy": before-hook-creation +spec: + restartPolicy: Never + securityContext: {{ include "pod-security-context" . | nindent 4 }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: {{- toYaml . | nindent 4 }} + {{- end }} + containers: + - name: {{ template "redpanda.name" . }} + image: {{ .Values.image.repository }}:{{ template "redpanda.tag" . }} + command: + - /usr/bin/timeout + - "120" + - bash + - -c + - | + set -e + IFS=: read -r {{ include "rpk-sasl-environment-variables" . }} < <(grep "" $(find /etc/secrets/users/* -print)) + {{- if (include "redpanda-atleast-23-2-1" . | fromJson).bool }} + RPK_SASL_MECHANISM=${RPK_SASL_MECHANISM:-{{ .Values.auth.sasl.mechanism | upper }}} + {{- else }} + REDPANDA_SASL_MECHANISM=${REDPANDA_SASL_MECHANISM:-{{ .Values.auth.sasl.mechanism | upper }}} + {{- end }} + export {{ include "rpk-sasl-environment-variables" . }} + + set -x + + # check that the users list did update + ready_result_exit_code=1 + while [[ ${ready_result_exit_code} -ne 0 ]]; do + ready_result=$(rpk acl user list | grep anotheranotherme 2>&1) && ready_result_exit_code=$? + sleep 2 + done + + # check that sasl is not broken + {{ include "rpk-cluster-info" $ }} + volumeMounts: {{ include "default-mounts" . | nindent 8 }} + resources: +{{- toYaml .Values.statefulset.resources | nindent 12 }} + securityContext: {{ include "container-security-context" . | nindent 8 }} + volumes: {{ include "default-volumes" . | nindent 4 }} +{{- end }} diff --git a/charts/redpanda/redpanda/5.9.2/values.schema.json b/charts/redpanda/redpanda/5.9.2/values.schema.json new file mode 100644 index 0000000000..d22adcc2bc --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/values.schema.json @@ -0,0 +1,5494 @@ +{ + "$id": "https://github.com/redpanda-data/helm-charts/charts/redpanda/values", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "DO NOT EDIT!. This file was generated by ./cmd/genschema/genschema.go", + "properties": { + "affinity": { + "properties": { + "nodeAffinity": { + "properties": { + "preferredDuringSchedulingIgnoredDuringExecution": { + "items": { + "properties": { + "preference": { + "properties": { + "matchExpressions": { + "items": { + "properties": { + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + }, + "matchFields": { + "items": { + "properties": { + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, + "weight": { + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" + }, + "requiredDuringSchedulingIgnoredDuringExecution": { + "properties": { + "nodeSelectorTerms": { + "items": { + "properties": { + "matchExpressions": { + "items": { + "properties": { + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + }, + "matchFields": { + "items": { + "properties": { + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "podAffinity": { + "properties": { + "preferredDuringSchedulingIgnoredDuringExecution": { + "items": { + "properties": { + "podAffinityTerm": { + "properties": { + "labelSelector": { + "properties": { + "matchExpressions": { + "items": { + "properties": { + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + }, + "matchLabels": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + }, + "type": "object" + }, + "matchLabelKeys": { + "items": { + "type": "string" + }, + "type": "array" + }, + "mismatchLabelKeys": { + "items": { + "type": "string" + }, + "type": "array" + }, + "namespaceSelector": { + "properties": { + "matchExpressions": { + "items": { + "properties": { + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + }, + "matchLabels": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + }, + "type": "object" + }, + "namespaces": { + "items": { + "type": "string" + }, + "type": "array" + }, + "topologyKey": { + "type": "string" + } + }, + "type": "object" + }, + "weight": { + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" + }, + "requiredDuringSchedulingIgnoredDuringExecution": { + "items": { + "properties": { + "labelSelector": { + "properties": { + "matchExpressions": { + "items": { + "properties": { + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + }, + "matchLabels": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + }, + "type": "object" + }, + "matchLabelKeys": { + "items": { + "type": "string" + }, + "type": "array" + }, + "mismatchLabelKeys": { + "items": { + "type": "string" + }, + "type": "array" + }, + "namespaceSelector": { + "properties": { + "matchExpressions": { + "items": { + "properties": { + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + }, + "matchLabels": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + }, + "type": "object" + }, + "namespaces": { + "items": { + "type": "string" + }, + "type": "array" + }, + "topologyKey": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, + "podAntiAffinity": { + "properties": { + "preferredDuringSchedulingIgnoredDuringExecution": { + "items": { + "properties": { + "podAffinityTerm": { + "properties": { + "labelSelector": { + "properties": { + "matchExpressions": { + "items": { + "properties": { + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + }, + "matchLabels": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + }, + "type": "object" + }, + "matchLabelKeys": { + "items": { + "type": "string" + }, + "type": "array" + }, + "mismatchLabelKeys": { + "items": { + "type": "string" + }, + "type": "array" + }, + "namespaceSelector": { + "properties": { + "matchExpressions": { + "items": { + "properties": { + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + }, + "matchLabels": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + }, + "type": "object" + }, + "namespaces": { + "items": { + "type": "string" + }, + "type": "array" + }, + "topologyKey": { + "type": "string" + } + }, + "type": "object" + }, + "weight": { + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" + }, + "requiredDuringSchedulingIgnoredDuringExecution": { + "items": { + "properties": { + "labelSelector": { + "properties": { + "matchExpressions": { + "items": { + "properties": { + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + }, + "matchLabels": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + }, + "type": "object" + }, + "matchLabelKeys": { + "items": { + "type": "string" + }, + "type": "array" + }, + "mismatchLabelKeys": { + "items": { + "type": "string" + }, + "type": "array" + }, + "namespaceSelector": { + "properties": { + "matchExpressions": { + "items": { + "properties": { + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + }, + "matchLabels": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + }, + "type": "object" + }, + "namespaces": { + "items": { + "type": "string" + }, + "type": "array" + }, + "topologyKey": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "auditLogging": { + "properties": { + "clientMaxBufferSize": { + "type": "integer" + }, + "enabled": { + "type": "boolean" + }, + "enabledEventTypes": { + "oneOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ] + }, + "excludedPrincipals": { + "oneOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ] + }, + "excludedTopics": { + "oneOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ] + }, + "listener": { + "type": "string" + }, + "partitions": { + "type": "integer" + }, + "queueDrainIntervalMs": { + "type": "integer" + }, + "queueMaxBufferSizePerShard": { + "type": "integer" + }, + "replicationFactor": { + "oneOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + }, + "auth": { + "properties": { + "sasl": { + "properties": { + "enabled": { + "type": "boolean" + }, + "mechanism": { + "type": "string" + }, + "secretRef": { + "type": "string" + }, + "users": { + "items": { + "properties": { + "mechanism": { + "pattern": "^(SCRAM-SHA-512|SCRAM-SHA-256)$", + "type": "string" + }, + "name": { + "type": "string" + }, + "password": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "enabled" + ], + "type": "object" + } + }, + "required": [ + "sasl" + ], + "type": "object" + }, + "clusterDomain": { + "type": "string" + }, + "commonLabels": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "config": { + "properties": { + "cluster": { + "type": "object" + }, + "node": { + "type": "object" + }, + "pandaproxy_client": { + "properties": { + "consumer_heartbeat_interval_ms": { + "type": "integer" + }, + "consumer_rebalance_timeout_ms": { + "type": "integer" + }, + "consumer_request_max_bytes": { + "type": "integer" + }, + "consumer_request_timeout_ms": { + "type": "integer" + }, + "consumer_session_timeout_ms": { + "type": "integer" + }, + "produce_batch_delay_ms": { + "type": "integer" + }, + "produce_batch_record_count": { + "type": "integer" + }, + "produce_batch_size_bytes": { + "type": "integer" + }, + "retries": { + "type": "integer" + }, + "retry_base_backoff_ms": { + "type": "integer" + } + }, + "type": "object" + }, + "rpk": { + "type": "object" + }, + "schema_registry_client": { + "properties": { + "consumer_heartbeat_interval_ms": { + "type": "integer" + }, + "consumer_rebalance_timeout_ms": { + "type": "integer" + }, + "consumer_request_max_bytes": { + "type": "integer" + }, + "consumer_request_timeout_ms": { + "type": "integer" + }, + "consumer_session_timeout_ms": { + "type": "integer" + }, + "produce_batch_delay_ms": { + "type": "integer" + }, + "produce_batch_record_count": { + "type": "integer" + }, + "produce_batch_size_bytes": { + "type": "integer" + }, + "retries": { + "type": "integer" + }, + "retry_base_backoff_ms": { + "type": "integer" + } + }, + "type": "object" + }, + "tunable": { + "additionalProperties": true, + "properties": { + "group_initial_rebalance_delay": { + "type": "integer" + }, + "log_retention_ms": { + "type": "integer" + } + }, + "type": "object" + } + }, + "required": [ + "cluster", + "node", + "tunable" + ], + "type": "object" + }, + "connectors": { + "properties": { + "connectors": { + "properties": { + "fullnameOverwrite": { + "type": "string" + }, + "restPort": { + "type": "integer" + } + }, + "type": "object" + }, + "enabled": { + "type": "boolean" + } + }, + "type": "object" + }, + "console": { + "properties": { + "console": { + "properties": { + "config": { + "type": "object" + } + }, + "type": "object" + }, + "enabled": { + "type": "boolean" + } + }, + "type": "object" + }, + "enterprise": { + "properties": { + "license": { + "type": "string" + }, + "licenseSecretRef": { + "properties": { + "key": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "external": { + "properties": { + "addresses": { + "items": { + "type": "string" + }, + "type": "array" + }, + "annotations": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "domain": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "externalDns": { + "properties": { + "enabled": { + "type": "boolean" + } + }, + "required": [ + "enabled" + ], + "type": "object" + }, + "prefixTemplate": { + "type": "string" + }, + "service": { + "properties": { + "enabled": { + "type": "boolean" + } + }, + "required": [ + "enabled" + ], + "type": "object" + }, + "sourceRanges": { + "items": { + "type": "string" + }, + "type": "array" + }, + "type": { + "pattern": "^(LoadBalancer|NodePort)$", + "type": "string" + } + }, + "required": [ + "enabled" + ], + "type": "object" + }, + "force": { + "type": "boolean" + }, + "fullnameOverride": { + "type": "string" + }, + "image": { + "description": "Values used to define the container image to be used for Redpanda", + "properties": { + "pullPolicy": { + "description": "The Kubernetes Pod image pull policy.", + "pattern": "^(Always|Never|IfNotPresent)$", + "type": "string" + }, + "repository": { + "default": "docker.redpanda.com/redpandadata/redpanda", + "description": "container image repository", + "type": "string" + }, + "tag": { + "default": "Chart.appVersion", + "description": "The container image tag. Use the Redpanda release version. Must be a valid semver prefixed with a 'v'.", + "pattern": "^v(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$|^$", + "type": "string" + } + }, + "required": [ + "repository", + "pullPolicy" + ], + "type": "object" + }, + "imagePullSecrets": { + "items": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "license_key": { + "deprecated": true, + "pattern": "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?\\.(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$|^$", + "type": "string" + }, + "license_secret_ref": { + "deprecated": true, + "properties": { + "secret_key": { + "type": "string" + }, + "secret_name": { + "type": "string" + } + }, + "type": "object" + }, + "listeners": { + "properties": { + "admin": { + "properties": { + "appProtocol": { + "type": "string" + }, + "external": { + "minProperties": 1, + "patternProperties": { + "^[A-Za-z_][A-Za-z0-9_]*$": { + "properties": { + "advertisedPorts": { + "items": { + "type": "integer" + }, + "minItems": 1, + "type": "array" + }, + "enabled": { + "type": "boolean" + }, + "nodePort": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "tls": { + "properties": { + "cert": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "requireClientAuth": { + "type": "boolean" + }, + "trustStore": { + "maxProperties": 1, + "minProperties": 1, + "properties": { + "configMapKeyRef": { + "properties": { + "key": { + "type": "string" + }, + "name": { + "type": "string" + }, + "optional": { + "type": "boolean" + } + }, + "type": "object" + }, + "secretKeyRef": { + "properties": { + "key": { + "type": "string" + }, + "name": { + "type": "string" + }, + "optional": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "required": [ + "port" + ], + "type": "object" + } + }, + "type": "object" + }, + "port": { + "type": "integer" + }, + "tls": { + "properties": { + "cert": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "requireClientAuth": { + "type": "boolean" + }, + "trustStore": { + "maxProperties": 1, + "minProperties": 1, + "properties": { + "configMapKeyRef": { + "properties": { + "key": { + "type": "string" + }, + "name": { + "type": "string" + }, + "optional": { + "type": "boolean" + } + }, + "type": "object" + }, + "secretKeyRef": { + "properties": { + "key": { + "type": "string" + }, + "name": { + "type": "string" + }, + "optional": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "required": [ + "cert", + "requireClientAuth" + ], + "type": "object" + } + }, + "required": [ + "port", + "tls" + ], + "type": "object" + }, + "http": { + "properties": { + "authenticationMethod": { + "oneOf": [ + { + "enum": [ + "none", + "http_basic" + ], + "type": "string" + }, + { + "type": "null" + } + ] + }, + "enabled": { + "type": "boolean" + }, + "external": { + "minProperties": 1, + "patternProperties": { + "^[A-Za-z_][A-Za-z0-9_]*$": { + "properties": { + "advertisedPorts": { + "items": { + "type": "integer" + }, + "minItems": 1, + "type": "array" + }, + "authenticationMethod": { + "oneOf": [ + { + "enum": [ + "none", + "http_basic" + ], + "type": "string" + }, + { + "type": "null" + } + ] + }, + "enabled": { + "type": "boolean" + }, + "nodePort": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "prefixTemplate": { + "type": "string" + }, + "tls": { + "properties": { + "cert": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "requireClientAuth": { + "type": "boolean" + }, + "trustStore": { + "maxProperties": 1, + "minProperties": 1, + "properties": { + "configMapKeyRef": { + "properties": { + "key": { + "type": "string" + }, + "name": { + "type": "string" + }, + "optional": { + "type": "boolean" + } + }, + "type": "object" + }, + "secretKeyRef": { + "properties": { + "key": { + "type": "string" + }, + "name": { + "type": "string" + }, + "optional": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "required": [ + "port" + ], + "type": "object" + } + }, + "type": "object" + }, + "kafkaEndpoint": { + "pattern": "^[A-Za-z_-][A-Za-z0-9_-]*$", + "type": "string" + }, + "port": { + "type": "integer" + }, + "tls": { + "properties": { + "cert": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "requireClientAuth": { + "type": "boolean" + }, + "trustStore": { + "maxProperties": 1, + "minProperties": 1, + "properties": { + "configMapKeyRef": { + "properties": { + "key": { + "type": "string" + }, + "name": { + "type": "string" + }, + "optional": { + "type": "boolean" + } + }, + "type": "object" + }, + "secretKeyRef": { + "properties": { + "key": { + "type": "string" + }, + "name": { + "type": "string" + }, + "optional": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "required": [ + "cert", + "requireClientAuth" + ], + "type": "object" + } + }, + "required": [ + "enabled", + "tls", + "kafkaEndpoint", + "port" + ], + "type": "object" + }, + "kafka": { + "properties": { + "authenticationMethod": { + "oneOf": [ + { + "enum": [ + "sasl", + "none", + "mtls_identity" + ], + "type": "string" + }, + { + "type": "null" + } + ] + }, + "external": { + "minProperties": 1, + "patternProperties": { + "^[A-Za-z_][A-Za-z0-9_]*$": { + "properties": { + "advertisedPorts": { + "items": { + "type": "integer" + }, + "minItems": 1, + "type": "array" + }, + "authenticationMethod": { + "oneOf": [ + { + "enum": [ + "sasl", + "none", + "mtls_identity" + ], + "type": "string" + }, + { + "type": "null" + } + ] + }, + "enabled": { + "type": "boolean" + }, + "nodePort": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "prefixTemplate": { + "type": "string" + }, + "tls": { + "properties": { + "cert": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "requireClientAuth": { + "type": "boolean" + }, + "trustStore": { + "maxProperties": 1, + "minProperties": 1, + "properties": { + "configMapKeyRef": { + "properties": { + "key": { + "type": "string" + }, + "name": { + "type": "string" + }, + "optional": { + "type": "boolean" + } + }, + "type": "object" + }, + "secretKeyRef": { + "properties": { + "key": { + "type": "string" + }, + "name": { + "type": "string" + }, + "optional": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "required": [ + "port" + ], + "type": "object" + } + }, + "type": "object" + }, + "port": { + "type": "integer" + }, + "tls": { + "properties": { + "cert": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "requireClientAuth": { + "type": "boolean" + }, + "trustStore": { + "maxProperties": 1, + "minProperties": 1, + "properties": { + "configMapKeyRef": { + "properties": { + "key": { + "type": "string" + }, + "name": { + "type": "string" + }, + "optional": { + "type": "boolean" + } + }, + "type": "object" + }, + "secretKeyRef": { + "properties": { + "key": { + "type": "string" + }, + "name": { + "type": "string" + }, + "optional": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "required": [ + "cert", + "requireClientAuth" + ], + "type": "object" + } + }, + "required": [ + "tls", + "port" + ], + "type": "object" + }, + "rpc": { + "properties": { + "port": { + "type": "integer" + }, + "tls": { + "properties": { + "cert": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "requireClientAuth": { + "type": "boolean" + }, + "trustStore": { + "maxProperties": 1, + "minProperties": 1, + "properties": { + "configMapKeyRef": { + "properties": { + "key": { + "type": "string" + }, + "name": { + "type": "string" + }, + "optional": { + "type": "boolean" + } + }, + "type": "object" + }, + "secretKeyRef": { + "properties": { + "key": { + "type": "string" + }, + "name": { + "type": "string" + }, + "optional": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "required": [ + "cert", + "requireClientAuth" + ], + "type": "object" + } + }, + "required": [ + "port", + "tls" + ], + "type": "object" + }, + "schemaRegistry": { + "properties": { + "authenticationMethod": { + "oneOf": [ + { + "enum": [ + "none", + "http_basic" + ], + "type": "string" + }, + { + "type": "null" + } + ] + }, + "enabled": { + "type": "boolean" + }, + "external": { + "minProperties": 1, + "patternProperties": { + "^[A-Za-z_][A-Za-z0-9_]*$": { + "properties": { + "advertisedPorts": { + "items": { + "type": "integer" + }, + "minItems": 1, + "type": "array" + }, + "authenticationMethod": { + "oneOf": [ + { + "enum": [ + "none", + "http_basic" + ], + "type": "string" + }, + { + "type": "null" + } + ] + }, + "enabled": { + "type": "boolean" + }, + "nodePort": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "tls": { + "properties": { + "cert": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "requireClientAuth": { + "type": "boolean" + }, + "trustStore": { + "maxProperties": 1, + "minProperties": 1, + "properties": { + "configMapKeyRef": { + "properties": { + "key": { + "type": "string" + }, + "name": { + "type": "string" + }, + "optional": { + "type": "boolean" + } + }, + "type": "object" + }, + "secretKeyRef": { + "properties": { + "key": { + "type": "string" + }, + "name": { + "type": "string" + }, + "optional": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "kafkaEndpoint": { + "pattern": "^[A-Za-z_-][A-Za-z0-9_-]*$", + "type": "string" + }, + "port": { + "type": "integer" + }, + "tls": { + "properties": { + "cert": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "requireClientAuth": { + "type": "boolean" + }, + "trustStore": { + "maxProperties": 1, + "minProperties": 1, + "properties": { + "configMapKeyRef": { + "properties": { + "key": { + "type": "string" + }, + "name": { + "type": "string" + }, + "optional": { + "type": "boolean" + } + }, + "type": "object" + }, + "secretKeyRef": { + "properties": { + "key": { + "type": "string" + }, + "name": { + "type": "string" + }, + "optional": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "required": [ + "cert", + "requireClientAuth" + ], + "type": "object" + } + }, + "required": [ + "enabled", + "kafkaEndpoint", + "port", + "tls" + ], + "type": "object" + } + }, + "required": [ + "admin", + "http", + "kafka", + "schemaRegistry", + "rpc" + ], + "type": "object" + }, + "logging": { + "properties": { + "logLevel": { + "pattern": "^(error|warn|info|debug|trace)$", + "type": "string" + }, + "usageStats": { + "properties": { + "clusterId": { + "type": "string" + }, + "enabled": { + "type": "boolean" + } + }, + "required": [ + "enabled" + ], + "type": "object" + } + }, + "required": [ + "logLevel", + "usageStats" + ], + "type": "object" + }, + "monitoring": { + "properties": { + "enableHttp2": { + "type": "boolean" + }, + "enabled": { + "type": "boolean" + }, + "labels": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "scrapeInterval": { + "type": "string" + }, + "tlsConfig": { + "properties": { + "ca": { + "properties": { + "configMap": { + "properties": { + "key": { + "type": "string" + }, + "name": { + "type": "string" + }, + "optional": { + "type": "boolean" + } + }, + "type": "object" + }, + "secret": { + "properties": { + "key": { + "type": "string" + }, + "name": { + "type": "string" + }, + "optional": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "caFile": { + "type": "string" + }, + "cert": { + "properties": { + "configMap": { + "properties": { + "key": { + "type": "string" + }, + "name": { + "type": "string" + }, + "optional": { + "type": "boolean" + } + }, + "type": "object" + }, + "secret": { + "properties": { + "key": { + "type": "string" + }, + "name": { + "type": "string" + }, + "optional": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "certFile": { + "type": "string" + }, + "insecureSkipVerify": { + "type": "boolean" + }, + "keyFile": { + "type": "string" + }, + "keySecret": { + "properties": { + "key": { + "type": "string" + }, + "name": { + "type": "string" + }, + "optional": { + "type": "boolean" + } + }, + "type": "object" + }, + "serverName": { + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "enabled", + "scrapeInterval" + ], + "type": "object" + }, + "nameOverride": { + "type": "string" + }, + "nodeSelector": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "post_install_job": { + "properties": { + "affinity": { + "properties": { + "nodeAffinity": { + "properties": { + "preferredDuringSchedulingIgnoredDuringExecution": { + "items": { + "properties": { + "preference": { + "properties": { + "matchExpressions": { + "items": { + "properties": { + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + }, + "matchFields": { + "items": { + "properties": { + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, + "weight": { + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" + }, + "requiredDuringSchedulingIgnoredDuringExecution": { + "properties": { + "nodeSelectorTerms": { + "items": { + "properties": { + "matchExpressions": { + "items": { + "properties": { + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + }, + "matchFields": { + "items": { + "properties": { + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "podAffinity": { + "properties": { + "preferredDuringSchedulingIgnoredDuringExecution": { + "items": { + "properties": { + "podAffinityTerm": { + "properties": { + "labelSelector": { + "properties": { + "matchExpressions": { + "items": { + "properties": { + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + }, + "matchLabels": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + }, + "type": "object" + }, + "matchLabelKeys": { + "items": { + "type": "string" + }, + "type": "array" + }, + "mismatchLabelKeys": { + "items": { + "type": "string" + }, + "type": "array" + }, + "namespaceSelector": { + "properties": { + "matchExpressions": { + "items": { + "properties": { + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + }, + "matchLabels": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + }, + "type": "object" + }, + "namespaces": { + "items": { + "type": "string" + }, + "type": "array" + }, + "topologyKey": { + "type": "string" + } + }, + "type": "object" + }, + "weight": { + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" + }, + "requiredDuringSchedulingIgnoredDuringExecution": { + "items": { + "properties": { + "labelSelector": { + "properties": { + "matchExpressions": { + "items": { + "properties": { + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + }, + "matchLabels": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + }, + "type": "object" + }, + "matchLabelKeys": { + "items": { + "type": "string" + }, + "type": "array" + }, + "mismatchLabelKeys": { + "items": { + "type": "string" + }, + "type": "array" + }, + "namespaceSelector": { + "properties": { + "matchExpressions": { + "items": { + "properties": { + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + }, + "matchLabels": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + }, + "type": "object" + }, + "namespaces": { + "items": { + "type": "string" + }, + "type": "array" + }, + "topologyKey": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, + "podAntiAffinity": { + "properties": { + "preferredDuringSchedulingIgnoredDuringExecution": { + "items": { + "properties": { + "podAffinityTerm": { + "properties": { + "labelSelector": { + "properties": { + "matchExpressions": { + "items": { + "properties": { + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + }, + "matchLabels": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + }, + "type": "object" + }, + "matchLabelKeys": { + "items": { + "type": "string" + }, + "type": "array" + }, + "mismatchLabelKeys": { + "items": { + "type": "string" + }, + "type": "array" + }, + "namespaceSelector": { + "properties": { + "matchExpressions": { + "items": { + "properties": { + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + }, + "matchLabels": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + }, + "type": "object" + }, + "namespaces": { + "items": { + "type": "string" + }, + "type": "array" + }, + "topologyKey": { + "type": "string" + } + }, + "type": "object" + }, + "weight": { + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" + }, + "requiredDuringSchedulingIgnoredDuringExecution": { + "items": { + "properties": { + "labelSelector": { + "properties": { + "matchExpressions": { + "items": { + "properties": { + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + }, + "matchLabels": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + }, + "type": "object" + }, + "matchLabelKeys": { + "items": { + "type": "string" + }, + "type": "array" + }, + "mismatchLabelKeys": { + "items": { + "type": "string" + }, + "type": "array" + }, + "namespaceSelector": { + "properties": { + "matchExpressions": { + "items": { + "properties": { + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + }, + "matchLabels": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + }, + "type": "object" + }, + "namespaces": { + "items": { + "type": "string" + }, + "type": "array" + }, + "topologyKey": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "annotations": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "labels": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "podTemplate": { + "properties": { + "annotations": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "labels": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "spec": { + "properties": { + "containers": { + "items": { + "properties": { + "env": { + "items": { + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + }, + "valueFrom": { + "properties": { + "configMapKeyRef": { + "properties": { + "key": { + "type": "string" + }, + "name": { + "type": "string" + }, + "optional": { + "type": "boolean" + } + }, + "type": "object" + }, + "fieldRef": { + "properties": { + "apiVersion": { + "type": "string" + }, + "fieldPath": { + "type": "string" + } + }, + "type": "object" + }, + "resourceFieldRef": { + "properties": { + "containerName": { + "type": "string" + }, + "divisor": { + "oneOf": [ + { + "type": "integer" + }, + { + "pattern": "^[0-9]+(\\.[0-9]){0,1}(m|k|M|G|T|P|Ki|Mi|Gi|Ti|Pi)?$", + "type": "string" + } + ] + }, + "resource": { + "type": "string" + } + }, + "type": "object" + }, + "secretKeyRef": { + "properties": { + "key": { + "type": "string" + }, + "name": { + "type": "string" + }, + "optional": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "type": "array" + }, + "name": { + "enum": [ + "redpanda", + "post-install", + "post-upgrade" + ], + "type": "string" + }, + "securityContext": { + "properties": { + "allowPrivilegeEscalation": { + "type": "boolean" + }, + "capabilities": { + "properties": { + "add": { + "items": { + "type": "string" + }, + "type": "array" + }, + "drop": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "privileged": { + "type": "boolean" + }, + "procMount": { + "type": "string" + }, + "readOnlyRootFilesystem": { + "type": "boolean" + }, + "runAsGroup": { + "type": "integer" + }, + "runAsNonRoot": { + "type": "boolean" + }, + "runAsUser": { + "type": "integer" + }, + "seLinuxOptions": { + "properties": { + "level": { + "type": "string" + }, + "role": { + "type": "string" + }, + "type": { + "type": "string" + }, + "user": { + "type": "string" + } + }, + "type": "object" + }, + "seccompProfile": { + "properties": { + "localhostProfile": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "type": "object" + }, + "windowsOptions": { + "properties": { + "gmsaCredentialSpec": { + "type": "string" + }, + "gmsaCredentialSpecName": { + "type": "string" + }, + "hostProcess": { + "type": "boolean" + }, + "runAsUserName": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "required": [ + "name", + "env" + ], + "type": "object" + }, + "type": "array" + }, + "securityContext": { + "properties": { + "fsGroup": { + "type": "integer" + }, + "fsGroupChangePolicy": { + "enum": [ + "OnRootMismatch", + "Always" + ], + "type": "string" + }, + "runAsGroup": { + "type": "integer" + }, + "runAsNonRoot": { + "type": "boolean" + }, + "runAsUser": { + "type": "integer" + }, + "seLinuxOptions": { + "properties": { + "level": { + "type": "string" + }, + "role": { + "type": "string" + }, + "type": { + "type": "string" + }, + "user": { + "type": "string" + } + }, + "type": "object" + }, + "seccompProfile": { + "properties": { + "localhostProfile": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "type": "object" + }, + "supplementalGroups": { + "items": { + "type": "integer" + }, + "type": "array" + }, + "sysctls": { + "items": { + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "windowsOptions": { + "properties": { + "gmsaCredentialSpec": { + "type": "string" + }, + "gmsaCredentialSpecName": { + "type": "string" + }, + "hostProcess": { + "type": "boolean" + }, + "runAsUserName": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "required": [ + "containers" + ], + "type": "object" + } + }, + "required": [ + "labels", + "annotations", + "spec" + ], + "type": "object" + }, + "resources": { + "properties": { + "claims": { + "items": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "limits": { + "additionalProperties": { + "oneOf": [ + { + "type": "integer" + }, + { + "pattern": "^[0-9]+(\\.[0-9]){0,1}(m|k|M|G|T|P|Ki|Mi|Gi|Ti|Pi)?$", + "type": "string" + } + ] + }, + "type": "object" + }, + "requests": { + "additionalProperties": { + "oneOf": [ + { + "type": "integer" + }, + { + "pattern": "^[0-9]+(\\.[0-9]){0,1}(m|k|M|G|T|P|Ki|Mi|Gi|Ti|Pi)?$", + "type": "string" + } + ] + }, + "type": "object" + } + }, + "type": "object" + }, + "securityContext": { + "properties": { + "allowPrivilegeEscalation": { + "type": "boolean" + }, + "capabilities": { + "properties": { + "add": { + "items": { + "type": "string" + }, + "type": "array" + }, + "drop": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "privileged": { + "type": "boolean" + }, + "procMount": { + "type": "string" + }, + "readOnlyRootFilesystem": { + "type": "boolean" + }, + "runAsGroup": { + "type": "integer" + }, + "runAsNonRoot": { + "type": "boolean" + }, + "runAsUser": { + "type": "integer" + }, + "seLinuxOptions": { + "properties": { + "level": { + "type": "string" + }, + "role": { + "type": "string" + }, + "type": { + "type": "string" + }, + "user": { + "type": "string" + } + }, + "type": "object" + }, + "seccompProfile": { + "properties": { + "localhostProfile": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "type": "object" + }, + "windowsOptions": { + "properties": { + "gmsaCredentialSpec": { + "type": "string" + }, + "gmsaCredentialSpecName": { + "type": "string" + }, + "hostProcess": { + "type": "boolean" + }, + "runAsUserName": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "post_upgrade_job": { + "properties": { + "affinity": { + "properties": { + "nodeAffinity": { + "properties": { + "preferredDuringSchedulingIgnoredDuringExecution": { + "items": { + "properties": { + "preference": { + "properties": { + "matchExpressions": { + "items": { + "properties": { + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + }, + "matchFields": { + "items": { + "properties": { + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, + "weight": { + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" + }, + "requiredDuringSchedulingIgnoredDuringExecution": { + "properties": { + "nodeSelectorTerms": { + "items": { + "properties": { + "matchExpressions": { + "items": { + "properties": { + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + }, + "matchFields": { + "items": { + "properties": { + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "podAffinity": { + "properties": { + "preferredDuringSchedulingIgnoredDuringExecution": { + "items": { + "properties": { + "podAffinityTerm": { + "properties": { + "labelSelector": { + "properties": { + "matchExpressions": { + "items": { + "properties": { + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + }, + "matchLabels": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + }, + "type": "object" + }, + "matchLabelKeys": { + "items": { + "type": "string" + }, + "type": "array" + }, + "mismatchLabelKeys": { + "items": { + "type": "string" + }, + "type": "array" + }, + "namespaceSelector": { + "properties": { + "matchExpressions": { + "items": { + "properties": { + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + }, + "matchLabels": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + }, + "type": "object" + }, + "namespaces": { + "items": { + "type": "string" + }, + "type": "array" + }, + "topologyKey": { + "type": "string" + } + }, + "type": "object" + }, + "weight": { + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" + }, + "requiredDuringSchedulingIgnoredDuringExecution": { + "items": { + "properties": { + "labelSelector": { + "properties": { + "matchExpressions": { + "items": { + "properties": { + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + }, + "matchLabels": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + }, + "type": "object" + }, + "matchLabelKeys": { + "items": { + "type": "string" + }, + "type": "array" + }, + "mismatchLabelKeys": { + "items": { + "type": "string" + }, + "type": "array" + }, + "namespaceSelector": { + "properties": { + "matchExpressions": { + "items": { + "properties": { + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + }, + "matchLabels": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + }, + "type": "object" + }, + "namespaces": { + "items": { + "type": "string" + }, + "type": "array" + }, + "topologyKey": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, + "podAntiAffinity": { + "properties": { + "preferredDuringSchedulingIgnoredDuringExecution": { + "items": { + "properties": { + "podAffinityTerm": { + "properties": { + "labelSelector": { + "properties": { + "matchExpressions": { + "items": { + "properties": { + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + }, + "matchLabels": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + }, + "type": "object" + }, + "matchLabelKeys": { + "items": { + "type": "string" + }, + "type": "array" + }, + "mismatchLabelKeys": { + "items": { + "type": "string" + }, + "type": "array" + }, + "namespaceSelector": { + "properties": { + "matchExpressions": { + "items": { + "properties": { + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + }, + "matchLabels": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + }, + "type": "object" + }, + "namespaces": { + "items": { + "type": "string" + }, + "type": "array" + }, + "topologyKey": { + "type": "string" + } + }, + "type": "object" + }, + "weight": { + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" + }, + "requiredDuringSchedulingIgnoredDuringExecution": { + "items": { + "properties": { + "labelSelector": { + "properties": { + "matchExpressions": { + "items": { + "properties": { + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + }, + "matchLabels": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + }, + "type": "object" + }, + "matchLabelKeys": { + "items": { + "type": "string" + }, + "type": "array" + }, + "mismatchLabelKeys": { + "items": { + "type": "string" + }, + "type": "array" + }, + "namespaceSelector": { + "properties": { + "matchExpressions": { + "items": { + "properties": { + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + }, + "matchLabels": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + }, + "type": "object" + }, + "namespaces": { + "items": { + "type": "string" + }, + "type": "array" + }, + "topologyKey": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "annotations": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "backoffLimit": { + "type": "integer" + }, + "enabled": { + "type": "boolean" + }, + "extraEnv": { + "items": { + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + }, + "valueFrom": { + "properties": { + "configMapKeyRef": { + "properties": { + "key": { + "type": "string" + }, + "name": { + "type": "string" + }, + "optional": { + "type": "boolean" + } + }, + "type": "object" + }, + "fieldRef": { + "properties": { + "apiVersion": { + "type": "string" + }, + "fieldPath": { + "type": "string" + } + }, + "type": "object" + }, + "resourceFieldRef": { + "properties": { + "containerName": { + "type": "string" + }, + "divisor": { + "oneOf": [ + { + "type": "integer" + }, + { + "pattern": "^[0-9]+(\\.[0-9]){0,1}(m|k|M|G|T|P|Ki|Mi|Gi|Ti|Pi)?$", + "type": "string" + } + ] + }, + "resource": { + "type": "string" + } + }, + "type": "object" + }, + "secretKeyRef": { + "properties": { + "key": { + "type": "string" + }, + "name": { + "type": "string" + }, + "optional": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "type": "array" + }, + "extraEnvFrom": { + "items": { + "properties": { + "configMapRef": { + "properties": { + "name": { + "type": "string" + }, + "optional": { + "type": "boolean" + } + }, + "type": "object" + }, + "prefix": { + "type": "string" + }, + "secretRef": { + "properties": { + "name": { + "type": "string" + }, + "optional": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "type": "array" + }, + "labels": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "podTemplate": { + "properties": { + "annotations": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "labels": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "spec": { + "properties": { + "containers": { + "items": { + "properties": { + "env": { + "items": { + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + }, + "valueFrom": { + "properties": { + "configMapKeyRef": { + "properties": { + "key": { + "type": "string" + }, + "name": { + "type": "string" + }, + "optional": { + "type": "boolean" + } + }, + "type": "object" + }, + "fieldRef": { + "properties": { + "apiVersion": { + "type": "string" + }, + "fieldPath": { + "type": "string" + } + }, + "type": "object" + }, + "resourceFieldRef": { + "properties": { + "containerName": { + "type": "string" + }, + "divisor": { + "oneOf": [ + { + "type": "integer" + }, + { + "pattern": "^[0-9]+(\\.[0-9]){0,1}(m|k|M|G|T|P|Ki|Mi|Gi|Ti|Pi)?$", + "type": "string" + } + ] + }, + "resource": { + "type": "string" + } + }, + "type": "object" + }, + "secretKeyRef": { + "properties": { + "key": { + "type": "string" + }, + "name": { + "type": "string" + }, + "optional": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "type": "array" + }, + "name": { + "enum": [ + "redpanda", + "post-install", + "post-upgrade" + ], + "type": "string" + }, + "securityContext": { + "properties": { + "allowPrivilegeEscalation": { + "type": "boolean" + }, + "capabilities": { + "properties": { + "add": { + "items": { + "type": "string" + }, + "type": "array" + }, + "drop": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "privileged": { + "type": "boolean" + }, + "procMount": { + "type": "string" + }, + "readOnlyRootFilesystem": { + "type": "boolean" + }, + "runAsGroup": { + "type": "integer" + }, + "runAsNonRoot": { + "type": "boolean" + }, + "runAsUser": { + "type": "integer" + }, + "seLinuxOptions": { + "properties": { + "level": { + "type": "string" + }, + "role": { + "type": "string" + }, + "type": { + "type": "string" + }, + "user": { + "type": "string" + } + }, + "type": "object" + }, + "seccompProfile": { + "properties": { + "localhostProfile": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "type": "object" + }, + "windowsOptions": { + "properties": { + "gmsaCredentialSpec": { + "type": "string" + }, + "gmsaCredentialSpecName": { + "type": "string" + }, + "hostProcess": { + "type": "boolean" + }, + "runAsUserName": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "required": [ + "name", + "env" + ], + "type": "object" + }, + "type": "array" + }, + "securityContext": { + "properties": { + "fsGroup": { + "type": "integer" + }, + "fsGroupChangePolicy": { + "enum": [ + "OnRootMismatch", + "Always" + ], + "type": "string" + }, + "runAsGroup": { + "type": "integer" + }, + "runAsNonRoot": { + "type": "boolean" + }, + "runAsUser": { + "type": "integer" + }, + "seLinuxOptions": { + "properties": { + "level": { + "type": "string" + }, + "role": { + "type": "string" + }, + "type": { + "type": "string" + }, + "user": { + "type": "string" + } + }, + "type": "object" + }, + "seccompProfile": { + "properties": { + "localhostProfile": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "type": "object" + }, + "supplementalGroups": { + "items": { + "type": "integer" + }, + "type": "array" + }, + "sysctls": { + "items": { + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "windowsOptions": { + "properties": { + "gmsaCredentialSpec": { + "type": "string" + }, + "gmsaCredentialSpecName": { + "type": "string" + }, + "hostProcess": { + "type": "boolean" + }, + "runAsUserName": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "required": [ + "containers" + ], + "type": "object" + } + }, + "required": [ + "labels", + "annotations", + "spec" + ], + "type": "object" + }, + "resources": { + "properties": { + "claims": { + "items": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "limits": { + "additionalProperties": { + "oneOf": [ + { + "type": "integer" + }, + { + "pattern": "^[0-9]+(\\.[0-9]){0,1}(m|k|M|G|T|P|Ki|Mi|Gi|Ti|Pi)?$", + "type": "string" + } + ] + }, + "type": "object" + }, + "requests": { + "additionalProperties": { + "oneOf": [ + { + "type": "integer" + }, + { + "pattern": "^[0-9]+(\\.[0-9]){0,1}(m|k|M|G|T|P|Ki|Mi|Gi|Ti|Pi)?$", + "type": "string" + } + ] + }, + "type": "object" + } + }, + "type": "object" + }, + "securityContext": { + "properties": { + "allowPrivilegeEscalation": { + "type": "boolean" + }, + "capabilities": { + "properties": { + "add": { + "items": { + "type": "string" + }, + "type": "array" + }, + "drop": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "privileged": { + "type": "boolean" + }, + "procMount": { + "type": "string" + }, + "readOnlyRootFilesystem": { + "type": "boolean" + }, + "runAsGroup": { + "type": "integer" + }, + "runAsNonRoot": { + "type": "boolean" + }, + "runAsUser": { + "type": "integer" + }, + "seLinuxOptions": { + "properties": { + "level": { + "type": "string" + }, + "role": { + "type": "string" + }, + "type": { + "type": "string" + }, + "user": { + "type": "string" + } + }, + "type": "object" + }, + "seccompProfile": { + "properties": { + "localhostProfile": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "type": "object" + }, + "windowsOptions": { + "properties": { + "gmsaCredentialSpec": { + "type": "string" + }, + "gmsaCredentialSpecName": { + "type": "string" + }, + "hostProcess": { + "type": "boolean" + }, + "runAsUserName": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "rackAwareness": { + "properties": { + "enabled": { + "type": "boolean" + }, + "nodeAnnotation": { + "type": "string" + } + }, + "required": [ + "enabled", + "nodeAnnotation" + ], + "type": "object" + }, + "rbac": { + "properties": { + "annotations": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "enabled": { + "type": "boolean" + } + }, + "required": [ + "enabled", + "annotations" + ], + "type": "object" + }, + "resources": { + "properties": { + "cpu": { + "properties": { + "cores": { + "oneOf": [ + { + "type": "integer" + }, + { + "pattern": "^[0-9]+(\\.[0-9]){0,1}(m|k|M|G|T|P|Ki|Mi|Gi|Ti|Pi)?$", + "type": "string" + } + ] + }, + "overprovisioned": { + "type": "boolean" + } + }, + "required": [ + "cores" + ], + "type": "object" + }, + "memory": { + "properties": { + "container": { + "properties": { + "max": { + "oneOf": [ + { + "type": "integer" + }, + { + "pattern": "^[0-9]+(\\.[0-9]){0,1}(m|k|M|G|T|P|Ki|Mi|Gi|Ti|Pi)?$", + "type": "string" + } + ] + }, + "min": { + "oneOf": [ + { + "type": "integer" + }, + { + "pattern": "^[0-9]+(\\.[0-9]){0,1}(m|k|M|G|T|P|Ki|Mi|Gi|Ti|Pi)?$", + "type": "string" + } + ] + } + }, + "required": [ + "max" + ], + "type": "object" + }, + "enable_memory_locking": { + "type": "boolean" + }, + "redpanda": { + "properties": { + "memory": { + "oneOf": [ + { + "type": "integer" + }, + { + "pattern": "^[0-9]+(\\.[0-9]){0,1}(m|k|M|G|T|P|Ki|Mi|Gi|Ti|Pi)?$", + "type": "string" + } + ] + }, + "reserveMemory": { + "oneOf": [ + { + "type": "integer" + }, + { + "pattern": "^[0-9]+(\\.[0-9]){0,1}(m|k|M|G|T|P|Ki|Mi|Gi|Ti|Pi)?$", + "type": "string" + } + ] + } + }, + "type": "object" + } + }, + "required": [ + "container" + ], + "type": "object" + } + }, + "required": [ + "cpu", + "memory" + ], + "type": "object" + }, + "service": { + "properties": { + "internal": { + "properties": { + "annotations": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + }, + "type": "object" + }, + "name": { + "type": "string" + } + }, + "type": "object" + }, + "serviceAccount": { + "properties": { + "annotations": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "create": { + "type": "boolean" + }, + "name": { + "type": "string" + } + }, + "required": [ + "create", + "name", + "annotations" + ], + "type": "object" + }, + "statefulset": { + "properties": { + "additionalRedpandaCmdFlags": { + "items": { + "type": "string" + }, + "type": "array" + }, + "additionalSelectorLabels": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "annotations": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "budget": { + "properties": { + "maxUnavailable": { + "type": "integer" + } + }, + "required": [ + "maxUnavailable" + ], + "type": "object" + }, + "extraVolumeMounts": { + "type": "string" + }, + "extraVolumes": { + "type": "string" + }, + "initContainerImage": { + "properties": { + "repository": { + "type": "string" + }, + "tag": { + "type": "string" + } + }, + "type": "object" + }, + "initContainers": { + "properties": { + "configurator": { + "properties": { + "extraVolumeMounts": { + "type": "string" + }, + "resources": { + "type": "object" + } + }, + "type": "object" + }, + "extraInitContainers": { + "type": "string" + }, + "fsValidator": { + "properties": { + "enabled": { + "type": "boolean" + }, + "expectedFS": { + "type": "string" + }, + "extraVolumeMounts": { + "type": "string" + }, + "resources": { + "type": "object" + } + }, + "type": "object" + }, + "setDataDirOwnership": { + "properties": { + "enabled": { + "type": "boolean" + }, + "extraVolumeMounts": { + "type": "string" + }, + "resources": { + "type": "object" + } + }, + "type": "object" + }, + "setTieredStorageCacheDirOwnership": { + "properties": { + "extraVolumeMounts": { + "type": "string" + }, + "resources": { + "type": "object" + } + }, + "type": "object" + }, + "tuning": { + "properties": { + "extraVolumeMounts": { + "type": "string" + }, + "resources": { + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "livenessProbe": { + "properties": { + "failureThreshold": { + "type": "integer" + }, + "initialDelaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + } + }, + "required": [ + "initialDelaySeconds", + "failureThreshold", + "periodSeconds" + ], + "type": "object" + }, + "nodeAffinity": { + "type": "object" + }, + "nodeSelector": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "podAffinity": { + "type": "object" + }, + "podAntiAffinity": { + "properties": { + "custom": { + "type": "object" + }, + "topologyKey": { + "type": "string" + }, + "type": { + "pattern": "^(hard|soft|custom)$", + "type": "string" + }, + "weight": { + "type": "integer" + } + }, + "required": [ + "topologyKey", + "type", + "weight" + ], + "type": "object" + }, + "podSecurityContext": { + "deprecated": true, + "properties": { + "allowPriviledgeEscalation": { + "type": "boolean" + }, + "allowPrivilegeEscalation": { + "type": "boolean" + }, + "fsGroup": { + "type": "integer" + }, + "fsGroupChangePolicy": { + "enum": [ + "OnRootMismatch", + "Always" + ], + "type": "string" + }, + "runAsGroup": { + "type": "integer" + }, + "runAsNonRoot": { + "type": "boolean" + }, + "runAsUser": { + "type": "integer" + } + }, + "type": "object" + }, + "podTemplate": { + "properties": { + "annotations": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "labels": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "spec": { + "properties": { + "containers": { + "items": { + "properties": { + "env": { + "items": { + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + }, + "valueFrom": { + "properties": { + "configMapKeyRef": { + "properties": { + "key": { + "type": "string" + }, + "name": { + "type": "string" + }, + "optional": { + "type": "boolean" + } + }, + "type": "object" + }, + "fieldRef": { + "properties": { + "apiVersion": { + "type": "string" + }, + "fieldPath": { + "type": "string" + } + }, + "type": "object" + }, + "resourceFieldRef": { + "properties": { + "containerName": { + "type": "string" + }, + "divisor": { + "oneOf": [ + { + "type": "integer" + }, + { + "pattern": "^[0-9]+(\\.[0-9]){0,1}(m|k|M|G|T|P|Ki|Mi|Gi|Ti|Pi)?$", + "type": "string" + } + ] + }, + "resource": { + "type": "string" + } + }, + "type": "object" + }, + "secretKeyRef": { + "properties": { + "key": { + "type": "string" + }, + "name": { + "type": "string" + }, + "optional": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "type": "array" + }, + "name": { + "enum": [ + "redpanda", + "post-install", + "post-upgrade" + ], + "type": "string" + }, + "securityContext": { + "properties": { + "allowPrivilegeEscalation": { + "type": "boolean" + }, + "capabilities": { + "properties": { + "add": { + "items": { + "type": "string" + }, + "type": "array" + }, + "drop": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "privileged": { + "type": "boolean" + }, + "procMount": { + "type": "string" + }, + "readOnlyRootFilesystem": { + "type": "boolean" + }, + "runAsGroup": { + "type": "integer" + }, + "runAsNonRoot": { + "type": "boolean" + }, + "runAsUser": { + "type": "integer" + }, + "seLinuxOptions": { + "properties": { + "level": { + "type": "string" + }, + "role": { + "type": "string" + }, + "type": { + "type": "string" + }, + "user": { + "type": "string" + } + }, + "type": "object" + }, + "seccompProfile": { + "properties": { + "localhostProfile": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "type": "object" + }, + "windowsOptions": { + "properties": { + "gmsaCredentialSpec": { + "type": "string" + }, + "gmsaCredentialSpecName": { + "type": "string" + }, + "hostProcess": { + "type": "boolean" + }, + "runAsUserName": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "required": [ + "name", + "env" + ], + "type": "object" + }, + "type": "array" + }, + "securityContext": { + "properties": { + "fsGroup": { + "type": "integer" + }, + "fsGroupChangePolicy": { + "enum": [ + "OnRootMismatch", + "Always" + ], + "type": "string" + }, + "runAsGroup": { + "type": "integer" + }, + "runAsNonRoot": { + "type": "boolean" + }, + "runAsUser": { + "type": "integer" + }, + "seLinuxOptions": { + "properties": { + "level": { + "type": "string" + }, + "role": { + "type": "string" + }, + "type": { + "type": "string" + }, + "user": { + "type": "string" + } + }, + "type": "object" + }, + "seccompProfile": { + "properties": { + "localhostProfile": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "type": "object" + }, + "supplementalGroups": { + "items": { + "type": "integer" + }, + "type": "array" + }, + "sysctls": { + "items": { + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "windowsOptions": { + "properties": { + "gmsaCredentialSpec": { + "type": "string" + }, + "gmsaCredentialSpecName": { + "type": "string" + }, + "hostProcess": { + "type": "boolean" + }, + "runAsUserName": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "required": [ + "containers" + ], + "type": "object" + } + }, + "required": [ + "labels", + "annotations", + "spec" + ], + "type": "object" + }, + "priorityClassName": { + "type": "string" + }, + "readinessProbe": { + "properties": { + "failureThreshold": { + "type": "integer" + }, + "initialDelaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "successThreshold": { + "type": "integer" + }, + "timeoutSeconds": { + "type": "integer" + } + }, + "required": [ + "initialDelaySeconds", + "failureThreshold", + "periodSeconds" + ], + "type": "object" + }, + "replicas": { + "type": "integer" + }, + "securityContext": { + "deprecated": true, + "properties": { + "allowPriviledgeEscalation": { + "type": "boolean" + }, + "allowPrivilegeEscalation": { + "type": "boolean" + }, + "fsGroup": { + "type": "integer" + }, + "fsGroupChangePolicy": { + "enum": [ + "OnRootMismatch", + "Always" + ], + "type": "string" + }, + "runAsGroup": { + "type": "integer" + }, + "runAsNonRoot": { + "type": "boolean" + }, + "runAsUser": { + "type": "integer" + } + }, + "type": "object" + }, + "sideCars": { + "properties": { + "configWatcher": { + "properties": { + "enabled": { + "type": "boolean" + }, + "extraVolumeMounts": { + "type": "string" + }, + "resources": { + "type": "object" + }, + "securityContext": { + "properties": { + "allowPrivilegeEscalation": { + "type": "boolean" + }, + "capabilities": { + "properties": { + "add": { + "items": { + "type": "string" + }, + "type": "array" + }, + "drop": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "privileged": { + "type": "boolean" + }, + "procMount": { + "type": "string" + }, + "readOnlyRootFilesystem": { + "type": "boolean" + }, + "runAsGroup": { + "type": "integer" + }, + "runAsNonRoot": { + "type": "boolean" + }, + "runAsUser": { + "type": "integer" + }, + "seLinuxOptions": { + "properties": { + "level": { + "type": "string" + }, + "role": { + "type": "string" + }, + "type": { + "type": "string" + }, + "user": { + "type": "string" + } + }, + "type": "object" + }, + "seccompProfile": { + "properties": { + "localhostProfile": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "type": "object" + }, + "windowsOptions": { + "properties": { + "gmsaCredentialSpec": { + "type": "string" + }, + "gmsaCredentialSpecName": { + "type": "string" + }, + "hostProcess": { + "type": "boolean" + }, + "runAsUserName": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "controllers": { + "properties": { + "createRBAC": { + "type": "boolean" + }, + "enabled": { + "type": "boolean" + }, + "healthProbeAddress": { + "type": "string" + }, + "image": { + "properties": { + "repository": { + "default": "docker.redpanda.com/redpandadata/redpanda-operator", + "type": "string" + }, + "tag": { + "default": "Chart.appVersion", + "pattern": "^v(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$|^$", + "type": "string" + } + }, + "required": [ + "tag", + "repository" + ], + "type": "object" + }, + "metricsAddress": { + "type": "string" + }, + "resources": true, + "run": { + "items": { + "type": "string" + }, + "type": "array" + }, + "securityContext": { + "properties": { + "allowPrivilegeEscalation": { + "type": "boolean" + }, + "capabilities": { + "properties": { + "add": { + "items": { + "type": "string" + }, + "type": "array" + }, + "drop": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "privileged": { + "type": "boolean" + }, + "procMount": { + "type": "string" + }, + "readOnlyRootFilesystem": { + "type": "boolean" + }, + "runAsGroup": { + "type": "integer" + }, + "runAsNonRoot": { + "type": "boolean" + }, + "runAsUser": { + "type": "integer" + }, + "seLinuxOptions": { + "properties": { + "level": { + "type": "string" + }, + "role": { + "type": "string" + }, + "type": { + "type": "string" + }, + "user": { + "type": "string" + } + }, + "type": "object" + }, + "seccompProfile": { + "properties": { + "localhostProfile": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "type": "object" + }, + "windowsOptions": { + "properties": { + "gmsaCredentialSpec": { + "type": "string" + }, + "gmsaCredentialSpecName": { + "type": "string" + }, + "hostProcess": { + "type": "boolean" + }, + "runAsUserName": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "startupProbe": { + "properties": { + "failureThreshold": { + "type": "integer" + }, + "initialDelaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + } + }, + "required": [ + "initialDelaySeconds", + "failureThreshold", + "periodSeconds" + ], + "type": "object" + }, + "terminationGracePeriodSeconds": { + "type": "integer" + }, + "tolerations": { + "items": { + "properties": { + "effect": { + "type": "string" + }, + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "tolerationSeconds": { + "type": "integer" + }, + "value": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "topologySpreadConstraints": { + "items": { + "properties": { + "maxSkew": { + "type": "integer" + }, + "topologyKey": { + "type": "string" + }, + "whenUnsatisfiable": { + "pattern": "^(ScheduleAnyway|DoNotSchedule)$", + "type": "string" + } + }, + "type": "object" + }, + "minItems": 1, + "type": "array" + }, + "updateStrategy": { + "properties": { + "type": { + "pattern": "^(RollingUpdate|OnDelete)$", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + } + }, + "required": [ + "additionalSelectorLabels", + "replicas", + "updateStrategy", + "podTemplate", + "budget", + "startupProbe", + "livenessProbe", + "readinessProbe", + "podAffinity", + "podAntiAffinity", + "nodeSelector", + "priorityClassName", + "topologySpreadConstraints", + "tolerations", + "securityContext", + "sideCars" + ], + "type": "object" + }, + "storage": { + "properties": { + "hostPath": { + "type": "string" + }, + "persistentVolume": { + "deprecated": true, + "properties": { + "annotations": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "labels": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "nameOverwrite": { + "type": "string" + }, + "size": { + "oneOf": [ + { + "type": "integer" + }, + { + "pattern": "^[0-9]+(\\.[0-9]){0,1}(m|k|M|G|T|P|Ki|Mi|Gi|Ti|Pi)?$", + "type": "string" + } + ] + }, + "storageClass": { + "type": "string" + } + }, + "required": [ + "annotations", + "enabled", + "labels", + "size", + "storageClass" + ], + "type": "object" + }, + "tiered": { + "properties": { + "config": { + "properties": { + "cloud_storage_access_key": { + "type": "string" + }, + "cloud_storage_api_endpoint": { + "type": "string" + }, + "cloud_storage_api_endpoint_port": { + "type": "integer" + }, + "cloud_storage_azure_adls_endpoint": { + "type": "string" + }, + "cloud_storage_azure_adls_port": { + "type": "integer" + }, + "cloud_storage_bucket": { + "type": "string" + }, + "cloud_storage_cache_check_interval": { + "type": "integer" + }, + "cloud_storage_cache_directory": { + "type": "string" + }, + "cloud_storage_cache_size": { + "oneOf": [ + { + "type": "integer" + }, + { + "pattern": "^[0-9]+(\\.[0-9]){0,1}(m|k|M|G|T|P|Ki|Mi|Gi|Ti|Pi)?$", + "type": "string" + } + ] + }, + "cloud_storage_credentials_source": { + "pattern": "^(config_file|aws_instance_metadata|sts|gcp_instance_metadata)$", + "type": "string" + }, + "cloud_storage_disable_tls": { + "type": "boolean" + }, + "cloud_storage_enable_remote_read": { + "type": "boolean" + }, + "cloud_storage_enable_remote_write": { + "type": "boolean" + }, + "cloud_storage_enabled": { + "type": "boolean" + }, + "cloud_storage_initial_backoff_ms": { + "type": "integer" + }, + "cloud_storage_manifest_upload_timeout_ms": { + "type": "integer" + }, + "cloud_storage_max_connection_idle_time_ms": { + "type": "integer" + }, + "cloud_storage_max_connections": { + "type": "integer" + }, + "cloud_storage_reconciliation_interval_ms": { + "type": "integer" + }, + "cloud_storage_region": { + "type": "string" + }, + "cloud_storage_secret_key": { + "type": "string" + }, + "cloud_storage_segment_max_upload_interval_sec": { + "type": "integer" + }, + "cloud_storage_segment_upload_timeout_ms": { + "type": "integer" + }, + "cloud_storage_trust_file": { + "type": "string" + }, + "cloud_storage_upload_ctrl_d_coeff": { + "type": "integer" + }, + "cloud_storage_upload_ctrl_max_shares": { + "type": "integer" + }, + "cloud_storage_upload_ctrl_min_shares": { + "type": "integer" + }, + "cloud_storage_upload_ctrl_p_coeff": { + "type": "integer" + }, + "cloud_storage_upload_ctrl_update_interval_ms": { + "type": "integer" + } + }, + "required": [ + "cloud_storage_enabled", + "cloud_storage_bucket", + "cloud_storage_region" + ], + "type": "object" + }, + "credentialsSecretRef": { + "properties": { + "accessKey": { + "properties": { + "configurationKey": { + "type": "string" + }, + "key": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "type": "object" + }, + "configurationKey": { + "deprecated": true, + "type": "string" + }, + "key": { + "deprecated": true, + "type": "string" + }, + "name": { + "deprecated": true, + "type": "string" + }, + "secretKey": { + "properties": { + "configurationKey": { + "type": "string" + }, + "key": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "hostPath": { + "type": "string" + }, + "mountType": { + "pattern": "^(none|hostPath|emptyDir|persistentVolume)$", + "type": "string" + }, + "persistentVolume": { + "properties": { + "annotations": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "labels": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "nameOverwrite": { + "type": "string" + }, + "size": { + "type": "string" + }, + "storageClass": { + "type": "string" + } + }, + "required": [ + "annotations", + "labels", + "storageClass" + ], + "type": "object" + } + }, + "required": [ + "mountType" + ], + "type": "object" + }, + "tieredConfig": { + "deprecated": true, + "properties": { + "cloud_storage_access_key": { + "type": "string" + }, + "cloud_storage_api_endpoint": { + "type": "string" + }, + "cloud_storage_api_endpoint_port": { + "type": "integer" + }, + "cloud_storage_azure_adls_endpoint": { + "type": "string" + }, + "cloud_storage_azure_adls_port": { + "type": "integer" + }, + "cloud_storage_bucket": { + "type": "string" + }, + "cloud_storage_cache_check_interval": { + "type": "integer" + }, + "cloud_storage_cache_directory": { + "type": "string" + }, + "cloud_storage_cache_size": { + "oneOf": [ + { + "type": "integer" + }, + { + "pattern": "^[0-9]+(\\.[0-9]){0,1}(m|k|M|G|T|P|Ki|Mi|Gi|Ti|Pi)?$", + "type": "string" + } + ] + }, + "cloud_storage_credentials_source": { + "pattern": "^(config_file|aws_instance_metadata|sts|gcp_instance_metadata)$", + "type": "string" + }, + "cloud_storage_disable_tls": { + "type": "boolean" + }, + "cloud_storage_enable_remote_read": { + "type": "boolean" + }, + "cloud_storage_enable_remote_write": { + "type": "boolean" + }, + "cloud_storage_enabled": { + "type": "boolean" + }, + "cloud_storage_initial_backoff_ms": { + "type": "integer" + }, + "cloud_storage_manifest_upload_timeout_ms": { + "type": "integer" + }, + "cloud_storage_max_connection_idle_time_ms": { + "type": "integer" + }, + "cloud_storage_max_connections": { + "type": "integer" + }, + "cloud_storage_reconciliation_interval_ms": { + "type": "integer" + }, + "cloud_storage_region": { + "type": "string" + }, + "cloud_storage_secret_key": { + "type": "string" + }, + "cloud_storage_segment_max_upload_interval_sec": { + "type": "integer" + }, + "cloud_storage_segment_upload_timeout_ms": { + "type": "integer" + }, + "cloud_storage_trust_file": { + "type": "string" + }, + "cloud_storage_upload_ctrl_d_coeff": { + "type": "integer" + }, + "cloud_storage_upload_ctrl_max_shares": { + "type": "integer" + }, + "cloud_storage_upload_ctrl_min_shares": { + "type": "integer" + }, + "cloud_storage_upload_ctrl_p_coeff": { + "type": "integer" + }, + "cloud_storage_upload_ctrl_update_interval_ms": { + "type": "integer" + } + }, + "type": "object" + }, + "tieredStorageHostPath": { + "deprecated": true, + "type": "string" + }, + "tieredStoragePersistentVolume": { + "deprecated": true, + "properties": { + "annotations": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "labels": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "storageClass": { + "type": "string" + } + }, + "required": [ + "annotations", + "enabled", + "labels", + "storageClass" + ], + "type": "object" + } + }, + "required": [ + "hostPath", + "tiered", + "persistentVolume" + ], + "type": "object" + }, + "tests": { + "properties": { + "enabled": { + "type": "boolean" + } + }, + "type": "object" + }, + "tls": { + "properties": { + "certs": { + "minProperties": 1, + "patternProperties": { + "^[A-Za-z_][A-Za-z0-9_]*$": { + "properties": { + "applyInternalDNSNames": { + "type": "boolean" + }, + "caEnabled": { + "type": "boolean" + }, + "clientSecretRef": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "duration": { + "pattern": ".*[smh]$", + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "issuerRef": { + "properties": { + "group": { + "type": "string" + }, + "kind": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "type": "object" + }, + "secretRef": { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "caEnabled" + ], + "type": "object" + } + }, + "type": "object" + }, + "enabled": { + "type": "boolean" + } + }, + "required": [ + "enabled", + "certs" + ], + "type": "object" + }, + "tolerations": { + "items": { + "properties": { + "effect": { + "type": "string" + }, + "key": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "tolerationSeconds": { + "type": "integer" + }, + "value": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "tuning": { + "properties": { + "ballast_file_path": { + "type": "string" + }, + "ballast_file_size": { + "type": "string" + }, + "tune_aio_events": { + "type": "boolean" + }, + "tune_ballast_file": { + "type": "boolean" + }, + "tune_clocksource": { + "type": "boolean" + }, + "well_known_io": { + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "affinity", + "image" + ], + "type": "object" +} diff --git a/charts/redpanda/redpanda/5.9.2/values.yaml b/charts/redpanda/redpanda/5.9.2/values.yaml new file mode 100644 index 0000000000..c1f8f10819 --- /dev/null +++ b/charts/redpanda/redpanda/5.9.2/values.yaml @@ -0,0 +1,1321 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You 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. + +# This file contains values for variables referenced from yaml files in the templates directory. +# +# For further information on Helm templating see the documentation at: +# https://helm.sh/docs/chart_template_guide/values_files/ + +# +# >>> This chart requires Helm version 3.6.0 or greater <<< +# + +# Common settings +# +# -- Override `redpanda.name` template. +nameOverride: "" +# -- Override `redpanda.fullname` template. +fullnameOverride: "" +# -- Default Kubernetes cluster domain. +clusterDomain: cluster.local +# -- Additional labels to add to all Kubernetes objects. +# For example, `my.k8s.service: redpanda`. +commonLabels: {} +# -- Node selection constraints for scheduling Pods, can override this for StatefulSets. +# For details, +# see the [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector). +nodeSelector: {} +# -- Affinity constraints for scheduling Pods, can override this for StatefulSets and Jobs. +# For details, +# see the [Kubernetes documentation](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity). +affinity: {} +# -- Taints to be tolerated by Pods, can override this for StatefulSets. +# For details, +# see the [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/). +tolerations: [] + +# -- Redpanda Docker image settings. +image: + # -- Docker repository from which to pull the Redpanda Docker image. + repository: docker.redpanda.com/redpandadata/redpanda + # -- The Redpanda version. + # See DockerHub for: + # [All stable versions](https://hub.docker.com/r/redpandadata/redpanda/tags) + # and [all unstable versions](https://hub.docker.com/r/redpandadata/redpanda-unstable/tags). + # @default -- `Chart.appVersion`. + tag: "" + # -- The imagePullPolicy. + # If `image.tag` is 'latest', the default is `Always`. + pullPolicy: IfNotPresent + +# -- Redpanda Service settings. +# service: +# -- set service.name to override the default service name +# name: redpanda +# -- internal Service +# internal: +# -- add annotations to the internal Service +# annotations: {} +# +# -- eg. for a bare metal install using external-dns +# annotations: +# "external-dns.alpha.kubernetes.io/hostname": redpanda.domain.dom +# "external-dns.alpha.kubernetes.io/endpoints-type": HostIP + +# -- Pull secrets may be used to provide credentials to image repositories +# See the [Kubernetes documentation](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/). +imagePullSecrets: [] + +# -- DEPRECATED Enterprise license key (optional). +# For details, +# see the [License documentation](https://docs.redpanda.com/docs/get-started/licenses/?platform=kubernetes#redpanda-enterprise-edition). +license_key: "" +# -- DEPRECATED Secret name and secret key where the license key is stored. +license_secret_ref: {} + # secret_name: my-secret + # secret_key: key-where-license-is-stored + +# -- Audit logging for a redpanda cluster, must have enabled sasl and have one kafka listener supporting sasl authentication +# for audit logging to work. Note this feature is only available for redpanda versions >= v23.3.0. +auditLogging: + # -- Enable or disable audit logging, for production clusters we suggest you enable, + # however, this will only work if you also enable sasl and a listener with sasl enabled. + enabled: false + # -- Kafka listener name, note that it must have `authenticationMethod` set to `sasl`. + # For external listeners, use the external listener name, such as `default`. + listener: internal + # -- Integer value defining the number of partitions used by a newly created audit topic. + partitions: 12 + # -- Event types that should be captured by audit logs, default is [`admin`, `authenticate`, `management`]. + enabledEventTypes: + # -- List of topics to exclude from auditing, default is null. + excludedTopics: + # -- List of principals to exclude from auditing, default is null. + excludedPrincipals: + # -- Defines the number of bytes (in bytes) allocated by the internal audit client for audit messages. + clientMaxBufferSize: 16777216 + # -- In ms, frequency in which per shard audit logs are batched to client for write to audit log. + queueDrainIntervalMs: 500 + # -- Defines the maximum amount of memory used (in bytes) by the audit buffer in each shard. + queueMaxBufferSizePerShard: 1048576 + # -- Defines the replication factor for a newly created audit log topic. This configuration applies + # only to the audit log topic and may be different from the cluster or other topic configurations. + # This cannot be altered for existing audit log topics. Setting this value is optional. If a value is not provided, + # Redpanda will use the `internal_topic_replication_factor cluster` config value. Default is `null` + replicationFactor: + +# -- Enterprise (optional) +# For details, +# see the [License documentation](https://docs.redpanda.com/docs/get-started/licenses/?platform=kubernetes#redpanda-enterprise-edition). +enterprise: + # -- license (optional). + license: "" + # -- Secret name and key where the license key is stored. + licenseSecretRef: {} + # name: my-secret + # key: key-where-license-is-stored + +# -- Rack Awareness settings. +# For details, +# see the [Rack Awareness documentation](https://docs.redpanda.com/docs/manage/kubernetes/kubernetes-rack-awareness/). +rackAwareness: + # -- When running in multiple racks or availability zones, use a Kubernetes Node + # annotation value as the Redpanda rack value. + # Enabling this requires running with a service account with "get" Node permissions. + # To have the Helm chart configure these permissions, + # set `serviceAccount.create=true` and `rbac.enabled=true`. + enabled: false + # -- The common well-known annotation to use as the rack ID. + # Override this only if you use a custom Node annotation. + nodeAnnotation: topology.kubernetes.io/zone + +# +# -- Redpanda Console settings. +# For a reference of configuration settings, +# see the [Redpanda Console documentation](https://docs.redpanda.com/docs/reference/console/config/). +console: + enabled: true + configmap: + create: false + secret: + create: false + deployment: + create: false + config: {} + +# +# -- Redpanda Managed Connectors settings +# For a reference of configuration settings, +# see the [Redpanda Connectors documentation](https://docs.redpanda.com/docs/deploy/deployment-option/cloud/managed-connectors/). +connectors: + enabled: false + deployment: + create: false + test: + create: false + +# -- Authentication settings. +# For details, +# see the [SASL documentation](https://docs.redpanda.com/docs/manage/kubernetes/security/sasl-kubernetes/). +auth: + sasl: + # -- Enable SASL authentication. + # If you enable SASL authentication, you must provide a Secret in `auth.sasl.secretRef`. + enabled: false + # -- The authentication mechanism to use for the superuser. Options are `SCRAM-SHA-256` and `SCRAM-SHA-512`. + mechanism: SCRAM-SHA-512 + # -- A Secret that contains your superuser credentials. + # For details, + # see the [SASL documentation](https://docs.redpanda.com/docs/manage/kubernetes/security/sasl-kubernetes/#use-secrets). + secretRef: "redpanda-users" + # -- Optional list of superusers. + # These superusers will be created in the Secret whose name is defined in `auth.sasl.secretRef`. + # If this list is empty, + # the Secret in `auth.sasl.secretRef` must already exist in the cluster before you deploy the chart. + # Uncomment the sample list if you wish to try adding sample sasl users or override to use your own. + users: [] + # - name: admin + # password: change-me + # mechanism: SCRAM-SHA-512 + +# -- TLS settings. +# For details, see the [TLS documentation](https://docs.redpanda.com/docs/manage/kubernetes/security/kubernetes-tls/). +tls: + # -- Enable TLS globally for all listeners. + # Each listener must include a Certificate name in its `.tls` object. + # To allow you to enable TLS for individual listeners, + # Certificates in `auth.tls.certs` are always loaded, even if `tls.enabled` is `false`. + # See `listeners..tls.enabled`. + enabled: true + # -- List all Certificates here, + # then you can reference a specific Certificate's name + # in each listener's `listeners..tls.cert` setting. + certs: + # -- This key is the Certificate name. + # To apply the Certificate to a specific listener, + # reference the Certificate's name in `listeners..tls.cert`. + default: + # -- To use a custom pre-installed Issuer, + # add its name and kind to the `issuerRef` object. + # issuerRef: + # name: redpanda-default-root-issuer + # kind: Issuer # Can be Issuer or ClusterIssuer + # -- To use a secret with custom tls files, + # secretRef: + # name: my-tls-secret + # -- Set the `caEnabled` flag to `true` only for Certificates + # that are not authenticated using public authorities. + caEnabled: true + # duration: 43800h + # if you wish to have Kubernetes internal dns names (IE the headless service of the redpanda StatefulSet) included in `dnsNames` of the certificate even, when supplying an issuer. + # applyInternalDNSNames: false + # -- Example external tls configuration + # uncomment and set the right key to the listeners that require them + # also enable the tls setting for those listeners. + external: + # -- To use a custom pre-installed Issuer, + # add its name and kind to the `issuerRef` object. + # issuerRef: + # name: redpanda-default-root-issuer + # kind: Issuer # Can be Issuer or ClusterIssuer + # -- To use a secret with custom tls files, + # secretRef: + # name: my-tls-secret + # -- Set the `caEnabled` flag to `true` only for Certificates + # that are not authenticated using public authorities. + caEnabled: true + # duration: 43800h + # if you wish to for apply internal dns names to the certificate even when supplying an issuer + # applyInternalDNSNames: false + +# -- External access settings. +# For details, +# see the [Networking and Connectivity documentation](https://docs.redpanda.com/docs/manage/kubernetes/networking/networking-and-connectivity/). +external: + # -- Service allows you to manage the creation of an external kubernetes service object + service: + # -- Enabled if set to false will not create the external service type + # You can still set your cluster with external access but not create the supporting service (NodePort/LoadBalander). + # Set this to false if you rather manage your own service. + enabled: true + # -- Enable external access for each Service. + # You can toggle external access for each listener in + # `listeners..external..enabled`. + enabled: true + # -- External access type. Only `NodePort` and `LoadBalancer` are supported. + # If undefined, then advertised listeners will be configured in Redpanda, + # but the helm chart will not create a Service. + # You must create a Service manually. + # Warning: If you use LoadBalancers, you will likely experience higher latency and increased packet loss. + # NodePort is recommended in cases where latency is a priority. + type: NodePort + # Optional source range for external access. Only applicable when external.type is LoadBalancer + # sourceRanges: [] + # -- Optional domain advertised to external clients + # If specified, then it will be appended to the `external.addresses` values as each broker's advertised address + # domain: local + # Optional list of addresses that the Redpanda brokers advertise. + # Provide one entry for each broker in order of StatefulSet replicas. + # The number of brokers is defined in statefulset.replicas. + # The values can be IP addresses or DNS names. + # If external.domain is set, the domain is appended to these values. + # There is an option to define a single external address for all brokers and leverage + # prefixTemplate as it will be calculated during initContainer execution. + # addresses: + # - redpanda-0 + # - redpanda-1 + # - redpanda-2 + # + # annotations: + # For example: + # cloud.google.com/load-balancer-type: "Internal" + # service.beta.kubernetes.io/aws-load-balancer-type: nlb + # If you enable externalDns, each LoadBalancer service instance + # will be annotated with external-dns hostname + # matching external.addresses + external.domain + # externalDns: + # enabled: true + # prefixTemplate: "" + +# -- Log-level settings. +logging: + # -- Log level + # Valid values (from least to most verbose) are: `warn`, `info`, `debug`, and `trace`. + logLevel: info + # -- Send usage statistics back to Redpanda Data. + # For details, + # see the [stats reporting documentation](https://docs.redpanda.com/docs/cluster-administration/monitoring/#stats-reporting). + usageStats: + # Enable the `rpk.enable_usage_stats` property. + enabled: true + # Your cluster ID (optional) + # clusterId: your-helm-cluster + +# -- Monitoring. +# This will create a ServiceMonitor that can be used by Prometheus-Operator or VictoriaMetrics-Operator to scrape the metrics. +monitoring: + enabled: false + scrapeInterval: 30s + labels: {} + # Enables http2 for scraping metrics for prometheus. Used when Istio's mTLS is enabled and using tlsConfig. + # enableHttp2: true + # tlsConfig: + # caFile: /etc/prom-certs/root-cert.pem + # certFile: /etc/prom-certs/cert-chain.pem + # insecureSkipVerify: true + # keyFile: /etc/prom-certs/key.pem + +# -- Pod resource management. +# This section simplifies resource allocation +# by providing a single location where resources are defined. +# Helm sets these resource values within the `statefulset.yaml` and `configmap.yaml` templates. +# +# The default values are for a development environment. +# Production-level values and other considerations are documented, +# where those values are different from the default. +# For details, +# see the [Pod resources documentation](https://docs.redpanda.com/docs/manage/kubernetes/manage-resources/). +resources: + # + # -- CPU resources. + # For details, + # see the [Pod resources documentation](https://docs.redpanda.com/docs/manage/kubernetes/manage-resources/#configure-cpu-resources). + cpu: + # -- Redpanda makes use of a thread per core model. + # For details, see this [blog](https://redpanda.com/blog/tpc-buffers). + # For this reason, Redpanda should only be given full cores. + # + # Note: You can increase cores, but decreasing cores is not currently supported. + # See the [GitHub issue](https://github.com/redpanda-data/redpanda/issues/350). + # + # This setting is equivalent to `--smp`, `resources.requests.cpu`, and `resources.limits.cpu`. + # For production, use `4` or greater. + # + # To maximize efficiency, use the `static` CPU manager policy by specifying an even integer for + # CPU resource requests and limits. This policy gives the Pods running Redpanda brokers + # access to exclusive CPUs on the node. See + # https://kubernetes.io/docs/tasks/administer-cluster/cpu-management-policies/#static-policy. + cores: 1 + # + # -- Overprovisioned means Redpanda won't assume it has all of the provisioned CPU. + # This should be true unless the container has CPU affinity. + # Equivalent to: `--idle-poll-time-us 0 --thread-affinity 0 --poll-aio 0` + # + # If the value of full cores in `resources.cpu.cores` is less than `1`, this + # setting is set to `true`. + # overprovisioned: false + # + # -- Memory resources + # For details, + # see the [Pod resources documentation](https://docs.redpanda.com/docs/manage/kubernetes/manage-resources/#configure-memory-resources). + memory: + # -- Enables memory locking. + # For production, set to `true`. + # enable_memory_locking: false + # + # It is recommended to have at least 2Gi of memory per core for the Redpanda binary. + # This memory is taken from the total memory given to each container. + # The Helm chart allocates 80% of the container's memory to Redpanda, leaving the rest for + # the Seastar subsystem (reserveMemory) and other container processes. + # So at least 2.5Gi per core is recommended in order to ensure Redpanda has a full 2Gi. + # + # These values affect `--memory` and `--reserve-memory` flags passed to Redpanda and the memory + # requests/limits in the StatefulSet. + # Valid suffixes: k, M, G, T, P, Ki, Mi, Gi, Ti, Pi + # To create `Guaranteed` Pod QoS for Redpanda brokers, provide both container max and min values for the container. + # For details, see + # https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/#create-a-pod-that-gets-assigned-a-qos-class-of-guaranteed + # * Every container in the Pod must have a memory limit and a memory request. + # * For every container in the Pod, the memory limit must equal the memory request. + # + container: + # Minimum memory count for each Redpanda broker. + # If omitted, the `min` value is equal to the `max` value (requested resources defaults to limits). + # This setting is equivalent to `resources.requests.memory`. + # For production, use 10Gi or greater. + # min: 2.5Gi + # + # -- Maximum memory count for each Redpanda broker. + # Equivalent to `resources.limits.memory`. + # For production, use `10Gi` or greater. + max: 2.5Gi + # + # This optional `redpanda` object allows you to specify the memory size for both the Redpanda + # process and the underlying reserved memory used by Seastar. + # This section is omitted by default, and memory sizes are calculated automatically + # based on container memory. + # Uncommenting this section and setting memory and reserveMemory values will disable + # automatic calculation. + # + # If you are setting the following values manually, keep in mind the following guidelines. + # Getting this wrong may lead to performance issues, instability, and loss of data: + # The amount of memory to allocate to a container is determined by the sum of three values: + # 1. Redpanda (at least 2Gi per core, ~80% of the container's total memory) + # 2. Seastar subsystem (200Mi * 0.2% of the container's total memory, 200Mi < x < 1Gi) + # 3. Other container processes (whatever small amount remains) + # redpanda: + # Memory for the Redpanda process. + # This must be lower than the container's memory (resources.memory.container.min if provided, otherwise + # resources.memory.container.max). + # Equivalent to --memory. + # For production, use 8Gi or greater. + # memory: 2Gi + # + # Memory reserved for the Seastar subsystem. + # Any value above 1Gi will provide diminishing performance benefits. + # Equivalent to --reserve-memory. + # For production, use 1Gi. + # reserveMemory: 200Mi + +# -- Persistence settings. +# For details, see the [storage documentation](https://docs.redpanda.com/docs/manage/kubernetes/configure-storage/). +storage: + # -- Absolute path on the host to store Redpanda's data. + # If unspecified, then an `emptyDir` volume is used. + # If specified but `persistentVolume.enabled` is true, `storage.hostPath` has no effect. + hostPath: "" + # -- If `persistentVolume.enabled` is true, a PersistentVolumeClaim is created and + # used to store Redpanda's data. Otherwise, `storage.hostPath` is used. + persistentVolume: + enabled: true + size: 20Gi + # -- To disable dynamic provisioning, set to `-`. + # If undefined or empty (default), then no storageClassName spec is set, + # and the default dynamic provisioner is 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: {} + # -- Option to change volume claim template name for tiered storage persistent volume + # if tiered.mountType is set to `persistentVolume` + nameOverwrite: "" + # + # Settings for the Tiered Storage cache. + # For details, + # see the [Tiered Storage documentation](https://docs.redpanda.com/docs/manage/kubernetes/tiered-storage/#caching). + + tiered: + # mountType can be one of: + # - none: does not mount a volume. Tiered storage will use the data directory. + # - hostPath: will allow you to chose a path on the Node the pod is running on + # - emptyDir: will mount a fresh empty directory every time the pod starts + # - persistentVolume: creates and mounts a PersistentVolumeClaim + mountType: emptyDir + + # For the maximum size of the disk cache, see `tieredConfig.cloud_storage_cache_size`. + # + # -- Absolute path on the host to store Redpanda's Tiered Storage cache. + hostPath: "" + # PersistentVolumeClaim to be created for the Tiered Storage cache and + # used to store data retrieved from cloud storage, such as S3). + persistentVolume: + # -- To disable dynamic provisioning, set to "-". + # If undefined or empty (default), then no storageClassName spec is set, + # and the default dynamic provisioner is 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: {} + + # credentialsSecretRef can be used to set `cloud_storage_secret_key` and/or `cloud_storage_access_key` from + # referenced Kubernetes Secret + credentialsSecretRef: + accessKey: + # https://docs.redpanda.com/current/reference/cluster-properties/#cloud_storage_access_key + configurationKey: cloud_storage_access_key + # name: + # key: + secretKey: + # https://docs.redpanda.com/current/reference/cluster-properties/#cloud_storage_secret_key + # or + # https://docs.redpanda.com/current/reference/cluster-properties/#cloud_storage_azure_shared_key + configurationKey: cloud_storage_secret_key + # name: + # key + # -- DEPRECATED `configurationKey`, `name` and `key`. Please use `accessKey` and `secretKey` + # configurationKey: cloud_storage_secret_key + # name: + # key: + # + # -- Tiered Storage settings + # Requires `enterprise.licenseKey` or `enterprised.licenseSecretRef` + # For details, + # see the [Tiered Storage documentation](https://docs.redpanda.com/docs/manage/kubernetes/tiered-storage/). + config: + # -- Global flag that enables Tiered Storage if a license key is provided. + # See the [property reference documentation](https://docs.redpanda.com/docs/reference/cluster-properties/#cloud_storage_enabled). + cloud_storage_enabled: false + # -- Cluster level default remote write configuration for new topics. + # See the [property reference documentation](https://docs.redpanda.com/docs/reference/tunable-properties/#cloud_storage_enable_remote_write). + cloud_storage_enable_remote_write: true + # -- Cluster level default remote read configuration for new topics. + # See the [property reference documentation](https://docs.redpanda.com/docs/reference/tunable-properties/#cloud_storage_enable_remote_read). + cloud_storage_enable_remote_read: true + # -- AWS or GCP region for where the bucket used for Tiered Storage is located (required for AWS and GCP). + # See the [property reference documentation](https://docs.redpanda.com/docs/reference/cluster-properties/#cloud_storage_region). + cloud_storage_region: "" + # -- AWS or GCP bucket name used for Tiered Storage (required for AWS and GCP). + # See the [property reference documentation](https://docs.redpanda.com/docs/reference/cluster-properties/#cloud_storage_bucket). + cloud_storage_bucket: "" + # -- AWS or GCP access key (required for AWS and GCP authentication with access keys). + # See the [property reference documentation](https://docs.redpanda.com/docs/reference/cluster-properties/#cloud_storage_access_key). + cloud_storage_access_key: "" + # -- AWS or GCP secret key (required for AWS and GCP authentication with access keys). + # See the [property reference documentation](https://docs.redpanda.com/docs/reference/cluster-properties/#cloud_storage_secret_key). + cloud_storage_secret_key: "" + # -- AWS or GCP API endpoint. + # * For AWS, this can be left blank as it is generated automatically using the bucket and region. For example, `.s3..amazonaws.com`. + # * For GCP, use `storage.googleapis.com` + # See the [property reference documentation](https://docs.redpanda.com/docs/reference/cluster-properties/#cloud_storage_api_endpoint). + cloud_storage_api_endpoint: "" + # -- Name of the Azure container to use with Tiered Storage (required for ABS/ADLS). + # Note that the container must belong to the account specified by `cloud_storage_azure_storage_account`. + # See the [property reference documentation](https://docs.redpanda.com/docs/reference/cluster-properties/#cloud_storage_azure_container). + cloud_storage_azure_container: null + # The managed identity ID to access the Azure storage account. + # See the [property reference documentation](https://docs.redpanda.com/docs/reference/cluster-properties/#cloud_storage_azure_managed_identity_id). + cloud_storage_azure_managed_identity_id: null + # -- Name of the Azure storage account to use with Tiered Storage (required for ABS/ADLS). + # See the [property reference documentation](https://docs.redpanda.com/docs/reference/cluster-properties/#cloud_storage_azure_storage_account). + cloud_storage_azure_storage_account: null + # -- Shared key to be used for Azure Shared Key authentication with the Azure storage account specified by `cloud_storage_azure_storage_account`. + # Note that the key should be base64 encoded. + # See the [property reference documentation](https://docs.redpanda.com/docs/reference/cluster-properties/#cloud_storage_azure_shared_key). + cloud_storage_azure_shared_key: null + # -- Azure ADLS endpoint and port (required for ABS hierarchical namespaces). + # Available starting from 23.2.8. + # cloud_storage_azure_adls_endpoint: "" + # cloud_storage_azure_adls_port: "" + # -- Source of credentials used to connect to cloud services (required for AWS and GCP authentication with IAM roles). + # * `config_file` + # * `aws_instance_metadata` + # * `sts` + # * `gcp_instance_metadata` + # * `azure_aks_oidc_federation` + # * `azure_vm_instance_metadata` + # See the [property reference documentation](https://docs.redpanda.com/docs/reference/cluster-properties/#cloud_storage_credentials_source). + cloud_storage_credentials_source: config_file + + # -- Maximum size of the disk cache used by Tiered Storage. + # Default is 20 GiB. + # See the [property reference documentation](https://docs.redpanda.com/docs/reference/cluster-properties/#cloud_storage_cache_size). + cloud_storage_cache_size: 5368709120 + # cloud_storage_cache_directory: "" + # cloud_storage_cache_check_interval: 30000 + # cloud_storage_initial_backoff_ms: 100 + # cloud_storage_max_connections: 20 + # cloud_storage_segment_upload_timeout_ms: 30000 + # cloud_storage_manifest_upload_timeout_ms: 10000 + # cloud_storage_max_connection_idle_time_ms: 5000 + # cloud_storage_idle_timeout_ms: 10000 + # cloud_storage_segment_max_upload_interval_sec: 1 + # cloud_storage_trust_file: "" + # cloud_storage_upload_ctrl_update_interval_ms: 60000 + # cloud_storage_upload_ctrl_p_coeff: -2 + # cloud_storage_upload_ctrl_d_coeff: 0 + # cloud_storage_upload_ctrl_min_shares: 100 + # cloud_storage_upload_ctrl_max_shares: 1000 + # DEPRECATED: cloud_storage_reconciliation_interval_ms: 10000 + # cloud_storage_disable_tls: false + # cloud_storage_api_endpoint_port: 443 + # cloud_storage_idle_threshold_rps: 1 + # cloud_storage_enable_segment_merging: true + # cloud_storage_segment_size_target: # The default segment size is controlled by log_segment_size + # cloud_storage_segment_size_min: # Default is 50% of log segment size + # storage.tieredStorageHostPath has been deprecated. Use storage.tiered.hostPath and configure storage.tiered.mountType instead. + # storage.tieredStoragePersistentVolume has been deprecated. Use storage.tiered.persistentVolume and configure storage.tiered.mountType instead. + # storage.tieredConfig has been deprecated. Use storage.tiered.config instead. + +post_install_job: + enabled: true + # Resource requests and limits for the post-install batch job + # resources: + # requests: + # cpu: 1 + # memory: 512Mi + # limits: + # cpu: 2 + # memory: 1024Mi + # labels: {} + # annotations: {} + affinity: {} + + podTemplate: + # -- Additional labels to apply to the Pods of this Job. + labels: {} + # -- Additional annotations to apply to the Pods of this Job. + annotations: {} + # -- A subset of Kubernetes' PodSpec type that will be merged into the + # final PodSpec. See [Merge Semantics](#merging-semantics) for details. + spec: + securityContext: {} + containers: + - name: post-install + securityContext: {} + env: [] + +post_upgrade_job: + enabled: true + # Resource requests and limits for the post-upgrade batch job + # resources: + # requests: + # cpu: 1 + # memory: 512Mi + # limits: + # cpu: 2 + # memory: 1024Mi + # labels: {} + # annotations: {} + # Additional environment variables for the Post Upgrade Job + # extraEnv: + # - name: AWS_SECRET_ACCESS_KEY + # valueFrom: + # secretKeyRef: + # name: my-secret + # key: redpanda-aws-secret-access-key + # Additional environment variables for the Post Upgrade Job mapped from Secret or ConfigMap + # extraEnvFrom: + # - secretRef: + # name: redpanda-aws-secrets + # DEPRECATED. Please use podTemplate.securityContext + # You can set the security context as nessesary for the post-upgrade job as follows + # securityContext: + # allowPrivilegeEscalation: false + # runAsNonRoot: true + affinity: {} + # When helm upgrade is performed the post-upgrade job is scheduled before Statefulset successfully finish + # its rollout. User can extend Job default backoff limit of `6`. + # backoffLimit: + + podTemplate: + # -- Additional labels to apply to the Pods of this Job. + labels: {} + # -- Additional annotations to apply to the Pods of this Job. + annotations: {} + # -- A subset of Kubernetes' PodSpec type that will be merged into the + # final PodSpec. See [Merge Semantics](#merging-semantics) for details. + spec: + securityContext: {} + containers: + - name: post-upgrade + securityContext: {} + env: [] + +statefulset: + # -- Number of Redpanda brokers (Redpanda Data recommends setting this to the number of worker nodes in the cluster) + replicas: 3 + updateStrategy: + type: RollingUpdate + budget: + maxUnavailable: 1 + # -- DEPRECATED Please use statefulset.podTemplate.annotations. + # Annotations are used only for `Statefulset.spec.template.metadata.annotations`. The StatefulSet does not have + # any dedicated annotation. + annotations: {} + # -- Additional labels to be added to statefulset label selector. + # For example, `my.k8s.service: redpanda`. + additionalSelectorLabels: {} + podTemplate: + # -- Additional labels to apply to the Pods of the StatefulSet. + labels: {} + # -- Additional annotations to apply to the Pods of the StatefulSet. + annotations: {} + # -- A subset of Kubernetes' PodSpec type that will be merged into the + # final PodSpec. See [Merge Semantics](#merging-semantics) for details. + spec: + securityContext: {} + containers: + - name: redpanda + securityContext: {} + env: [] + # -- Adjust the period for your probes to meet your needs. + # For details, + # see the [Kubernetes documentation](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes). + startupProbe: + initialDelaySeconds: 1 + failureThreshold: 120 + periodSeconds: 10 + livenessProbe: + initialDelaySeconds: 10 + failureThreshold: 3 + periodSeconds: 10 + readinessProbe: + initialDelaySeconds: 1 + failureThreshold: 3 + periodSeconds: 10 + successThreshold: 1 + # + # StatefulSet resources: + # Resources are set through the top-level resources section above. + # It is recommended to set resource values in that section rather than here, as this will guarantee + # memory is allocated across containers, Redpanda, and the Seastar subsystem correctly. + # This automatic memory allocation is in place because Repanda and the Seastar subsystem require flags + # at startup that set the amount of memory available to each process. + # Kubernetes (mainly statefulset), Redpanda, and Seastar memory values are tightly coupled. + # Adding a resource section here will be ignored. + # + # -- Inter-Pod Affinity rules for scheduling Pods of this StatefulSet. + # For details, + # see the [Kubernetes documentation](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. + # For details, + # see the [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#inter-pod-affinity-and-anti-affinity). + # You may either edit the default settings for anti-affinity rules, + # or specify new anti-affinity rules to use instead of the defaults. + podAntiAffinity: + # -- The topologyKey to be used. + # Can be used to spread across different nodes, AZs, regions etc. + topologyKey: kubernetes.io/hostname + # -- Valid anti-affinity types are `soft`, `hard`, or `custom`. + # Use `custom` if you want to supply your own anti-affinity rules in the `podAntiAffinity.custom` object. + type: hard + # -- Weight for `soft` anti-affinity rules. + # Does not apply to other anti-affinity types. + weight: 100 + # -- Change `podAntiAffinity.type` to `custom` and provide your own podAntiAffinity rules here. + custom: {} + # -- Node selection constraints for scheduling Pods of this StatefulSet. + # These constraints override the global `nodeSelector` value. + # For details, + # see the [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector). + nodeSelector: {} + # -- PriorityClassName given to Pods of this StatefulSet. + # For details, + # see the [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#priorityclass). + priorityClassName: "" + # -- Taints to be tolerated by Pods of this StatefulSet. + # These tolerations override the global tolerations value. + # For details, + # see the [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/). + tolerations: [] + # For details, + # see the [Kubernetes documentation](https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/). + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: ScheduleAnyway + # -- DEPRECATED: Prefer to use podTemplate.spec.securityContext or podTemplate.spec.containers[0].securityContext. + securityContext: + fsGroup: 101 + runAsUser: 101 + fsGroupChangePolicy: OnRootMismatch + sideCars: + configWatcher: + enabled: true + # -- To create `Guaranteed` Pods for Redpanda brokers, provide both requests and limits for CPU and memory. For details, see + # https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/#create-a-pod-that-gets-assigned-a-qos-class-of-guaranteed + # * Every container in the Pod must have a memory limit and a memory request. + # * For every container in the Pod, the memory limit must equal the memory request. + # * Every container in the Pod must have a CPU limit and a CPU request. + # * For every container in the Pod, the CPU limit must equal the CPU request. + # + # To maximize efficiency, use the `static` CPU manager policy by specifying an even integer for + # CPU resource requests and limits. This policy gives the Pods running Redpanda brokers + # access to exclusive CPUs on the node. For details, see + # https://kubernetes.io/docs/tasks/administer-cluster/cpu-management-policies/#static-policy + resources: {} + securityContext: {} + extraVolumeMounts: |- + # Configure extra controllers to run as sidecars inside the Pods running Redpanda brokers. + # Available controllers: + # - Decommission Controller: The Decommission Controller ensures smooth scaling down operations. + # This controller is responsible for monitoring changes in the number of StatefulSet replicas and orchestrating + # the decommissioning of brokers when necessary. It also sets the reclaim policy for the decommissioned + # broker's PersistentVolume to `Retain` and deletes the corresponding PersistentVolumeClaim. + # - Node-PVC Controller: The Node-PVC Controller handles the PVCs of deleted brokers. + # By setting the PV Retain policy to retain, it facilitates the rescheduling of brokers to new, healthy nodes when + # an existing node is removed. + controllers: + image: + tag: v2.1.10-23.2.18 + repository: docker.redpanda.com/redpandadata/redpanda-operator + # You must also enable RBAC, `rbac.enabled=true`, to deploy this sidecar + enabled: false + # -- To create `Guaranteed` Pods for Redpanda brokers, provide both requests and limits for CPU and memory. For details, see + # https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/#create-a-pod-that-gets-assigned-a-qos-class-of-guaranteed + # + # * Every container in the Pod must have a CPU limit and a CPU request. + # * For every container in the Pod, the CPU limit must equal the CPU request. + # * Every container in the Pod must have a CPU limit and a CPU request. + # * For every container in the Pod, the CPU limit must equal the CPU request. + # + # To maximize efficiency, use the `static` CPU manager policy by specifying an even integer for + # CPU resource requests and limits. This policy gives the Pods running Redpanda brokers + # access to exclusive CPUs on the node. For details, see + # https://kubernetes.io/docs/tasks/administer-cluster/cpu-management-policies/#static-policy + resources: {} + securityContext: {} + healthProbeAddress: ":8085" + metricsAddress: ":9082" + run: + - all + createRBAC: true + initContainers: + fsValidator: + enabled: false + expectedFS: xfs + # -- To create `Guaranteed` Pods for Redpanda brokers, provide both requests and limits for CPU and memory. For details, see + # https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/#create-a-pod-that-gets-assigned-a-qos-class-of-guaranteed + # * Every container in the Pod must have a CPU limit and a CPU request. + # * For every container in the Pod, the CPU limit must equal the CPU request. + resources: {} + extraVolumeMounts: |- + tuning: + # -- To create `Guaranteed` Pods for Redpanda brokers, provide both requests and limits for CPU and memory. For details, see + # https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/#create-a-pod-that-gets-assigned-a-qos-class-of-guaranteed + # * Every container in the Pod must have a CPU limit and a CPU request. + # * For every container in the Pod, the CPU limit must equal the CPU request. + resources: {} + extraVolumeMounts: |- + setDataDirOwnership: + # -- In environments where root is not allowed, you cannot change the ownership of files and directories. + # Enable `setDataDirOwnership` when using default minikube cluster configuration. + enabled: false + # -- To create `Guaranteed` Pods for Redpanda brokers, provide both requests and limits for CPU and memory. For details, see + # https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/#create-a-pod-that-gets-assigned-a-qos-class-of-guaranteed + # * Every container in the Pod must have a CPU limit and a CPU request. + # * For every container in the Pod, the CPU limit must equal the CPU request. + resources: {} + extraVolumeMounts: |- + setTieredStorageCacheDirOwnership: + # -- To create `Guaranteed` Pods for Redpanda brokers, provide both requests and limits for CPU and memory. For details, see + # https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/#create-a-pod-that-gets-assigned-a-qos-class-of-guaranteed + # * Every container in the Pod must have a CPU limit and a CPU request. + # * For every container in the Pod, the CPU limit must equal the CPU request. + resources: {} + extraVolumeMounts: |- + configurator: + # -- To create `Guaranteed` Pods for Redpanda brokers, provide both requests and limits for CPU and memory. For details, see + # https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/#create-a-pod-that-gets-assigned-a-qos-class-of-guaranteed + # * Every container in the Pod must have a CPU limit and a CPU request. + # * For every container in the Pod, the CPU limit must equal the CPU request. + resources: {} + extraVolumeMounts: |- + ## Additional init containers + extraInitContainers: |- +# - name: "test-init-container" +# image: "mintel/docker-alpine-bash-curl-jq:latest" +# command: [ "/bin/bash", "-c" ] +# args: +# - | +# set -xe +# echo "Hello World!" + initContainerImage: + repository: busybox + tag: latest + # -- Additional flags to pass to redpanda, + additionalRedpandaCmdFlags: [] +# - --unsafe-bypass-fsync + # -- Termination grace period in seconds is time required to execute preStop hook + # which puts particular Redpanda Pod (process/container) into maintenance mode. + # Before settle down on particular value please put Redpanda under load and perform + # rolling upgrade or rolling restart. That value needs to accommodate two processes: + # * preStop hook needs to put Redpanda into maintenance mode + # * after preStop hook Redpanda needs to handle gracefully SIGTERM signal + # + # Both processes are executed sequentially where preStop hook has hard deadline in the + # middle of terminationGracePeriodSeconds. + # + # REF: + # https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#hook-handler-execution + # https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-termination + terminationGracePeriodSeconds: 90 + ## Additional Volumes that you mount + extraVolumes: |- + ## Additional Volume mounts for redpanda container + extraVolumeMounts: |- + +# -- Service account management. +serviceAccount: + # -- Specifies whether a service account should be created. + create: false + # -- Annotations to add to the service account. + annotations: {} + # -- The name of the service account to use. + # If not set and `serviceAccount.create` is `true`, + # a name is generated using the `redpanda.fullname` template. + name: "" + +# -- Role Based Access Control. +rbac: + # -- Enable for features that need extra privileges. + # If you use the Redpanda Operator, + # you must deploy it with the `--set rbac.createRPKBundleCRs=true` flag + # to give it the required ClusterRoles. + enabled: false + # -- Annotations to add to the `rbac` resources. + annotations: {} + +# -- Redpanda tuning settings. +# Each is set to their default values in Redpanda. +tuning: + # -- Increase the maximum number of outstanding asynchronous IO operations if the + # current value is below a certain threshold. This allows Redpanda to make as many + # simultaneous IO requests as possible, increasing throughput. + # + # When this option is enabled, Helm creates a privileged container. If your security profile does not allow this, you can disable this container by setting `tune_aio_events` to `false`. + # For more details, see the [tuning documentation](https://docs.redpanda.com/docs/deploy/deployment-option/self-hosted/kubernetes/kubernetes-tune-workers/). + tune_aio_events: true + # + # Syncs NTP + # tune_clocksource: false + # + # Creates a "ballast" file so that, if a Redpanda node runs out of space, + # you can delete the ballast file to allow the node to resume operations and then + # delete a topic or records to reduce the space used by Redpanda. + # tune_ballast_file: false + # + # The path where the ballast file will be created. + # ballast_file_path: "/var/lib/redpanda/data/ballast" + # + # The ballast file size. + # ballast_file_size: "1GiB" + # + # (Optional) The vendor, VM type and storage device type that redpanda will run on, in + # the format ::. This hints to rpk which configuration values it + # should use for the redpanda IO scheduler. + # Some valid values are "gcp:c2-standard-16:nvme", "aws:i3.xlarge:default" + # well_known_io: "" + # + # The following tuning parameters must be false in container environments and will be ignored: + # tune_network + # tune_disk_scheduler + # tune_disk_nomerges + # tune_disk_irq + # tune_fstrim + # tune_cpu + # tune_swappiness + # tune_transparent_hugepages + # tune_coredump + + +# -- Listener settings. +# +# Override global settings configured above for individual +# listeners. +# For details, +# see the [listeners documentation](https://docs.redpanda.com/docs/manage/kubernetes/networking/configure-listeners/). +listeners: + # -- Admin API listener (only one). + admin: + # -- The port for both internal and external connections to the Admin API. + port: 9644 + # -- Optional instrumentation hint - https://kubernetes.io/docs/concepts/services-networking/service/#application-protocol + # appProtocol: + # -- Optional external access settings. + external: + # -- Name of the external listener. + default: + port: 9645 + # Override the global `external.enabled` for only this listener. + # enabled: true + # -- The port advertised to this listener's external clients. + # List one port if you want to use the same port for each broker (would be the case when using NodePort service). + # Otherwise, list the port you want to use for each broker in order of StatefulSet replicas. + # If undefined, `listeners.admin.port` is used. + tls: + # enabled: true + cert: external + advertisedPorts: + - 31644 + # -- Optional TLS section (required if global TLS is enabled) + tls: + # Optional flag to override the global TLS enabled flag. + # enabled: true + # -- Name of the Certificate used for TLS (must match a Certificate name that is registered in tls.certs). + cert: default + # -- If true, the truststore file for this listener is included in the ConfigMap. + requireClientAuth: false + # -- Kafka API listeners. + kafka: + # -- The port for internal client connections. + port: 9093 + # default is "sasl" + authenticationMethod: + tls: + # Optional flag to override the global TLS enabled flag. + # enabled: true + cert: default + requireClientAuth: false + external: + default: + # enabled: true + # -- The port used for external client connections. + port: 9094 + # prefixTemplate: "" + # -- If undefined, `listeners.kafka.external.default.port` is used. + advertisedPorts: + - 31092 + tls: + # enabled: true + cert: external + # default is "sasl" + authenticationMethod: + # -- RPC listener (this is never externally accessible). + rpc: + port: 33145 + tls: + # Optional flag to override the global TLS enabled flag. + # enabled: true + cert: default + requireClientAuth: false + # -- Schema registry listeners. + schemaRegistry: + enabled: true + port: 8081 + kafkaEndpoint: default + # default is "http_basic" + authenticationMethod: + tls: + # Optional flag to override the global TLS enabled flag. + # enabled: true + cert: default + requireClientAuth: false + external: + default: + # enabled: true + port: 8084 + advertisedPorts: + - 30081 + tls: + # enabled: true + cert: external + requireClientAuth: false + # default is "http_basic" + authenticationMethod: + # -- HTTP API listeners (aka PandaProxy). + http: + enabled: true + port: 8082 + kafkaEndpoint: default + # default is "http_basic" + authenticationMethod: + tls: + # Optional flag to override the global TLS enabled flag. + # enabled: true + cert: default + requireClientAuth: false + external: + default: + # enabled: true + port: 8083 + # prefixTemplate: "" + advertisedPorts: + - 30082 + tls: + # enabled: true + cert: external + requireClientAuth: false + # default is "http_basic" + authenticationMethod: + +# Expert Config +# Here be dragons! +# +# -- This section contains various settings supported by Redpanda that may not work +# correctly in a Kubernetes cluster. Changing these settings comes with some risk. +# +# Use these settings to customize various Redpanda configurations that are not covered in other sections. +# These values have no impact on the configuration or behavior of the Kubernetes objects deployed by Helm, +# and therefore should not be modified for the purpose of configuring those objects. +# Instead, these settings get passed directly to the Redpanda binary at startup. +# For descriptions of these properties, +# see the [configuration documentation](https://docs.redpanda.com/docs/cluster-administration/configuration/). +config: + rpk: {} + # additional_start_flags: # List of flags to pass to rpk, e.g., ` "--idle-poll-time-us=0"` + cluster: + default_topic_replications: 3 # Default replication factor for new topics + # There is logic in the chart that will set this to 1 if there are fewer than 3 statefulset.replicas + # auto_create_topics_enabled: true # Allow topic auto creation + # transaction_coordinator_replication: 1 # Replication factor for a transaction coordinator topic + # id_allocator_replication: 1 # Replication factor for an ID allocator topic + # default_topic_partitions: 1 # Default number of partitions per topic + # disable_metrics: false # Disable registering metrics + # enable_coproc: false # Enable coprocessing mode + # enable_idempotence: false # Enable idempotent producer + # enable_pid_file: true # Enable pid file; You probably don't want to change this + # enable_transactions: false # Enable transactions + # group_max_session_timeout_ms: 300s # The maximum allowed session timeout for registered consumers; Longer timeouts give consumers more time to process messages in between heartbeats at the cost of a longer time to detect failures; Default quota tracking window size in milliseconds + # group_min_session_timeout_ms: Optional # The minimum allowed session timeout for registered consumers; Shorter timeouts result in quicker failure detection at the cost of more frequent consumer heartbeating + # kafka_group_recovery_timeout_ms: 30000ms # Kafka group recovery timeout expressed in milliseconds + # kafka_qdc_enable: false # Enable kafka queue depth control + # kafka_qdc_max_latency_ms: 80ms # Max latency threshold for kafka queue depth control depth tracking + # log_cleanup_policy: deletion # Default topic cleanup policy + # log_compaction_interval_ms: 5min # How often do we trigger background compaction + # log_compression_type: producer # Default topic compression type + # log_message_timestamp_type: create_time # Default topic messages timestamp type + # retention_bytes: None # max bytes per partition on disk before triggering a compaction + # rm_sync_timeout_ms: 2000ms + # rm_violation_recovery_policy: crash # Describes how to recover from an invariant violation happened on the partition level + # target_quota_byte_rate: 2GB # Target quota byte rate in bytes per second + # tm_sync_timeout_ms: 2000ms # Time to wait state catch up before rejecting a request + # tm_violation_recovery_policy: crash # Describes how to recover from an invariant violation happened on the transaction coordinator level + # transactional_id_expiration_ms: 10080min # Producer ids are expired once this time has elapsed after the last write with the given producer ID + # -- Tunable cluster properties. + tunable: + # -- See the [property reference documentation](https://docs.redpanda.com/docs/reference/tunable-properties/#log_segment_size). + log_segment_size: 134217728 # 128 mb + # -- See the [property reference documentation](https://docs.redpanda.com/docs/reference/tunable-properties/#log_segment_size_min). + log_segment_size_min: 16777216 # 16 mb + # -- See the [property reference documentation](https://docs.redpanda.com/docs/reference/tunable-properties/#log_segment_size_max). + log_segment_size_max: 268435456 # 256 mb + # -- See the [property reference documentation](https://docs.redpanda.com/docs/reference/tunable-properties/#kafka_batch_max_bytes). + kafka_batch_max_bytes: 1048576 # 1 mb + # -- See the [property reference documentation](https://docs.redpanda.com/docs/reference/tunable-properties/#topic_partitions_per_shard). + topic_partitions_per_shard: 1000 + # -- See the [property reference documentation](https://docs.redpanda.com/docs/reference/tunable-properties/#compacted_log_segment_size). + compacted_log_segment_size: 67108864 # 64 mb + # -- See the [property reference documentation](https://docs.redpanda.com/docs/reference/tunable-properties/#max_compacted_log_segment_size). + max_compacted_log_segment_size: 536870912 # 512 mb + # -- See the [property reference documentation](https://docs.redpanda.com/docs/reference/cluster-properties/#kafka_connection_rate_limit). + kafka_connection_rate_limit: 1000 + # -- See the [property reference documentation](https://docs.redpanda.com/docs/reference/tunable-properties/#group_topic_partitions). + group_topic_partitions: 16 + # cloud_storage_enable_remote_read: true # cluster wide configuration for read from remote cloud storage + # cloud_storage_enable_remote_write: true # cluster wide configuration for writing to remote cloud storage + + # alter_topic_cfg_timeout_ms: 5s # Time to wait for entries replication in controller log when executing alter configuration request + # compacted_log_segment_size: 256MiB # How large in bytes should each compacted log segment be (default 256MiB) + # controller_backend_housekeeping_interval_ms: 1s # Interval between iterations of controller backend housekeeping loop + # coproc_max_batch_size: 32kb # Maximum amount of bytes to read from one topic read + # coproc_max_inflight_bytes: 10MB # Maximum amountt of inflight bytes when sending data to wasm engine + # coproc_max_ingest_bytes: 640kb # Maximum amount of data to hold from input logs in memory + # coproc_offset_flush_interval_ms: 300000ms # Interval for which all coprocessor offsets are flushed to disk + # create_topic_timeout_ms: 2000ms # Timeout (ms) to wait for new topic creation + # default_num_windows: 10 # Default number of quota tracking windows + # default_window_sec: 1000ms # Default quota tracking window size in milliseconds + # log_retention_ms: 6.048e+8 # delete segments older than this (default 1 week) + # disable_batch_cache: false # Disable batch cache in log manager + # fetch_reads_debounce_timeout: 1ms # Time to wait for next read in fetch request when requested min bytes wasn't reached + # fetch_session_eviction_timeout_ms: 60s # Minimum time before which unused session will get evicted from sessions; Maximum time after which inactive session will be deleted is two time given configuration valuecache + # group_initial_rebalance_delay: 300 # Extra delay (ms) added to rebalance phase to wait for new members + # group_new_member_join_timeout: 30000ms # Timeout for new member joins + # group_topic_partitions: 1 # Number of partitions in the internal group membership topic + # id_allocator_batch_size: 1000 # ID allocator allocates messages in batches (each batch is a one log record) and then serves requests from memory without touching the log until the batch is exhausted + # id_allocator_log_capacity: 100 # Capacity of the id_allocator log in number of messages; Once it reached id_allocator_stm should compact the log + # join_retry_timeout_ms: 5s # Time between cluster join retries in milliseconds + # kafka_qdc_idle_depth: 10 # Queue depth when idleness is detected in kafka queue depth control + # kafka_qdc_latency_alpha: 0.002 # Smoothing parameter for kafka queue depth control latency tracking + # kafka_qdc_max_depth: 100 # Maximum queue depth used in kafka queue depth control + # kafka_qdc_min_depth: 1 # Minimum queue depth used in kafka queue depth control + # kafka_qdc_window_count: 12 # Number of windows used in kafka queue depth control latency tracking + # kafka_qdc_window_size_ms: 1500ms # Window size for kafka queue depth control latency tracking + # kvstore_flush_interval: 10ms # Key-value store flush interval (ms) + # kvstore_max_segment_size: 16MB # Key-value maximum segment size (bytes) + # log_segment_size: 1GB # How large in bytes should each log segment be (default 1G) + # max_compacted_log_segment_size: 5GB # Max compacted segment size after consolidation + # max_kafka_throttle_delay_ms: 60000ms # Fail-safe maximum throttle delay on kafka requests + # metadata_dissemination_interval_ms: 3000ms # Interaval for metadata dissemination batching + # metadata_dissemination_retries: 10 # Number of attempts of looking up a topic's meta data like shard before failing a request + # metadata_dissemination_retry_delay_ms: 500ms # Delay before retry a topic lookup in a shard or other meta tables + # quota_manager_gc_sec: 30000ms # Quota manager GC frequency in milliseconds + # raft_learner_recovery_rate: 104857600 # Raft learner recovery rate in bytes per second + # raft_heartbeat_disconnect_failures: 3 # After how many failed heartbeats to forcibly close an unresponsive TCP connection. Set to 0 to disable force disconnection. + # raft_heartbeat_interval_ms: 150 # The interval in ms between raft leader heartbeats. + # raft_heartbeat_timeout_ms: 3000 # Raft heartbeat RPC timeout. + # raft_io_timeout_ms: 10000 # Raft I/O timeout. + # raft_max_concurrent_append_requests_per_follower: 16 # Maximum number of concurrent append entries requests sent by leader to one follower. + # raft_max_recovery_memory: 33554432 # Maximum memory that can be used for reads in the raft recovery process. + # raft_recovery_default_read_size: 524288 # Default size of read issued during raft follower recovery. + # raft_replicate_batch_window_size: 1048576 # Maximum size of requests cached for replication. + # raft_smp_max_non_local_requests: # Maximum number of x-core requests pending in Raft seastar::smp group. (for more details look at seastar::smp_service_group documentation). + # raft_timeout_now_timeout_ms: 1000 # Timeout for a timeout now request. + # raft_transfer_leader_recovery_timeout_ms: 1000 # Timeout waiting for follower recovery when transferring leadership. + # raft_election_timeout_ms: 1500ms # Election timeout expressed in milliseconds TBD - election_time_out + # readers_cache_eviction_timeout_ms: 30s # Duration after which inactive readers will be evicted from cache + # reclaim_growth_window: 3000ms # Length of time in which reclaim sizes grow + # reclaim_max_size: 4MB # Maximum batch cache reclaim size + # reclaim_min_size: 128KB # Minimum batch cache reclaim size + # reclaim_stable_window: 10000ms # Length of time above which growth is reset + # recovery_append_timeout_ms: 5s # Timeout for append entries requests issued while updating stale follower + # release_cache_on_segment_roll: false # Free cache when segments roll + # replicate_append_timeout_ms: 3s # Timeout for append entries requests issued while replicating entries + # segment_appender_flush_timeout_ms: 1ms # Maximum delay until buffered data is written + # wait_for_leader_timeout_ms: 5000ms # Timeout (ms) to wait for leadership in metadata cache + # -- Node (broker) properties. + # See the [property reference documentation](https://docs.redpanda.com/docs/reference/node-properties/). + node: + # -- Crash loop limit + # A limit on the number of consecutive times a broker can crash within one hour before its crash-tracking logic is reset. + # This limit prevents a broker from getting stuck in an infinite cycle of crashes. + # User can disable this crash loop limit check by the following action: + # + # * One hour elapses since the last crash + # * The node configuration file, redpanda.yaml, is updated via config.cluster or config.node or config.tunable objects + # * The startup_log file in the node’s data_directory is manually deleted + # + # Default to 5 + # REF: https://docs.redpanda.com/current/reference/node-properties/#crash_loop_limit + crash_loop_limit: 5 + # node_id: # Unique ID identifying a node in the cluster + # data_directory: # Place where redpanda will keep the data + # admin_api_doc_dir: /usr/share/redpanda/admin-api-doc # Admin API doc directory + # api_doc_dir: /usr/share/redpanda/proxy-api-doc # API doc directory + # coproc_supervisor_server: 127.0.0.1:43189 # IpAddress and port for supervisor service + # dashboard_dir: None # serve http dashboard on / url + # developer_mode: true # Skips most of the checks performed at startup + # recovery_mode_enabled: false # Sets recovery mode of a cluster + + # Reference schema registry client https://docs.redpanda.com/current/reference/node-configuration-sample/ + schema_registry_client: {} + # # Number of times to retry a request to a broker + # # Default: 5 + # retries: 5 + # + # # Delay (in milliseconds) for initial retry backoff + # # Default: 100ms + # retry_base_backoff_ms: 100 + # + # # Number of records to batch before sending to broker + # # Default: 1000 + # produce_batch_record_count: 1000 + # + # # Number of bytes to batch before sending to broker + # # Defautl 1MiB + # produce_batch_size_bytes: 1048576 + # + # # Delay (in milliseconds) to wait before sending batch + # # Default: 100ms + # produce_batch_delay_ms: 100 + # + # # Interval (in milliseconds) for consumer request timeout + # # Default: 100ms + # consumer_request_timeout_ms: 100 + # + # # Max bytes to fetch per request + # # Default: 1MiB + # consumer_request_max_bytes: 1048576 + # + # # Timeout (in milliseconds) for consumer session + # # Default: 10s + # consumer_session_timeout_ms: 10000 + # + # # Timeout (in milliseconds) for consumer rebalance + # # Default: 2s + # consumer_rebalance_timeout_ms: 2000 + # + # # Interval (in milliseconds) for consumer heartbeats + # # Default: 500ms + # consumer_heartbeat_interval_ms: 500 + + # Reference panda proxy client https://docs.redpanda.com/current/reference/node-configuration-sample/ + pandaproxy_client: {} + # # Number of times to retry a request to a broker + # # Default: 5 + # retries: 5 + # + # # Delay (in milliseconds) for initial retry backoff + # # Default: 100ms + # retry_base_backoff_ms: 100 + # + # # Number of records to batch before sending to broker + # # Default: 1000 + # produce_batch_record_count: 1000 + # + # # Number of bytes to batch before sending to broker + # # Defautl 1MiB + # produce_batch_size_bytes: 1048576 + # + # # Delay (in milliseconds) to wait before sending batch + # # Default: 100ms + # produce_batch_delay_ms: 100 + # + # # Interval (in milliseconds) for consumer request timeout + # # Default: 100ms + # consumer_request_timeout_ms: 100 + # + # # Max bytes to fetch per request + # # Default: 1MiB + # consumer_request_max_bytes: 1048576 + # + # # Timeout (in milliseconds) for consumer session + # # Default: 10s + # consumer_session_timeout_ms: 10000 + # + # # Timeout (in milliseconds) for consumer rebalance + # # Default: 2s + # consumer_rebalance_timeout_ms: 2000 + # + # # Interval (in milliseconds) for consumer heartbeats + # # Default: 500ms + # consumer_heartbeat_interval_ms: 500 + + # Invalid properties + # Any of these properties will be ignored. These otherwise valid properties are not allowed + # to be used in this section since they impact deploying Redpanda in Kubernetes. + # Make use of the above sections to modify these values instead (see comments below). + # admin: "127.0.0.1:9644" # Address and port of admin server: use listeners.admin + # admin_api_tls: validate_many # TLS configuration for admin HTTP server: use listeners.admin.tls + # advertised_kafka_api: None # Address of Kafka API published to the clients + # advertised_pandaproxy_api: None # Rest API address and port to publish to client + # advertised_rpc_api: None # Address of RPC endpoint published to other cluster members + # enable_admin_api: true # Enable the admin API + # enable_sasl: false # Enable SASL authentication for Kafka connections + # kafka_api: "127.0.0.1:9092" # Address and port of an interface to listen for Kafka API requests + # kafka_api_tls: None # TLS configuration for Kafka API endpoint + # pandaproxy_api: "0.0.0.0:8082" # Rest API listen address and port + # pandaproxy_api_tls: validate_many # TLS configuration for Pandaproxy api + # rpc_server: "127.0.0.1:33145" # IP address and port for RPC server + # rpc_server_tls: validate # TLS configuration for RPC server + # superusers: None # List of superuser usernames + +tests: + enabled: true diff --git a/index.yaml b/index.yaml index 5c1901ae2d..0968c0cc45 100644 --- a/index.yaml +++ b/index.yaml @@ -20446,6 +20446,31 @@ entries: - assets/clastix/kamaji-console-0.0.4.tgz version: 0.0.4 kong: + - annotations: + catalog.cattle.io/certified: partner + catalog.cattle.io/display-name: Kong Gateway + catalog.cattle.io/release-name: kong + apiVersion: v2 + appVersion: "3.6" + created: "2024-08-30T00:51:01.97835777Z" + dependencies: + - condition: postgresql.enabled + name: postgresql + repository: file://./charts/postgresql + version: 11.9.13 + description: The Cloud-Native Ingress and API-management + digest: d96bd5f8e5d914ae8552ae6cb7c667203e6bde1b587e9a70635b738dc29fdd32 + home: https://konghq.com/ + icon: file://assets/icons/kong.png + maintainers: + - email: team-k8s@konghq.com + name: team-k8s-bot + name: kong + sources: + - https://github.com/Kong/charts/tree/main/charts/kong + urls: + - assets/kong/kong-2.41.0.tgz + version: 2.41.0 - annotations: catalog.cattle.io/certified: partner catalog.cattle.io/display-name: Kong Gateway @@ -22260,6 +22285,38 @@ entries: catalog.cattle.io/kube-version: '>=1.22.0-0' catalog.cattle.io/release-name: linkerd-control-plane apiVersion: v2 + appVersion: edge-24.8.3 + created: "2024-08-30T00:51:02.41787433Z" + dependencies: + - name: partials + repository: file://./charts/partials + version: 0.1.0 + description: 'Linkerd gives you observability, reliability, and security for your + microservices — with no code change required. ' + digest: 53da2413df66c421f9ae6920f7d0084e368a53d3643173bfec0b2bdf5e6329b3 + home: https://linkerd.io + icon: file://assets/icons/linkerd-control-plane.png + keywords: + - service-mesh + kubeVersion: '>=1.22.0-0' + maintainers: + - email: cncf-linkerd-dev@lists.cncf.io + name: Linkerd authors + url: https://linkerd.io/ + name: linkerd-control-plane + sources: + - https://github.com/linkerd/linkerd2/ + type: application + urls: + - assets/linkerd/linkerd-control-plane-2024.8.3.tgz + version: 2024.8.3 + - annotations: + catalog.cattle.io/auto-install: linkerd-crds + catalog.cattle.io/certified: partner + catalog.cattle.io/display-name: Linkerd Control Plane + catalog.cattle.io/kube-version: '>=1.22.0-0' + catalog.cattle.io/release-name: linkerd-control-plane + apiVersion: v2 appVersion: edge-24.8.2 created: "2024-08-06T00:47:28.460808141Z" dependencies: @@ -22268,7 +22325,7 @@ entries: version: 0.1.0 description: 'Linkerd gives you observability, reliability, and security for your microservices — with no code change required. ' - digest: aaceb46fcf80aec619f10928f59b6280814875026753d67150d78096942d06c8 + digest: 51fad32307295b2f21fb6ce35289feb7ec00747546a6f441c59728ff89856386 home: https://linkerd.io icon: file://assets/icons/linkerd-control-plane.png keywords: @@ -23331,6 +23388,36 @@ entries: - assets/linkerd/linkerd-control-plane-1.12.5.tgz version: 1.12.5 linkerd-crds: + - annotations: + catalog.cattle.io/certified: partner + catalog.cattle.io/display-name: Linkerd CRDs + catalog.cattle.io/kube-version: '>=1.22.0-0' + catalog.cattle.io/release-name: linkerd-crds + apiVersion: v2 + created: "2024-08-30T00:51:02.494226658Z" + dependencies: + - name: partials + repository: file://./charts/partials + version: 0.1.0 + description: 'Linkerd gives you observability, reliability, and security for your + microservices — with no code change required. ' + digest: 4a74e800e283c245fea722193cb3c661fb861e30a3fdcbfdbcaaf1167c0fb5cc + home: https://linkerd.io + icon: file://assets/icons/linkerd-crds.png + keywords: + - service-mesh + kubeVersion: '>=1.22.0-0' + maintainers: + - email: cncf-linkerd-dev@lists.cncf.io + name: Linkerd authors + url: https://linkerd.io/ + name: linkerd-crds + sources: + - https://github.com/linkerd/linkerd2/ + type: application + urls: + - assets/linkerd/linkerd-crds-2024.8.3.tgz + version: 2024.8.3 - annotations: catalog.cattle.io/certified: partner catalog.cattle.io/display-name: Linkerd CRDs @@ -24689,6 +24776,54 @@ entries: - assets/loft/loft-3.2.0.tgz version: 3.2.0 microgateway: + - annotations: + artifacthub.io/category: security + artifacthub.io/license: MIT + artifacthub.io/links: | + - name: Airlock Microgateway Documentation + url: https://docs.airlock.com/microgateway/4.3/ + - name: Airlock Microgateway Labs + url: https://play.instruqt.com/airlock/invite/hyi9fy4b4jzc?icp_referrer=artifacthub.io + - name: Airlock Microgateway Forum + url: https://forum.airlock.com/ + catalog.cattle.io/certified: partner + catalog.cattle.io/display-name: Airlock Microgateway + catalog.cattle.io/kube-version: '>=1.25.0-0' + catalog.cattle.io/release-name: microgateway + charts.openshift.io/name: Airlock Microgateway + apiVersion: v2 + appVersion: 4.3.2 + created: "2024-08-30T00:50:59.329077791Z" + description: A Helm chart for deploying the Airlock Microgateway + digest: 6bda6fb8aa8e93db14d560587e6856a489a9133205fc4f5c2b29ec9ecf7f11e7 + home: https://www.airlock.com/en/microgateway + icon: file://assets/icons/microgateway.svg + keywords: + - WAF + - Web Application Firewall + - WAAP + - Web Application and API protection + - OWASP + - Airlock + - Microgateway + - Security + - Filtering + - DevSecOps + - shift left + - control plane + - Operator + kubeVersion: '>=1.25.0-0' + maintainers: + - email: support@airlock.com + name: Airlock + url: https://www.airlock.com/ + name: microgateway + sources: + - https://github.com/airlock/microgateway + type: application + urls: + - assets/airlock/microgateway-4.3.2.tgz + version: 4.3.2 - annotations: artifacthub.io/category: security artifacthub.io/license: MIT @@ -24834,6 +24969,53 @@ entries: - assets/airlock/microgateway-4.2.3.tgz version: 4.2.3 microgateway-cni: + - annotations: + artifacthub.io/category: security + artifacthub.io/license: MIT + artifacthub.io/links: | + - name: Airlock Microgateway Documentation + url: https://docs.airlock.com/microgateway/4.3/ + - name: Airlock Microgateway Labs + url: https://play.instruqt.com/airlock/invite/hyi9fy4b4jzc?icp_referrer=artifacthub.io + - name: Airlock Microgateway Forum + url: https://forum.airlock.com/ + catalog.cattle.io/certified: partner + catalog.cattle.io/display-name: Airlock Microgateway CNI + catalog.cattle.io/kube-version: '>=1.25.0-0' + catalog.cattle.io/release-name: microgateway-cni + charts.openshift.io/name: Airlock Microgateway CNI + apiVersion: v2 + appVersion: 4.3.2 + created: "2024-08-30T00:50:59.331502562Z" + description: A Helm chart for deploying the Airlock Microgateway CNI plugin + digest: 4806a5cceba0dd17e41699f27d04b73689adfa5e074c71e100231da8a947106b + home: https://www.airlock.com/en/microgateway + icon: file://assets/icons/microgateway-cni.svg + keywords: + - WAF + - Web Application Firewall + - WAAP + - Web Application and API protection + - OWASP + - Airlock + - Microgateway + - Security + - Filtering + - DevSecOps + - shift left + - CNI + kubeVersion: '>=1.25.0-0' + maintainers: + - email: support@airlock.com + name: Airlock + url: https://www.airlock.com/ + name: microgateway-cni + sources: + - https://github.com/airlock/microgateway + type: application + urls: + - assets/airlock/microgateway-cni-4.3.2.tgz + version: 4.3.2 - annotations: artifacthub.io/category: security artifacthub.io/license: MIT @@ -31395,6 +31577,50 @@ entries: - assets/quobyte/quobyte-cluster-0.1.8.tgz version: 0.1.8 redpanda: + - annotations: + artifacthub.io/images: | + - name: redpanda + image: docker.redpanda.com/redpandadata/redpanda:v24.2.3 + - name: busybox + image: busybox:latest + - name: mintel/docker-alpine-bash-curl-jq + image: mintel/docker-alpine-bash-curl-jq:latest + artifacthub.io/license: Apache-2.0 + artifacthub.io/links: | + - name: Documentation + url: https://docs.redpanda.com + - name: "Helm (>= 3.10.0)" + url: https://helm.sh/docs/intro/install/ + catalog.cattle.io/certified: partner + catalog.cattle.io/display-name: Redpanda + catalog.cattle.io/kube-version: '>=1.21-0' + catalog.cattle.io/release-name: redpanda + apiVersion: v2 + appVersion: v24.2.3 + created: "2024-08-30T00:51:03.840842012Z" + dependencies: + - condition: console.enabled + name: console + repository: file://./charts/console + version: '>=0.5 <1.0' + - condition: connectors.enabled + name: connectors + repository: file://./charts/connectors + version: '>=0.1.2 <1.0' + description: Redpanda is the real-time engine for modern apps. + digest: 53b504cc03601a9967dbfdbdb37cf9fb33f8d995c2f18220ac5cf463b2268866 + icon: file://assets/icons/redpanda.svg + kubeVersion: '>=1.21-0' + maintainers: + - name: redpanda-data + url: https://github.com/orgs/redpanda-data/people + name: redpanda + sources: + - https://github.com/redpanda-data/helm-charts + type: application + urls: + - assets/redpanda/redpanda-5.9.2.tgz + version: 5.9.2 - annotations: artifacthub.io/images: | - name: redpanda @@ -40898,4 +41124,4 @@ entries: urls: - assets/netfoundry/ziti-host-1.5.1.tgz version: 1.5.1 -generated: "2024-08-29T00:50:30.107476326Z" +generated: "2024-08-30T00:50:59.320900655Z"